diff --git a/.github/agents/architect.agent.md b/.github/agents/architect.agent.md index 6c1a5ef0..3dd7ada4 100644 --- a/.github/agents/architect.agent.md +++ b/.github/agents/architect.agent.md @@ -22,11 +22,6 @@ agents: - engineer - tester - release -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) - - Claude Opus 4.7 (copilot) user-invocable: true target: vscode --- @@ -110,16 +105,31 @@ Planner-coordinated mode (`@planner` invokes this role as a subagent): - Execute architect-stage scope only; do not invoke downstream roles unless explicitly asked. - End with a structured stage report using this schema: -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` ## assess current state @@ -207,4 +217,4 @@ that requires changes to upstream items, flag it and trigger a reverse handoff. - `@#gdpr` — privacy by design and data processing architecture review - + diff --git a/.github/agents/designer.agent.md b/.github/agents/designer.agent.md index 5314478b..22e46bf7 100644 --- a/.github/agents/designer.agent.md +++ b/.github/agents/designer.agent.md @@ -21,10 +21,6 @@ agents: - engineer - tester - release -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) user-invocable: true target: vscode --- @@ -123,16 +119,31 @@ Planner-coordinated mode (`@planner` invokes this role as a subagent): - Execute designer-stage scope only; do not invoke downstream roles unless explicitly asked. - End with a structured stage report using this schema: -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` ## assess current state @@ -220,4 +231,4 @@ that requires changes to upstream items, flag it and trigger a reverse handoff. - `@#openapi` — OpenAPI 3.1 spec writing and review - + diff --git a/.github/agents/engineer.agent.md b/.github/agents/engineer.agent.md index e766781a..661c16d7 100644 --- a/.github/agents/engineer.agent.md +++ b/.github/agents/engineer.agent.md @@ -21,10 +21,6 @@ agents: - engineer - tester - release -model: - - auto - - GPT-5.3-Codex (copilot) - - Claude Sonnet 4.6 (copilot) user-invocable: true target: vscode --- @@ -100,16 +96,31 @@ Planner-coordinated mode (`@planner` invokes this role as a subagent): - Execute engineer-stage scope only; do not invoke downstream roles unless explicitly asked. - End with a structured stage report using this schema: -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` ## parallel delegation @@ -221,4 +232,4 @@ that requires changes to upstream items, flag it and trigger a reverse handoff. - `@#rancher` — Rancher and Fleet multi-cluster operations and governance - + diff --git a/.github/agents/planner.agent.md b/.github/agents/planner.agent.md index 7289bccc..ddca4242 100644 --- a/.github/agents/planner.agent.md +++ b/.github/agents/planner.agent.md @@ -16,10 +16,6 @@ agents: - engineer - tester - release -model: - - auto - - GPT-5.3-Codex (copilot) - - Claude Sonnet 4.6 (copilot) user-invocable: true target: vscode --- @@ -99,6 +95,23 @@ Signs a request is a focused task (not a pipeline run): When in doubt, ask: "Does this need more than one role to complete?" If not, route directly. +## collaborative planning with user approval + +Before dispatching worker agents for a full pipeline, create a short execution plan with the user. + +1. Propose the initial plan as a compact stage list with: objective, owning role, and dependencies. +1. Ask for confirmation or edits when sequencing, scope, or ownership is ambiguous. +1. Apply user feedback and freeze the plan baseline for this run. +1. Start delegation only after the plan is accepted. + +During execution, the plan may change only when new facts appear. When replanning is needed: + +1. Explain what changed and why the current plan is no longer valid. +1. Propose the minimal plan delta. +1. Ask for approval before continuing with the updated plan. + +The planner owns planning and orchestration decisions. Worker agents execute scoped tasks from the accepted plan. + ## working principles - **Classify before orchestrating.** Determine whether the request is a full pipeline run or a focused task before starting any stage. Starting the pipeline for a focused task is overhead without benefit. @@ -126,6 +139,71 @@ For every ready stage or domain question: If a domain question surfaces mid-orchestration that no stage report has answered, route it to the relevant specialist instead of answering it yourself. +## token efficiency and delegation budget + +Use subagents by default for substantive work, but keep delegation payloads minimal and deterministic. + +1. Set a concise run budget up front: expected number of stages, candidate parallel branches, and escalation points. +1. Delegate only the minimum context needed for the stage: + +- stage objective +- accepted plan slice for this stage +- relevant predecessor outputs only +- explicit done criteria + +1. Prefer delta handoffs. If a stage reruns, pass only what changed since the last attempt. +1. Avoid duplicate calls. Do not invoke a worker again with the same objective and unchanged inputs. +1. Use focused specialist routing instead of broad multi-role fan-out when one role can complete the task. +1. Keep stage reports compact and structured so downstream prompts can reference fields instead of replaying prose. + +Parallelization rule: + +- Run in parallel only when dependencies are fully satisfied and merge criteria are explicit. +- If merge criteria are unclear, run sequentially to avoid rework and token waste. + +Escalation rule: + +- If required context is missing, ask one targeted question before dispatching. +- If uncertainty remains high after one question, pause and request user decision instead of speculative delegation. + +## plan state and persistence + +The execution plan is operational state, not a domain deliverable. + +Planner-run state schema (keep this shape stable across the run): + +```yaml +planner_run_state: + planner_run_id: + plan_version: + stage_status_map: + : ready|blocked|skipped|pending + blockers: + - +``` + +State update protocol: + +1. Initialize `planner_run_state` before first delegation. + +1. Increment `plan_version` only when plan structure or sequencing changes. + +1. Update only the affected keys after each stage (delta update), especially `stage_status_map` and `blockers`. + +1. Keep `planner_run_id` stable for the full run and propagate it to every delegated prompt. + +1. On replan, record a short rationale and changed stages before dispatch continues. + +1. Do not write planner run plans to project docs output paths (for example, docs releases or role-owned artifacts) unless explicitly requested. + +1. Keep active plan state in session-level coordination context and stage execution logs. + +1. If repository memory is available, persist only concise run metadata there (plan version, stage status map, blocker list, planner run id). + +1. Persist plan state updates as deltas, not full rewrites. + +1. Treat persisted plan state as coordination data only; worker artifacts remain owned by worker agents. + ## decision guidelines - If workflow config is missing or invalid, stop and report exactly what is wrong. @@ -176,16 +254,31 @@ Planner run correlation: When invoking a worker stage, require this structured stage report at the end: -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` ## success criteria @@ -231,4 +324,4 @@ that requires changes to upstream items, flag it and trigger a reverse handoff. - `@#analyse` - assess stage impact, skip rationale, and trade-offs - + diff --git a/.github/agents/product.agent.md b/.github/agents/product.agent.md index 16513d4f..3be3d1ea 100644 --- a/.github/agents/product.agent.md +++ b/.github/agents/product.agent.md @@ -21,11 +21,6 @@ agents: - engineer - tester - release -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) - - Claude Opus 4.7 (copilot) user-invocable: true target: vscode --- @@ -111,16 +106,31 @@ Planner-coordinated mode (`@planner` invokes this role as a subagent): - Execute product-stage scope only; do not invoke downstream roles unless explicitly asked. - End with a structured stage report using this schema: -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` ## how you work @@ -192,4 +202,4 @@ that requires changes to upstream items, flag it and trigger a reverse handoff. - `@#gh-issues` — create and manage GitHub Issues for requirements, tasks, and user stories - + diff --git a/.github/agents/release.agent.md b/.github/agents/release.agent.md index 72a03f3d..771a31d5 100644 --- a/.github/agents/release.agent.md +++ b/.github/agents/release.agent.md @@ -22,10 +22,6 @@ agents: - engineer - tester - release -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) user-invocable: true target: vscode --- @@ -107,16 +103,31 @@ Planner-coordinated mode (`@planner` invokes this role as a subagent): - Execute release-stage scope only. - End with a structured stage report using this schema: -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` ## how you work @@ -182,4 +193,4 @@ that requires changes to upstream items, flag it and trigger a reverse handoff. - `@#copilot-ops` — operate Copilot governance settings with audit-first change control - + diff --git a/.github/agents/tester.agent.md b/.github/agents/tester.agent.md index 0b28761a..4b4ac090 100644 --- a/.github/agents/tester.agent.md +++ b/.github/agents/tester.agent.md @@ -21,10 +21,6 @@ agents: - engineer - tester - release -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) user-invocable: true target: vscode --- @@ -108,16 +104,31 @@ Planner-coordinated mode (`@planner` invokes this role as a subagent): - Execute tester-stage scope only; do not invoke downstream roles unless explicitly asked. - End with a structured stage report using this schema: -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` ## assess current state @@ -207,4 +218,4 @@ that requires changes to upstream items, flag it and trigger a reverse handoff. - `@#rancher` — Rancher/Fleet configuration and multi-cluster governance review - + diff --git a/.github/instructions/git.instructions.md b/.github/instructions/git.instructions.md index c0549cd8..3a7f2967 100644 --- a/.github/instructions/git.instructions.md +++ b/.github/instructions/git.instructions.md @@ -3,36 +3,36 @@ name: git description: 'Git and release hygiene conventions. Use when creating commits, branches, or release-related changes.' applyTo: '**/*' --- -Use these Git and release hygiene conventions in this project. +Use these Git and release hygiene conventions. ## Branch naming 1. Use `type/short-description` branch names. -1. Keep branch names lowercase and use hyphens to separate words. -1. Use one of these allowed branch types when branch validation is enabled: +1. Keep names lowercase and hyphenated. +1. Use one of these branch types when validation is enabled: `feature`, `bugfix`, `hotfix`, `release`, `chore`, `feat`, `fix`, `docs`, `refactor`, `perf`, `test`, `ci`, `build`, `style`, `opt`, `patch`, `dependabot`. ## Commit messages 1. Use Conventional Commits: `type(optional-scope)!: short summary`. -1. Keep commit subjects clear, imperative, and within repository limits. -1. Keep the commit subject at 100 characters or fewer when commit policy CI enforces this limit. -1. Include `!` or a `BREAKING CHANGE:` footer when behavior changes are breaking. -1. Keep commit type and scope aligned with repository policy. +1. Keep subjects clear, imperative, and within repository limits. +1. Keep commit subjects at 100 characters or fewer when policy CI enforces that limit. +1. Add `!` or a `BREAKING CHANGE:` footer for breaking behavior. +1. Match type and scope to repository policy. ## SemVer alignment -1. Treat commit messages as release inputs when the repository uses semantic version automation. -1. Ensure major, minor, and patch intent is reflected in the commit type and breaking markers. +1. Treat commit messages as release inputs when semantic version automation is in use. +1. Reflect major, minor, and patch intent in the commit type and breaking markers. 1. Do not merge release-impacting changes with ambiguous commit messages. ## Security and credentials 1. Never ask users to paste passphrases, tokens, API keys, or private keys into chat. -1. Never echo or log secrets from terminal prompts, command output, or environment variables. +1. Never echo or log secrets from prompts, command output, or environment variables. 1. Never place credentials in commit messages, source files, workflow files, or documentation. -1. Prefer existing secure authentication flows (for example SSH agent, OS keychain, `gh auth`). +1. Prefer existing secure auth flows such as SSH agent, OS keychain, or `gh auth`. ## Safe Git operations @@ -41,4 +41,4 @@ Use these Git and release hygiene conventions in this project. 1. Prefer local verification before pushing release-impacting changes. - + diff --git a/.github/instructions/helm.instructions.md b/.github/instructions/helm.instructions.md index b2f596a4..d1ee8aed 100644 --- a/.github/instructions/helm.instructions.md +++ b/.github/instructions/helm.instructions.md @@ -3,7 +3,7 @@ name: helm description: 'Helm chart conventions. Use when writing or reviewing Helm charts, templates, and values files.' applyTo: '**/charts/**/*.{yaml,yml,tpl}' --- -Use these Helm conventions in this project. +Use these Helm conventions. ## Chart structure @@ -13,10 +13,10 @@ Use these Helm conventions in this project. ## Templating quality -1. Quote string values where ambiguity may cause rendering/type errors. -1. Guard optional blocks with conditionals to avoid emitting invalid YAML. +1. Quote string values where ambiguity may cause rendering or type errors. +1. Guard optional blocks with conditionals to avoid invalid YAML. 1. Keep names and labels deterministic via helper templates. -1. Avoid embedding large opaque blobs in templates; externalize where possible. +1. Avoid embedding large opaque blobs; externalize where possible. ## Values and secrets @@ -39,10 +39,10 @@ Use these Helm conventions in this project. ## References -> Always use the official documentation for the exact Helm and Kubernetes versions in use - chart schema, flags, and behavior evolve between releases. +> Always use the official documentation for the exact Helm and Kubernetes versions in use; chart schema, flags, and behavior evolve between releases. - [Helm docs](https://helm.sh/docs/) - [Helm chart best practices](https://helm.sh/docs/chart_best_practices/) - + diff --git a/.github/instructions/java.instructions.md b/.github/instructions/java.instructions.md index 4ecbb781..1cd287f3 100644 --- a/.github/instructions/java.instructions.md +++ b/.github/instructions/java.instructions.md @@ -3,13 +3,13 @@ name: java description: 'Java coding conventions for projects. Use when writing or reviewing Java source files, tests, and build configuration.' applyTo: '**/*.java' --- -Use these Java conventions in this project. +Use these Java conventions. ## Design and readability -1. Prefer explicit, domain-meaningful names over abbreviations; follow standard Java naming conventions. -1. Keep methods focused; split methods that mix parsing, I/O, and business rules. -1. Prefer immutable objects; make fields `final` by default and expose mutation only where required. +1. Prefer explicit, domain-meaningful names over abbreviations. +1. Keep methods focused. +1. Prefer immutable objects; make fields `final` by default. 1. Prefer straightforward control flow over clever one-liners. ## Types and APIs @@ -17,13 +17,13 @@ Use these Java conventions in this project. 1. Keep public APIs minimal and stable; mark implementation details `package-private` or `private`. 1. Program to interfaces, not implementations, for dependencies that may change. 1. Use records for simple value types where the Java version supports them. -1. Prefer `Optional` as a return type for values that may be absent; do not use it for fields or parameters. +1. Prefer `Optional` as a return type for absent values; do not use it for fields or parameters. ## Null safety 1. Annotate method parameters and return types with `@NonNull` or `@Nullable` where nullability is meaningful. 1. Never return `null` from a public method that could return `Optional` instead. -1. Fail fast on unexpected nulls at system boundaries using explicit precondition checks. +1. Fail fast on unexpected nulls at system boundaries. ## Exception handling @@ -56,4 +56,4 @@ Use these Java conventions in this project. 1. Do not suppress static analysis warnings without a documented, task-specific reason. - + diff --git a/.github/instructions/k8s.instructions.md b/.github/instructions/k8s.instructions.md index 8317d189..7e4d950d 100644 --- a/.github/instructions/k8s.instructions.md +++ b/.github/instructions/k8s.instructions.md @@ -3,7 +3,7 @@ name: k8s description: 'Kubernetes manifest conventions. Use when writing or reviewing Kubernetes workload and service manifests.' applyTo: '**/{k8s,kubernetes,manifests}/**/*.{yaml,yml}' --- -Use these Kubernetes conventions in this project. +Use these Kubernetes conventions. ## API and versioning @@ -14,7 +14,7 @@ Use these Kubernetes conventions in this project. ## Workload safety 1. Set CPU and memory `requests` and `limits` for every container. -1. Define both readiness and liveness probes for long-running services. +1. Define readiness and liveness probes for long-running services. 1. Avoid mutable image tags (`:latest`); use pinned tags or immutable digests. 1. Set rollout strategy explicitly for Deployments handling production traffic. @@ -35,7 +35,7 @@ Use these Kubernetes conventions in this project. 1. Use PodDisruptionBudgets for critical workloads. 1. Configure `terminationGracePeriodSeconds` and preStop hooks where graceful shutdown is required. -1. Add resource annotations/labels needed by observability and runtime policies. +1. Add resource annotations or labels needed by observability and runtime policies. ## Validation @@ -45,10 +45,10 @@ Use these Kubernetes conventions in this project. ## References -> Always use the official documentation for the exact Kubernetes version in use - API versions and defaults change between releases. +> Always use the official documentation for the exact Kubernetes version in use; API versions and defaults change between releases. - [Kubernetes docs](https://kubernetes.io/docs/) - [Kubernetes API reference](https://kubernetes.io/docs/reference/kubernetes-api/) - + diff --git a/.github/instructions/markdown.instructions.md b/.github/instructions/markdown.instructions.md index 09674dbc..19ba8c5f 100644 --- a/.github/instructions/markdown.instructions.md +++ b/.github/instructions/markdown.instructions.md @@ -3,52 +3,52 @@ name: markdown description: 'Markdown authoring conventions for documentation, README files, ADRs, and other hand-authored prose. Use when writing or reviewing any Markdown file.' applyTo: '**/*.md' --- -Use these Markdown conventions in this project. +Use these Markdown conventions. ## Structure and headings -1. Keep heading levels sequential — do not skip levels (e.g. from `##` to `####`). +1. Keep heading levels sequential. 1. Prefer flat heading structures; rarely go deeper than `####`. 1. Keep headings short and descriptive. ## Prose and tone -1. Write in clear, direct language — prefer active voice over passive voice. -1. Keep sentences short; split complex ideas across multiple sentences rather than commas and semicolons. -1. Be consistent with terminology throughout the file; introduce a term once and reuse it. +1. Write in clear, direct language with active voice. +1. Keep sentences short. +1. Be consistent with terminology throughout the file. 1. Avoid filler phrases such as "please note", "it is important to", and "simply". ## Lists and tables -1. Use numbered lists for ordered steps; use unordered lists for non-ordered items. -1. Keep list items parallel in grammar and structure. -1. Prefer a table over nested unordered lists when presenting structured comparisons. -1. Keep table columns to what is necessary; remove columns with no meaningful content. +1. Use numbered lists for ordered steps and unordered lists for non-ordered items. +1. Keep list items parallel. +1. Prefer tables over nested lists for structured comparisons. +1. Keep tables lean. ## Code blocks and inline code -1. Specify a language identifier on fenced code blocks where a language can be determined. +1. Specify a language identifier on fenced code blocks when possible. 1. Use inline code for file names, paths, commands, identifiers, and literal values. 1. Do not put prose in a code block; reserve code blocks for commands, source code, and literal output. ## Links and references -1. Use descriptive link text — avoid bare URLs and text like "click here" or "this link". +1. Use descriptive link text. 1. Prefer relative links for documents within the same repository. -1. Verify that section anchors match actual heading text before committing. +1. Verify that section anchors match actual heading text. ## Diagrams -1. Use Mermaid for process, flow, interaction, lifecycle, and decision diagrams when the target environment renders it (GitHub, VS Code, compatible docs tools). -1. Fall back to ASCII or plain-text descriptions when Mermaid rendering cannot be guaranteed (e.g. PyPI, email, plain-text viewers). -1. Use ASCII or text trees for directory layouts and file hierarchies regardless of environment. +1. Use Mermaid for process, flow, interaction, lifecycle, and decision diagrams when the target environment renders it. +1. Fall back to ASCII or plain text when Mermaid cannot be guaranteed. +1. Use ASCII or text trees for directory layouts and file hierarchies. 1. Do not embed a diagram where a simple sentence or table communicates the same information. ## Maintenance -1. Update documentation in the same change as the behavior or interface it describes. -1. Remove outdated content rather than leaving it with a "TODO: update" comment. -1. Keep examples accurate and runnable — a broken example is worse than no example. +1. Update documentation with the behavior or interface it describes. +1. Remove outdated content rather than leaving a TODO. +1. Keep examples accurate and runnable. - + diff --git a/.github/instructions/python.instructions.md b/.github/instructions/python.instructions.md index 273e75bf..8f1086d9 100644 --- a/.github/instructions/python.instructions.md +++ b/.github/instructions/python.instructions.md @@ -3,26 +3,26 @@ name: python description: 'Python coding conventions for projects. Use when writing or reviewing Python modules, tests, CLI code, and package internals.' applyTo: '**/*.py' --- -Use these Python conventions in this project. +Use these Python conventions. ## Design and readability 1. Prefer explicit, domain-meaningful names over abbreviations. -1. Keep functions focused; split functions that mix parsing, I/O, and business rules. -1. Prefer straightforward control flow over clever one-liners. -1. Raise precise exceptions with actionable error messages. +1. Keep functions focused. +1. Prefer straightforward control flow. +1. Raise precise exceptions with actionable messages. ## Typing and APIs 1. Add type hints to public functions, methods, and module-level constants. -1. Keep public interfaces stable and backward compatible unless the task explicitly allows breaking changes. -1. Use dataclasses or TypedDict for structured data instead of untyped dicts when shape is known. +1. Keep public interfaces stable and backward compatible unless breaking changes are explicitly allowed. +1. Use dataclasses or TypedDict for structured data. ## Imports and dependencies 1. Group imports as standard library, third-party, and local modules. 1. Keep imports minimal and remove unused imports. -1. Avoid adding runtime dependencies unless there is a clear benefit over stdlib or existing project dependencies. +1. Avoid adding runtime dependencies unless there is a clear benefit over stdlib or existing dependencies. ## Testing and verification @@ -42,4 +42,4 @@ Use these Python conventions in this project. 1. Do not silence lint/type errors unless there is a documented, task-specific reason. - + diff --git a/.github/instructions/rancher.instructions.md b/.github/instructions/rancher.instructions.md index 74645675..2858173c 100644 --- a/.github/instructions/rancher.instructions.md +++ b/.github/instructions/rancher.instructions.md @@ -3,13 +3,13 @@ name: rancher description: 'Rancher and Fleet conventions. Use when writing or reviewing Rancher/Fleet configuration files and cluster governance manifests.' applyTo: '**/{rancher,fleet}/**/*.{yaml,yml}' --- -Use these Rancher conventions in this project. +Use these Rancher conventions. ## Scope and environment 1. Keep environment and cluster targeting explicit; avoid wildcard targeting for production bundles. 1. Separate dev, staging, and production policies and rollout paths. -1. Document expected project/namespace scope for each config set. +1. Document expected project and namespace scope for each config set. ## Fleet and GitOps hygiene @@ -28,20 +28,20 @@ Use these Rancher conventions in this project. 1. Do not hardcode credentials or tokens in Rancher/Fleet config files. 1. Reference secrets from approved secret management paths. -1. Keep auditability for cluster/project configuration changes. +1. Keep auditability for cluster and project configuration changes. ## Operations -1. Validate target clusters/projects before applying any change. +1. Validate target clusters and projects before applying any change. 1. Include rollback guidance for application and bundle updates. 1. Treat drift and failed bundle rollout as operational incidents with follow-up remediation. ## References -> Always use the official documentation for the exact Rancher and Fleet versions in use - features and defaults vary between releases. +> Always use the official documentation for the exact Rancher and Fleet versions in use; features and defaults vary between releases. - [Rancher docs](https://ranchermanager.docs.rancher.com/) - [Fleet docs](https://fleet.rancher.io/) - + diff --git a/.github/instructions/security.instructions.md b/.github/instructions/security.instructions.md index 0bf57f53..a6fba560 100644 --- a/.github/instructions/security.instructions.md +++ b/.github/instructions/security.instructions.md @@ -3,43 +3,43 @@ name: security description: 'Security policy for all code, configuration, and infrastructure. Use when writing or reviewing any code, configuration, or workflow file.' applyTo: '**/*' --- -Apply these security policies in this project. +Use these security policies. ## Secrets and credentials -1. Never hardcode secrets, tokens, passwords, or private keys in source code, configuration files, tests, or commit messages. -1. Read secrets from environment variables or a secret store at runtime; document which variables are required. -1. Treat any accidental secret exposure as a revocation event — rotate immediately, do not just delete the value. +1. Never hardcode secrets, tokens, passwords, or private keys in source code, config files, tests, or commit messages. +1. Read secrets from environment variables or a secret store at runtime; document required variables. +1. Treat accidental exposure as a revocation event; rotate immediately. ## Input and trust boundaries 1. Validate and sanitize all input that crosses a trust boundary: HTTP requests, CLI arguments, environment variables, files, and inter-service messages. -1. Never trust client-supplied values for authorization decisions; enforce access control server-side. -1. Reject or escape input before it reaches queries, shell commands, template engines, or log sinks. +1. Never trust client-supplied values for authorization decisions. +1. Reject or escape input before it reaches queries, shell commands, template engines, or logs. ## Authentication and authorization -1. Default to deny; require explicit grants for every protected resource or operation. -1. Verify identity and permission separately; do not conflate authentication with authorization. -1. Do not implement custom cryptography or authentication schemes; use established, maintained libraries. +1. Default to deny; require explicit grants for protected resources or operations. +1. Verify identity and permission separately. +1. Use established, maintained libraries; do not implement custom cryptography or auth schemes. ## Dependencies and supply chain 1. Pin dependency versions in manifests; do not use unbounded version ranges in production code. -1. Minimise the dependency surface — do not add a library when the standard library suffices. -1. Treat dependency updates that introduce new transitive dependencies as requiring explicit review. +1. Minimise the dependency surface. +1. Treat updates that add new transitive dependencies as requiring explicit review. ## Error handling and observability 1. Never expose internal stack traces, system paths, or configuration details to external callers. 1. Do not log sensitive data: passwords, tokens, PII, or session identifiers. -1. Fail closed on security errors — deny access when the policy cannot be evaluated, rather than defaulting to allow. +1. Fail closed on security errors. ## Destructive and privileged operations -1. Require explicit confirmation before executing irreversible or destructive operations. -1. Apply least privilege: request only the permissions a component actually needs. -1. Isolate privileged logic; keep it minimal, auditable, and separate from business logic. +1. Require explicit confirmation before irreversible or destructive operations. +1. Apply least privilege. +1. Keep privileged logic minimal, auditable, and separate from business logic. - + diff --git a/.github/instructions/terraform.instructions.md b/.github/instructions/terraform.instructions.md index c355a8ae..2cbf6ef7 100644 --- a/.github/instructions/terraform.instructions.md +++ b/.github/instructions/terraform.instructions.md @@ -3,37 +3,37 @@ name: terraform description: 'Terraform coding conventions for projects. Use when writing or reviewing Terraform modules, root configurations, variable files, and state configuration.' applyTo: '**/*.tf' --- -Use these Terraform conventions in this project. +Use these Terraform conventions. ## Structure and file layout -1. Split configuration into `main.tf`, `variables.tf`, `outputs.tf`, `providers.tf`, `versions.tf`, and `locals.tf` — do not put everything in one file. -1. Keep one module per directory; avoid multi-purpose root modules. -1. Place reusable logic in `modules//` with its own `variables.tf` and `outputs.tf`. +1. Split config into `main.tf`, `variables.tf`, `outputs.tf`, `providers.tf`, `versions.tf`, and `locals.tf`. +1. Keep one module per directory. +1. Put reusable logic in `modules//` with its own `variables.tf` and `outputs.tf`. ## Versioning and pinning -1. Pin the Terraform binary version with `required_version = "~> X.Y"` in a `versions.tf` file. -1. Pin every provider with `version = "~> X.Y"` in `required_providers` — never use unbounded ranges in production. +1. Pin the Terraform version with `required_version = "~> X.Y"` in `versions.tf`. +1. Pin each provider with `version = "~> X.Y"` in `required_providers`; never use unbounded ranges in production. 1. Commit `.terraform.lock.hcl` to source control. -1. Pin external module sources to a specific git ref or registry semver tag — never `?ref=main`. +1. Pin external module sources to a specific git ref or registry semver tag; never `?ref=main`. ## State management -1. Use a remote backend with encryption and state locking for all non-local work. +1. Use a remote backend with encryption and locking for all non-local work. 1. Enable versioning on the S3 state bucket. -1. Never store secrets in state outputs — mark sensitive outputs with `sensitive = true`. +1. Never expose secrets via outputs; mark sensitive outputs with `sensitive = true`. ## Variables and outputs -1. Add `type`, `description`, and a sensible `default` to every variable. -1. Add validation blocks for constrained variables (`AllowedValues` equivalents). -1. Mark secret variables with `sensitive = true` — never hardcode them in `.tf` files or committed `.tfvars`. +1. Add `type`, `description`, and a sensible `default` for every variable. +1. Add validation blocks for constrained variables. +1. Mark secret variables with `sensitive = true`; never hardcode them in `.tf` files or committed `.tfvars`. 1. Add `description` to every output; mark secret outputs `sensitive = true`. ## Naming and tagging -1. Use `locals` to construct name prefixes and centralise tag maps. +1. Use `locals` to build name prefixes and centralise tag maps. 1. Name physical resources with `"${local.name_prefix}-"` to ensure cross-stack uniqueness. 1. Apply a common tag map (`local.common_tags`) to every taggable resource; include at minimum `Environment` and `ManagedBy = "terraform"`. @@ -41,23 +41,23 @@ Use these Terraform conventions in this project. 1. Block public access on all S3 buckets unless intentionally public; document the exception. 1. Enable `storage_encrypted = true` and `deletion_protection = true` on all RDS instances. -1. Restrict security group rules — avoid `0.0.0.0/0` on management ports; add a comment when HTTPS/443 is open. -1. Apply least-privilege IAM policies — no `*` actions on `*` resources. +1. Restrict security group rules; avoid `0.0.0.0/0` on management ports and add a comment when HTTPS/443 is open. +1. Apply least-privilege IAM policies; no `*` actions on `*` resources. 1. Enable KMS key rotation (`enable_key_rotation = true`). ## Tooling 1. Run `terraform fmt -check -recursive` in CI and auto-format locally. 1. Run `terraform validate` before every plan. -1. Run `tfsec` or `checkov` on all changes; fix HIGH and CRITICAL findings before merging. +1. Run `tfsec` or `checkov` on all changes; fix HIGH/CRITICAL findings before merging. ## References -> Always use the official documentation for the provider and Terraform version in use — resource arguments and defaults change between provider releases. +> Use official docs for the provider and Terraform version in use; resource arguments and defaults change between releases. - [Terraform documentation](https://developer.hashicorp.com/terraform/docs) - [Terraform provider registry](https://registry.terraform.io/) - [tfsec](https://aquasecurity.github.io/tfsec/) · [checkov](https://www.checkov.io/) - + diff --git a/.github/instructions/terragrunt.instructions.md b/.github/instructions/terragrunt.instructions.md index 302f3e72..021a2bc2 100644 --- a/.github/instructions/terragrunt.instructions.md +++ b/.github/instructions/terragrunt.instructions.md @@ -3,40 +3,40 @@ name: terragrunt description: 'Terragrunt coding conventions for projects. Use when writing or reviewing Terragrunt HCL configurations, root configs, unit modules, and dependency blocks.' applyTo: '**/terragrunt.hcl' --- -Use these Terragrunt conventions in this project. +Use these Terragrunt conventions. ## Structure and hierarchy 1. Maintain a strict directory hierarchy that maps to deployment topology: `infra///terragrunt.hcl`. -1. Keep one root `terragrunt.hcl` at the repository root or top-level `infra/` directory; inherit it in all units via `include "root" { path = find_in_parent_folders() }`. -1. Use `account.hcl` files at the account/environment level for account ID, region, and environment name — read them with `read_terragrunt_config(find_in_parent_folders("account.hcl"))`. +1. Keep one root `terragrunt.hcl` at repo root or top-level `infra/`; inherit it in all units via `include "root" { path = find_in_parent_folders() }`. +1. Use `account.hcl` files at the account/environment level for account ID, region, and environment name; read them with `read_terragrunt_config(find_in_parent_folders("account.hcl"))`. ## Remote state and backend generation -1. Generate `backend.tf` from the root `remote_state` block — never hand-write backend files in units. -1. Use `path_relative_to_include()` as the state key so each unit gets a unique, auto-named state file. +1. Generate `backend.tf` from the root `remote_state` block; never hand-write backend files in units. +1. Use `path_relative_to_include()` as the state key so each unit gets a unique state file. 1. Enable encryption and state locking on the S3 backend; enable versioning on the state bucket. ## Provider generation -1. Generate `provider.tf` from the root `generate "provider"` block — never duplicate provider configuration across units. -1. Include `default_tags` in the generated provider block to ensure consistent tagging across all resources. +1. Generate `provider.tf` from the root `generate "provider"` block; never duplicate provider configuration across units. +1. Include `default_tags` in the generated provider block to keep tagging consistent across resources. ## Module sources and pinning -1. Pin all module sources to a specific git ref or registry semver tag — never `?ref=main` or floating tags. -1. Prefer sourcing from a versioned internal registry or tagged git commit over local paths in shared modules. +1. Pin all module sources to a specific git ref or registry semver tag; never `?ref=main` or floating tags. +1. Prefer a versioned internal registry or tagged git commit over local paths in shared modules. ## Dependency blocks -1. Add `mock_outputs` to every `dependency` block for the `validate` and `plan` commands — this allows planning without deploying dependencies first. +1. Add `mock_outputs` to every `dependency` block for the `validate` and `plan` commands; this allows planning without deploying dependencies first. 1. Declare only the outputs you actually use from a dependency; do not expose the full output set. -1. Keep `dependency` blocks at unit level — do not express dependencies in the root config. +1. Keep `dependency` blocks at unit level; do not express dependencies in root config. ## DRY inputs -1. Extract shared inputs for an ecosystem (e.g. RDS defaults) into `_envcommon/.hcl`; load with `read_terragrunt_config`. -1. Use `merge(local.common.inputs, { ... })` to override defaults per environment — do not copy-paste full input maps. +1. Extract shared inputs for an ecosystem into `_envcommon/.hcl`; load with `read_terragrunt_config`. +1. Use `merge(local.common.inputs, { ... })` to override defaults per environment; do not copy-paste full input maps. ## CI/CD @@ -46,15 +46,15 @@ Use these Terragrunt conventions in this project. ## Secrets -1. Never hardcode secrets in `.hcl` files — supply them via environment variables (`TF_VAR_*`) or a secrets manager data source. +1. Never hardcode secrets in `.hcl` files; supply them via environment variables (`TF_VAR_*`) or a secrets manager data source. 1. Do not commit `.tfvars` files containing real secrets. ## References -> Always use the official documentation for the Terragrunt version in use — built-in functions and CLI flags evolve with each release. +> Use official docs for the Terragrunt version in use; built-in functions and CLI flags evolve between releases. - [Terragrunt documentation](https://terragrunt.gruntwork.io/docs/) - [Terragrunt CLI reference](https://terragrunt.gruntwork.io/docs/reference/cli-options/) - + diff --git a/.github/instructions/testing.instructions.md b/.github/instructions/testing.instructions.md index 0507e1a7..99c6021b 100644 --- a/.github/instructions/testing.instructions.md +++ b/.github/instructions/testing.instructions.md @@ -3,44 +3,44 @@ name: testing description: 'Test authoring conventions for any language or framework. Use when writing or reviewing tests, test plans, or test coverage decisions.' applyTo: '**/*' --- -Use these testing conventions in this project. +Use these testing conventions. ## Scope and intent 1. Write tests to verify observable behavior, not internal implementation details. 1. A test that passes when behavior is wrong, or fails when behavior is correct, has negative value. -1. Tests are documentation — a reader should understand what the system does by reading the test. +1. Tests should read like documentation. ## Naming and structure -1. Name tests to describe what they verify: what the subject does, under what condition, and what the expected outcome is. -1. Keep each test focused on one behavior; avoid asserting unrelated outcomes in a single test. -1. Group related tests together; separate unrelated test concerns into distinct test units. +1. Name tests by subject, condition, and expected outcome. +1. Keep each test focused on one behavior. +1. Group related tests together; separate unrelated concerns. ## Coverage and completeness -1. Cover the success path, expected failure paths, and boundary conditions for every behavioral change. -1. Treat missing tests for changed behavior as a defect — a change without tests is not complete. -1. Do not chase a coverage number; cover behaviors that matter rather than lines that exist. +1. Cover success paths, expected failure paths, and boundary conditions for every behavioral change. +1. Treat missing tests for changed behavior as a defect. +1. Cover behaviors that matter rather than lines that exist. ## Test quality -1. Make tests deterministic — a test that passes or fails non-deterministically is unreliable and must be fixed. -1. Keep tests independent; no test should depend on execution order or shared mutable state. -1. Prefer clear, direct assertions over indirect checks; assert the outcome, not the path to it. -1. Avoid logic (loops, conditionals) in tests; if a test needs logic, split it into multiple focused tests. +1. Make tests deterministic. +1. Keep tests independent. +1. Prefer clear, direct assertions. +1. Avoid logic in tests; split tests that need it. ## Test boundaries -1. Use unit tests for isolated logic; use integration tests when behavior crosses component or service boundaries. -1. Mock or stub only what is necessary to isolate the subject; avoid over-mocking that disconnects the test from real behavior. -1. Test contracts and interfaces, not just internal units — what the caller observes is what matters. +1. Use unit tests for isolated logic; use integration tests when behavior crosses boundaries. +1. Mock or stub only what is necessary. +1. Test contracts and interfaces, not just internal units. ## Maintenance 1. Update tests in the same change as the behavior they cover. -1. Remove tests that no longer reflect real behavior rather than commenting them out. -1. Treat flaky tests as bugs; do not merge code with known test reliability issues. +1. Remove tests that no longer reflect real behavior. +1. Treat flaky tests as bugs. - + diff --git a/.github/instructions/typescript.instructions.md b/.github/instructions/typescript.instructions.md index 0a96373d..9a6f8f3b 100644 --- a/.github/instructions/typescript.instructions.md +++ b/.github/instructions/typescript.instructions.md @@ -3,19 +3,19 @@ name: typescript description: 'TypeScript coding conventions for projects. Use when writing or reviewing TypeScript or JavaScript modules, components, and package internals.' applyTo: '**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs}' --- -Use these TypeScript conventions in this project. +Use these TypeScript conventions. ## Type safety -1. Enable and respect strict mode; do not disable strictness per-file without a documented reason. +1. Enable and respect strict mode; do not disable strictness per file without a documented reason. 1. Avoid `any`; prefer `unknown` when the type is genuinely unknown and narrow it explicitly. -1. Prefer `interface` for object shapes that may be extended; use `type` for unions, intersections, and aliases. +1. Prefer `interface` for extendable object shapes; use `type` for unions, intersections, and aliases. 1. Do not use type assertions (`as`) to silence type errors; fix the type instead. ## Design and readability 1. Prefer explicit, domain-meaningful names over abbreviations. -1. Keep functions focused; split functions that mix parsing, I/O, and business rules. +1. Keep functions focused. 1. Prefer straightforward control flow over clever one-liners. 1. Use `const` by default; use `let` only when reassignment is required; never use `var`. @@ -49,4 +49,4 @@ Use these TypeScript conventions in this project. 1. Do not suppress lint or type errors with inline disable comments unless there is a documented, task-specific reason. - + diff --git a/.github/prompts/api-design-review.prompt.md b/.github/prompts/api-design-review.prompt.md index 8fd41dc8..bc479abf 100644 --- a/.github/prompts/api-design-review.prompt.md +++ b/.github/prompts/api-design-review.prompt.md @@ -3,15 +3,14 @@ description: 'Review an API design or OpenAPI spec for correctness, completeness name: api-design-review argument-hint: '[OpenAPI spec file, design doc, or endpoint scope]' agent: designer -model: GPT-5.3-Codex (copilot) tools: - read - search --- Review the provided API design or OpenAPI specification for correctness, completeness, and consistency. -Focus on issues that affect consumers: breaking contracts, ambiguous semantics, missing error cases, and inconsistent conventions. -Do not focus on implementation details or tooling preferences. +Focus on consumer impact: breaking contracts, ambiguous semantics, missing errors, and inconsistent conventions. +Ignore implementation details and tooling preferences. Output exactly in this format: @@ -55,4 +54,4 @@ List fields or objects that are missing required constraints, descriptions, or e - top priority fix in one sentence - + diff --git a/.github/prompts/architecture-risk.prompt.md b/.github/prompts/architecture-risk.prompt.md index e11c75c4..4d83a9f9 100644 --- a/.github/prompts/architecture-risk.prompt.md +++ b/.github/prompts/architecture-risk.prompt.md @@ -3,7 +3,6 @@ description: 'Identify architectural risks, tradeoffs, and mitigation priorities name: architecture-risk argument-hint: '[design doc, ADR, or architecture scope]' agent: architect -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -11,7 +10,7 @@ tools: Evaluate the provided architecture for delivery and runtime risk. Prioritize issues that could cause outages, data loss, severe operability pain, or major rework. -Do not focus on stylistic preferences. +Ignore stylistic preferences. Output exactly in this format: @@ -52,4 +51,4 @@ List security-specific risks not covered above: auth boundaries, sensitive data - one-sentence rationale - + diff --git a/.github/prompts/artifact-integrity.prompt.md b/.github/prompts/artifact-integrity.prompt.md index 9a60bd4b..107b07e2 100644 --- a/.github/prompts/artifact-integrity.prompt.md +++ b/.github/prompts/artifact-integrity.prompt.md @@ -3,21 +3,20 @@ description: 'Check source templates against generated artifacts and identify dr name: artifact-integrity argument-hint: '[artifact type, path, or full repo]' agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search --- -Check source templates against generated artifacts and identify drift or missing regeneration. +Check source templates against generated artifacts and identify drift. -Compare `src/vstack/_templates/` sources against their installed counterparts in `.github/` -and the manifest at `.vstack/vstack.json`. Surface any mismatch, stale output, or gap. +Compare `src/vstack/_templates/` sources with installed artifacts in `.github/` +and the manifest at `.vstack/vstack.json`. Surface mismatches, stale output, or gaps. Output exactly in this format: ## Drift Findings -List every source-to-artifact mismatch detected. +List all source-to-artifact mismatches. For each item: @@ -28,7 +27,7 @@ For each item: ## Regeneration Actions -List the exact commands needed to bring generated artifacts back into sync. +List exact commands needed to bring generated artifacts back into sync. For each action: @@ -38,7 +37,7 @@ For each action: ## Risk If Unfixed -Describe the production risk if drift is left unresolved. +Describe production risk if drift is left unresolved. For each drift item from above: @@ -47,7 +46,7 @@ For each drift item from above: ## Verification Steps -Provide a checklist to confirm the repository is back in a clean state after regeneration. +Provide a checklist to confirm the repository is clean after regeneration. - [ ] `python3 -m vstack install` completes without errors - [ ] `vstack validate` reports no unresolved template tokens @@ -56,4 +55,4 @@ Provide a checklist to confirm the repository is back in a clean state after reg - [ ] All regenerated files match their source checksums in `.vstack/vstack.json` - + diff --git a/.github/prompts/ci-triage.prompt.md b/.github/prompts/ci-triage.prompt.md index d7fe20bf..cb4c3d8b 100644 --- a/.github/prompts/ci-triage.prompt.md +++ b/.github/prompts/ci-triage.prompt.md @@ -3,7 +3,6 @@ description: 'Triage CI failures into root-cause clusters and prioritize the fas name: ci-triage argument-hint: '[workflow run, failing job, or log scope]' agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -43,4 +42,4 @@ Ordered by unblock value. - [ ] confirm no new failures - + diff --git a/.github/prompts/dependency-audit.prompt.md b/.github/prompts/dependency-audit.prompt.md index 301f7c89..ed23c0d1 100644 --- a/.github/prompts/dependency-audit.prompt.md +++ b/.github/prompts/dependency-audit.prompt.md @@ -3,14 +3,13 @@ description: 'Audit dependencies for vulnerabilities, outdated versions, licence name: dependency-audit argument-hint: '[dependency manifest, lockfile, or package scope]' agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search --- Audit the provided dependency manifest or lockfile for vulnerabilities, outdated packages, licence risks, and supply chain hygiene. -Prefer evidence from the manifest itself; flag items that require external verification. +Prefer evidence from the manifest itself; flag items that need external verification. Output exactly in this format: @@ -27,8 +26,8 @@ For each item: ## Outdated Packages -List dependencies that are significantly behind their latest stable release and carry meaningful risk. -Do not list minor version differences without impact. +List dependencies significantly behind latest stable releases where risk is meaningful. +Do not list low-impact minor version differences. For each item: @@ -53,11 +52,11 @@ For each item: ## Supply Chain Hygiene -List packages with unusual provenance concerns: abandoned maintainers, single-maintainer with no backup, recent ownership transfers, or typosquatting risk. +List packages with unusual provenance concerns: abandoned maintainers, single-maintainer projects, recent ownership transfers, or typosquatting risk. ## Recommended Actions -Ordered list of actions by priority (critical first). +Ordered action list by priority (critical first). - + diff --git a/.github/prompts/incident-timeline.prompt.md b/.github/prompts/incident-timeline.prompt.md index 50de85d1..ee49e9a1 100644 --- a/.github/prompts/incident-timeline.prompt.md +++ b/.github/prompts/incident-timeline.prompt.md @@ -3,7 +3,6 @@ description: 'Build a structured, evidence-based incident timeline and action-or name: incident-timeline argument-hint: '[logs, alerts, timeline notes, or incident ID]' agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -57,4 +56,4 @@ For each action: List the minimum controls needed to reduce repeat probability. - + diff --git a/.github/prompts/migration-plan.prompt.md b/.github/prompts/migration-plan.prompt.md index 4f379cbb..1a9b34f1 100644 --- a/.github/prompts/migration-plan.prompt.md +++ b/.github/prompts/migration-plan.prompt.md @@ -3,7 +3,6 @@ description: 'Produce a safe migration plan with sequencing, fallback paths, and name: migration-plan argument-hint: '[migration scope or affected components]' agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -43,4 +42,4 @@ For each phase: - success criteria - + diff --git a/.github/prompts/migration-safety.prompt.md b/.github/prompts/migration-safety.prompt.md index fb22c4bf..84851f93 100644 --- a/.github/prompts/migration-safety.prompt.md +++ b/.github/prompts/migration-safety.prompt.md @@ -3,7 +3,6 @@ description: 'Review database migration safety, rollback strategy, and zero-down name: migration-safety argument-hint: '[migration files, schema, or rollout plan]' agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -12,7 +11,7 @@ tools: Review the selected migration plan and code for production safety. Focus on forward compatibility, rollback feasibility, data integrity, and operational risk. -Assume a live system with concurrent reads/writes. +Assume a live system with concurrent reads and writes. Output exactly in this format: @@ -52,4 +51,4 @@ List missing migration tests (forward, backward, data invariants, load-sensitive - biggest remaining risk in one sentence - + diff --git a/.github/prompts/ops-readiness.prompt.md b/.github/prompts/ops-readiness.prompt.md index 82c67f61..4441fa7f 100644 --- a/.github/prompts/ops-readiness.prompt.md +++ b/.github/prompts/ops-readiness.prompt.md @@ -3,7 +3,6 @@ description: 'Assess operational readiness across observability, runbooks, failu name: ops-readiness argument-hint: '[service, component, or release scope]' agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -42,4 +41,4 @@ For each gap: - target milestone - + diff --git a/.github/prompts/code-review.prompt.md b/.github/prompts/quick-review.prompt.md similarity index 85% rename from .github/prompts/code-review.prompt.md rename to .github/prompts/quick-review.prompt.md index ed73e5aa..fb57b96c 100644 --- a/.github/prompts/code-review.prompt.md +++ b/.github/prompts/quick-review.prompt.md @@ -1,9 +1,8 @@ --- description: 'Review a change for bugs, regressions, and missing tests.' -name: code-review +name: quick-review argument-hint: '[scope or files to review]' agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -51,4 +50,4 @@ End with: - Biggest remaining risk: one sentence - + diff --git a/.github/prompts/release-check.prompt.md b/.github/prompts/release-check.prompt.md index ec135f70..58d23ca0 100644 --- a/.github/prompts/release-check.prompt.md +++ b/.github/prompts/release-check.prompt.md @@ -3,7 +3,6 @@ description: 'Evaluate release gate readiness using required reports, artifacts, name: release-check argument-hint: '[release scope or target branch]' agent: release -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -46,4 +45,4 @@ Ordered actions to reach READY. - verification step - + diff --git a/.github/prompts/repo-assessment.prompt.md b/.github/prompts/repo-assessment.prompt.md index d3b3403f..06b17f72 100644 --- a/.github/prompts/repo-assessment.prompt.md +++ b/.github/prompts/repo-assessment.prompt.md @@ -3,15 +3,14 @@ description: 'Assess a repository for production-readiness gaps and prioritized name: repo-assessment argument-hint: '[repository scope or component path]' agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search --- -Assess this repository for production-readiness gaps and prioritized improvement opportunities. +Assess this repository for production-readiness gaps and prioritized improvements. -Focus on evidence found in source files, tests, CI configuration, docs, and manifests. -Prefer concrete findings over speculative risks. +Base findings on evidence in source files, tests, CI config, docs, and manifests. +Prefer concrete findings over speculation. Output exactly in this format: @@ -27,8 +26,7 @@ For each item: ## High-ROI Improvements -List high-value improvements that reduce operational risk or developer friction. -Rank by impact relative to effort. +List high-value improvements that reduce operational risk or developer friction, ranked by impact versus effort. For each item: @@ -38,7 +36,7 @@ For each item: ## Testing and Verification Gaps -List behavioral paths that are untested or where test coverage provides false confidence. +List untested behavioral paths or areas where coverage may give false confidence. For each item: @@ -48,12 +46,11 @@ For each item: ## Suggested Next Sprint Backlog -Provide a short, actionable list of tasks suitable for the next sprint. -Order from highest to lowest priority. +Provide a short, actionable next-sprint task list ordered from highest to lowest priority. - task title - owner role (product | architect | designer | engineer | tester | release) - one-line rationale - + diff --git a/.github/prompts/template-impact.prompt.md b/.github/prompts/template-impact.prompt.md index 087c5228..138e837c 100644 --- a/.github/prompts/template-impact.prompt.md +++ b/.github/prompts/template-impact.prompt.md @@ -3,7 +3,6 @@ description: 'Assess impact of a template change on generated artifacts, tests, name: template-impact argument-hint: '[template path or change scope]' agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -43,4 +42,4 @@ List highest-risk regressions first. - expected pass criteria - + diff --git a/.github/prompts/test-gaps.prompt.md b/.github/prompts/test-gaps.prompt.md index 60c600db..34ec33e5 100644 --- a/.github/prompts/test-gaps.prompt.md +++ b/.github/prompts/test-gaps.prompt.md @@ -3,7 +3,6 @@ description: 'Identify missing behavioral coverage and prioritize test additions name: test-gaps argument-hint: '[component, feature, or repository scope]' agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -40,4 +39,4 @@ Ordered from highest to lowest risk reduction. - acceptance check - + diff --git a/.github/prompts/upgrade-plan.prompt.md b/.github/prompts/upgrade-plan.prompt.md index 9865d4ab..b4cc41db 100644 --- a/.github/prompts/upgrade-plan.prompt.md +++ b/.github/prompts/upgrade-plan.prompt.md @@ -3,7 +3,6 @@ description: 'Build a safe upgrade plan with sequencing, compatibility checks, a name: upgrade-plan argument-hint: '[target version, component, or full repo]' agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -43,4 +42,4 @@ For each major step: - pass criteria - + diff --git a/.github/prompts/workflow-check.prompt.md b/.github/prompts/workflow-check.prompt.md index 2b24e1a5..15c5eba9 100644 --- a/.github/prompts/workflow-check.prompt.md +++ b/.github/prompts/workflow-check.prompt.md @@ -3,7 +3,6 @@ description: 'Review workflow stage flow, gate usage, and handoff integrity acro name: workflow-check argument-hint: '[workflow scope or stage list]' agent: planner -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -46,4 +45,4 @@ Provide an ordered short list of actions. - expected result - + diff --git a/.github/skills/adr/SKILL.md b/.github/skills/adr/SKILL.md index 09c69c32..5af24c33 100644 --- a/.github/skills/adr/SKILL.md +++ b/.github/skills/adr/SKILL.md @@ -180,4 +180,4 @@ is a kebab-case title. After writing, state the file path and summary so the architect or product role can review. - + diff --git a/.github/skills/analyse/SKILL.md b/.github/skills/analyse/SKILL.md index be1d5f81..14c6f158 100644 --- a/.github/skills/analyse/SKILL.md +++ b/.github/skills/analyse/SKILL.md @@ -214,4 +214,4 @@ State conclusions with confidence level: ``` - + diff --git a/.github/skills/architecture/SKILL.md b/.github/skills/architecture/SKILL.md index f96e38ea..b876d265 100644 --- a/.github/skills/architecture/SKILL.md +++ b/.github/skills/architecture/SKILL.md @@ -278,4 +278,4 @@ For each significant structural decision made during this review (technology cho - Update `docs/architecture/overview.md` to reflect the final decisions. - + diff --git a/.github/skills/ask/SKILL.md b/.github/skills/ask/SKILL.md new file mode 100644 index 00000000..d5c7d2e0 --- /dev/null +++ b/.github/skills/ask/SKILL.md @@ -0,0 +1,127 @@ +--- +name: ask +description: 'Read-only technical Q&A for the current codebase. Clarifies ambiguous questions, gathers evidence from code and docs, and returns concise, referenced answers without making any changes. Use for "how does this work", "where is X", "why might this fail", and "what should we do" guidance.' +license: 'MIT' +compatibility: 'Requires a skills-compatible agent with repository file access and optional web lookup.' +metadata: + owner: vstack + maturity: stable +allowed-tools: 'execute read search web vscode' +argument-hint: '[question about code, architecture, behavior, or workflow]' +user-invocable: true +disable-model-invocation: false +--- +## Skill Context + +This skill is part of **vstack** — a VS Code-native AI engineering workflow system. + +### AskUserQuestion Format + +When you need clarification, use this exact format — never invent or guess: + +> **Question:** [The specific question] +> **Options:** A) … | B) … | C) … +> **Default if no response:** [What you'll do] + +Never ask more than one question at a time without waiting for the answer. + +### Diagram Convention + +When producing hand-authored Markdown outputs, prefer Mermaid for flow, +interaction, lifecycle, state, topology, dependency, and decision diagrams when +the format is supported and improves clarity. Use ASCII as a fallback when +Mermaid is unsupported or would be less readable. Keep ASCII/text trees for +directory structures and other scan-friendly hierarchies. + +# ask — Read-Only Technical Q&A + +Answer questions clearly using evidence from the repository. +Do not edit files, run write operations, or apply changes. + +## Out of scope + +- Implementing fixes or refactors (route to `engineer`) +- Running destructive commands or state-changing operations +- Producing release artifacts (route to `release`) + +## Workflow + +1. Understand the question and classify it: + - code behavior/explanation + - architecture/ownership + - debugging hypothesis + - API usage/contract + - process/tooling guidance +1. Identify what evidence is needed. +1. Gather evidence with focused search and minimal file reads. +1. Ask one clarification question if ambiguity blocks a reliable answer. +1. Respond with direct answer + evidence + actionable next steps. + +## Clarification rule + +If the question is ambiguous, ask exactly one focused question before deeper research. +Use options when useful and include a default assumption. + +Example format: + +- Question: Which path do you mean by "review flow"? +- Options: A) PR review lifecycle | B) code quality skill flow | C) release sign-off flow +- Default if no response: B + +## Research strategy + +Prefer broad-to-narrow exploration: + +1. Find candidate areas quickly. +1. Narrow to specific symbols/functions/configs. +1. Read only files required to answer confidently. + +Recommended commands: + +```bash +rg -n "" src tests docs 2>/dev/null | head -120 +rg --files src tests docs | head -200 +``` + +When needed, inspect relevant runtime evidence: + +```bash +# read-only diagnostics/examples +# terminal output snapshots or test failure summaries can be used as evidence +``` + +## Answer quality rules + +- Lead with the answer, then provide evidence. +- Distinguish verified facts from assumptions. +- Reference concrete files and symbols for code-related questions. +- Keep answers concise but complete for the asked scope. +- If changes are needed, describe them but do not apply them. + +## Output contract + +Use this format: + +```text +## Answer +[Direct answer in plain language] + +## Evidence +- [file/symbol]: [what it shows] +- [file/symbol]: [what it shows] + +## Recommended Next Step +- [single best next action] + +## Confidence +[high/medium/low + one-line reason] +``` + +## Escalation guidance + +- If the question requires implementation, hand off to `engineer` with a scoped summary. +- If it requires deep root-cause investigation, hand off to `debug`. +- If it requires risk/impact comparison, hand off to `analyse`. + + + diff --git a/.github/skills/aws-cli/SKILL.md b/.github/skills/aws-cli/SKILL.md index 4b6ac35f..cdf9d9d3 100644 --- a/.github/skills/aws-cli/SKILL.md +++ b/.github/skills/aws-cli/SKILL.md @@ -374,4 +374,4 @@ aws ce get-cost-and-usage \ - [AWS CLI named profiles](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) - + diff --git a/.github/skills/cicd/SKILL.md b/.github/skills/cicd/SKILL.md index 9490d4ec..b1617ed5 100644 --- a/.github/skills/cicd/SKILL.md +++ b/.github/skills/cicd/SKILL.md @@ -221,4 +221,4 @@ Configure these in GitHub → Settings → Branches. - [GitHub-hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners) - + diff --git a/.github/skills/cloudformation/SKILL.md b/.github/skills/cloudformation/SKILL.md index 0b0830cb..0a977151 100644 --- a/.github/skills/cloudformation/SKILL.md +++ b/.github/skills/cloudformation/SKILL.md @@ -344,4 +344,4 @@ AppSecurityGroup: - [AWS SAM documentation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/) - + diff --git a/.github/skills/code-review/SKILL.md b/.github/skills/code-review/SKILL.md index ec347847..e252cd5b 100644 --- a/.github/skills/code-review/SKILL.md +++ b/.github/skills/code-review/SKILL.md @@ -218,4 +218,4 @@ Confidence: [HIGH/MEDIUM/LOW — explain if not HIGH] ``` - + diff --git a/.github/skills/codeql/SKILL.md b/.github/skills/codeql/SKILL.md index 471bef03..8c5fe5bb 100644 --- a/.github/skills/codeql/SKILL.md +++ b/.github/skills/codeql/SKILL.md @@ -251,4 +251,4 @@ GITHUB_TOKEN= codeql github upload-results \ - [Supported languages and frameworks](https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/codeql-code-scanning-for-compiled-languages) - + diff --git a/.github/skills/concise/SKILL.md b/.github/skills/concise/SKILL.md index a3539465..50555769 100644 --- a/.github/skills/concise/SKILL.md +++ b/.github/skills/concise/SKILL.md @@ -147,4 +147,4 @@ Current mode unchanged: - [ ] User confirmation/status returned in deterministic format - + diff --git a/.github/skills/consult/SKILL.md b/.github/skills/consult/SKILL.md index b0b20874..b2dc644f 100644 --- a/.github/skills/consult/SKILL.md +++ b/.github/skills/consult/SKILL.md @@ -218,4 +218,4 @@ reason: [one sentence] ``` - + diff --git a/.github/skills/container/SKILL.md b/.github/skills/container/SKILL.md index 139773a5..9f349da7 100644 --- a/.github/skills/container/SKILL.md +++ b/.github/skills/container/SKILL.md @@ -153,4 +153,4 @@ For production-like local testing, write a separate `docker-compose.prod.yml` wi - [Docker official images](https://hub.docker.com/search?image_filter=official) - + diff --git a/.github/skills/conventional-commit/SKILL.md b/.github/skills/conventional-commit/SKILL.md index d2fe0338..e884555c 100644 --- a/.github/skills/conventional-commit/SKILL.md +++ b/.github/skills/conventional-commit/SKILL.md @@ -155,4 +155,4 @@ Remaining changes: If commit is blocked, report exact reason and proposed fix. - + diff --git a/.github/skills/copilot-ops/SKILL.md b/.github/skills/copilot-ops/SKILL.md index 43a155ed..642e1965 100644 --- a/.github/skills/copilot-ops/SKILL.md +++ b/.github/skills/copilot-ops/SKILL.md @@ -87,4 +87,4 @@ Provide this structure: Escalate when permissions are insufficient, settings conflict across scopes, or policy intent is ambiguous. - + diff --git a/.github/skills/debug/SKILL.md b/.github/skills/debug/SKILL.md index 41345d65..0b1e40f6 100644 --- a/.github/skills/debug/SKILL.md +++ b/.github/skills/debug/SKILL.md @@ -258,4 +258,4 @@ Prevention: [any follow-up items] ``` - + diff --git a/.github/skills/dependabot/SKILL.md b/.github/skills/dependabot/SKILL.md index ac188073..26a45e55 100644 --- a/.github/skills/dependabot/SKILL.md +++ b/.github/skills/dependabot/SKILL.md @@ -320,4 +320,4 @@ updates: - [Dependabot security updates](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/about-dependabot-security-updates) - + diff --git a/.github/skills/dependency/SKILL.md b/.github/skills/dependency/SKILL.md index b8b579a1..381df948 100644 --- a/.github/skills/dependency/SKILL.md +++ b/.github/skills/dependency/SKILL.md @@ -318,4 +318,4 @@ Action items (priority order): - [PyPI / npm / crates.io / Maven Central](https://pypi.org) (replace with the relevant registry) - + diff --git a/.github/skills/design/SKILL.md b/.github/skills/design/SKILL.md index 7e68dc72..757ffd76 100644 --- a/.github/skills/design/SKILL.md +++ b/.github/skills/design/SKILL.md @@ -243,4 +243,4 @@ Output a complete design document to `docs/design/overview.md` or `openapi.yaml` ``` - + diff --git a/.github/skills/docs/SKILL.md b/.github/skills/docs/SKILL.md index 3a5d7e9f..fd7c2f3c 100644 --- a/.github/skills/docs/SKILL.md +++ b/.github/skills/docs/SKILL.md @@ -151,4 +151,4 @@ Skipped (n/a): ``` - + diff --git a/.github/skills/explore/SKILL.md b/.github/skills/explore/SKILL.md index de25faf0..570742f8 100644 --- a/.github/skills/explore/SKILL.md +++ b/.github/skills/explore/SKILL.md @@ -1,6 +1,6 @@ --- name: explore -description: 'Repository and system discovery. Maps the architecture, understands the codebase, identifies technical debt, and produces a structured onboarding summary. Use at the start of any engagement with an unfamiliar codebase, when asked to "understand this codebase", "map the architecture", "explore the repo", or "what does this service do?".' +description: 'Fast codebase exploration and technical Q&A. Uses broad-to-narrow search, parallel context gathering, and depth modes (`quick`, `medium`, `thorough`) to map architecture, find reusable patterns, and answer targeted questions without making code changes. Use when asked to "explore the repo", "where is X implemented", "how does this system work", or "find examples to reuse".' license: 'MIT' compatibility: 'Requires a skills-compatible agent with repository file access and terminal command execution when needed.' metadata: @@ -33,195 +33,120 @@ the format is supported and improves clarity. Use ASCII as a fallback when Mermaid is unsupported or would be less readable. Keep ASCII/text trees for directory structures and other scan-friendly hierarchies. -# explore — Codebase & Architecture Discovery +# explore — Fast Repository Exploration & Reuse Discovery -Map an unfamiliar codebase and produce a structured onboarding summary. -Report findings; do not change code. +Answer codebase questions quickly and accurately. +Map architecture, find reusable patterns, and return targeted evidence. +Do not change files. ## Out of scope -- Fixing issues found during exploration (use `debug` or `verify`) -- Architecture recommendations (use `architecture`) -- Performance analysis (use `performance` or `analyse`) +- Implementing or fixing code (use `engineer`, `debug`, or `verify` workflows) +- Full architecture decisioning (use `architecture`) +- Deep security/performance audits (use `security` or `performance`) -## Phase 1: Project Overview +## Operating modes -```bash -# Identify project type and tech stack -ls -la -cat README.md 2>/dev/null | head -60 || cat README.rst 2>/dev/null | head -60 || true -cat package.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('Name:', d.get('name'), '| Version:', d.get('version'), '| Main:', d.get('main',''))" 2>/dev/null || true -cat pyproject.toml 2>/dev/null | head -20 || true -cat go.mod 2>/dev/null | head -10 || true -cat Cargo.toml 2>/dev/null | head -10 || true -``` +Choose depth based on user intent. -Record: +- `quick` (2-5 minutes): answer one focused question with minimal reads. +- `medium` (5-15 minutes): map the relevant subsystem and provide reuse candidates. +- `thorough` (15+ minutes): broader architecture map with risks, dependencies, and integration points. -- **Project name and purpose** -- **Tech stack** (language, framework, runtime) -- **Project type** (API service, library, CLI, worker, monorepo) +If the user does not specify a depth, default to `medium`. -## Phase 2: Directory Structure +## Search strategy (broad -> narrow) -```bash -# Top-level structure -find . -maxdepth 3 -not -path '*/node_modules/*' -not -path '*/.git/*' \ - -not -path '*/vendor/*' -not -path '*/__pycache__/*' -not -path '*/dist/*' \ - -not -path '*/.venv/*' | sort | head -80 -``` +1. Start broad to find candidate areas quickly. +1. Narrow to concrete symbols, endpoints, and call paths. +1. Read only the files needed to answer confidently. +1. Stop when evidence is sufficient; avoid exhaustive sweeps by default. -Identify: +Prefer parallel discovery for independent branches. +Examples: -- Where source code lives (`src/`, `lib/`, `pkg/`, top-level) -- Where tests live (`test/`, `tests/`, `spec/`, `__tests__/`) -- Where configs live (`config/`, `.env*`, `*config.yaml`) -- CI/CD configuration (`.github/workflows/`, `.gitlab-ci.yml`, etc.) -- Infrastructure code (`k8s/`, `terraform/`, `docker-compose.yml`) +- API layer + data layer + job/worker layer +- frontend feature + backend endpoint +- primary implementation + analogous implementation template -## Phase 3: Dependencies & External Services +## Recommended command patterns ```bash -# Dependency overview -cat package.json 2>/dev/null | python3 -c " -import sys, json -d = json.load(sys.stdin) -deps = {**d.get('dependencies',{}), **d.get('devDependencies',{})} -print('Dependencies:', len(deps)) -for k,v in list(deps.items())[:20]: print(f' {k}: {v}') -" 2>/dev/null || true - -cat pyproject.toml 2>/dev/null | grep -A 20 '\[tool.poetry.dependencies\]' | head -25 || true -cat go.mod 2>/dev/null | grep -E '^require|^\t' | head -20 || true - -# External services referenced -grep -r -E 'postgres|mysql|redis|mongodb|kafka|rabbitmq|elasticsearch|dynamodb|s3' \ - --include='*.ts' --include='*.py' --include='*.go' --include='*.yaml' --include='*.env*' \ - --exclude-dir=node_modules --exclude-dir=vendor . 2>/dev/null | grep -v test | head -20 -``` +# 1) Inventory project shape quickly +ls -la +find . -maxdepth 3 \ + -not -path '*/.git/*' -not -path '*/node_modules/*' -not -path '*/vendor/*' \ + -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/.venv/*' \ + -not -path '*/__pycache__/*' | head -120 -## Phase 4: API & Service Contracts +# 2) Locate likely implementation areas +rg --files | head -200 +rg -n "router|endpoint|handler|service|repository|controller|usecase|workflow" src tests docs 2>/dev/null | head -120 -```bash -# Check for API spec files -find . -name 'openapi*.yaml' -o -name 'openapi*.json' -o -name 'swagger*.yaml' \ - -o -name '*.proto' -o -name 'asyncapi*.yaml' 2>/dev/null | head -10 - -# Check for route definitions -grep -r -n '@app.route\|router\.\|@Get\|@Post\|path=' \ - --include='*.ts' --include='*.py' --include='*.go' \ - --exclude-dir=node_modules . 2>/dev/null | head -30 +# 3) Find symbol definitions/usages once a likely area is known +rg -n "" src tests docs 2>/dev/null | head -120 ``` -## Phase 5: Test Infrastructure +Language and contract hints: ```bash -# Detect test runner and run tests -if [ -f package.json ]; then - if grep -q '"vitest"' package.json 2>/dev/null; then - npx vitest run - elif grep -q '"jest"' package.json 2>/dev/null; then - npx jest - elif grep -q '"bun"' package.json 2>/dev/null; then - bun test - else - npm test - fi -elif [ -f pyproject.toml ] || [ -f setup.py ]; then - python -m pytest -v -elif [ -f go.mod ]; then - go test ./... -elif [ -f Cargo.toml ]; then - cargo test -else - echo "No recognized test framework detected." -fi +cat pyproject.toml 2>/dev/null | head -80 || true +cat package.json 2>/dev/null | head -80 || true +cat go.mod 2>/dev/null | head -80 || true +find . \( -name 'openapi*.yaml' -o -name 'openapi*.json' -o -name '*.proto' \) 2>/dev/null | head -40 ``` -```bash -# Test count and coverage setup -find . \( -name '*.test.*' -o -name '*_test.*' -o -name '*spec.*' \) \ - -not -path '*/node_modules/*' -not -path '*/.venv/*' 2>/dev/null | wc -l +## Reuse-first discovery -# Coverage config -cat .nycrc 2>/dev/null || cat vitest.config.* 2>/dev/null | head -20 || \ - cat pytest.ini 2>/dev/null | head -20 || true -``` +Always look for an existing analogous implementation before suggesting net-new structure. -## Phase 6: CI/CD Pipeline +For each candidate pattern, capture: -```bash -# CI config -ls .github/workflows/ 2>/dev/null | head -10 -cat .github/workflows/*.yml 2>/dev/null | head -80 || true -cat .gitlab-ci.yml 2>/dev/null | head -60 || true -``` +- where it lives (file + symbol) +- why it is analogous +- what can be reused directly +- what must be adapted -## Phase 7: Technical Debt & Health +When asked to support implementation planning, return at least one "golden path" example and one fallback example. -```bash -# Check for TODO/FIXME/HACK comments -grep -r -n "TODO\|FIXME\|HACK\|XXX\|DEPRECATED\|BUG" \ - --include='*.ts' --include='*.py' --include='*.go' \ - --exclude-dir=node_modules . 2>/dev/null | head -30 +## Evidence quality rules -# Check for TODOS.md -cat TODOS.md 2>/dev/null | head -40 || true -``` +- Prefer explicit evidence over assumptions. +- Cite concrete files and symbols, not only directories. +- Distinguish facts from inferences. +- If confidence is low, say what is missing and what to check next. -## Discovery Report +## Output contract -Produce a structured summary: +Tailor output to the requested depth, but keep this structure: ```text -## Discovery Report — [project name] — [date] - -### Overview -Purpose: [one paragraph] -Type: [API service / library / CLI / worker / ...] -Stack: [language, framework, runtime versions] - -### Architecture -[Mermaid diagram of service topology or module structure when possible; ASCII fallback if needed] - -### Data Stores - -- [Database]: [what it stores, ORM/driver used] -- [Cache]: [what is cached, TTL strategy] - -### Key External Dependencies - -- [Service A]: [purpose, auth method] -- [Service B]: [purpose] +## Exploration Result -### API Surface +### Answer +[Direct answer to the question in 2-6 sentences] -[Summarize endpoints or exported functions] +### Evidence +- [file/symbol]: [what it proves] +- [file/symbol]: [what it proves] -### Test Coverage +### Reusable Patterns +- [pattern A]: [why reusable, adaptation notes] +- [pattern B]: [why reusable, adaptation notes] -- Unit tests: [Y/N, count, coverage %] -- Integration tests: [Y/N] -- Contract tests: [Y/N] +### Suggested Next Checks +- [targeted check 1] +- [targeted check 2] -### CI/CD - -- CI: [GitHub Actions/GitLab CI/etc] -- Deploy target: [Fly.io/Render/K8s/etc] -- Release process: [manual/automated] - -### Technical Debt - -- [Key items from TODOS.md or code comments] - -### Onboarding Notes +### Confidence +[high/medium/low + one-line reason] +``` -- How to run locally: [command] -- How to run tests: [command] -- Key config: [env vars] -- Gotchas: [anything that surprised me] +For `thorough` mode, append: -``` +- subsystem map +- major dependency boundaries +- main risk hotspots (coupling, missing tests, unclear ownership) - + diff --git a/.github/skills/gdpr/SKILL.md b/.github/skills/gdpr/SKILL.md index a7230232..38df7c70 100644 --- a/.github/skills/gdpr/SKILL.md +++ b/.github/skills/gdpr/SKILL.md @@ -246,4 +246,4 @@ Use `@example.com` for all test email addresses. - [EDPB guidelines](https://www.edpb.europa.eu/our-work-tools/general-guidance/guidelines-recommendations-best-practices_en) - + diff --git a/.github/skills/gh-issues/SKILL.md b/.github/skills/gh-issues/SKILL.md index 32cda576..0245f9da 100644 --- a/.github/skills/gh-issues/SKILL.md +++ b/.github/skills/gh-issues/SKILL.md @@ -230,4 +230,4 @@ https://github.com///issues/ - [GitHub Issues documentation](https://docs.github.com/en/issues) - + diff --git a/.github/skills/gh-release/SKILL.md b/.github/skills/gh-release/SKILL.md index 25cbac72..b974fe98 100644 --- a/.github/skills/gh-release/SKILL.md +++ b/.github/skills/gh-release/SKILL.md @@ -214,4 +214,4 @@ If blocked, report exact blocker and required user action. - [GitHub Releases documentation](https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases) - + diff --git a/.github/skills/guardrails/SKILL.md b/.github/skills/guardrails/SKILL.md index bdcd4785..22b45321 100644 --- a/.github/skills/guardrails/SKILL.md +++ b/.github/skills/guardrails/SKILL.md @@ -72,4 +72,4 @@ Activate careful mode for this session. Two behaviors are now enabled. Explicitly ask to "disable guardrails". - + diff --git a/.github/skills/helm/SKILL.md b/.github/skills/helm/SKILL.md index 45a10083..21cc6a56 100644 --- a/.github/skills/helm/SKILL.md +++ b/.github/skills/helm/SKILL.md @@ -140,4 +140,4 @@ Practices: - [Chart best practices](https://helm.sh/docs/chart_best_practices/) - + diff --git a/.github/skills/incident/SKILL.md b/.github/skills/incident/SKILL.md index 723822fb..f35c97e2 100644 --- a/.github/skills/incident/SKILL.md +++ b/.github/skills/incident/SKILL.md @@ -251,4 +251,4 @@ Next: invoke @#rca and @#postmortem to produce written artifacts. ``` - + diff --git a/.github/skills/inspect/SKILL.md b/.github/skills/inspect/SKILL.md index f6a99571..60b1354c 100644 --- a/.github/skills/inspect/SKILL.md +++ b/.github/skills/inspect/SKILL.md @@ -155,4 +155,4 @@ Confirm for changed paths: ``` - + diff --git a/.github/skills/k8s/SKILL.md b/.github/skills/k8s/SKILL.md index 8b69ea44..06f45e41 100644 --- a/.github/skills/k8s/SKILL.md +++ b/.github/skills/k8s/SKILL.md @@ -144,4 +144,4 @@ Common failure classes: - [Kubernetes API reference](https://kubernetes.io/docs/reference/kubernetes-api/) - + diff --git a/.github/skills/migrate/SKILL.md b/.github/skills/migrate/SKILL.md index 8d66f152..e0622b61 100644 --- a/.github/skills/migrate/SKILL.md +++ b/.github/skills/migrate/SKILL.md @@ -320,4 +320,4 @@ Pre-deploy checklist: ``` - + diff --git a/.github/skills/onboard/SKILL.md b/.github/skills/onboard/SKILL.md index 201114d4..d1534f91 100644 --- a/.github/skills/onboard/SKILL.md +++ b/.github/skills/onboard/SKILL.md @@ -302,4 +302,4 @@ Gaps remaining (if any): ``` - + diff --git a/.github/skills/openapi/SKILL.md b/.github/skills/openapi/SKILL.md index 4143a37d..99270f79 100644 --- a/.github/skills/openapi/SKILL.md +++ b/.github/skills/openapi/SKILL.md @@ -403,4 +403,4 @@ Summary: [N critical, N warnings, N info] - [Redocly CLI (linting)](https://redocly.com/docs/cli/) - + diff --git a/.github/skills/performance/SKILL.md b/.github/skills/performance/SKILL.md index ea3b6a69..1c1c5b70 100644 --- a/.github/skills/performance/SKILL.md +++ b/.github/skills/performance/SKILL.md @@ -242,4 +242,4 @@ For each bottleneck identified: ``` - + diff --git a/.github/skills/postmortem/SKILL.md b/.github/skills/postmortem/SKILL.md index 9f7d813b..d75e88ae 100644 --- a/.github/skills/postmortem/SKILL.md +++ b/.github/skills/postmortem/SKILL.md @@ -184,4 +184,4 @@ Status: Draft — ready for team review ``` - + diff --git a/.github/skills/pr/SKILL.md b/.github/skills/pr/SKILL.md index 248c156f..ffab2dae 100644 --- a/.github/skills/pr/SKILL.md +++ b/.github/skills/pr/SKILL.md @@ -151,4 +151,4 @@ Next steps depend on the repository CI/CD configuration: ``` - + diff --git a/.github/skills/rancher/SKILL.md b/.github/skills/rancher/SKILL.md index 9bc615c9..3496fc54 100644 --- a/.github/skills/rancher/SKILL.md +++ b/.github/skills/rancher/SKILL.md @@ -113,4 +113,4 @@ Checks: - [Fleet documentation](https://fleet.rancher.io/) - + diff --git a/.github/skills/rca/SKILL.md b/.github/skills/rca/SKILL.md index 112588d6..189f70f9 100644 --- a/.github/skills/rca/SKILL.md +++ b/.github/skills/rca/SKILL.md @@ -207,4 +207,4 @@ Status: Draft — ready for review ``` - + diff --git a/.github/skills/refactor/SKILL.md b/.github/skills/refactor/SKILL.md index 095a91ef..117299ba 100644 --- a/.github/skills/refactor/SKILL.md +++ b/.github/skills/refactor/SKILL.md @@ -372,4 +372,4 @@ Behavior changed: No ``` - + diff --git a/.github/skills/release-notes/SKILL.md b/.github/skills/release-notes/SKILL.md index 683a1ef8..7079958f 100644 --- a/.github/skills/release-notes/SKILL.md +++ b/.github/skills/release-notes/SKILL.md @@ -147,4 +147,4 @@ Prepend a new entry at the top of `CHANGELOG.md`: Keep existing entries intact. - + diff --git a/.github/skills/requirements/SKILL.md b/.github/skills/requirements/SKILL.md index 4ab1418c..27c155d4 100644 --- a/.github/skills/requirements/SKILL.md +++ b/.github/skills/requirements/SKILL.md @@ -199,4 +199,4 @@ Write all findings to `docs/product/requirements.md`: After writing, summarize what was decided so the architect role can start. - + diff --git a/.github/skills/secret-scan/SKILL.md b/.github/skills/secret-scan/SKILL.md index 4c5c71ff..fe8b204c 100644 --- a/.github/skills/secret-scan/SKILL.md +++ b/.github/skills/secret-scan/SKILL.md @@ -240,4 +240,4 @@ credential formats. - [Supported secret patterns](https://docs.github.com/en/code-security/secret-scanning/introduction/supported-secret-scanning-patterns) - + diff --git a/.github/skills/security/SKILL.md b/.github/skills/security/SKILL.md index 5f060ed3..98e9eae1 100644 --- a/.github/skills/security/SKILL.md +++ b/.github/skills/security/SKILL.md @@ -295,4 +295,4 @@ Scope: [full/diff/dependency/config] - [STRIDE threat modeling (Microsoft)](https://learn.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats) - + diff --git a/.github/skills/space-setup/SKILL.md b/.github/skills/space-setup/SKILL.md index 2a6886e1..7b18080e 100644 --- a/.github/skills/space-setup/SKILL.md +++ b/.github/skills/space-setup/SKILL.md @@ -51,7 +51,7 @@ Set up a project Space that keeps Copilot context focused, current, and easy to 1. Create or update the Space using GitHub UI (or approved API workflow). 1. Validate discoverability: each key topic maps to at least one source document. 1. Record refresh cadence and owner. -1. Re-check after `vstack install` or release docs updates. +1. Re-check after major context source changes or release docs updates. ## Output format @@ -87,4 +87,4 @@ Provide this structure: Escalate when required docs are missing, stale, or inconsistent across product/architecture/design baselines. - + diff --git a/.github/skills/terraform/SKILL.md b/.github/skills/terraform/SKILL.md index 528328b9..91952005 100644 --- a/.github/skills/terraform/SKILL.md +++ b/.github/skills/terraform/SKILL.md @@ -335,4 +335,4 @@ Run `terraform plan` after every state operation to verify the outcome. - [tfsec rules](https://aquasecurity.github.io/tfsec/latest/checks/aws/) · [checkov checks](https://www.checkov.io/5.Policy%20Index/terraform.html) - + diff --git a/.github/skills/terragrunt/SKILL.md b/.github/skills/terragrunt/SKILL.md index 44f7ca02..a52fa871 100644 --- a/.github/skills/terragrunt/SKILL.md +++ b/.github/skills/terragrunt/SKILL.md @@ -307,4 +307,4 @@ Use `--terragrunt-non-interactive` in CI to prevent hanging on prompts. - [Gruntwork module registry](https://www.gruntwork.io/) - + diff --git a/.github/skills/threat-model/SKILL.md b/.github/skills/threat-model/SKILL.md index 20afb766..1d844845 100644 --- a/.github/skills/threat-model/SKILL.md +++ b/.github/skills/threat-model/SKILL.md @@ -245,4 +245,4 @@ For each high-priority threat include: - Final report is written to `docs/architecture/threat-model.md`. - + diff --git a/.github/skills/verify/SKILL.md b/.github/skills/verify/SKILL.md index 2681dadf..e49084cb 100644 --- a/.github/skills/verify/SKILL.md +++ b/.github/skills/verify/SKILL.md @@ -266,4 +266,4 @@ scope: [path/component/full] ``` - + diff --git a/.github/skills/vision/SKILL.md b/.github/skills/vision/SKILL.md index ae6b54f5..e9db400e 100644 --- a/.github/skills/vision/SKILL.md +++ b/.github/skills/vision/SKILL.md @@ -206,4 +206,4 @@ For each finding: explain the tradeoff, give an opinionated recommendation, ask Present as: "Overall assessment: [READY/NEEDS REVISION/SCOPE CHANGE] because [1-2 sentence reason]." - + diff --git a/.gitignore b/.gitignore index 5230db83..e82c93c0 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ env/ # Testing .pytest_cache/ +.pytest-tmp/ .vstack/tmp/ .hypothesis/ .nox/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 208efd43..066b2a08 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: - id: check-yaml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.15 + rev: v0.15.17 hooks: - id: ruff args: [--fix] diff --git a/.vstack/vstack.json b/.vstack/vstack.json index 1b9834f4..3757a5f5 100644 --- a/.vstack/vstack.json +++ b/.vstack/vstack.json @@ -1,134 +1,141 @@ { "manifest_version": 2, "hash_algorithm": "sha256", - "vstack_version": "3.3.0", - "installed_at": "2026-05-14T15:15:33.016787+00:00", + "vstack_version": "3.5.2", + "installed_at": "2026-06-18T21:27:59.158223+00:00", "artifacts": { "skills": [ { "name": "adr", "file": "skills/adr/SKILL.md", "version": "20260421003", - "checksum": "660cee62bfe5bdbc51c93e1e6d65c04ef26b0fc9c18b26dc8a9cfc6aa199994f", + "checksum": "d1a7118ffe80c1e3dabe5a9c61527649d94fed1919355c075b6d161cb298c488", "checksum_algorithm": "sha256" }, { "name": "analyse", "file": "skills/analyse/SKILL.md", "version": "20260421004", - "checksum": "7fc5684df41ba2cfd0508617362bb9027050f0d0101fe444472ceeb1ee07dd1f", + "checksum": "27958cda3e2ffa1069694b87b8037f1282b38c8a3062b53a0ba38bfcc6db2a6f", "checksum_algorithm": "sha256" }, { "name": "architecture", "file": "skills/architecture/SKILL.md", "version": "20260421005", - "checksum": "839a87531273f69845d2113954965cc9aa9e5fe045a42594b0fab4d5cd0e7338", + "checksum": "baec1e369565923b9b65c4454438c26660def4a1ca5b7dbb73831ee23c66d969", + "checksum_algorithm": "sha256" + }, + { + "name": "ask", + "file": "skills/ask/SKILL.md", + "version": "20260618001", + "checksum": "6fcc051e9dbf84d3982b028f8f570646507786c77f06f46fc94f3d9eb82dfcf6", "checksum_algorithm": "sha256" }, { "name": "aws-cli", "file": "skills/aws-cli/SKILL.md", "version": "20260502033", - "checksum": "6f3da80eb03666101bedddaabe3774d997f1fc31d4786dfd9b0ac8b2c4064a6c", + "checksum": "1a99a18d1d88ee59c619df917b770e25d06fde83775ec362103722ec56039128", "checksum_algorithm": "sha256" }, { "name": "cicd", "file": "skills/cicd/SKILL.md", "version": "20260421006", - "checksum": "bdb38ffafcff74f7d8b9efb65d4cd58f7c2c9a860566fdd3e4b33146b3ac8d7c", + "checksum": "c5cf78dff347011a2f0d4f4ad2bc6136ff13598fa79e622100052a62d27f1979", "checksum_algorithm": "sha256" }, { "name": "cloudformation", "file": "skills/cloudformation/SKILL.md", "version": "20260502032", - "checksum": "f8359146f2627e4722d89eab80c635c42612c4577a761702f7b18ca26db6b791", + "checksum": "b1ab1a0060cc3bc2d78dd491f6833fe82949e4599929876263d619c16570818c", "checksum_algorithm": "sha256" }, { "name": "code-review", "file": "skills/code-review/SKILL.md", "version": "20260421007", - "checksum": "abf20f1908d61edd0e2d7aabfc1e0d35267cafa8ba275e351f533164dd16245e", + "checksum": "73d7a84f1ff483c9c4740ede0565e25c687c2aa58f3e439570a151ea74bc6909", "checksum_algorithm": "sha256" }, { "name": "codeql", "file": "skills/codeql/SKILL.md", "version": "20260502026", - "checksum": "0639f1f709c1e59695dd10fca77eff0d95330d9d87022c8cfc69bd536779d95a", + "checksum": "9735fc168e6baa5838e15ea4f8476c5aff558b5c40c88778537f5747e8302fbb", "checksum_algorithm": "sha256" }, { "name": "concise", "file": "skills/concise/SKILL.md", "version": "20260421008", - "checksum": "7e92fd137f5e53a61c8cd0be7900e7213f8c2664eece7964d747e2894b17c412", + "checksum": "0898086a72de845312a44ae66c621ac151471575d0400d1e725fc601d131d410", "checksum_algorithm": "sha256" }, { "name": "consult", "file": "skills/consult/SKILL.md", "version": "20260421009", - "checksum": "2531a34f02e26444a8b3949665a2efaaa783ff54a7dcf5359ea289c093aea15a", + "checksum": "78a742f75405b390198682c4b589f599059ebe2bd0bbbed3ad4009c7b58d44d1", "checksum_algorithm": "sha256" }, { "name": "container", "file": "skills/container/SKILL.md", "version": "20260421010", - "checksum": "d9850dbc2cc08d449cb8e3d209bf43c161c635edb94853b5791df96cdc4f51d8", + "checksum": "8096db61dad4da7142b0b3af9f549de9a4d0e3724ce5b9825d11e1d26625aacd", "checksum_algorithm": "sha256" }, { "name": "conventional-commit", "file": "skills/conventional-commit/SKILL.md", "version": "20260502024", - "checksum": "31b240e3754ec56617fe1e9a63caa02b79219e70a924cd35cb14787d7e0be547", + "checksum": "911699e6975a38c5ba039fe51734dc6569464c4ddbfdefe543aa1fd1c0a3ebc2", "checksum_algorithm": "sha256" }, { "name": "copilot-ops", "file": "skills/copilot-ops/SKILL.md", "version": "20260513012", - "checksum": "b5727ee50c1b43b3a3cc03bf885e0ff8d04103792edb6d416615c0e387e6af4b", + "checksum": "66aad0602d1226ddedb187e8cacee120085f9d61918c15eea36e65d1c58e5e4b", "checksum_algorithm": "sha256" }, { "name": "debug", "file": "skills/debug/SKILL.md", "version": "20260421011", - "checksum": "acad2aa9f450cd3acf50e463ae4638f2fa0d0f826dcf89a3fd250759454d1259", + "checksum": "780ffc03fced9cd63784516c01d9093a04afa6716ae1bbb58f9623ad4e70a330", "checksum_algorithm": "sha256" }, { "name": "dependabot", "file": "skills/dependabot/SKILL.md", "version": "20260502027", - "checksum": "e8bec8a5d869e36db5e903f772ec3ec7cf4c53425f52ff344d6a3e50cf87cd74", + "checksum": "4af792ccf284ebd90cfff344981330860754ebd508a0972a5828041264ab13c2", "checksum_algorithm": "sha256" }, { "name": "dependency", "file": "skills/dependency/SKILL.md", "version": "20260421012", - "checksum": "63bb8ea35a4cd91a8f3ed3cf4a63538f319d0998b55fc192a65698c2882924dc", + "checksum": "efd6ac0f65563280f3b65c917ce0e0435f136a7b2b61b4235b73a6680054f4fa", "checksum_algorithm": "sha256" }, { "name": "design", "file": "skills/design/SKILL.md", "version": "20260421013", - "checksum": "38f5b8e4ae06b1c7ac5d34f3b20a20674889d7e8f111efd8cc7cbfc93883805c", + "checksum": "827f2096de17b79a15edda8dfe1c7eb725e57644b1e1849b84ff2436ab00b9f7", "checksum_algorithm": "sha256" }, { "name": "docs", "file": "skills/docs/SKILL.md", "version": "20260421014", - "checksum": "5b47bd9609692a0460cfbdb6c3a9a2d8df47bf33346248feccbf4932b342f193", + "checksum": "d1f846fd6f0c2060f3e14364d85fd36c3f844b7e87943041aae29b991ca87400", "checksum_algorithm": "sha256" }, { @@ -142,189 +149,189 @@ "name": "gdpr", "file": "skills/gdpr/SKILL.md", "version": "20260502029", - "checksum": "fc447778cf54e5cc2e9db9fa0afd148befd219bf75eca1b5cb52f5fab6a6b326", + "checksum": "b951685bf023719cdf1cca54da3123e3a49e9daaae605c9b2c8b3d8a0b621cf3", "checksum_algorithm": "sha256" }, { "name": "gh-issues", "file": "skills/gh-issues/SKILL.md", "version": "20260502025", - "checksum": "c23fe777594698b8966cee3f441eb9b83be03fe44113ed1fe8cf7f7a39437f21", + "checksum": "62e10f92ec8161ac4a6a462c639cdcf4fe6de6a8d8d6e78406baf3df674772ea", "checksum_algorithm": "sha256" }, { "name": "gh-release", "file": "skills/gh-release/SKILL.md", "version": "20260502023", - "checksum": "104748dbc32a0d71dc10b823aaf29cf40e5f043ebaf48e8d0ec05770c405a72f", + "checksum": "521a7e7a47858964becce87d67fc1b04be7a254f22042e4104b5f4ab8feec1de", "checksum_algorithm": "sha256" }, { "name": "guardrails", "file": "skills/guardrails/SKILL.md", "version": "20260421016", - "checksum": "a68bd4ace0d0b8336259c38f7a9040a07f9d5c128e8341ed11de009e272772b7", + "checksum": "e430676727efc0af0d2c90ad401fbe975fed605c1ab317433c395c30ef353cf3", "checksum_algorithm": "sha256" }, { "name": "helm", "file": "skills/helm/SKILL.md", "version": "20260502037", - "checksum": "f381e65e7f3d2f6d48e0f8bc4b60a43976007dd483df35fc6f47c0a4cc36f574", + "checksum": "d4aa2b14f3ded1fe66652078147d837f68274ed46865a45574a8181f6dc567a0", "checksum_algorithm": "sha256" }, { "name": "incident", "file": "skills/incident/SKILL.md", "version": "20260503002", - "checksum": "3f2f2d25d854f875fecacf0c37f011a371d9562c74fcdec33a2f6e2205280b86", + "checksum": "ffb4fe3d7ffa82e9631e5b1803ca2fd9cbe0face600a2f9ff279a988961d1438", "checksum_algorithm": "sha256" }, { "name": "inspect", "file": "skills/inspect/SKILL.md", "version": "20260421018", - "checksum": "326118838d0765a986303f156be13a1ed911d93bb8b98031213ad60df072341c", + "checksum": "b1479ec7127179e90b964a060def86c0537e4961c2dad358065a553e07c8c656", "checksum_algorithm": "sha256" }, { "name": "k8s", "file": "skills/k8s/SKILL.md", "version": "20260502036", - "checksum": "24c8b619676fa5dbdd9d37d303d0daa1749f9634b25d9a50f40145af92f58e1f", + "checksum": "dcb7daba10d8f5f29c5b1624ed3153d07ec9fbf5033e60106f862245f3a23f88", "checksum_algorithm": "sha256" }, { "name": "migrate", "file": "skills/migrate/SKILL.md", "version": "20260421019", - "checksum": "490cf5b4bd2c24c02f3582474342770de3185e127a1b5cabb1d11ac2e1368471", + "checksum": "027d8d23d9acded4bd2d4a48757b72c7038335ba2ec1a164b2a6a81ff3f431ef", "checksum_algorithm": "sha256" }, { "name": "onboard", "file": "skills/onboard/SKILL.md", "version": "20260421020", - "checksum": "821ef6e1d5b966bc766e93de2d0fac5b07beff6b613df96edaddaa837cfcf2fa", + "checksum": "210a550aa23c030308288873c0c9fcda20b3c7d6d56aa02af4d1e313018c1ae0", "checksum_algorithm": "sha256" }, { "name": "openapi", "file": "skills/openapi/SKILL.md", "version": "20260421021", - "checksum": "335ec305224de282ffebdac4ba7de85c39642ac24e5d5094ea75f3f65ec52458", + "checksum": "46d2a449339dc4e5b93824fd77d2188ce201e4028c6b22cb360704a3e5e0c61d", "checksum_algorithm": "sha256" }, { "name": "performance", "file": "skills/performance/SKILL.md", "version": "20260421022", - "checksum": "b5dfd2444ed586d9b28072fed3a9c68083967138292d278947dd3de1bbdacbac", + "checksum": "88fb845c2db58984f2c726153ab817d2df94f79e9cda0418206c2f64e9acad83", "checksum_algorithm": "sha256" }, { "name": "postmortem", "file": "skills/postmortem/SKILL.md", "version": "20260503001", - "checksum": "47db46e73a7d89e5f88ecf590935443ec72ce3a2c8e617c745c64f976f4b3de8", + "checksum": "3265d54b21248f3018b8c8de324f9d2ef931f9aa29ff86fffa7e630672ad8852", "checksum_algorithm": "sha256" }, { "name": "pr", "file": "skills/pr/SKILL.md", "version": "20260502013", - "checksum": "ddb2623a4a2f1b78928adc2c0b91d73bcde7e75f66971ab96e4e7a147029ce4b", + "checksum": "3ea70bf79776775b2174145604370240f212aefd524bb453474fe26faa518431", "checksum_algorithm": "sha256" }, { "name": "rancher", "file": "skills/rancher/SKILL.md", "version": "20260502038", - "checksum": "78c74f5f34fbf8645cf1c8f12fd2e5dd4ecc4c7ca6538a175c5b374c8f283685", + "checksum": "d9342961f22c3c074c2b56526f19146e9be804de989bcaf8825ccce864ab84dd", "checksum_algorithm": "sha256" }, { "name": "rca", "file": "skills/rca/SKILL.md", "version": "20260503001", - "checksum": "1b0e0b50fd1f0ffae4dc0f1efb2e7b11902e0cc82abc0db26eb4af3c33046e39", + "checksum": "d4064c4de4accb4516ea8b2589af1a99ea1849ca1ec68bf550b52b991726f86b", "checksum_algorithm": "sha256" }, { "name": "refactor", "file": "skills/refactor/SKILL.md", "version": "20260421023", - "checksum": "49e8ca19efb904cc8a76b6dc0d6ae0e8d98c09ec955aa7801329fd0c31953906", + "checksum": "9cc473ef664c14bf46d94ec72ff88f033d82f101378ffafdde2c1e8c95c63721", "checksum_algorithm": "sha256" }, { "name": "release-notes", "file": "skills/release-notes/SKILL.md", "version": "20260502014", - "checksum": "c577aab7c8fbfb7c36f200df915f38740bd80801b4ffa99f295ce45e46630dfe", + "checksum": "a79d3f80984742f6a0f72ad5e74aa97dd71671453457b2c6cbd80d22a08f079d", "checksum_algorithm": "sha256" }, { "name": "requirements", "file": "skills/requirements/SKILL.md", "version": "20260421024", - "checksum": "3abbb55f2f40116f49a2afdd44998569798f4a31a7d2f7a17321e919577862ff", + "checksum": "c9a1e46a4c900d3d1d5aca041a45e297a573049b817a6fa65404c70c2241af04", "checksum_algorithm": "sha256" }, { "name": "secret-scan", "file": "skills/secret-scan/SKILL.md", "version": "20260502028", - "checksum": "22e8c718ec7816a8ff5d7d23ab4a9b162078cca013a1a7dcb08ed70d44986a84", + "checksum": "2e178e00848c1d56b067bbd90a873b12a9cfb72ec7e11ac66e7734c37348ecfd", "checksum_algorithm": "sha256" }, { "name": "security", "file": "skills/security/SKILL.md", "version": "20260421025", - "checksum": "6d9932e00f748c279fa3d5797c10ab72f464417689239e3ab754d19635db56f8", + "checksum": "ff11a5019935a3bdc6812ead3ffc1c5ec168687084ee8f3270fff5c11b91df27", "checksum_algorithm": "sha256" }, { "name": "space-setup", "file": "skills/space-setup/SKILL.md", "version": "20260513011", - "checksum": "b51fa34b06f0e525a676d7710afc3141651c264a5066b202d27024223a2f9116", + "checksum": "541d52e3cb9bd2bb146cfcd5e15c221c1e2fd969e5d53ec95afd6936cead4d93", "checksum_algorithm": "sha256" }, { "name": "terraform", "file": "skills/terraform/SKILL.md", "version": "20260502030", - "checksum": "9c444d7820abcab11b5a9f1852d48ee0a8849b6ae84fc3b55fefcd0be01afb45", + "checksum": "0bf87febb18fb906b05089dd3e9a1ee30be6081af2500898772edf7ee093d04e", "checksum_algorithm": "sha256" }, { "name": "terragrunt", "file": "skills/terragrunt/SKILL.md", "version": "20260502031", - "checksum": "c554b16835ecdb6a25f255d7259cfd8743b4b62229d2046b32f086be3c62f137", + "checksum": "cffa2202419e8fb3044448ffbad3f429a901da80dc75ad34eb57027844965ebc", "checksum_algorithm": "sha256" }, { "name": "threat-model", "file": "skills/threat-model/SKILL.md", "version": "20260502021", - "checksum": "0f38e80568f3bdf79ad494c5a1a1df42e3f9a6266067e59912f7c3f94cfa6d3b", + "checksum": "63a94d7ba49319cd30f909bbe5c9b3bd568a1d407a820faa1062d33d1677ec4a", "checksum_algorithm": "sha256" }, { "name": "verify", "file": "skills/verify/SKILL.md", "version": "20260421026", - "checksum": "022a46d89e7f0649ebe48b83c8e45024d6b8dc5e98690b0e7f537c7bcd83b454", + "checksum": "d714ad908a70630fee45d6cccc08cd28240b45bfbb0d8934170ef3d41a5f422d", "checksum_algorithm": "sha256" }, { "name": "vision", "file": "skills/vision/SKILL.md", "version": "20260421027", - "checksum": "0eba784c38eaa7923e3e74973c26aba96f50de1540a42e2e9f448ab3b7be26ac", + "checksum": "a7834e34890c760358aab4367a0b00bcdde2cda5770074f32496c7b81b975eaa", "checksum_algorithm": "sha256" } ], @@ -333,49 +340,49 @@ "name": "architect", "file": "agents/architect.agent.md", "version": "20260514001", - "checksum": "f5825dcefab201323fd02cc24c4116ea3ff4e7c296def9fc145d26d1dbfa772c", + "checksum": "a0453c790c2e49323662a4b2211e6158edafdd332591474c3d939cda5585368c", "checksum_algorithm": "sha256" }, { "name": "designer", "file": "agents/designer.agent.md", "version": "20260514001", - "checksum": "b7287f9e6f4b5b827cecf1046f3c5a9040e5c39670ac92e33160846536bf3f9a", + "checksum": "08438715457d0216bbca4b368827b45413f4c09d92128bc24125fd79d8b072a5", "checksum_algorithm": "sha256" }, { "name": "engineer", "file": "agents/engineer.agent.md", "version": "20260514001", - "checksum": "61a849498e17ba97e7745e473e88ed87ce9ba8092fa52f8a1b4e83e3c52fe3c2", + "checksum": "3187faa902abe99b2944119f5a2eef8127861034228599e9576367159031e8e6", "checksum_algorithm": "sha256" }, { "name": "planner", "file": "agents/planner.agent.md", "version": "20260514001", - "checksum": "9e781e704a26ed3452a39d806f2707e2504573b19836470c1d990aa228dbf8c4", + "checksum": "d4622d23a90848b0d832c1826ca611bd3defb49507482f080a2bd3b40ccbe9e5", "checksum_algorithm": "sha256" }, { "name": "product", "file": "agents/product.agent.md", "version": "20260514001", - "checksum": "dca487d907f07564402e5ee438c53f798333f036a1cffce64dc4d3e606374347", + "checksum": "179f648e5d7e9d7f3b658d7d37850a9e88b48cd07ea2983fa4eba35394e577b8", "checksum_algorithm": "sha256" }, { "name": "release", "file": "agents/release.agent.md", "version": "20260514001", - "checksum": "7facd81e618c2dde4269d34d974330b080d9a72b9ecdcb4d9b5212fbebfefba1", + "checksum": "c6d0f7a94baea9142d9b6e4f10c2b9c97df71b623b9102a148beaf8f1e66331a", "checksum_algorithm": "sha256" }, { "name": "tester", "file": "agents/tester.agent.md", "version": "20260514001", - "checksum": "94afee30b6e36d163db40fe60df17887a88e925114ead51788ba699b13f894f6", + "checksum": "6fc99a5378200374712eb395305a8dd53ceb4b21607273524fdce3a402b4c6dd", "checksum_algorithm": "sha256" } ], @@ -384,84 +391,84 @@ "name": "git", "file": "instructions/git.instructions.md", "version": "20260421001", - "checksum": "50292cc92514aabafc923c2d5602dc3798b2cc53c64d3a1f3670eeb3e653774a", + "checksum": "ede529d47f678ca4edc702a2f11ee0d592bbd659406e96973544d0dad46a6ef4", "checksum_algorithm": "sha256" }, { "name": "helm", "file": "instructions/helm.instructions.md", "version": "20260502040", - "checksum": "5a790c2db1233c812f9f0489695007ed5279613679351b6d366733fb455673d1", + "checksum": "79ff2eaff0ff0d0c9796ff460e51367b89e0c088854b0506b88764ba376d0b7b", "checksum_algorithm": "sha256" }, { "name": "java", "file": "instructions/java.instructions.md", "version": "20260502001", - "checksum": "62128ca849d5801303f08aa510fb5dffc828280dfa62afacfbdacd4cb1a79c95", + "checksum": "fa1ff382f9afea8c4361a6f270a4bfc40e0eed348ced4980d4f8cf3062ab98ca", "checksum_algorithm": "sha256" }, { "name": "k8s", "file": "instructions/k8s.instructions.md", "version": "20260502039", - "checksum": "0cf9d21e7b5d8f1926fac733fdbfd57962e68fa261fabf069284094b36f1bca4", + "checksum": "0c148024ecbc67fbb118c1be8f79ac1e7110d72e3d8bd05492dc3f70bb82d2cf", "checksum_algorithm": "sha256" }, { "name": "markdown", "file": "instructions/markdown.instructions.md", "version": "20260502002", - "checksum": "29549348a1decc726120556759f4143969b76f09beae45e282f8f1de10525b5f", + "checksum": "c454f98405f1fa28e634114c09b6105a4978f9c5e5a80f25a5f92d8ab928fd1f", "checksum_algorithm": "sha256" }, { "name": "python", "file": "instructions/python.instructions.md", "version": "20260421002", - "checksum": "2048623b7be0ac88a7fd23506393e622623cd3adc08d3381b78f8b56246278f6", + "checksum": "1a1ec48c59d8c06042fd11e608628d5b95c98721c306307cd63a4464ddb4633b", "checksum_algorithm": "sha256" }, { "name": "rancher", "file": "instructions/rancher.instructions.md", "version": "20260502041", - "checksum": "ab02a63cb6608cbe401059abc7ddc53edf7babc81473beb6b79047fb630f827a", + "checksum": "70d23ecbbed475d9f194fc6942ecdffd9f38bd25d0f964c6587f38ff582091d9", "checksum_algorithm": "sha256" }, { "name": "security", "file": "instructions/security.instructions.md", "version": "20260502003", - "checksum": "26e6a131d5fa4c5d18aa6387298bb6cac0671952d7f755f3d54c20543f522164", + "checksum": "d76252eee3c7c2104ba7224cc036814ebd64bfd8a2ba313a896a3812e7b52c1f", "checksum_algorithm": "sha256" }, { "name": "terraform", "file": "instructions/terraform.instructions.md", "version": "20260502034", - "checksum": "1f289acb0fb7f5e40d5fa12b9089e61d66acb16b3102e80eb5a869b6ed8b1be0", + "checksum": "94b086415ef2df255d3d7b9ecc5ea26d137e7e6fa6052194aacedf220802e4e4", "checksum_algorithm": "sha256" }, { "name": "terragrunt", "file": "instructions/terragrunt.instructions.md", "version": "20260502035", - "checksum": "29d1fe7d0eb9acad2ccdbb08a64f6a27638302a95644b4889e1dcf27abfcb6ca", + "checksum": "73835aa567b9dd0fe2feb23ec12dcefb54c20d10e6c15ead44769a06b2263819", "checksum_algorithm": "sha256" }, { "name": "testing", "file": "instructions/testing.instructions.md", "version": "20260502004", - "checksum": "d9938a75a75a82b306fe70795493afdef6342636821a2fc3a5e583ecab119466", + "checksum": "0f6496700448188a02b94b55f6ba16b9a56bfc1e6a02d495ebcf8edfc1e79895", "checksum_algorithm": "sha256" }, { "name": "typescript", "file": "instructions/typescript.instructions.md", "version": "20260502005", - "checksum": "941a2aa7fd520db9d7b0b30af5dde179135b12c3a9cba059de498a4874708264", + "checksum": "11ef4a3d557c02d5ec7d3ed906bdee78b544238a31bf1262ef0a1c0bcbf7fd80", "checksum_algorithm": "sha256" } ], @@ -470,112 +477,112 @@ "name": "api-design-review", "file": "prompts/api-design-review.prompt.md", "version": "20260502006", - "checksum": "6144af4f462af890edf3a4e342feb05792fdf2ab678ff2187048e0f17a288a22", + "checksum": "8be0d1018797d93752aeb3391908a5545bfa94f48b4f48cca9cc5e3aaea9864e", "checksum_algorithm": "sha256" }, { "name": "architecture-risk", "file": "prompts/architecture-risk.prompt.md", "version": "20260502007", - "checksum": "895bb3e17af65b472dfb010dfa956954dce26b5213c8fee60b846fa1581b1d36", + "checksum": "979d5b160d0bf1cea5622b1faf5ea3cbf7e8530cb7fae82bb94315a231af1ed9", "checksum_algorithm": "sha256" }, { "name": "artifact-integrity", "file": "prompts/artifact-integrity.prompt.md", "version": "20260513002", - "checksum": "a51ff1fb889996bf1c0256d304b647f9670413cea4506de951f722deaf65fbf1", + "checksum": "6c892db0542b24113722182d29f0968346760ad3b5345f7d8e43be770248f95c", "checksum_algorithm": "sha256" }, { "name": "ci-triage", "file": "prompts/ci-triage.prompt.md", "version": "20260513006", - "checksum": "7f0d5e006fac21b32dfebf4c00b5dfb918205a86816feaa6466375d4cc939ed4", - "checksum_algorithm": "sha256" - }, - { - "name": "code-review", - "file": "prompts/code-review.prompt.md", - "version": "20260502008", - "checksum": "ad3d379f2305e693717f0a24decb6549fd82e30c021754d78a52b32e0f5e0b9e", + "checksum": "27ca3d26344c4148161077044dfb02574a45bd357b0cfdb9b11301ca5117f222", "checksum_algorithm": "sha256" }, { "name": "dependency-audit", "file": "prompts/dependency-audit.prompt.md", "version": "20260502009", - "checksum": "4d861e7b4c1fd55af72a0a260d9ce81487d7ab53bfa6bdb041de0c196e4e09a9", + "checksum": "57dc831fe7a2ef8a4877c09ef9288a5c97565eba6fe41b70e8fdf466e1685a6e", "checksum_algorithm": "sha256" }, { "name": "incident-timeline", "file": "prompts/incident-timeline.prompt.md", "version": "20260502010", - "checksum": "641bb8380390974ce7ce6753e30b748e6bd224175a6451b6a1077e4ab50891e0", + "checksum": "d7b4aba9d2507df5b5bbbdd03a35c88ef27002057c5ba45da04c3c6196c8ac4b", "checksum_algorithm": "sha256" }, { "name": "migration-plan", "file": "prompts/migration-plan.prompt.md", "version": "20260513010", - "checksum": "27e71a0c33c1067e58fa6d0fd1dd73711cdb3b24ced0cca8fee2f9c93a056219", + "checksum": "d9299c25ea9e37327c98017fc7ab6423e711f86bec7a1c7731f972b82a4a7af7", "checksum_algorithm": "sha256" }, { "name": "migration-safety", "file": "prompts/migration-safety.prompt.md", "version": "20260502011", - "checksum": "7dce672410844c8f84f29f2b50b1e046aaaa9d2cf5512bfb6b34140ea3c54619", + "checksum": "f2c4e7bf66d53dd60318247b3984749eaaa97dd6c48b3556234084557df4c9b8", "checksum_algorithm": "sha256" }, { "name": "ops-readiness", "file": "prompts/ops-readiness.prompt.md", "version": "20260513009", - "checksum": "f900b61282f2fee3c55f2dbb09f9fd3b30c73cc61b4433152bf144625e48cb19", + "checksum": "7a1f0f797ba6ddd718dfc3919a9cf231eddfdb28a11039e64651ca80cb473dca", + "checksum_algorithm": "sha256" + }, + { + "name": "quick-review", + "file": "prompts/quick-review.prompt.md", + "version": "20260502008", + "checksum": "8dee6c82ce7e7c32dfd1ebfa25358d40f8d5f2c283bf5e81b5bb54de86f49133", "checksum_algorithm": "sha256" }, { "name": "release-check", "file": "prompts/release-check.prompt.md", "version": "20260513004", - "checksum": "a86cfabdd3a578bb1a862d9d3f58da7b98b37ce17f99f43767192eb2c43a5dd5", + "checksum": "cab13f10f1bc5aad1f51faa70b24b50ee2a03a21e827af0fbf0d0dee80609018", "checksum_algorithm": "sha256" }, { "name": "repo-assessment", "file": "prompts/repo-assessment.prompt.md", "version": "20260513001", - "checksum": "3f6c684e633576ff96dae2dfc2f482f80494b590645cd313a207c59cbc54bc11", + "checksum": "0d322d57b762cc754e539b251c3f66a5c7c5e0060034d912fbd423f309276cd5", "checksum_algorithm": "sha256" }, { "name": "template-impact", "file": "prompts/template-impact.prompt.md", "version": "20260513005", - "checksum": "ce5afc1b4b9664530a897f5f432148c93cda6ef4ffceaa750df70012c1f5cded", + "checksum": "7eedc035cf2c485c93427ac2e15fccd94acca399be18b1b2032ccdf5d5459ef0", "checksum_algorithm": "sha256" }, { "name": "test-gaps", "file": "prompts/test-gaps.prompt.md", "version": "20260513007", - "checksum": "a3e7cfcbe5c0725ddaaa9739d1b06554bd2bbdd2350ed42df893b17f4e0b6a36", + "checksum": "0b86d3e6fa5d342f38703cfdadbf03dfc9c28f44cad66a77e724b2d27614d7b1", "checksum_algorithm": "sha256" }, { "name": "upgrade-plan", "file": "prompts/upgrade-plan.prompt.md", "version": "20260513008", - "checksum": "0fdebb072412f09f090f57c921ead6324e531948f2eca686b146445afd25867b", + "checksum": "d136dcb807854b25f8346d378b3e33aebe8711674d2d76acfc9189e0d44abdc3", "checksum_algorithm": "sha256" }, { "name": "workflow-check", "file": "prompts/workflow-check.prompt.md", "version": "20260513003", - "checksum": "e4c5ad55fa1f494c45b24e5cea49e798a3d57055992755f4c03187a177a65f15", + "checksum": "7eceb8d766731806efc16225c6e309cf42859f4bddf68e958d0ed79ff4d8f0a3", "checksum_algorithm": "sha256" } ], @@ -583,50 +590,50 @@ { "name": "agent-call-audit", "file": "hooks/agent-call-audit.json", - "version": "3.3.0", - "checksum": "71552673112f56307087074e30563c726331fddb0f6b21256ac3ac083e6485ae", + "version": "3.5.2", + "checksum": "a03cc5df031670dd4902599048a9fc955a852862b2cb73408f5889ee74baa636", "checksum_algorithm": "sha256" }, { "name": "log-retention-cleanup", "file": "hooks/log-retention-cleanup.json", - "version": "3.3.0", - "checksum": "76f2ecb32c1ed259ee155a2e3f3332a06dffdb3d25514b62b3e81e9c2a1b9cad", + "version": "3.5.2", + "checksum": "2c3048637dc0f85b7196934b0f6c5a2ee9a21739b45bc7a529e2f5531f2b2609", "checksum_algorithm": "sha256" }, { "name": "post-commit-security-scan", "file": "hooks/post-commit-security-scan.json", - "version": "3.3.0", - "checksum": "56d0238d2a3ae556c62c1aa75fbd75449f1037fae70e85fdc4c88d87d262d183", + "version": "3.5.2", + "checksum": "154305889deb5676a6b7d686400b14b4237687be130438d19843341addbdff8e", "checksum_algorithm": "sha256" }, { "name": "post-edit-format", "file": "hooks/post-edit-format.json", - "version": "3.3.0", - "checksum": "26fc1244e2e5d549c3327e1993ccad078c6f6522239979f0e6b010f1edf9b111", + "version": "3.5.2", + "checksum": "5911a2fc0211b268749e5200db8d43eec953f456294c8cbc5556cea9ab11f875", "checksum_algorithm": "sha256" }, { "name": "post-edit-markdown-quality", "file": "hooks/post-edit-markdown-quality.json", - "version": "3.3.0", - "checksum": "ee0458ddcfca3d38714cf50c9b41741ef89ac3f99b3e4736ad449e5a4c07d972", + "version": "3.5.2", + "checksum": "b8ef6b1805492a580902675ccd16564c693ec2ccf30fdb81d6b1d8dce610ab22", "checksum_algorithm": "sha256" }, { "name": "pre-tool-safety-gate", "file": "hooks/pre-tool-safety-gate.json", - "version": "3.3.0", - "checksum": "d6de87491ae43cfa1a99b7fe8293f4f18e0568125f9fcd37a2c6a58fba6c84b7", + "version": "3.5.2", + "checksum": "1d55d6c9cee6137472e37c9e16febb5a96419fc0813c4c474af5a50ee03ee5a0", "checksum_algorithm": "sha256" }, { "name": "session-audit", "file": "hooks/session-audit.json", - "version": "3.3.0", - "checksum": "df02c7bb679f6c2512171c51f266c2d9fed26908fe249a9f2912c44fbd7e8f44", + "version": "3.5.2", + "checksum": "0190aa65dfea26b2129ad8a5304377b2d40febf03779f561194e788bb8b27bfa", "checksum_algorithm": "sha256" } ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 9173f1f9..45f2f6db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,85 +4,73 @@ ## [3.5.2](https://github.com/eschaar/vstack/compare/3.5.1...3.5.2) (2026-06-09) - ### Maintenance -* **ci:** bump the gha-patch-minor group with 2 updates ([#73](https://github.com/eschaar/vstack/issues/73)) ([7c322ec](https://github.com/eschaar/vstack/commit/7c322ec62c4d75f453f415b8e1603ff6e8385ed9)) -* **deps:** bump the pip-patch-minor group with 2 updates ([#72](https://github.com/eschaar/vstack/issues/72)) ([45801fe](https://github.com/eschaar/vstack/commit/45801fe7192ab90032ddfec99e2e7c3dd679096e)) +- **ci:** bump the gha-patch-minor group with 2 updates ([#73](https://github.com/eschaar/vstack/issues/73)) ([7c322ec](https://github.com/eschaar/vstack/commit/7c322ec62c4d75f453f415b8e1603ff6e8385ed9)) +- **deps:** bump the pip-patch-minor group with 2 updates ([#72](https://github.com/eschaar/vstack/issues/72)) ([45801fe](https://github.com/eschaar/vstack/commit/45801fe7192ab90032ddfec99e2e7c3dd679096e)) ## [3.5.1](https://github.com/eschaar/vstack/compare/3.5.0...3.5.1) (2026-06-02) - ### Fixes -* **ci:** fix Homebrew token action for publish workflow ([#69](https://github.com/eschaar/vstack/issues/69)) ([f2bd2b1](https://github.com/eschaar/vstack/commit/f2bd2b1e0ee4a7d21b4c73e1bc1971caee7ea474)) +- **ci:** fix Homebrew token action for publish workflow ([#69](https://github.com/eschaar/vstack/issues/69)) ([f2bd2b1](https://github.com/eschaar/vstack/commit/f2bd2b1e0ee4a7d21b4c73e1bc1971caee7ea474)) ## [3.5.0](https://github.com/eschaar/vstack/compare/3.4.2...3.5.0) (2026-06-02) - ### Features -* add Homebrew distribution channel for vstack ([#66](https://github.com/eschaar/vstack/issues/66)) ([6939f31](https://github.com/eschaar/vstack/commit/6939f31e5f9c09492bcd0532dd7626823e8e0f7a)) - +- add Homebrew distribution channel for vstack ([#66](https://github.com/eschaar/vstack/issues/66)) ([6939f31](https://github.com/eschaar/vstack/commit/6939f31e5f9c09492bcd0532dd7626823e8e0f7a)) ### Fixes -* **ci:** harden Homebrew publish workflow auth and environment separation ([#68](https://github.com/eschaar/vstack/issues/68)) ([3651714](https://github.com/eschaar/vstack/commit/3651714997f6b6c3988f974c8985ec6a6fd0d463)) +- **ci:** harden Homebrew publish workflow auth and environment separation ([#68](https://github.com/eschaar/vstack/issues/68)) ([3651714](https://github.com/eschaar/vstack/commit/3651714997f6b6c3988f974c8985ec6a6fd0d463)) ## [3.5.0](https://github.com/eschaar/vstack/compare/3.4.2...3.5.0) (2026-06-02) - ### Features -* **ci:** add homebrew private tap publish job ([feature/publish_in_homebrew](https://github.com/eschaar/vstack/tree/feature/publish_in_homebrew)) - +- **ci:** add homebrew private tap publish job ([feature/publish_in_homebrew](https://github.com/eschaar/vstack/tree/feature/publish_in_homebrew)) ### Documentation -* **architecture:** add ADR-030 and homebrew distribution plan -* **cicd:** extend workflow table and sequence diagram with homebrew tap stage -* **design:** update workflow.md publish.yml description -* **product:** add FR-8 homebrew distribution requirement; align roadmap - +- **architecture:** add ADR-030 and homebrew distribution plan +- **cicd:** extend workflow table and sequence diagram with homebrew tap stage +- **design:** update workflow.md publish.yml description +- **product:** add FR-8 homebrew distribution requirement; align roadmap ### Tests -* **ci:** add publish workflow contract tests for homebrew job +- **ci:** add publish workflow contract tests for homebrew job ## [3.4.2](https://github.com/eschaar/vstack/compare/3.4.1...3.4.2) (2026-05-28) - ### Maintenance -* **ci:** handle disabled auto-merge gracefully ([ac91e78](https://github.com/eschaar/vstack/commit/ac91e780f1e6e9c0746683f186a47716a8c8ca12)) -* **ci:** updated dependencies ([576d27d](https://github.com/eschaar/vstack/commit/576d27db9e296da685c3849347453de2e0a13a03)) +- **ci:** handle disabled auto-merge gracefully ([ac91e78](https://github.com/eschaar/vstack/commit/ac91e780f1e6e9c0746683f186a47716a8c8ca12)) +- **ci:** updated dependencies ([576d27d](https://github.com/eschaar/vstack/commit/576d27db9e296da685c3849347453de2e0a13a03)) ## [3.4.1](https://github.com/eschaar/vstack/compare/3.4.0...3.4.1) (2026-05-19) - ### Maintenance -* **ci:** bump actions/create-github-app-token ([351e2cb](https://github.com/eschaar/vstack/commit/351e2cb1c312b4a5406bbf698e73ed0b81ee1137)) -* **ci:** bump actions/github-script ([e17ddb0](https://github.com/eschaar/vstack/commit/e17ddb0a5b5d75b6c59580b6f50c254964774a5d)) -* **ci:** bump googleapis/release-please-action ([805e319](https://github.com/eschaar/vstack/commit/805e3194eec77c83a6dc6c2ab7572f3e8fbeb293)) +- **ci:** bump actions/create-github-app-token ([351e2cb](https://github.com/eschaar/vstack/commit/351e2cb1c312b4a5406bbf698e73ed0b81ee1137)) +- **ci:** bump actions/github-script ([e17ddb0](https://github.com/eschaar/vstack/commit/e17ddb0a5b5d75b6c59580b6f50c254964774a5d)) +- **ci:** bump googleapis/release-please-action ([805e319](https://github.com/eschaar/vstack/commit/805e3194eec77c83a6dc6c2ab7572f3e8fbeb293)) ## [3.4.0](https://github.com/eschaar/vstack/compare/3.3.0...3.4.0) (2026-05-14) - ### Features -* **workflow:** improve planner routing and stabilize artifact generation ([0cf4bd2](https://github.com/eschaar/vstack/commit/0cf4bd2db4e62774d958363cd3b3c9c89a24d666)) - +- **workflow:** improve planner routing and stabilize artifact generation ([0cf4bd2](https://github.com/eschaar/vstack/commit/0cf4bd2db4e62774d958363cd3b3c9c89a24d666)) ### Fixes -* **ci:** ignore vstack metadata version-only drift in verify guard ([41bac6f](https://github.com/eschaar/vstack/commit/41bac6f87dd5c54abda580dfad2d5c1e523a877f)) -* **docs:** align examples and pytest temp path guidance ([7d26d52](https://github.com/eschaar/vstack/commit/7d26d5219f08368d8f62990cc999c143ad7c5e55)) - +- **ci:** ignore vstack metadata version-only drift in verify guard ([41bac6f](https://github.com/eschaar/vstack/commit/41bac6f87dd5c54abda580dfad2d5c1e523a877f)) +- **docs:** align examples and pytest temp path guidance ([7d26d52](https://github.com/eschaar/vstack/commit/7d26d5219f08368d8f62990cc999c143ad7c5e55)) ### Maintenance -* **ci:** bump trufflesecurity/trufflehog ([722d74e](https://github.com/eschaar/vstack/commit/722d74eacf73e1bd4f193beccf74ada8858b6b5f)) +- **ci:** bump trufflesecurity/trufflehog ([722d74e](https://github.com/eschaar/vstack/commit/722d74eacf73e1bd4f193beccf74ada8858b6b5f)) ## [3.3.0](https://github.com/eschaar/vstack/compare/3.2.0...3.3.0) (2026-05-12) diff --git a/docs/architecture/adr/020-install-init-command-semantics.md b/docs/architecture/adr/020-install-init-command-semantics.md index 8bb8d632..1787ed43 100644 --- a/docs/architecture/adr/020-install-init-command-semantics.md +++ b/docs/architecture/adr/020-install-init-command-semantics.md @@ -54,13 +54,14 @@ location changes) and remains a separate, explicit command. ### conservative policy for `.github/` (inherited from ADR-015) -| Flag | Behaviour | -| --------------------- | ------------------------------------------------------------------------------ | -| _(default)_ | Skip untracked files; skip modified tracked files; replace clean tracked files | -| `--force` | Overwrite all target files | -| `--force-name ` | Overwrite one named artifact | -| `--adopt-name ` | Take ownership of an untracked file without overwriting | -| `--update` | Overwrite clean tracked files; skip locally modified files | +| Flag | Behaviour | +| --------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| _(default)_ | Skip untracked files; skip modified tracked files; replace clean tracked files; report obsolete candidates without removing | +| `--force` | Overwrite all target files | +| `--force-name ` | Overwrite one named artifact | +| `--adopt-name ` | Take ownership of an untracked file without overwriting | +| `--update` | Overwrite clean tracked files; skip locally modified files | +| `--prune` | Remove obsolete tracked artifacts that are clean (checksum matches manifest); preserve locally modified obsolete files | ### additive policy for `.vstack/templates/` and `docs/` diff --git a/docs/architecture/homebrew-publish-plan.md b/docs/architecture/homebrew-publish-plan.md index 719485c8..2b35bbe3 100644 --- a/docs/architecture/homebrew-publish-plan.md +++ b/docs/architecture/homebrew-publish-plan.md @@ -14,15 +14,15 @@ ______________________________________________________________________ ## decision: private tap vs homebrew-core -| Factor | Private tap | homebrew-core | -|---|---|---| -| Setup time | Hours | Days–weeks (PR review) | -| Release automation | Full control | Maintainers must submit bump PRs or use bots | -| Acceptance bar | None | 30-day PyPI history, notable adoption, strict criteria | -| Install UX | `brew tap eschaar/vstack && brew install vstack` | `brew install vstack` | -| Formula ownership | Maintainer-owned | Homebrew project | -| Update autonomy | Immediate | Subject to Homebrew review cycles | -| Blast radius on mistake | Isolated tap repo | Homebrew-core infrastructure | +| Factor | Private tap | homebrew-core | +| ----------------------- | ------------------------------------------------ | ------------------------------------------------------ | +| Setup time | Hours | Days–weeks (PR review) | +| Release automation | Full control | Maintainers must submit bump PRs or use bots | +| Acceptance bar | None | 30-day PyPI history, notable adoption, strict criteria | +| Install UX | `brew tap eschaar/vstack && brew install vstack` | `brew install vstack` | +| Formula ownership | Maintainer-owned | Homebrew project | +| Update autonomy | Immediate | Subject to Homebrew review cycles | +| Blast radius on mistake | Isolated tap repo | Homebrew-core infrastructure | **Recommendation: private tap now, homebrew-core later.** @@ -38,7 +38,7 @@ The current release pipeline has two stages: 1. `release.yml` — merge to `main` triggers release-please; on release PR merge, creates the SemVer tag and GitHub Release. -2. `publish.yml` — triggered on `release: published`; builds and publishes the wheel and +1. `publish.yml` — triggered on `release: published`; builds and publishes the wheel and sdist to PyPI. Homebrew publishing inserts as a third, sequential stage after PyPI publish succeeds. @@ -68,11 +68,11 @@ sequenceDiagram TAP->>U: install from formula (virtualenv wrapping sdist) ``` - Install UX constraints in this phase: +Install UX constraints in this phase: - - The private tap path supports plain `brew install vstack` after a one-time `brew tap eschaar/vstack`. - - The fully-qualified fallback `brew install eschaar/vstack/vstack` remains valid without a prior tap. - - Universal plain `brew install vstack` for users who never tapped requires formula acceptance in `Homebrew/homebrew-core`. +- The private tap path supports plain `brew install vstack` after a one-time `brew tap eschaar/vstack`. +- The fully-qualified fallback `brew install eschaar/vstack/vstack` remains valid without a prior tap. +- Universal plain `brew install vstack` for users who never tapped requires formula acceptance in `Homebrew/homebrew-core`. ______________________________________________________________________ @@ -163,9 +163,9 @@ ______________________________________________________________________ ### checksum verification 1. The publish workflow fetches the sdist tarball from PyPI. -2. It computes `sha256sum` locally and also reads the sha256 from the PyPI JSON API. -3. The two values must match before the workflow proceeds. -4. The tap formula embeds the verified sha256; Homebrew verifies it again at install time. +1. It computes `sha256sum` locally and also reads the sha256 from the PyPI JSON API. +1. The two values must match before the workflow proceeds. +1. The tap formula embeds the verified sha256; Homebrew verifies it again at install time. ### supply-chain hardening @@ -282,58 +282,58 @@ ______________________________________________________________________ ### initial bootstrap 1. Create `github.com/eschaar/homebrew-vstack` as a public repository. -2. Add `Formula/` directory and commit the initial `Formula/vstack.rb` for the latest +1. Add `Formula/` directory and commit the initial `Formula/vstack.rb` for the latest released version. Compute the sha256 with: ```bash curl -fsSL https://files.pythonhosted.org/packages/source/v/vstack/vstack-X.Y.Z.tar.gz \ | sha256sum ``` -3. Add and enable `formula-update.yml` and `test.yml` workflows in the tap repo. -4. Set branch protection on `main`: require `test.yml` to pass. -5. Create a fine-grained PAT with `contents: write` scope limited to `homebrew-vstack`. +1. Add and enable `formula-update.yml` and `test.yml` workflows in the tap repo. +1. Set branch protection on `main`: require `test.yml` to pass. +1. Create a fine-grained PAT with `contents: write` scope limited to `homebrew-vstack`. Store it as secret `HOMEBREW_TAP_TOKEN` in the `pypi` Actions environment of this repo. -6. Pin the `peter-evans/repository-dispatch` action to a full commit SHA in `publish.yml`. -7. Merge the `publish-homebrew` job into `publish.yml` behind a feature flag +1. Pin the `peter-evans/repository-dispatch` action to a full commit SHA in `publish.yml`. +1. Merge the `publish-homebrew` job into `publish.yml` behind a feature flag (`HOMEBREW_TAP_ENABLED: "true"` env var) for safe rollout. -8. Run a manual test: publish a dry-run release (or trigger `workflow_dispatch`) and +1. Run a manual test: publish a dry-run release (or trigger `workflow_dispatch`) and verify the tap formula is updated correctly. -9. Document install instructions in `README.md` once bootstrap is validated. +1. Document install instructions in `README.md` once bootstrap is validated. ### recurring release flow (maintainer view) Every release follows the existing process unchanged. The only additions are: 1. After `release.yml` creates the GitHub Release, `publish.yml` runs as before. -2. The new `publish-homebrew` job triggers automatically after PyPI publish succeeds. -3. Monitor the tap repo's `formula-update.yml` run to confirm success. -4. `brew update && brew upgrade vstack` on the release engineer's machine to confirm +1. The new `publish-homebrew` job triggers automatically after PyPI publish succeeds. +1. Monitor the tap repo's `formula-update.yml` run to confirm success. +1. `brew update && brew upgrade vstack` on the release engineer's machine to confirm the new version installs correctly. ### rollback and fix-forward -| Scenario | Action | -|---|---| -| Formula update committed with wrong sha256 | Manually push a corrected formula commit to the tap repo; no effect on PyPI | -| `formula-update.yml` fails mid-run | Re-run the workflow from the tap repo Actions UI; it is idempotent | -| Tap formula test fails | Push a fix commit to `Formula/vstack.rb`; the test workflow re-runs | +| Scenario | Action | +| ------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| Formula update committed with wrong sha256 | Manually push a corrected formula commit to the tap repo; no effect on PyPI | +| `formula-update.yml` fails mid-run | Re-run the workflow from the tap repo Actions UI; it is idempotent | +| Tap formula test fails | Push a fix commit to `Formula/vstack.rb`; the test workflow re-runs | | PyPI publish succeeds but Homebrew dispatch fails | Trigger `publish-homebrew` job via `workflow_dispatch` on `publish.yml` with the release tag | -| Wrong version formula is live | Push a corrected formula commit; advise users to `brew update && brew upgrade vstack` | -| `HOMEBREW_TAP_TOKEN` expires | Rotate PAT, update secret; no user-visible impact until next release | +| Wrong version formula is live | Push a corrected formula commit; advise users to `brew update && brew upgrade vstack` | +| `HOMEBREW_TAP_TOKEN` expires | Rotate PAT, update secret; no user-visible impact until next release | ______________________________________________________________________ ## risk register -| Risk | Likelihood | Impact | Mitigation | -|---|---|---|---| -| PyPI tarball URL changes format | Low | High | Read URL from PyPI JSON API dynamically, not hardcoded | -| Tap dispatch token leaked | Low | Medium | Fine-grained PAT scoped to tap repo only; rotate on any exposure | -| sha256 mismatch at install (supply chain attack) | Very low | Critical | Double-verify: PyPI metadata vs downloaded tarball; Homebrew verifies again | -| `formula-update.yml` pushes a broken formula | Low | Medium | Branch protection + `test.yml` gate on `main`; fix-forward is low-friction | -| PyPI publish succeeds but tap update fails silently | Medium | Low | Add required status check or Slack/issue notification on failure | -| Homebrew-core submission rejected later | Low | Low | Private tap provides immediate value; core submission is optional | -| PyYAML resource block falls out of sync | Medium | Medium | Add a release checklist item: verify tap resource versions match `pyproject.toml` | -| Rate limiting on PyPI JSON API from CI | Very low | Low | Cache the JSON response in the workflow step; retry once | +| Risk | Likelihood | Impact | Mitigation | +| --------------------------------------------------- | ---------- | -------- | --------------------------------------------------------------------------------- | +| PyPI tarball URL changes format | Low | High | Read URL from PyPI JSON API dynamically, not hardcoded | +| Tap dispatch token leaked | Low | Medium | Fine-grained PAT scoped to tap repo only; rotate on any exposure | +| sha256 mismatch at install (supply chain attack) | Very low | Critical | Double-verify: PyPI metadata vs downloaded tarball; Homebrew verifies again | +| `formula-update.yml` pushes a broken formula | Low | Medium | Branch protection + `test.yml` gate on `main`; fix-forward is low-friction | +| PyPI publish succeeds but tap update fails silently | Medium | Low | Add required status check or Slack/issue notification on failure | +| Homebrew-core submission rejected later | Low | Low | Private tap provides immediate value; core submission is optional | +| PyYAML resource block falls out of sync | Medium | Medium | Add a release checklist item: verify tap resource versions match `pyproject.toml` | +| Rate limiting on PyPI JSON API from CI | Very low | Low | Cache the JSON response in the workflow step; retry once | ______________________________________________________________________ diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md index 811c3b4a..ae83f89f 100644 --- a/docs/architecture/overview.md +++ b/docs/architecture/overview.md @@ -187,16 +187,16 @@ ______________________________________________________________________ These bind architecture decisions. Full list in `docs/product/requirements.md`. -| ID | Requirement | Architectural binding | -| ----- | --------------------------------------------------------------------------------- | ---------------------------------------------------------- | -| NFR-1 | No external binary dependencies in skill template content | ADR-006; one pip dependency (`pyyaml`) allowed per ADR-025 | -| NFR-2 | Python 3.11–3.14 compatibility | ADR-007 | -| NFR-3 | Manifest writes are atomic | ADR-016 | -| NFR-4 | All public behavior covered by automated tests; CI enforces test pass | `tests/` structure, `verify.yml` workflow | -| NFR-5 | CLI operates standalone; no VS Code process required for CLI operations | ADR-006; only `pyyaml` required at runtime (ADR-025) | -| NFR-6 | Lint and type checking pass on every commit; CI gate enforces zero violations | `pyproject.toml` ruff + mypy config | -| NFR-7 | Generated output lives under `.github/` only; templates never modified at runtime | ADR-012 | -| NFR-8 | Homebrew formula updates require dual SHA-256 verification (PyPI metadata vs downloaded tarball); pre-release tags are excluded from Homebrew publish | ADR-030 | +| ID | Requirement | Architectural binding | +| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | +| NFR-1 | No external binary dependencies in skill template content | ADR-006; one pip dependency (`pyyaml`) allowed per ADR-025 | +| NFR-2 | Python 3.11–3.14 compatibility | ADR-007 | +| NFR-3 | Manifest writes are atomic | ADR-016 | +| NFR-4 | All public behavior covered by automated tests; CI enforces test pass | `tests/` structure, `verify.yml` workflow | +| NFR-5 | CLI operates standalone; no VS Code process required for CLI operations | ADR-006; only `pyyaml` required at runtime (ADR-025) | +| NFR-6 | Lint and type checking pass on every commit; CI gate enforces zero violations | `pyproject.toml` ruff + mypy config | +| NFR-7 | Generated output lives under `.github/` only; templates never modified at runtime | ADR-012 | +| NFR-8 | Homebrew formula updates require dual SHA-256 verification (PyPI metadata vs downloaded tarball); pre-release tags are excluded from Homebrew publish | ADR-030 | ______________________________________________________________________ @@ -258,35 +258,35 @@ ______________________________________________________________________ All significant architectural decisions are recorded in `docs/architecture/adr/`. See individual files for context, decision, alternatives, and rationale. -| ADR | Title | Status | Notes | -| --- | ---------------------------------------------------- | ---------- | ------------------------------------------ | -| 001 | VS Code-native variant | accepted | | -| 002 | Artifact naming and compatibility policy | accepted | | -| 003 | Backend-first verify | accepted | | -| 004 | Direct execution and orchestrated pipeline | superseded | Superseded by ADR-024 | -| 005 | VS Code prompt format | superseded | Superseded by ADR-009 | -| 006 | No runtime dependency on external binaries | accepted | | -| 007 | Python runtime | accepted | | -| 008 | Agents over prompts | accepted | | -| 009 | 6-role agent model | accepted | | -| 010 | Artifact flow | accepted | | -| 011 | Skill restructure | accepted | | -| 012 | Flat templates and install-time generation | accepted | | -| 013 | Policy vs procedure boundary for instructions/skills | accepted | | -| 014 | Manifest schema versioning and explicit upgrade gate | accepted | | -| 015 | Conservative install-by-default | superseded | Superseded by ADR-020 | -| 016 | Atomic manifest writes | accepted | | -| 017 | Checksum backfill on upgrade | accepted | | -| 018 | Skill genericity boundary | accepted | | -| 019 | `.vstack/` project-scope directory | accepted | Introduced `.vstack/` directory | -| 020 | `install` and `init` command semantics | accepted | Breaking change; supersedes ADR-015 | -| 021 | Config-driven artifact paths in agent config | accepted | Machine-readable artifact ownership | -| 022 | Selective exclude filter in `.vstack/config.yaml` | accepted | Agents cannot be excluded (atomic unit) | -| 023 | Workflow contract in `.vstack/config.yaml` | accepted | Pipeline order, gate, hitl, handoffs | -| 024 | Subagent orchestration via VS Code native subagents | accepted | Supersedes ADR-004; planner coordinator | -| 025 | PyYAML as sole runtime dependency | accepted | Replaces hand-rolled frontmatter parser | -| 026 | Docs artifact migration policy | accepted | Versioned docs relocation maps | -| 027 | Repository hooks as first-class artifact type | accepted | Hook templates and manifest ownership | -| 028 | DAG dependency semantics for workflow stages | accepted | `depends_on`, cycle safety, compatibility | -| 029 | Multi-agentic execution model | accepted | DAG chosen; event-driven and tree compared | +| ADR | Title | Status | Notes | +| --- | ---------------------------------------------------- | ---------- | --------------------------------------------- | +| 001 | VS Code-native variant | accepted | | +| 002 | Artifact naming and compatibility policy | accepted | | +| 003 | Backend-first verify | accepted | | +| 004 | Direct execution and orchestrated pipeline | superseded | Superseded by ADR-024 | +| 005 | VS Code prompt format | superseded | Superseded by ADR-009 | +| 006 | No runtime dependency on external binaries | accepted | | +| 007 | Python runtime | accepted | | +| 008 | Agents over prompts | accepted | | +| 009 | 6-role agent model | accepted | | +| 010 | Artifact flow | accepted | | +| 011 | Skill restructure | accepted | | +| 012 | Flat templates and install-time generation | accepted | | +| 013 | Policy vs procedure boundary for instructions/skills | accepted | | +| 014 | Manifest schema versioning and explicit upgrade gate | accepted | | +| 015 | Conservative install-by-default | superseded | Superseded by ADR-020 | +| 016 | Atomic manifest writes | accepted | | +| 017 | Checksum backfill on upgrade | accepted | | +| 018 | Skill genericity boundary | accepted | | +| 019 | `.vstack/` project-scope directory | accepted | Introduced `.vstack/` directory | +| 020 | `install` and `init` command semantics | accepted | Breaking change; supersedes ADR-015 | +| 021 | Config-driven artifact paths in agent config | accepted | Machine-readable artifact ownership | +| 022 | Selective exclude filter in `.vstack/config.yaml` | accepted | Agents cannot be excluded (atomic unit) | +| 023 | Workflow contract in `.vstack/config.yaml` | accepted | Pipeline order, gate, hitl, handoffs | +| 024 | Subagent orchestration via VS Code native subagents | accepted | Supersedes ADR-004; planner coordinator | +| 025 | PyYAML as sole runtime dependency | accepted | Replaces hand-rolled frontmatter parser | +| 026 | Docs artifact migration policy | accepted | Versioned docs relocation maps | +| 027 | Repository hooks as first-class artifact type | accepted | Hook templates and manifest ownership | +| 028 | DAG dependency semantics for workflow stages | accepted | `depends_on`, cycle safety, compatibility | +| 029 | Multi-agentic execution model | accepted | DAG chosen; event-driven and tree compared | | 030 | Homebrew distribution via private tap | accepted | Private tap now; homebrew-core optional later | diff --git a/docs/design/agents.md b/docs/design/agents.md index 578671f1..66dd7b4d 100644 --- a/docs/design/agents.md +++ b/docs/design/agents.md @@ -67,21 +67,21 @@ Style rule: long `description` and `handoffs.prompt` values should use YAML bloc ### emitted to frontmatter -| Field | Type | Required | Notes | -| -------------------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | string | no | Overrides filename as picker label | -| `description` | string | no | Shown as placeholder text in chat input | -| `argument-hint` | string | no | Hint text shown after `@agent` in chat | -| `tools` | list | no | Tools available to this agent (see below) | -| `agents` | list | no | Subagents this agent may invoke; wildcard delegation (`["*"]`) is rejected by source verification, so use an explicit allowlist | -| `model` | list | no | Ordered model fallbacks (for example `auto` first, then role-appropriate pinned IDs). This preserves role intent while staying resilient to policy or availability drift. | -| `user-invocable` | bool | no | `true` = show in agents dropdown (default) | -| `disable-model-invocation` | bool | no | `true` = prevent other agents from calling this one | -| `target` | string | no | `vscode` (default) or `github-copilot` | -| `handoffs` | object-list | no | Sequential workflow handoffs — see [handoffs](#handoffs) below | -| `mcp-servers` | raw YAML | no | MCP server config (`github-copilot` target only) | -| `hooks` | raw YAML | no | Chat hooks (Preview — requires `chat.useCustomAgentHooks` setting) | -| `metadata` | raw YAML | no | String key/value annotations (`github-copilot` target only) | +| Field | Type | Required | Notes | +| -------------------------- | ----------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | string | no | Overrides filename as picker label | +| `description` | string | no | Shown as placeholder text in chat input | +| `argument-hint` | string | no | Hint text shown after `@agent` in chat | +| `tools` | list | no | Tools available to this agent (see below) | +| `agents` | list | no | Subagents this agent may invoke; wildcard delegation (`["*"]`) is rejected by source verification, so use an explicit allowlist | +| `model` | list | no | Optional model override. Omit by default so VS Code uses the currently selected model picker value. If present, use a prioritized fallback list only for explicit exceptions. | +| `user-invocable` | bool | no | `true` = show in agents dropdown (default) | +| `disable-model-invocation` | bool | no | `true` = prevent other agents from calling this one | +| `target` | string | no | `vscode` (default) or `github-copilot` | +| `handoffs` | object-list | no | Sequential workflow handoffs — see [handoffs](#handoffs) below | +| `mcp-servers` | raw YAML | no | MCP server config (`github-copilot` target only) | +| `hooks` | raw YAML | no | Chat hooks (Preview — requires `chat.useCustomAgentHooks` setting) | +| `metadata` | raw YAML | no | String key/value annotations (`github-copilot` target only) | ### vstack-internal only (not emitted) @@ -92,6 +92,8 @@ Style rule: long `description` and `handoffs.prompt` values should use YAML bloc Frontmatter multiline rendering is configured in generator code (`ArtifactTypeConfig.preserve_multiline_frontmatter`), not per-agent `config.yaml`. +Model policy: keep `model` out of source templates unless a role needs an explicit, justified override. That keeps the generated agents portable across users and orgs with different model access or cost policy. + ______________________________________________________________________ ## items diff --git a/docs/design/cicd.md b/docs/design/cicd.md index 29e39bf2..18b6f203 100644 --- a/docs/design/cicd.md +++ b/docs/design/cicd.md @@ -248,11 +248,11 @@ after PyPI publish succeeds and checksum verification passes. ### Payload schema -| Field | Type | Source | Description | -| ----------- | ------ | ----------------------------------------------------------------------- | ------------------------------------------------------------------ | -| `version` | string | `github.event.release.tag_name` | Release tag (e.g. `v1.4.0`); used in the tap commit message only | -| `sdist_url` | string | PyPI JSON API `.urls[].url` where `packagetype == "sdist"` | Canonical PyPI download URL embedded in the formula `url` field | -| `sha256` | string | Computed locally from downloaded tarball; cross-checked against PyPI API | SHA-256 digest of the sdist tarball; embedded in formula `sha256` | +| Field | Type | Source | Description | +| ----------- | ------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------- | +| `version` | string | `github.event.release.tag_name` | Release tag (e.g. `v1.4.0`); used in the tap commit message only | +| `sdist_url` | string | PyPI JSON API `.urls[].url` where `packagetype == "sdist"` | Canonical PyPI download URL embedded in the formula `url` field | +| `sha256` | string | Computed locally from downloaded tarball; cross-checked against PyPI API | SHA-256 digest of the sdist tarball; embedded in formula `sha256` | Example: @@ -279,10 +279,10 @@ Example: `formula-update.yml` applies exactly two field updates to `Formula/vstack.rb`: -| Field | Scope | Replacement behavior | -| -------- | ------------------------------- | ------------------------------------------- | -| `url` | Top-level formula `url` line | Replaced with the dispatched `sdist_url` | -| `sha256` | Top-level formula `sha256` line | Replaced with the dispatched `sha256` | +| Field | Scope | Replacement behavior | +| -------- | ------------------------------- | ---------------------------------------- | +| `url` | Top-level formula `url` line | Replaced with the dispatched `sdist_url` | +| `sha256` | Top-level formula `sha256` line | Replaced with the dispatched `sha256` | The `resource` blocks for runtime dependencies (currently `pyyaml`) contain their own `sha256` lines. The update script must target only the top-level formula fields and must diff --git a/docs/design/skills.md b/docs/design/skills.md index d87ae504..11c7f0fa 100644 --- a/docs/design/skills.md +++ b/docs/design/skills.md @@ -48,6 +48,7 @@ ______________________________________________________________________ | Skill | Description | Primary role(s) | Output artifact | | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------- | | `vision` | CEO/founder-mode plan review. Rethink from first principles, validate ambition, find the 10x solution. | product | `docs/product/vision.md` | +| `ask` | Read-only technical Q&A. Clarifies ambiguous questions, gathers repository evidence, and returns concise answers with references and confidence. | all roles | referenced answer + next-step guidance | | `requirements` | Collaborative requirements gathering. Clarifies what must be built, defines success criteria and NFRs. | product | `docs/product/requirements.md` | | `architecture` | Engineering-lead plan review. Lock in service boundaries, data models, API contracts, test strategy. | architect | `docs/architecture/overview.md` | | `adr` | Architecture Decision Record writing. Documents a decision with context, alternatives, and rationale. | architect | `docs/architecture/adr/NNN-*.md` | diff --git a/docs/design/workflow.md b/docs/design/workflow.md index d63f7917..f75d3def 100644 --- a/docs/design/workflow.md +++ b/docs/design/workflow.md @@ -219,15 +219,15 @@ ______________________________________________________________________ The repository uses a split workflow model so each automation concern is isolated and easy to reason about. -| Workflow | Trigger | Responsibility | -| --------------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------- | -| `.github/workflows/commit.yml` | Push to non-main branches and pull requests to `main` | Commit/branch policy and lint/typecheck gate. | -| `.github/workflows/check.yml` | Push to non-main branches and pull requests to `main` | Single-version unit tests (py3.11) for fast feedback. | -| `.github/workflows/verify.yml` | Pull request to `main` | Cross-version test matrix (py3.11–3.14) and artifact install/verify flow. | -| `.github/workflows/security.yml` | Pull request to `main` | Dependency vulnerability audit and secret scan. | -| `.github/workflows/codeql.yml` | Push/pull request to `main` + weekly schedule | Code scanning for GitHub Actions and Python. | -| `.github/workflows/automerge.yml` | Pull request target to `main` | Dependabot safe auto-merge policy for eligible updates. | -| `.github/workflows/release.yml` | Push to `main` | Run release-please to maintain release PRs and create tags/releases when merged. | +| Workflow | Trigger | Responsibility | +| --------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | +| `.github/workflows/commit.yml` | Push to non-main branches and pull requests to `main` | Commit/branch policy and lint/typecheck gate. | +| `.github/workflows/check.yml` | Push to non-main branches and pull requests to `main` | Single-version unit tests (py3.11) for fast feedback. | +| `.github/workflows/verify.yml` | Pull request to `main` | Cross-version test matrix (py3.11–3.14) and artifact install/verify flow. | +| `.github/workflows/security.yml` | Pull request to `main` | Dependency vulnerability audit and secret scan. | +| `.github/workflows/codeql.yml` | Push/pull request to `main` + weekly schedule | Code scanning for GitHub Actions and Python. | +| `.github/workflows/automerge.yml` | Pull request target to `main` | Dependabot safe auto-merge policy for eligible updates. | +| `.github/workflows/release.yml` | Push to `main` | Run release-please to maintain release PRs and create tags/releases when merged. | | `.github/workflows/publish.yml` | GitHub release published | Build package artifacts from the release tag, publish to PyPI, and optionally update the Homebrew tap. | Homebrew install UX constraints for the private tap path: diff --git a/docs/product/requirements.md b/docs/product/requirements.md index b66d78be..6bc77890 100644 --- a/docs/product/requirements.md +++ b/docs/product/requirements.md @@ -117,15 +117,15 @@ ______________________________________________________________________ ## non-functional requirements -| ID | Requirement | -| ----- | ------------------------------------------------------------------------------------------------------ | -| NFR-1 | One runtime dependency only: PyYAML (`pyyaml>=6.0`) for YAML frontmatter parsing. | -| NFR-2 | Python 3.11–3.14 compatibility. | -| NFR-3 | Manifest writes are atomic: write to a temporary file, then replace atomically. | -| NFR-4 | All public behavior exercised by automated tests (pytest). CI gate enforces test pass. | -| NFR-5 | CLI operates standalone; no VS Code process required for `install`, `verify`, or `validate`. | -| NFR-6 | Lint (ruff) and type checking pass on every commit. CI gate enforces zero violations. | -| NFR-7 | Generated output lives under `.github/` only; source templates under `_templates/` are never modified. | +| ID | Requirement | +| ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| NFR-1 | One runtime dependency only: PyYAML (`pyyaml>=6.0`) for YAML frontmatter parsing. | +| NFR-2 | Python 3.11–3.14 compatibility. | +| NFR-3 | Manifest writes are atomic: write to a temporary file, then replace atomically. | +| NFR-4 | All public behavior exercised by automated tests (pytest). CI gate enforces test pass. | +| NFR-5 | CLI operates standalone; no VS Code process required for `install`, `verify`, or `validate`. | +| NFR-6 | Lint (ruff) and type checking pass on every commit. CI gate enforces zero violations. | +| NFR-7 | Generated output lives under `.github/` only; source templates under `_templates/` are never modified. | | NFR-8 | macOS and Linux users can install via `brew install eschaar/vstack/vstack` without Python or pip awareness. The formula wraps the PyPI sdist in an isolated virtualenv. Formula updates are automated: triggered after each successful PyPI publish, with dual sha256 verification before the tap formula is updated. | ______________________________________________________________________ diff --git a/docs/product/roadmap.md b/docs/product/roadmap.md index 5f5ffb87..bd746d39 100644 --- a/docs/product/roadmap.md +++ b/docs/product/roadmap.md @@ -1,54 +1,56 @@ # vstack — roadmap > Maintained by: **product** role\ -> Last updated: 2026-06-02 +> Last updated: 2026-06-18 ______________________________________________________________________ ## feature status table -| Feature | Version | Status | Notes | -| --------------------------------------------- | ------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| foundation | v1.0.0 | shipped | Core template-driven install model is in place | -| backend-first verification | v1.0.0 | shipped | Verify/inspect focus on contracts, observability, security | -| VS Code agent migration | v1.x | shipped | Native `.github/agents/*.agent.md` output format implemented | -| role model + doc restructure | v1.1.0 | shipped | 6-role model, agent templates, and docs baseline established | -| docs information architecture (Diataxis) | t.b.d. | candidate | Adopt `docs/user/` with segmented tutorials/how-to/reference/explanation routes; scaffold first, migration later | -| new skill scaffolding | v2.2.0 | shipped | 42-skill set with canonical naming | -| agent skill wiring | v2.2.0 | shipped | Role-to-skill mapping, handoffs, and concise modes wired into all agents | -| CLI modularisation | v2.0.0 | shipped | 12 focused CLI modules; BaseCommand + CommandContext contract | -| manifest package | v2.0.0 | shipped | Dedicated `manifest/` package; atomic writes (ADR-016) | -| mypy type checking | v2.0.0 | shipped | Full mypy coverage enforced in CI; 100% test coverage gate | -| manifest schema versioning | v2.0.0 | shipped | `manifest_version: 2`; upgrade path via `manifest upgrade` (ADR-014) | -| checksum backfill | v2.0.0 | shipped | `manifest upgrade --backfill` adds SHA-256 for VSTACK-META-tagged files (ADR-017) | -| conservative install | v2.0.0 | shipped | Untracked files never overwritten; checksum-gated update (ADR-015, superseded by ADR-020) | -| dry-run install | v2.1.0 | shipped | `vstack install --dry-run` previews actions; type/name selectors in summary | -| project-scope directory | v3.0.0 | shipped | `.vstack/` directory: `config.yaml`, manifest, delta templates (ADR-019) | -| install/init command semantics | v3.0.0 | shipped | `install` = first-run setup; `init` = idempotent CI regeneration (ADR-020, breaking change) | -| manifest relocation | v3.0.0 | shipped | `vstack.json` moves from `.github/` to `.vstack/`; migration via `manifest upgrade` (ADR-014) | -| selective install | v3.0.0 | shipped | Per-type and per-name exclusions via `exclude:` in `.vstack/config.yaml`; agents always installed (ADR-022) | -| workflow contract source-of-truth | v3.1.0 | shipped | `workflow:` block in `.vstack/config.yaml`; `gate`, `hitl`, `handoffs` schema; `vstack migrate` command (ADR-023, ADR-026) | -| agent hooks support | v3.2.0 | shipped | First-class `hook` artifact type: generate `.github/hooks/.json` from templates and track in manifest | -| optional orchestrated role pipeline | v3.2.0 | shipped | `planner` coordinator agent implemented with mode-aware generation; default mode is `agentic` (`manual` and `hybrid` also supported) | -| parallel workflow via DAG model | t.b.d. | candidate | `depends_on` DAG semantics implemented in code; awaiting a release tag before being promoted to shipped | -| Homebrew distribution (private tap) | t.b.d. | candidate | `brew install eschaar/vstack/vstack` on macOS and Linux; private tap wrapping PyPI sdist; automated formula updates via `publish.yml` after PyPI publish | -| new skills (next batch) | t.b.d. | candidate | `space-setup`: set up Copilot Spaces; `copilot-ops`: operate Copilot governance settings with audit-first checks | -| team customization layer | t.b.d. | candidate | Deferred major update after VS Code-first model proves itself; custompacks, overlay merge rules, and install profiles all add major maintenance surface | -| multi-IDE support (IntelliJ first) | t.b.d. | candidate | Deferred until vstack proves stable in VS Code; likely a major follow-up because it needs separate targets, schemas, and more maintenance | -| plugin/bundle distribution model | t.b.d. | candidate | A self-contained, versioned bundle of vstack artifacts as a distribution model with no external registry or repository mapping | -| artifact integrity and verification hardening | t.b.d. | candidate | Layered checks, generated-artifact drift detection, and deterministic fixtures to reduce release risk. | -| hook telemetry parser hardening (P2) | t.b.d. | candidate | Optional deeper payload normalization for actor/tool/model extraction across broader event shapes without adding runtime dependencies. | -| planner analytics enrichment (P2) | t.b.d. | candidate | Optional aggregation/reporting on stage-report telemetry (`planner_run_id`, `model_used`, `subagents_invoked`) for post-run analysis. | -| golden-fixture coverage expansion | t.b.d. | candidate | Extend deterministic golden fixtures to cover additional high-impact templates per artifact type. | -| defect-fixture matrix expansion | t.b.d. | candidate | Expand defect fixtures across artifact types and failure classes with stable expected error assertions. | -| template-change-aware fixture CI gate | t.b.d. | candidate | Require fixture drift checks automatically in CI whenever template sources are modified. | -| fixture update policy in PR workflow | t.b.d. | candidate | Enforce contributor guidance that intended generated-output changes include fixture updates in the same pull request. | -| deeper targeted verify tier | t.b.d. | candidate | Define and run a deeper pre-merge/release verification tier covering integration, fixture, and contract checks. | -| heavy agent runtime framework | — | not planned | Keeps runtime lightweight and transparent | -| cloud control plane dependency | — | not planned | Keeps operation local/offline-capable | -| VS Code extension packaging | — | not planned | Not required for current install model | -| browser automation as default dependency | — | not planned | Backend/microservice-first remains default | -| install target directory override | — | not planned | Won't implement unless a concrete tool incompatibility with `.github/` arises | +| Feature | Version | Status | Notes | +| --------------------------------------------- | ------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| foundation | v1.0.0 | shipped | Core template-driven install model is in place | +| backend-first verification | v1.0.0 | shipped | Verify/inspect focus on contracts, observability, security | +| VS Code agent migration | v1.x | shipped | Native `.github/agents/*.agent.md` output format implemented | +| role model + doc restructure | v1.1.0 | shipped | 6-role model, agent templates, and docs baseline established | +| CLI modularisation | v2.0.0 | shipped | 12 focused CLI modules; BaseCommand + CommandContext contract | +| manifest package | v2.0.0 | shipped | Dedicated `manifest/` package; atomic writes (ADR-016) | +| mypy type checking | v2.0.0 | shipped | Full mypy coverage enforced in CI; 100% test coverage gate | +| manifest schema versioning | v2.0.0 | shipped | `manifest_version: 2`; upgrade path via `manifest upgrade` (ADR-014) | +| checksum backfill | v2.0.0 | shipped | `manifest upgrade --backfill` adds SHA-256 for VSTACK-META-tagged files (ADR-017) | +| conservative install | v2.0.0 | shipped | Untracked files never overwritten; checksum-gated update (ADR-015, superseded by ADR-020) | +| dry-run install | v2.1.0 | shipped | `vstack install --dry-run` previews actions; type/name selectors in summary | +| new skill scaffolding | v2.2.0 | shipped | 47-skill set with canonical naming | +| agent skill wiring | v2.2.0 | shipped | Role-to-skill mapping, handoffs, and concise modes wired into all agents | +| project-scope directory | v3.0.0 | shipped | `.vstack/` directory: `config.yaml`, manifest, delta templates (ADR-019) | +| install/init command semantics | v3.0.0 | shipped | `install` = first-run setup; `init` = idempotent CI regeneration (ADR-020, breaking change) | +| manifest relocation | v3.0.0 | shipped | `vstack.json` moves from `.github/` to `.vstack/`; migration via `manifest upgrade` (ADR-014) | +| selective install | v3.0.0 | shipped | Per-type and per-name exclusions via `exclude:` in `.vstack/config.yaml`; agents always installed (ADR-022) | +| workflow contract source-of-truth | v3.1.0 | shipped | `workflow:` block in `.vstack/config.yaml`; `gate`, `hitl`, `handoffs` schema; `vstack migrate` command (ADR-023, ADR-026) | +| agent hooks support | v3.2.0 | shipped | First-class `hook` artifact type: generate `.github/hooks/.json` from templates and track in manifest | +| optional orchestrated role pipeline | v3.2.0 | shipped | `planner` coordinator agent implemented with mode-aware generation; default mode is `agentic` (`manual` and `hybrid` also supported) | +| parallel workflow via DAG model | v3.3.0 | shipped | `depends_on` DAG semantics and planner parallel scheduling are shipped in v3.3.0 | +| new skills (next batch) | v3.3.0 | shipped | `space-setup`: set up Copilot Spaces; `copilot-ops`: operate Copilot governance settings with audit-first checks | +| golden-fixture coverage expansion | v3.3.0 | shipped | Extend deterministic golden fixtures to cover additional high-impact templates per artifact type. | +| defect-fixture matrix expansion | v3.3.0 | shipped | Expand defect fixtures across artifact types and failure classes with stable expected error assertions. | +| planner routing refinement | v3.4.0 | shipped | Planner/orchestrator routing follow-up to the DAG work | +| Homebrew distribution | v3.5.0 | shipped | Homebrew tap/formula publish flow added for install and upgrade via `brew` | +| docs information architecture (Diataxis) | t.b.d. | candidate | `docs/user/` scaffold and navigation are in place with segmented tutorials/how-to/reference/explanation routes; broader migration and fully realized IA come later | +| team customization layer | t.b.d. | candidate | Deferred major update after VS Code-first model proves itself; custompacks, overlay merge rules, and install profiles all add major maintenance surface | +| multi-IDE support (IntelliJ first) | t.b.d. | candidate | Deferred until vstack proves stable in VS Code; likely a major follow-up because it needs separate targets, schemas, and more maintenance | +| plugin/bundle distribution model | t.b.d. | candidate | A self-contained, versioned bundle of vstack artifacts as a distribution model with no external registry or repository mapping | +| artifact integrity and verification hardening | t.b.d. | candidate | Layered checks, generated-artifact drift detection, and deterministic fixtures to reduce release risk. | +| hook telemetry parser hardening (P2) | t.b.d. | candidate | Optional deeper payload normalization for actor/tool/model extraction across broader event shapes without adding runtime dependencies. | +| planner analytics enrichment (P2) | t.b.d. | candidate | Optional aggregation/reporting on stage-report telemetry (`planner_run_id`, `model_used`, `subagents_invoked`) for post-run analysis. | +| template-change-aware fixture CI gate | t.b.d. | candidate | Require fixture drift checks automatically in CI whenever template sources are modified. | +| fixture update policy in PR workflow | t.b.d. | candidate | Enforce contributor guidance that intended generated-output changes include fixture updates in the same pull request. | +| deeper targeted verify tier | t.b.d. | candidate | Define and run a deeper pre-merge/release verification tier covering integration, fixture, and contract checks. | +| obsolete artifact pruning for init | v3.5.x | shipped | `init --prune` removes safe obsolete tracked artifacts; default run reports candidates and preserves files; hook generator trailing-newline stability fix included. | +| heavy agent runtime framework | — | not planned | Keeps runtime lightweight and transparent | +| cloud control plane dependency | — | not planned | Keeps operation local/offline-capable | +| VS Code extension packaging | — | not planned | Not required for current install model | +| browser automation as default dependency | — | not planned | Backend/microservice-first remains default | +| install target directory override | — | not planned | Won't implement unless a concrete tool incompatibility with `.github/` arises | ______________________________________________________________________ @@ -99,7 +101,7 @@ Existing documentation now lives under `docs/user/`. ### new skill scaffolding [shipped — v2.2.0] -42 skills across 6 roles. Representative additions: +47 skills across 6 roles. Representative additions: - `requirements`, `adr`, `analyse` (new) - `gh-issues`, `codeql`, `dependabot`, `secret-scan`, `gh-release` @@ -220,9 +222,9 @@ Migration path: Ref: [GitHub — Customize agent workflows with hooks](https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/use-hooks) -### new skills (next batch) [candidate — t.b.d.] +### new skills (next batch) [shipped — v3.3.0] -Two new skills planned for the next skill expansion: +Two new skills now ship in the current baseline: #### `space-setup` @@ -247,12 +249,27 @@ Operational skill for Copilot governance and admin workflows. Covers audit-first Ref: [GitHub — Administer GitHub Copilot for your team](https://docs.github.com/en/copilot/how-tos/administer-copilot) +### planner routing refinement [shipped — v3.4.0] + +- Planner/orchestrator routing follow-up to the DAG work. + ### team customization layer [candidate — t.b.d.] This is a later major update, not a near-term roadmap item. The idea is valid, but it adds another product layer on top of a system that is still proving itself in its VS Code-first form. +### obsolete artifact pruning for init [shipped — v3.5.x] + +Shipped behavior: + +- `vstack init` reports obsolete candidates and preserves them in manifest state — no files deleted by default. +- `vstack init --prune` removes only safe obsolete tracked artifacts: tracked by manifest and unchanged from recorded checksum. +- Locally modified or untracked files are never removed. +- `vstack install` stays report-only for obsolete candidates; `--prune` is `init`-only. +- Summary output includes `obsolete` and `pruned` counters. +- Included fix: hook generator now appends a trailing newline so `end-of-file-fixer` no longer mutates generated `.github/hooks/*.json` files after formatting, preventing spurious checksum drift. + Teams may eventually want to tune agents to company context, replace generic skills with company-specific ones, and bundle those changes as a reusable custompack that travels with the project. That remains a plausible direction, but only after the core model has @@ -313,7 +330,7 @@ Not yet implemented (deferred to orchestrated pipeline milestone): - Generator-level cross-role validation of input/output chains - Central read-only contract export for external orchestrator consumption -### parallel workflow via DAG model [candidate — t.b.d.] +### parallel workflow via DAG model [shipped — v3.3.0] **What is DAG?** (Directed Acyclic Graph) @@ -383,9 +400,9 @@ Potential wall-clock reduction: 6 stages → 3 stages (~50% faster). **Remaining work beyond this release:** -1. Planner-level parallel dispatch scheduling and layer execution policy. -1. Explicit runtime join/failure strategy controls for parallel stage groups. -1. Additional integration tests for parallel orchestration execution traces. +1. Add configurable join/failure policy controls for parallel stage groups. +1. Expand orchestration integration tests for complex parallel execution traces. +1. Improve operator diagnostics for partial parallel-stage failures and recovery hints. **Backwards compatibility:** @@ -435,58 +452,10 @@ workflow: **Next steps:** -1. Implement planner runtime layer scheduling for parallel-ready stages. 1. Add explicit join policy knobs for DAG layer completion. 1. Expand orchestration integration tests for multi-stage parallel traces. 1. Add user-facing troubleshooting guidance for DAG misconfiguration recovery. -### Homebrew distribution (private tap) [candidate — t.b.d.] - -Provide a `brew install` path for macOS and Linux users who prefer not to manage Python -tooling directly. PyPI remains the canonical package source; the Homebrew formula wraps -the PyPI sdist in an isolated virtualenv. - -**Scope:** - -- Create `github.com/eschaar/homebrew-vstack` public tap repository with - `Formula/vstack.rb`. -- Add a `publish-homebrew` job to `publish.yml` that runs after the PyPI job succeeds. -- Automate formula version and sha256 updates via `repository_dispatch` to the tap repo. -- Require dual sha256 verification (PyPI JSON API + local recompute) before dispatching. -- Gate on `TRUSTED_RELEASE_ACTORS` and `prerelease == false` (matching existing publish guards). -- Use a fine-grained PAT (`HOMEBREW_TAP_TOKEN`) scoped to `contents: write` on the tap - repo only. Store in the `pypi` Actions environment. - -**Install UX (after bootstrap):** - -```bash -brew tap eschaar/vstack -brew install vstack -``` - -**Acceptance criteria:** - -- `brew install eschaar/vstack/vstack` succeeds on a clean macOS/Linux Actions runner. -- `vstack --version` and `vstack --help` run without errors after install. -- A new release automatically updates the tap formula within one workflow run. -- The PyPI job is unaffected if the Homebrew job fails (independent failure domain). - -**Risks and mitigations:** - -| Risk | Mitigation | -| --- | --- | -| Tap token leakage | Fine-grained PAT scoped to tap repo only; rotated on any exposure | -| sha256 mismatch after formula update | Dual verification in workflow; Homebrew re-verifies at install time | -| Formula update triggers before PyPI propagates | Retry loop in dispatch workflow; Homebrew fetches from PyPI at install time | -| PyPI dependency drift in formula | `resource` blocks in formula updated in step; gated by formula test workflow | - -**Next steps:** - -1. Architect to produce implementation-ready workflow changes to `publish.yml`. -1. Create tap repo and bootstrap the initial formula from the latest release. -1. Validate the end-to-end flow with a dry-run release trigger. -1. Update `README.md` with Homebrew install instructions once bootstrap is validated. - ### optional orchestrated role pipeline [shipped — v3.2.0] ADR-024 is implemented. @@ -577,7 +546,7 @@ guidance on which checks apply after each class of change. **Phase B — generated-artifact drift guard:** - Baseline shipped (2026-05-13): golden fixture drift tests added for - `instruction/security`, `agent/planner`, and `prompt/code-review` rendering in + `instruction/security`, `agent/planner`, and `prompt/quick-review` rendering in `tests/vstack/artifacts/test_generator.py`. - Expansion shipped (2026-05-13): golden fixture coverage now includes additional @@ -620,7 +589,7 @@ guidance on which checks apply after each class of change. #### Next follow-up steps -Tracked as dedicated candidate items in the feature status table: golden-fixture coverage expansion, defect-fixture matrix expansion, template-change-aware fixture CI gate, fixture update policy in PR workflow, and deeper targeted verify tier. +Tracked as dedicated candidate items in the feature status table: template-change-aware fixture CI gate, fixture update policy in PR workflow, and deeper targeted verify tier. **Expected outcomes:** @@ -665,6 +634,7 @@ ______________________________________________________________________ - `prompts/` - `instructions/` - `skills/` +- `hooks/` -All artifact types are supported globally. vstack provides generic, reusable -behavior; project-specific customization is out of scope. +All global-supported artifact types are included above. vstack provides generic, +reusable behavior; project-specific customization is out of scope. diff --git a/docs/releases/2026-06-02.md b/docs/releases/2026-06-02.md index e1a30c5a..d48d3826 100644 --- a/docs/releases/2026-06-02.md +++ b/docs/releases/2026-06-02.md @@ -11,13 +11,14 @@ environment once the tap repository is set up and secrets are provisioned (see No Python source changes are included in this release. All changes are in the CI/CD pipeline, documentation, and tests. ---- +______________________________________________________________________ ## What's New ### Homebrew private tap distribution (feature-flagged, disabled by default) - **New `publish-homebrew` CI job** added to `.github/workflows/publish.yml`. + - Controlled by `HOMEBREW_TAP_ENABLED` env var (defaults to `"false"`). - Runs only after `publish` (PyPI) job succeeds; non-prerelease only. - Dual SHA-256 verification: cross-checks PyPI JSON metadata against the locally @@ -57,33 +58,33 @@ CI/CD pipeline, documentation, and tests. - `test_homebrew_job_verifies_sdist_and_dispatches_update`: verifies sha256 verification logic and dispatch step contracts. ---- +______________________________________________________________________ ## Sign-off Record -| Role | Verdict | Reviewed scope | Gaps / deviations | Owner | -| --------- | ------- | ------------------------------------------------------------------- | ------------------------------------------------------ | ----- | -| Tester | OK | 658 tests pass; 100% coverage; T-001 fix verified; ruff + mypy clean | T-001 fix staged via `step.get("id")` — see B-001 | — | -| Architect | OK | ADR-030 accepted; architecture plan complete; overview aligned | Tap repo and secrets not yet created (pre-activation) | — | -| Designer | OK | cicd.md updated; workflow.md updated; sequence diagram correct | workflow.md update in working tree — see B-002 | — | -| Product | OK | requirements.md updated (FR-8); roadmap aligned | None | — | +| Role | Verdict | Reviewed scope | Gaps / deviations | Owner | +| --------- | ------- | -------------------------------------------------------------------- | ----------------------------------------------------- | ----- | +| Tester | OK | 658 tests pass; 100% coverage; T-001 fix verified; ruff + mypy clean | T-001 fix staged via `step.get("id")` — see B-001 | — | +| Architect | OK | ADR-030 accepted; architecture plan complete; overview aligned | Tap repo and secrets not yet created (pre-activation) | — | +| Designer | OK | cicd.md updated; workflow.md updated; sequence diagram correct | workflow.md update in working tree — see B-002 | — | +| Product | OK | requirements.md updated (FR-8); roadmap aligned | None | — | ---- +______________________________________________________________________ ## Blockers (must be resolved before commit) -| ID | Severity | Description | Owner | -| ----- | -------- | ----------------------------------------------------------------------------------------------------------------- | -------- | +| ID | Severity | Description | Owner | +| ----- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | | B-001 | Critical | `tests/vstack/test_publish_workflow.py` T-001 fix (`step.get("id")`) is in the working tree but **not staged**. If committed as-is, `test_homebrew_job_verifies_sdist_and_dispatches_update` will raise `KeyError: 'id'` and fail. Requires `git add tests/vstack/test_publish_workflow.py` before commit. | engineer | -| B-002 | Minor | `docs/design/workflow.md` designer update (publish.yml description extended) is not staged. Include in commit. | engineer | -| B-003 | Minor | `docs/reports/test-report.md` evidence artifact not staged. Should be committed for release traceability. | engineer | -| B-004 | Minor | `docs/reports/security-report.md` evidence artifact not staged. Should be committed for release traceability. | engineer | +| B-002 | Minor | `docs/design/workflow.md` designer update (publish.yml description extended) is not staged. Include in commit. | engineer | +| B-003 | Minor | `docs/reports/test-report.md` evidence artifact not staged. Should be committed for release traceability. | engineer | +| B-004 | Minor | `docs/reports/security-report.md` evidence artifact not staged. Should be committed for release traceability. | engineer | > **B-001 is a release blocker.** The PR cannot merge until the test fix is staged > and verified. B-002 through B-004 are traceability items and should be resolved > in the same commit. ---- +______________________________________________________________________ ## Activation checklist (post-merge, not a release gate) @@ -100,7 +101,7 @@ PR merge. Track separately. - [ ] Set `HOMEBREW_TAP_ENABLED: "true"` in `publish.yml` once tap repo is ready. - [ ] Validate end-to-end on a test release before enabling on production tags. ---- +______________________________________________________________________ ## Residual risks @@ -112,7 +113,7 @@ PR merge. Track separately. - Performance baseline was captured on `2026-05-14` (branch `chore/split-docs-and-hardening`). No Python source changes are included in this release; re-baselining is not required. ---- +______________________________________________________________________ ## Test evidence diff --git a/docs/reports/security-report.md b/docs/reports/security-report.md index dfeef21c..cd04c562 100644 --- a/docs/reports/security-report.md +++ b/docs/reports/security-report.md @@ -9,14 +9,14 @@ ______________________________________________________________________ ## Verdict -| Category | Findings | Blocking | -| ------------------------------------ | ------------------------------------------- | ---------------------------------------- | -| Static analysis (bandit) | 1 LOW | No — informational; import advisory only | -| Dependency CVEs | 0 known CVEs in current local env | No | -| Secrets in source | None | — | -| Injection risk | None identified | — | -| Auth / access control | N/A (local CLI, no network) | — | -| CI/CD workflow (publish-homebrew) | See W-001 – W-004 below | No — all informational or design notes | +| Category | Findings | Blocking | +| --------------------------------- | --------------------------------- | ---------------------------------------- | +| Static analysis (bandit) | 1 LOW | No — informational; import advisory only | +| Dependency CVEs | 0 known CVEs in current local env | No | +| Secrets in source | None | — | +| Injection risk | None identified | — | +| Auth / access control | N/A (local CLI, no network) | — | +| CI/CD workflow (publish-homebrew) | See W-001 – W-004 below | No — all informational or design notes | > **Ship readiness: PASS** — no blocking security findings; workflow security controls verified. @@ -142,16 +142,16 @@ ______________________________________________________________________ ## Summary of Advisory Items -| ID | Severity | Location / package | Action | -| ----- | ------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------- | -| S-001 | LOW | `src/vstack/constants.py` | Keep B404 import advisory documented; no unsafe subprocess use | -| S-002 | LOW | `pip`, `urllib3` (dev env) | **Resolved** by upgrading to `pip 26.1.1` and `urllib3 2.7.0` | -| W-001 | PASS | `publish-homebrew` feature flag | Committed as `false`; enabled by explicit maintainer change only | -| W-002 | PASS | `publish-homebrew` actor check | Mirrors `publish` job guard; no change needed | -| W-003 | PASS | `publish-homebrew` sdist checksum | Double-pinned: PyPI API vs downloaded tarball; formula embeds verified sha256 | -| W-004 | INFORMATIONAL | `publish-homebrew` dispatch signing | Configure `HOMEBREW_TAP_DISPATCH_SECRET` and enforce verification in tap repo before enabling the flag | -| W-005 | PASS | `publish-homebrew` curl dispatch | No shell injection; JSON built via Python, passed as file to curl | -| W-006 | PASS | `publish-homebrew` token handling | Token consumed from `secrets.*`; GitHub Actions masks it in logs | +| ID | Severity | Location / package | Action | +| ----- | ------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------ | +| S-001 | LOW | `src/vstack/constants.py` | Keep B404 import advisory documented; no unsafe subprocess use | +| S-002 | LOW | `pip`, `urllib3` (dev env) | **Resolved** by upgrading to `pip 26.1.1` and `urllib3 2.7.0` | +| W-001 | PASS | `publish-homebrew` feature flag | Committed as `false`; enabled by explicit maintainer change only | +| W-002 | PASS | `publish-homebrew` actor check | Mirrors `publish` job guard; no change needed | +| W-003 | PASS | `publish-homebrew` sdist checksum | Double-pinned: PyPI API vs downloaded tarball; formula embeds verified sha256 | +| W-004 | INFORMATIONAL | `publish-homebrew` dispatch signing | Configure `HOMEBREW_TAP_DISPATCH_SECRET` and enforce verification in tap repo before enabling the flag | +| W-005 | PASS | `publish-homebrew` curl dispatch | No shell injection; JSON built via Python, passed as file to curl | +| W-006 | PASS | `publish-homebrew` token handling | Token consumed from `secrets.*`; GitHub Actions masks it in logs | No remaining dependency CVEs were detected in the audited local environment. No security item blocks release. diff --git a/docs/user/how-to/reinitialize.md b/docs/user/how-to/reinitialize.md index 929acd9d..9ed41b4d 100644 --- a/docs/user/how-to/reinitialize.md +++ b/docs/user/how-to/reinitialize.md @@ -30,6 +30,20 @@ vstack init --only skill prompt vstack init --only hook ``` +## Remove Safe Obsolete Artifacts + +Use explicit prune mode when templates were renamed or removed and you want cleanup: + +```bash +vstack init --prune +``` + +Preview prune actions without writing files: + +```bash +vstack init --prune --dry-run +``` + ## Verify the Reinitialized State ```bash @@ -41,6 +55,7 @@ vstack manifest verify --target . - If a file is locally modified and not updated as expected, inspect `manifest status` output. - If you need explicit overwrite semantics, use install flags such as `--force-name` or `--force`. +- If obsolete candidates keep appearing, run `vstack init --prune` to remove only checksum-safe tracked files. ## Related Docs diff --git a/docs/user/how-to/update-managed-artifacts.md b/docs/user/how-to/update-managed-artifacts.md index 96378a1f..dccaf86e 100644 --- a/docs/user/how-to/update-managed-artifacts.md +++ b/docs/user/how-to/update-managed-artifacts.md @@ -19,6 +19,22 @@ vstack init --only hook vstack init --only hook agent ``` +## Remove obsolete tracked artifacts safely + +Use prune mode to remove tracked artifacts that are no longer generated: + +```bash +vstack init --prune +``` + +Run a preview first if needed: + +```bash +vstack init --prune --dry-run +``` + +Without `--prune`, obsolete candidates are reported and preserved. + ## Force overwrite managed artifacts Force overwrite for selected type scope: diff --git a/docs/user/reference/cli-commands.md b/docs/user/reference/cli-commands.md index 59d673e8..7a9d0fb7 100644 --- a/docs/user/reference/cli-commands.md +++ b/docs/user/reference/cli-commands.md @@ -33,6 +33,7 @@ vstack manifest upgrade --target . | `vstack install --adopt-name TYPE/NAME` | Track an existing unmanaged artifact without overwriting it. | | `vstack init` | Idempotent regeneration in current directory based on `.vstack/config.yaml`. | | `vstack init --target DIR` | Same as `init`, but explicit target path. | +| `vstack init --prune` | Remove safe obsolete tracked artifacts that are no longer generated; default mode only reports and preserves candidates. | | `vstack uninstall` | Remove tracked artifacts from current directory target when checksums still match manifest. | | `vstack uninstall --target DIR` | Same as `uninstall`, but explicit target path. | | `vstack uninstall --global` | Uninstall profile-scoped artifacts. | @@ -55,4 +56,6 @@ vstack manifest upgrade --target . Both commands default to current working directory when `--target` is omitted. +`vstack init --prune` applies only to obsolete tracked artifacts where the current file content still matches the manifest checksum. Locally modified or untracked files are never removed by this flag. + For manual-edit preservation and force-overwrite flows, see [Update managed artifacts](../how-to/update-managed-artifacts.md). diff --git a/docs/user/reference/prompts-overview.md b/docs/user/reference/prompts-overview.md index 21c34b3f..e0844e71 100644 --- a/docs/user/reference/prompts-overview.md +++ b/docs/user/reference/prompts-overview.md @@ -8,26 +8,28 @@ Prompts are reusable review and analysis templates that guide a focused task. In vstack, prompts are generated into `.github/prompts/*.prompt.md`. +Prompt files should stay model-agnostic by default. Leave `model` out unless a prompt has a specific, justified need to pin a model for reproducibility or model-specific behavior. + ## Built-in Prompts -| Prompt | What It Helps With | -| -------------------- | --------------------------------------------------------------------------------------------------- | -| `api-design-review` | Review an API design or OpenAPI spec for correctness, completeness, and consistency. | -| `architecture-risk` | Identify architectural risks, tradeoffs, and mitigation priorities for a proposed design. | -| `artifact-integrity` | Check source templates against generated artifacts and identify drift or missing regeneration. | -| `ci-triage` | Triage CI failures into root-cause clusters and prioritize the fastest safe recovery path. | -| `code-review` | Review a change for bugs, regressions, and missing tests. | -| `dependency-audit` | Audit dependencies for vulnerabilities, outdated versions, licence risks, and supply chain hygiene. | -| `incident-timeline` | Build a structured, evidence-based incident timeline and action-oriented postmortem summary. | -| `migration-plan` | Produce a safe migration plan with sequencing, fallback paths, and verification checkpoints. | -| `migration-safety` | Review database migration safety, rollback strategy, and zero-downtime risk. | -| `ops-readiness` | Assess operational readiness across observability, runbooks, failure handling, and supportability. | -| `release-check` | Evaluate release gate readiness using required reports, artifacts, and sign-off evidence. | -| `repo-assessment` | Assess a repository for production-readiness gaps and prioritized improvements. | -| `template-impact` | Assess impact of a template change on generated artifacts, tests, and release risk. | -| `test-gaps` | Identify missing behavioral coverage and prioritize test additions by production risk. | -| `upgrade-plan` | Build a safe upgrade plan with sequencing, compatibility checks, and rollback points. | -| `workflow-check` | Review workflow stage flow, gate usage, and handoff integrity across role artifacts. | +| Prompt | Scope | What It Helps With | +| -------------------- | ----------------- | --------------------------------------------------------------------------------------------------- | +| `api-design-review` | `general-purpose` | Review an API design or OpenAPI spec for correctness, completeness, and consistency. | +| `architecture-risk` | `general-purpose` | Identify architectural risks, tradeoffs, and mitigation priorities for a proposed design. | +| `artifact-integrity` | `vstack-internal` | Check source templates against generated artifacts and identify drift or missing regeneration. | +| `ci-triage` | `general-purpose` | Triage CI failures into root-cause clusters and prioritize the fastest safe recovery path. | +| `quick-review` | `general-purpose` | Review a change for bugs, regressions, and missing tests. | +| `dependency-audit` | `general-purpose` | Audit dependencies for vulnerabilities, outdated versions, licence risks, and supply chain hygiene. | +| `incident-timeline` | `general-purpose` | Build a structured, evidence-based incident timeline and action-oriented postmortem summary. | +| `migration-plan` | `general-purpose` | Produce a safe migration plan with sequencing, fallback paths, and verification checkpoints. | +| `migration-safety` | `general-purpose` | Review database migration safety, rollback strategy, and zero-downtime risk. | +| `ops-readiness` | `general-purpose` | Assess operational readiness across observability, runbooks, failure handling, and supportability. | +| `release-check` | `general-purpose` | Evaluate release gate readiness using required reports, artifacts, and sign-off evidence. | +| `repo-assessment` | `general-purpose` | Assess a repository for production-readiness gaps and prioritized improvements. | +| `template-impact` | `general-purpose` | Assess impact of a template change on generated artifacts, tests, and release risk. | +| `test-gaps` | `general-purpose` | Identify missing behavioral coverage and prioritize test additions by production risk. | +| `upgrade-plan` | `general-purpose` | Build a safe upgrade plan with sequencing, compatibility checks, and rollback points. | +| `workflow-check` | `general-purpose` | Review workflow stage flow, gate usage, and handoff integrity across role artifacts. | ## Related Docs diff --git a/docs/user/reference/skills-overview.md b/docs/user/reference/skills-overview.md index e75d1baa..5fe814e7 100644 --- a/docs/user/reference/skills-overview.md +++ b/docs/user/reference/skills-overview.md @@ -13,6 +13,7 @@ In vstack, skills are generated into `.github/skills//SKILL.md`. | Skill | What It Helps With | | --------------------- | ------------------------------------------------------------------------- | | `adr` | Architecture Decision Record writing for significant technical decisions. | +| `ask` | Read-only technical Q&A with code-backed evidence and clear guidance. | | `analyse` | Cross-cutting impact, tradeoff, and feasibility analysis. | | `architecture` | Engineering-lead architecture and execution-plan review. | | `aws-cli` | AWS CLI operations across core AWS services. | @@ -30,7 +31,7 @@ In vstack, skills are generated into `.github/skills//SKILL.md`. | `dependency` | Dependency health audit, upgrade strategy, and supply-chain checks. | | `design` | API and service interface design standards and contracts. | | `docs` | Post-release documentation alignment with shipped behavior. | -| `explore` | Repository architecture discovery and onboarding analysis. | +| `explore` | Fast codebase exploration, reuse discovery, and architecture mapping. | | `gdpr` | GDPR-compliant engineering review for data handling and flows. | | `gh-issues` | GitHub issue lifecycle management via `gh`. | | `gh-release` | GitHub Release drafting and publication flow via `gh`. | diff --git a/poetry.lock b/poetry.lock index 971a9505..02ae7543 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.4.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.3.4 and should not be changed by hand. [[package]] name = "ast-serialize" @@ -200,26 +200,26 @@ toml = ["tomli ; python_full_version <= \"3.11.0a6\""] [[package]] name = "distlib" -version = "0.4.0" +version = "0.4.3" description = "Distribution utilities" optional = false python-versions = "*" groups = ["dev"] files = [ - {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"}, - {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"}, + {file = "distlib-0.4.3-py2.py3-none-any.whl", hash = "sha256:4b0ce306c966eb73bc3a7b6abad017c556dadd92c44701562cd528ac7fde4d5b"}, + {file = "distlib-0.4.3.tar.gz", hash = "sha256:f152097224a0ae24be5a0f6bae1b9359af82133bce63f98a95f86cae1aede9ed"}, ] [[package]] name = "filelock" -version = "3.29.0" +version = "3.29.4" description = "A platform independent file lock." optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "filelock-3.29.0-py3-none-any.whl", hash = "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258"}, - {file = "filelock-3.29.0.tar.gz", hash = "sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90"}, + {file = "filelock-3.29.4-py3-none-any.whl", hash = "sha256:dac1648087d5115554850d113e7dd8c83ab2d38e3435dde2d4f163847e57b767"}, + {file = "filelock-3.29.4.tar.gz", hash = "sha256:10cdb3656fc44541cdf30652a93fb10ec6b05325620eb316bd26893e4201538a"}, ] [[package]] @@ -550,14 +550,14 @@ packaging = ">=25" [[package]] name = "pytest" -version = "9.0.3" +version = "9.1.0" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9"}, - {file = "pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"}, + {file = "pytest-9.1.0-py3-none-any.whl", hash = "sha256:8ebb0e7888bdf2bdfc602ec51f8f62d50200af37356c74e503c79a94f5c81f32"}, + {file = "pytest-9.1.0.tar.gz", hash = "sha256:41dd9148c08072446394cefd3d79701701335a9f4cae69ba92e39f6c7f5c061c"}, ] [package.dependencies] @@ -592,14 +592,14 @@ testing = ["process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "python-discovery" -version = "1.4.0" +version = "1.4.2" description = "Python interpreter discovery" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "python_discovery-1.4.0-py3-none-any.whl", hash = "sha256:26ed78d703e234879a66244c7d4114563fb13ec5cd30a2d1357e5fb4850782da"}, - {file = "python_discovery-1.4.0.tar.gz", hash = "sha256:eb8bc7daad3c226c147e45bb4e970a1feb1bf4048ee178e6db59e197b8010ce3"}, + {file = "python_discovery-1.4.2-py3-none-any.whl", hash = "sha256:475803f53b7b2ed6e490e27373f9d8340f7d2eebf9acdaf645d7d714c97bb500"}, + {file = "python_discovery-1.4.2.tar.gz", hash = "sha256:8f3746c4b4968d22afbb97d36e1a0e5b66e6c0f297290f2e95f05b9b8bf18690"}, ] [package.dependencies] @@ -695,30 +695,30 @@ files = [ [[package]] name = "ruff" -version = "0.15.16" +version = "0.15.18" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "ruff-0.15.16-py3-none-linux_armv6l.whl", hash = "sha256:6ac3c0b3969cc6cf6b158c4e2f8f682acb58e7d700d8a44b65ecdc72d66ab0b2"}, - {file = "ruff-0.15.16-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:197c207ed75ffba54a0dec23db4aa939a27a3053073e085e0042433cbdc58e4a"}, - {file = "ruff-0.15.16-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3a39fec45ab316cc23e7558f23fea4a70403ddb5648ea9a4a3854a16973d0071"}, - {file = "ruff-0.15.16-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba93191d79003116b95128c9d306e045200fdbd0bccb782b110f3cd1d4abc5cf"}, - {file = "ruff-0.15.16-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6ee4b90520630120ef032aa5cc10db483852dff950e78b1d717e2993a61ac8d"}, - {file = "ruff-0.15.16-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e4215bc938bc3c8215c1472c1aa437e310fee20cd427335fec9d7e609563628"}, - {file = "ruff-0.15.16-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c8d26be963b090f10e29abc8b3e74a2a321f6fa34e02424e30b5af89350ecbb"}, - {file = "ruff-0.15.16-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f198cf4123602a2280ed46c307bcbafe41758d6fee5b456b6b6058ca1514b3b4"}, - {file = "ruff-0.15.16-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb27515fa6240fb586ae82b901a59e67d24acff86f2190b433dc542fe0435aeb"}, - {file = "ruff-0.15.16-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a267c46ba1593fc26b8eecbea050b39d40c0b6bb7781ee11c90a02cd10032951"}, - {file = "ruff-0.15.16-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:528c68f39a91498a8d50e91ff5985df3d105782bab49cc378e73ac26bff083e8"}, - {file = "ruff-0.15.16-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7ed55c58950df60589a9a7a5d2f8fa5f54ebd287163be805adfe6ee95a9de123"}, - {file = "ruff-0.15.16-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d482feaf51512b50f9790ceb417a56a61dd1e9d9bf967662b9ed27c01b34f53a"}, - {file = "ruff-0.15.16-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1e15bc8c94513dae2a40cc9ef07c94fdd4ecc9e29dabebeebe170f952322c9e3"}, - {file = "ruff-0.15.16-py3-none-win32.whl", hash = "sha256:580378f7bd4aa25f72e74aa54948a9622f142b1e509521dd10902e886681cc1e"}, - {file = "ruff-0.15.16-py3-none-win_amd64.whl", hash = "sha256:408256017284eddf98fff77b29aa4fb30f586042d535b2d9befc6512f400aaec"}, - {file = "ruff-0.15.16-py3-none-win_arm64.whl", hash = "sha256:8cd61783afb39638a7133ef0d2dfb1e91277593962f81b5a8423eb0b888a6121"}, - {file = "ruff-0.15.16.tar.gz", hash = "sha256:d05e78d38c78caf020b03789e25106c93017db5a0cb6e2819885018c61343b78"}, + {file = "ruff-0.15.18-py3-none-linux_armv6l.whl", hash = "sha256:8b6850172348c8381b8b3084c5915a4393c2373b9b54cd5b5e1ea15812bc10df"}, + {file = "ruff-0.15.18-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3fccc153a85417dcd976883160cacce486997b0a0058dd18f54b8aaaac7d1ce2"}, + {file = "ruff-0.15.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08d4c86a68f2c3ec2c9d56380a71fb4a4f65373055cbb8caabd645e9102f38d4"}, + {file = "ruff-0.15.18-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37e5108745c2c0705da916d7d4de533ddf547051ef45f62888c31bae73f66318"}, + {file = "ruff-0.15.18-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56949a6ce8b3abde54c0bcb22cebfe57e8771cadc84b407ae8b8eaf67ebdcd43"}, + {file = "ruff-0.15.18-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01a754cd6a1b630d3f97e33eb452cf7a98040482318e870f8bc52a5a30e62657"}, + {file = "ruff-0.15.18-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ba7a07e03a44dbf10bb086ee06705b173625014ec99f73a7e6836a5e5590a0c"}, + {file = "ruff-0.15.18-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a2c40a41a4cadbcf5897b548ab29dfe248b20c540961c0247d98a3973c70403"}, + {file = "ruff-0.15.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0480ce690cbb6c4db6e5d08f19fce98e10ba131a8b60c1bcdac42771e3ae2d"}, + {file = "ruff-0.15.18-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2330215f1f393fa8733f55edce04fcf94c36a2c460fcde31f78cc84e4951e9b1"}, + {file = "ruff-0.15.18-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a6aa6a3d979e48ae617578183674bf264fbe7d0114a796a26bd678d67963c7ff"}, + {file = "ruff-0.15.18-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a81beadbbff2c9c245561ae3f77b16709d87f35eec650d0501679239d3449b22"}, + {file = "ruff-0.15.18-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2186d9e940ae332ab293623a75b5f4fe49565f449954d50a72a046683aa6b809"}, + {file = "ruff-0.15.18-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5c2abf140438032bc77b2284a6c9944ecd8a19e5f1c7b52b1b8e4a0a80d19a7a"}, + {file = "ruff-0.15.18-py3-none-win32.whl", hash = "sha256:02299e6e9fa5b297a3f6d5d10d7bcd655c925b028bb8b9d4588214549c6b9ec4"}, + {file = "ruff-0.15.18-py3-none-win_amd64.whl", hash = "sha256:dac80dc8d26b2257dbefabed62f5d255c3937b4ccb122da1fc634794fa3578b3"}, + {file = "ruff-0.15.18-py3-none-win_arm64.whl", hash = "sha256:b2c9257fcbd4a3e5b977a1904e6facca016bafe2edc17df24db67cfaee03b4e4"}, + {file = "ruff-0.15.18.tar.gz", hash = "sha256:2698a964c70e8bf402dcb99c8810472d270d141e7aa8c4e13599fd52033a2f33"}, ] [[package]] @@ -787,23 +787,23 @@ files = [ [[package]] name = "virtualenv" -version = "21.4.1" +version = "21.5.1" description = "Virtual Python Environment builder" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "virtualenv-21.4.1-py3-none-any.whl", hash = "sha256:caf4ff72d1b4039057f41d8e8466e859513d67c0400d9c6b62c02c9d1ebc3e12"}, - {file = "virtualenv-21.4.1.tar.gz", hash = "sha256:2ca543c713b72840ceffd94e9bdedfbd09a661defa1f7f69e5429ad4059442e2"}, + {file = "virtualenv-21.5.1-py3-none-any.whl", hash = "sha256:55aa670b67bbfb991b03fda39bd3276d92c419d702376e98c5df1c9989a26783"}, + {file = "virtualenv-21.5.1.tar.gz", hash = "sha256:dca3bf98275a59c652b69d68e73433e597d977c2da9198882479d1a7188009c8"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = {version = ">=3.24.2,<4", markers = "python_version >= \"3.10\""} platformdirs = ">=3.9.1,<5" -python-discovery = ">=1.4" +python-discovery = ">=1.4.2" [metadata] lock-version = "2.1" python-versions = ">=3.11,<3.15" -content-hash = "979714d01fbd2b242b9aca04292adac1abe3b90b2a45ebae9d9c360413ff4e1a" +content-hash = "63bd167f61f2c22c00ca47eed6c7a068b4fb56079073696b86974221c123b2d6" diff --git a/pyproject.toml b/pyproject.toml index 07b6f63a..9ba74d3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "VS Code-native AI engineering workflow system for microservices, license = "MIT" readme = "README-pypi.md" requires-python = ">=3.11,<3.15" -dependencies = ["pyyaml>=6.0"] +dependencies = ["pyyaml>=6.0.3"] keywords = [ "github-copilot", "vscode", diff --git a/src/vstack/_templates/agents/_partials/stage-report-contract.md b/src/vstack/_templates/agents/_partials/stage-report-contract.md index b9852be7..d23dbbfd 100644 --- a/src/vstack/_templates/agents/_partials/stage-report-contract.md +++ b/src/vstack/_templates/agents/_partials/stage-report-contract.md @@ -1,10 +1,25 @@ -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` diff --git a/src/vstack/_templates/agents/architect/config.yaml b/src/vstack/_templates/agents/architect/config.yaml index bc0bfa1a..d7869c05 100644 --- a/src/vstack/_templates/agents/architect/config.yaml +++ b/src/vstack/_templates/agents/architect/config.yaml @@ -16,11 +16,6 @@ tools: - vscode - todo - agent -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) - - Claude Opus 4.7 (copilot) agents: - product - architect diff --git a/src/vstack/_templates/agents/designer/config.yaml b/src/vstack/_templates/agents/designer/config.yaml index d08bfc7b..50405308 100644 --- a/src/vstack/_templates/agents/designer/config.yaml +++ b/src/vstack/_templates/agents/designer/config.yaml @@ -15,10 +15,6 @@ tools: - vscode - todo - agent -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) agents: - product - architect diff --git a/src/vstack/_templates/agents/engineer/config.yaml b/src/vstack/_templates/agents/engineer/config.yaml index 567c0e16..50792dd6 100644 --- a/src/vstack/_templates/agents/engineer/config.yaml +++ b/src/vstack/_templates/agents/engineer/config.yaml @@ -15,10 +15,6 @@ tools: - vscode - todo - agent -model: - - auto - - GPT-5.3-Codex (copilot) - - Claude Sonnet 4.6 (copilot) agents: - product - architect diff --git a/src/vstack/_templates/agents/planner/config.yaml b/src/vstack/_templates/agents/planner/config.yaml index c17ebc9d..18462c15 100644 --- a/src/vstack/_templates/agents/planner/config.yaml +++ b/src/vstack/_templates/agents/planner/config.yaml @@ -10,10 +10,6 @@ tools: - search - todo - agent -model: - - auto - - GPT-5.3-Codex (copilot) - - Claude Sonnet 4.6 (copilot) agents: - product - architect diff --git a/src/vstack/_templates/agents/planner/template.md b/src/vstack/_templates/agents/planner/template.md index a60de942..82f211dc 100644 --- a/src/vstack/_templates/agents/planner/template.md +++ b/src/vstack/_templates/agents/planner/template.md @@ -74,6 +74,23 @@ Signs a request is a focused task (not a pipeline run): When in doubt, ask: "Does this need more than one role to complete?" If not, route directly. +## collaborative planning with user approval + +Before dispatching worker agents for a full pipeline, create a short execution plan with the user. + +1. Propose the initial plan as a compact stage list with: objective, owning role, and dependencies. +1. Ask for confirmation or edits when sequencing, scope, or ownership is ambiguous. +1. Apply user feedback and freeze the plan baseline for this run. +1. Start delegation only after the plan is accepted. + +During execution, the plan may change only when new facts appear. When replanning is needed: + +1. Explain what changed and why the current plan is no longer valid. +1. Propose the minimal plan delta. +1. Ask for approval before continuing with the updated plan. + +The planner owns planning and orchestration decisions. Worker agents execute scoped tasks from the accepted plan. + ## working principles - **Classify before orchestrating.** Determine whether the request is a full pipeline run or a focused task before starting any stage. Starting the pipeline for a focused task is overhead without benefit. @@ -101,6 +118,71 @@ For every ready stage or domain question: If a domain question surfaces mid-orchestration that no stage report has answered, route it to the relevant specialist instead of answering it yourself. +## token efficiency and delegation budget + +Use subagents by default for substantive work, but keep delegation payloads minimal and deterministic. + +1. Set a concise run budget up front: expected number of stages, candidate parallel branches, and escalation points. +1. Delegate only the minimum context needed for the stage: + +- stage objective +- accepted plan slice for this stage +- relevant predecessor outputs only +- explicit done criteria + +1. Prefer delta handoffs. If a stage reruns, pass only what changed since the last attempt. +1. Avoid duplicate calls. Do not invoke a worker again with the same objective and unchanged inputs. +1. Use focused specialist routing instead of broad multi-role fan-out when one role can complete the task. +1. Keep stage reports compact and structured so downstream prompts can reference fields instead of replaying prose. + +Parallelization rule: + +- Run in parallel only when dependencies are fully satisfied and merge criteria are explicit. +- If merge criteria are unclear, run sequentially to avoid rework and token waste. + +Escalation rule: + +- If required context is missing, ask one targeted question before dispatching. +- If uncertainty remains high after one question, pause and request user decision instead of speculative delegation. + +## plan state and persistence + +The execution plan is operational state, not a domain deliverable. + +Planner-run state schema (keep this shape stable across the run): + +```yaml +planner_run_state: + planner_run_id: + plan_version: + stage_status_map: + : ready|blocked|skipped|pending + blockers: + - +``` + +State update protocol: + +1. Initialize `planner_run_state` before first delegation. + +1. Increment `plan_version` only when plan structure or sequencing changes. + +1. Update only the affected keys after each stage (delta update), especially `stage_status_map` and `blockers`. + +1. Keep `planner_run_id` stable for the full run and propagate it to every delegated prompt. + +1. On replan, record a short rationale and changed stages before dispatch continues. + +1. Do not write planner run plans to project docs output paths (for example, docs releases or role-owned artifacts) unless explicitly requested. + +1. Keep active plan state in session-level coordination context and stage execution logs. + +1. If repository memory is available, persist only concise run metadata there (plan version, stage status map, blocker list, planner run id). + +1. Persist plan state updates as deltas, not full rewrites. + +1. Treat persisted plan state as coordination data only; worker artifacts remain owned by worker agents. + ## decision guidelines - If workflow config is missing or invalid, stop and report exactly what is wrong. diff --git a/src/vstack/_templates/agents/product/config.yaml b/src/vstack/_templates/agents/product/config.yaml index 3db6bd4e..6d82a426 100644 --- a/src/vstack/_templates/agents/product/config.yaml +++ b/src/vstack/_templates/agents/product/config.yaml @@ -15,11 +15,6 @@ tools: - vscode - todo - agent -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) - - Claude Opus 4.7 (copilot) agents: - product - architect diff --git a/src/vstack/_templates/agents/release/config.yaml b/src/vstack/_templates/agents/release/config.yaml index f52aa3d0..c3566974 100644 --- a/src/vstack/_templates/agents/release/config.yaml +++ b/src/vstack/_templates/agents/release/config.yaml @@ -15,10 +15,6 @@ tools: - vscode - todo - agent -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) agents: - product - architect diff --git a/src/vstack/_templates/agents/tester/config.yaml b/src/vstack/_templates/agents/tester/config.yaml index e5227503..b5f45c2e 100644 --- a/src/vstack/_templates/agents/tester/config.yaml +++ b/src/vstack/_templates/agents/tester/config.yaml @@ -14,10 +14,6 @@ tools: - vscode - todo - agent -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) agents: - product - architect diff --git a/src/vstack/_templates/instructions/git/template.md b/src/vstack/_templates/instructions/git/template.md index c821d7bf..cda7444b 100644 --- a/src/vstack/_templates/instructions/git/template.md +++ b/src/vstack/_templates/instructions/git/template.md @@ -1,33 +1,33 @@ -Use these Git and release hygiene conventions in this project. +Use these Git and release hygiene conventions. ## Branch naming 1. Use `type/short-description` branch names. -1. Keep branch names lowercase and use hyphens to separate words. -1. Use one of these allowed branch types when branch validation is enabled: +1. Keep names lowercase and hyphenated. +1. Use one of these branch types when validation is enabled: `feature`, `bugfix`, `hotfix`, `release`, `chore`, `feat`, `fix`, `docs`, `refactor`, `perf`, `test`, `ci`, `build`, `style`, `opt`, `patch`, `dependabot`. ## Commit messages 1. Use Conventional Commits: `type(optional-scope)!: short summary`. -1. Keep commit subjects clear, imperative, and within repository limits. -1. Keep the commit subject at 100 characters or fewer when commit policy CI enforces this limit. -1. Include `!` or a `BREAKING CHANGE:` footer when behavior changes are breaking. -1. Keep commit type and scope aligned with repository policy. +1. Keep subjects clear, imperative, and within repository limits. +1. Keep commit subjects at 100 characters or fewer when policy CI enforces that limit. +1. Add `!` or a `BREAKING CHANGE:` footer for breaking behavior. +1. Match type and scope to repository policy. ## SemVer alignment -1. Treat commit messages as release inputs when the repository uses semantic version automation. -1. Ensure major, minor, and patch intent is reflected in the commit type and breaking markers. +1. Treat commit messages as release inputs when semantic version automation is in use. +1. Reflect major, minor, and patch intent in the commit type and breaking markers. 1. Do not merge release-impacting changes with ambiguous commit messages. ## Security and credentials 1. Never ask users to paste passphrases, tokens, API keys, or private keys into chat. -1. Never echo or log secrets from terminal prompts, command output, or environment variables. +1. Never echo or log secrets from prompts, command output, or environment variables. 1. Never place credentials in commit messages, source files, workflow files, or documentation. -1. Prefer existing secure authentication flows (for example SSH agent, OS keychain, `gh auth`). +1. Prefer existing secure auth flows such as SSH agent, OS keychain, or `gh auth`. ## Safe Git operations diff --git a/src/vstack/_templates/instructions/helm/template.md b/src/vstack/_templates/instructions/helm/template.md index 81a20eee..6e583eb8 100644 --- a/src/vstack/_templates/instructions/helm/template.md +++ b/src/vstack/_templates/instructions/helm/template.md @@ -1,4 +1,4 @@ -Use these Helm conventions in this project. +Use these Helm conventions. ## Chart structure @@ -8,10 +8,10 @@ Use these Helm conventions in this project. ## Templating quality -1. Quote string values where ambiguity may cause rendering/type errors. -1. Guard optional blocks with conditionals to avoid emitting invalid YAML. +1. Quote string values where ambiguity may cause rendering or type errors. +1. Guard optional blocks with conditionals to avoid invalid YAML. 1. Keep names and labels deterministic via helper templates. -1. Avoid embedding large opaque blobs in templates; externalize where possible. +1. Avoid embedding large opaque blobs; externalize where possible. ## Values and secrets @@ -34,7 +34,7 @@ Use these Helm conventions in this project. ## References -> Always use the official documentation for the exact Helm and Kubernetes versions in use - chart schema, flags, and behavior evolve between releases. +> Always use the official documentation for the exact Helm and Kubernetes versions in use; chart schema, flags, and behavior evolve between releases. - [Helm docs](https://helm.sh/docs/) - [Helm chart best practices](https://helm.sh/docs/chart_best_practices/) diff --git a/src/vstack/_templates/instructions/java/template.md b/src/vstack/_templates/instructions/java/template.md index 47c62b1a..93f25a4c 100644 --- a/src/vstack/_templates/instructions/java/template.md +++ b/src/vstack/_templates/instructions/java/template.md @@ -1,10 +1,10 @@ -Use these Java conventions in this project. +Use these Java conventions. ## Design and readability -1. Prefer explicit, domain-meaningful names over abbreviations; follow standard Java naming conventions. -1. Keep methods focused; split methods that mix parsing, I/O, and business rules. -1. Prefer immutable objects; make fields `final` by default and expose mutation only where required. +1. Prefer explicit, domain-meaningful names over abbreviations. +1. Keep methods focused. +1. Prefer immutable objects; make fields `final` by default. 1. Prefer straightforward control flow over clever one-liners. ## Types and APIs @@ -12,13 +12,13 @@ Use these Java conventions in this project. 1. Keep public APIs minimal and stable; mark implementation details `package-private` or `private`. 1. Program to interfaces, not implementations, for dependencies that may change. 1. Use records for simple value types where the Java version supports them. -1. Prefer `Optional` as a return type for values that may be absent; do not use it for fields or parameters. +1. Prefer `Optional` as a return type for absent values; do not use it for fields or parameters. ## Null safety 1. Annotate method parameters and return types with `@NonNull` or `@Nullable` where nullability is meaningful. 1. Never return `null` from a public method that could return `Optional` instead. -1. Fail fast on unexpected nulls at system boundaries using explicit precondition checks. +1. Fail fast on unexpected nulls at system boundaries. ## Exception handling diff --git a/src/vstack/_templates/instructions/k8s/template.md b/src/vstack/_templates/instructions/k8s/template.md index a43c8b38..7f933892 100644 --- a/src/vstack/_templates/instructions/k8s/template.md +++ b/src/vstack/_templates/instructions/k8s/template.md @@ -1,4 +1,4 @@ -Use these Kubernetes conventions in this project. +Use these Kubernetes conventions. ## API and versioning @@ -9,7 +9,7 @@ Use these Kubernetes conventions in this project. ## Workload safety 1. Set CPU and memory `requests` and `limits` for every container. -1. Define both readiness and liveness probes for long-running services. +1. Define readiness and liveness probes for long-running services. 1. Avoid mutable image tags (`:latest`); use pinned tags or immutable digests. 1. Set rollout strategy explicitly for Deployments handling production traffic. @@ -30,7 +30,7 @@ Use these Kubernetes conventions in this project. 1. Use PodDisruptionBudgets for critical workloads. 1. Configure `terminationGracePeriodSeconds` and preStop hooks where graceful shutdown is required. -1. Add resource annotations/labels needed by observability and runtime policies. +1. Add resource annotations or labels needed by observability and runtime policies. ## Validation @@ -40,7 +40,7 @@ Use these Kubernetes conventions in this project. ## References -> Always use the official documentation for the exact Kubernetes version in use - API versions and defaults change between releases. +> Always use the official documentation for the exact Kubernetes version in use; API versions and defaults change between releases. - [Kubernetes docs](https://kubernetes.io/docs/) - [Kubernetes API reference](https://kubernetes.io/docs/reference/kubernetes-api/) diff --git a/src/vstack/_templates/instructions/markdown/template.md b/src/vstack/_templates/instructions/markdown/template.md index b10327f8..f95c7fb5 100644 --- a/src/vstack/_templates/instructions/markdown/template.md +++ b/src/vstack/_templates/instructions/markdown/template.md @@ -1,46 +1,46 @@ -Use these Markdown conventions in this project. +Use these Markdown conventions. ## Structure and headings -1. Keep heading levels sequential — do not skip levels (e.g. from `##` to `####`). +1. Keep heading levels sequential. 1. Prefer flat heading structures; rarely go deeper than `####`. 1. Keep headings short and descriptive. ## Prose and tone -1. Write in clear, direct language — prefer active voice over passive voice. -1. Keep sentences short; split complex ideas across multiple sentences rather than commas and semicolons. -1. Be consistent with terminology throughout the file; introduce a term once and reuse it. +1. Write in clear, direct language with active voice. +1. Keep sentences short. +1. Be consistent with terminology throughout the file. 1. Avoid filler phrases such as "please note", "it is important to", and "simply". ## Lists and tables -1. Use numbered lists for ordered steps; use unordered lists for non-ordered items. -1. Keep list items parallel in grammar and structure. -1. Prefer a table over nested unordered lists when presenting structured comparisons. -1. Keep table columns to what is necessary; remove columns with no meaningful content. +1. Use numbered lists for ordered steps and unordered lists for non-ordered items. +1. Keep list items parallel. +1. Prefer tables over nested lists for structured comparisons. +1. Keep tables lean. ## Code blocks and inline code -1. Specify a language identifier on fenced code blocks where a language can be determined. +1. Specify a language identifier on fenced code blocks when possible. 1. Use inline code for file names, paths, commands, identifiers, and literal values. 1. Do not put prose in a code block; reserve code blocks for commands, source code, and literal output. ## Links and references -1. Use descriptive link text — avoid bare URLs and text like "click here" or "this link". +1. Use descriptive link text. 1. Prefer relative links for documents within the same repository. -1. Verify that section anchors match actual heading text before committing. +1. Verify that section anchors match actual heading text. ## Diagrams -1. Use Mermaid for process, flow, interaction, lifecycle, and decision diagrams when the target environment renders it (GitHub, VS Code, compatible docs tools). -1. Fall back to ASCII or plain-text descriptions when Mermaid rendering cannot be guaranteed (e.g. PyPI, email, plain-text viewers). -1. Use ASCII or text trees for directory layouts and file hierarchies regardless of environment. +1. Use Mermaid for process, flow, interaction, lifecycle, and decision diagrams when the target environment renders it. +1. Fall back to ASCII or plain text when Mermaid cannot be guaranteed. +1. Use ASCII or text trees for directory layouts and file hierarchies. 1. Do not embed a diagram where a simple sentence or table communicates the same information. ## Maintenance -1. Update documentation in the same change as the behavior or interface it describes. -1. Remove outdated content rather than leaving it with a "TODO: update" comment. -1. Keep examples accurate and runnable — a broken example is worse than no example. +1. Update documentation with the behavior or interface it describes. +1. Remove outdated content rather than leaving a TODO. +1. Keep examples accurate and runnable. diff --git a/src/vstack/_templates/instructions/python/template.md b/src/vstack/_templates/instructions/python/template.md index bf6f27bf..6ae978fc 100644 --- a/src/vstack/_templates/instructions/python/template.md +++ b/src/vstack/_templates/instructions/python/template.md @@ -1,23 +1,23 @@ -Use these Python conventions in this project. +Use these Python conventions. ## Design and readability 1. Prefer explicit, domain-meaningful names over abbreviations. -1. Keep functions focused; split functions that mix parsing, I/O, and business rules. -1. Prefer straightforward control flow over clever one-liners. -1. Raise precise exceptions with actionable error messages. +1. Keep functions focused. +1. Prefer straightforward control flow. +1. Raise precise exceptions with actionable messages. ## Typing and APIs 1. Add type hints to public functions, methods, and module-level constants. -1. Keep public interfaces stable and backward compatible unless the task explicitly allows breaking changes. -1. Use dataclasses or TypedDict for structured data instead of untyped dicts when shape is known. +1. Keep public interfaces stable and backward compatible unless breaking changes are explicitly allowed. +1. Use dataclasses or TypedDict for structured data. ## Imports and dependencies 1. Group imports as standard library, third-party, and local modules. 1. Keep imports minimal and remove unused imports. -1. Avoid adding runtime dependencies unless there is a clear benefit over stdlib or existing project dependencies. +1. Avoid adding runtime dependencies unless there is a clear benefit over stdlib or existing dependencies. ## Testing and verification diff --git a/src/vstack/_templates/instructions/rancher/template.md b/src/vstack/_templates/instructions/rancher/template.md index ba1072c7..10b733f8 100644 --- a/src/vstack/_templates/instructions/rancher/template.md +++ b/src/vstack/_templates/instructions/rancher/template.md @@ -1,10 +1,10 @@ -Use these Rancher conventions in this project. +Use these Rancher conventions. ## Scope and environment 1. Keep environment and cluster targeting explicit; avoid wildcard targeting for production bundles. 1. Separate dev, staging, and production policies and rollout paths. -1. Document expected project/namespace scope for each config set. +1. Document expected project and namespace scope for each config set. ## Fleet and GitOps hygiene @@ -23,17 +23,17 @@ Use these Rancher conventions in this project. 1. Do not hardcode credentials or tokens in Rancher/Fleet config files. 1. Reference secrets from approved secret management paths. -1. Keep auditability for cluster/project configuration changes. +1. Keep auditability for cluster and project configuration changes. ## Operations -1. Validate target clusters/projects before applying any change. +1. Validate target clusters and projects before applying any change. 1. Include rollback guidance for application and bundle updates. 1. Treat drift and failed bundle rollout as operational incidents with follow-up remediation. ## References -> Always use the official documentation for the exact Rancher and Fleet versions in use - features and defaults vary between releases. +> Always use the official documentation for the exact Rancher and Fleet versions in use; features and defaults vary between releases. - [Rancher docs](https://ranchermanager.docs.rancher.com/) - [Fleet docs](https://fleet.rancher.io/) diff --git a/src/vstack/_templates/instructions/security/template.md b/src/vstack/_templates/instructions/security/template.md index 6e9a117f..ded1b1b0 100644 --- a/src/vstack/_templates/instructions/security/template.md +++ b/src/vstack/_templates/instructions/security/template.md @@ -1,37 +1,37 @@ -Apply these security policies in this project. +Use these security policies. ## Secrets and credentials -1. Never hardcode secrets, tokens, passwords, or private keys in source code, configuration files, tests, or commit messages. -1. Read secrets from environment variables or a secret store at runtime; document which variables are required. -1. Treat any accidental secret exposure as a revocation event — rotate immediately, do not just delete the value. +1. Never hardcode secrets, tokens, passwords, or private keys in source code, config files, tests, or commit messages. +1. Read secrets from environment variables or a secret store at runtime; document required variables. +1. Treat accidental exposure as a revocation event; rotate immediately. ## Input and trust boundaries 1. Validate and sanitize all input that crosses a trust boundary: HTTP requests, CLI arguments, environment variables, files, and inter-service messages. -1. Never trust client-supplied values for authorization decisions; enforce access control server-side. -1. Reject or escape input before it reaches queries, shell commands, template engines, or log sinks. +1. Never trust client-supplied values for authorization decisions. +1. Reject or escape input before it reaches queries, shell commands, template engines, or logs. ## Authentication and authorization -1. Default to deny; require explicit grants for every protected resource or operation. -1. Verify identity and permission separately; do not conflate authentication with authorization. -1. Do not implement custom cryptography or authentication schemes; use established, maintained libraries. +1. Default to deny; require explicit grants for protected resources or operations. +1. Verify identity and permission separately. +1. Use established, maintained libraries; do not implement custom cryptography or auth schemes. ## Dependencies and supply chain 1. Pin dependency versions in manifests; do not use unbounded version ranges in production code. -1. Minimise the dependency surface — do not add a library when the standard library suffices. -1. Treat dependency updates that introduce new transitive dependencies as requiring explicit review. +1. Minimise the dependency surface. +1. Treat updates that add new transitive dependencies as requiring explicit review. ## Error handling and observability 1. Never expose internal stack traces, system paths, or configuration details to external callers. 1. Do not log sensitive data: passwords, tokens, PII, or session identifiers. -1. Fail closed on security errors — deny access when the policy cannot be evaluated, rather than defaulting to allow. +1. Fail closed on security errors. ## Destructive and privileged operations -1. Require explicit confirmation before executing irreversible or destructive operations. -1. Apply least privilege: request only the permissions a component actually needs. -1. Isolate privileged logic; keep it minimal, auditable, and separate from business logic. +1. Require explicit confirmation before irreversible or destructive operations. +1. Apply least privilege. +1. Keep privileged logic minimal, auditable, and separate from business logic. diff --git a/src/vstack/_templates/instructions/terraform/template.md b/src/vstack/_templates/instructions/terraform/template.md index 3fbeabb8..46f0ca12 100644 --- a/src/vstack/_templates/instructions/terraform/template.md +++ b/src/vstack/_templates/instructions/terraform/template.md @@ -1,34 +1,34 @@ -Use these Terraform conventions in this project. +Use these Terraform conventions. ## Structure and file layout -1. Split configuration into `main.tf`, `variables.tf`, `outputs.tf`, `providers.tf`, `versions.tf`, and `locals.tf` — do not put everything in one file. -1. Keep one module per directory; avoid multi-purpose root modules. -1. Place reusable logic in `modules//` with its own `variables.tf` and `outputs.tf`. +1. Split config into `main.tf`, `variables.tf`, `outputs.tf`, `providers.tf`, `versions.tf`, and `locals.tf`. +1. Keep one module per directory. +1. Put reusable logic in `modules//` with its own `variables.tf` and `outputs.tf`. ## Versioning and pinning -1. Pin the Terraform binary version with `required_version = "~> X.Y"` in a `versions.tf` file. -1. Pin every provider with `version = "~> X.Y"` in `required_providers` — never use unbounded ranges in production. +1. Pin the Terraform version with `required_version = "~> X.Y"` in `versions.tf`. +1. Pin each provider with `version = "~> X.Y"` in `required_providers`; never use unbounded ranges in production. 1. Commit `.terraform.lock.hcl` to source control. -1. Pin external module sources to a specific git ref or registry semver tag — never `?ref=main`. +1. Pin external module sources to a specific git ref or registry semver tag; never `?ref=main`. ## State management -1. Use a remote backend with encryption and state locking for all non-local work. +1. Use a remote backend with encryption and locking for all non-local work. 1. Enable versioning on the S3 state bucket. -1. Never store secrets in state outputs — mark sensitive outputs with `sensitive = true`. +1. Never expose secrets via outputs; mark sensitive outputs with `sensitive = true`. ## Variables and outputs -1. Add `type`, `description`, and a sensible `default` to every variable. -1. Add validation blocks for constrained variables (`AllowedValues` equivalents). -1. Mark secret variables with `sensitive = true` — never hardcode them in `.tf` files or committed `.tfvars`. +1. Add `type`, `description`, and a sensible `default` for every variable. +1. Add validation blocks for constrained variables. +1. Mark secret variables with `sensitive = true`; never hardcode them in `.tf` files or committed `.tfvars`. 1. Add `description` to every output; mark secret outputs `sensitive = true`. ## Naming and tagging -1. Use `locals` to construct name prefixes and centralise tag maps. +1. Use `locals` to build name prefixes and centralise tag maps. 1. Name physical resources with `"${local.name_prefix}-"` to ensure cross-stack uniqueness. 1. Apply a common tag map (`local.common_tags`) to every taggable resource; include at minimum `Environment` and `ManagedBy = "terraform"`. @@ -36,19 +36,19 @@ Use these Terraform conventions in this project. 1. Block public access on all S3 buckets unless intentionally public; document the exception. 1. Enable `storage_encrypted = true` and `deletion_protection = true` on all RDS instances. -1. Restrict security group rules — avoid `0.0.0.0/0` on management ports; add a comment when HTTPS/443 is open. -1. Apply least-privilege IAM policies — no `*` actions on `*` resources. +1. Restrict security group rules; avoid `0.0.0.0/0` on management ports and add a comment when HTTPS/443 is open. +1. Apply least-privilege IAM policies; no `*` actions on `*` resources. 1. Enable KMS key rotation (`enable_key_rotation = true`). ## Tooling 1. Run `terraform fmt -check -recursive` in CI and auto-format locally. 1. Run `terraform validate` before every plan. -1. Run `tfsec` or `checkov` on all changes; fix HIGH and CRITICAL findings before merging. +1. Run `tfsec` or `checkov` on all changes; fix HIGH/CRITICAL findings before merging. ## References -> Always use the official documentation for the provider and Terraform version in use — resource arguments and defaults change between provider releases. +> Use official docs for the provider and Terraform version in use; resource arguments and defaults change between releases. - [Terraform documentation](https://developer.hashicorp.com/terraform/docs) - [Terraform provider registry](https://registry.terraform.io/) diff --git a/src/vstack/_templates/instructions/terragrunt/template.md b/src/vstack/_templates/instructions/terragrunt/template.md index 3363e57d..15e97db0 100644 --- a/src/vstack/_templates/instructions/terragrunt/template.md +++ b/src/vstack/_templates/instructions/terragrunt/template.md @@ -1,37 +1,37 @@ -Use these Terragrunt conventions in this project. +Use these Terragrunt conventions. ## Structure and hierarchy 1. Maintain a strict directory hierarchy that maps to deployment topology: `infra///terragrunt.hcl`. -1. Keep one root `terragrunt.hcl` at the repository root or top-level `infra/` directory; inherit it in all units via `include "root" { path = find_in_parent_folders() }`. -1. Use `account.hcl` files at the account/environment level for account ID, region, and environment name — read them with `read_terragrunt_config(find_in_parent_folders("account.hcl"))`. +1. Keep one root `terragrunt.hcl` at repo root or top-level `infra/`; inherit it in all units via `include "root" { path = find_in_parent_folders() }`. +1. Use `account.hcl` files at the account/environment level for account ID, region, and environment name; read them with `read_terragrunt_config(find_in_parent_folders("account.hcl"))`. ## Remote state and backend generation -1. Generate `backend.tf` from the root `remote_state` block — never hand-write backend files in units. -1. Use `path_relative_to_include()` as the state key so each unit gets a unique, auto-named state file. +1. Generate `backend.tf` from the root `remote_state` block; never hand-write backend files in units. +1. Use `path_relative_to_include()` as the state key so each unit gets a unique state file. 1. Enable encryption and state locking on the S3 backend; enable versioning on the state bucket. ## Provider generation -1. Generate `provider.tf` from the root `generate "provider"` block — never duplicate provider configuration across units. -1. Include `default_tags` in the generated provider block to ensure consistent tagging across all resources. +1. Generate `provider.tf` from the root `generate "provider"` block; never duplicate provider configuration across units. +1. Include `default_tags` in the generated provider block to keep tagging consistent across resources. ## Module sources and pinning -1. Pin all module sources to a specific git ref or registry semver tag — never `?ref=main` or floating tags. -1. Prefer sourcing from a versioned internal registry or tagged git commit over local paths in shared modules. +1. Pin all module sources to a specific git ref or registry semver tag; never `?ref=main` or floating tags. +1. Prefer a versioned internal registry or tagged git commit over local paths in shared modules. ## Dependency blocks -1. Add `mock_outputs` to every `dependency` block for the `validate` and `plan` commands — this allows planning without deploying dependencies first. +1. Add `mock_outputs` to every `dependency` block for the `validate` and `plan` commands; this allows planning without deploying dependencies first. 1. Declare only the outputs you actually use from a dependency; do not expose the full output set. -1. Keep `dependency` blocks at unit level — do not express dependencies in the root config. +1. Keep `dependency` blocks at unit level; do not express dependencies in root config. ## DRY inputs -1. Extract shared inputs for an ecosystem (e.g. RDS defaults) into `_envcommon/.hcl`; load with `read_terragrunt_config`. -1. Use `merge(local.common.inputs, { ... })` to override defaults per environment — do not copy-paste full input maps. +1. Extract shared inputs for an ecosystem into `_envcommon/.hcl`; load with `read_terragrunt_config`. +1. Use `merge(local.common.inputs, { ... })` to override defaults per environment; do not copy-paste full input maps. ## CI/CD @@ -41,12 +41,12 @@ Use these Terragrunt conventions in this project. ## Secrets -1. Never hardcode secrets in `.hcl` files — supply them via environment variables (`TF_VAR_*`) or a secrets manager data source. +1. Never hardcode secrets in `.hcl` files; supply them via environment variables (`TF_VAR_*`) or a secrets manager data source. 1. Do not commit `.tfvars` files containing real secrets. ## References -> Always use the official documentation for the Terragrunt version in use — built-in functions and CLI flags evolve with each release. +> Use official docs for the Terragrunt version in use; built-in functions and CLI flags evolve between releases. - [Terragrunt documentation](https://terragrunt.gruntwork.io/docs/) - [Terragrunt CLI reference](https://terragrunt.gruntwork.io/docs/reference/cli-options/) diff --git a/src/vstack/_templates/instructions/testing/template.md b/src/vstack/_templates/instructions/testing/template.md index c533285a..2c7f3091 100644 --- a/src/vstack/_templates/instructions/testing/template.md +++ b/src/vstack/_templates/instructions/testing/template.md @@ -1,38 +1,38 @@ -Use these testing conventions in this project. +Use these testing conventions. ## Scope and intent 1. Write tests to verify observable behavior, not internal implementation details. 1. A test that passes when behavior is wrong, or fails when behavior is correct, has negative value. -1. Tests are documentation — a reader should understand what the system does by reading the test. +1. Tests should read like documentation. ## Naming and structure -1. Name tests to describe what they verify: what the subject does, under what condition, and what the expected outcome is. -1. Keep each test focused on one behavior; avoid asserting unrelated outcomes in a single test. -1. Group related tests together; separate unrelated test concerns into distinct test units. +1. Name tests by subject, condition, and expected outcome. +1. Keep each test focused on one behavior. +1. Group related tests together; separate unrelated concerns. ## Coverage and completeness -1. Cover the success path, expected failure paths, and boundary conditions for every behavioral change. -1. Treat missing tests for changed behavior as a defect — a change without tests is not complete. -1. Do not chase a coverage number; cover behaviors that matter rather than lines that exist. +1. Cover success paths, expected failure paths, and boundary conditions for every behavioral change. +1. Treat missing tests for changed behavior as a defect. +1. Cover behaviors that matter rather than lines that exist. ## Test quality -1. Make tests deterministic — a test that passes or fails non-deterministically is unreliable and must be fixed. -1. Keep tests independent; no test should depend on execution order or shared mutable state. -1. Prefer clear, direct assertions over indirect checks; assert the outcome, not the path to it. -1. Avoid logic (loops, conditionals) in tests; if a test needs logic, split it into multiple focused tests. +1. Make tests deterministic. +1. Keep tests independent. +1. Prefer clear, direct assertions. +1. Avoid logic in tests; split tests that need it. ## Test boundaries -1. Use unit tests for isolated logic; use integration tests when behavior crosses component or service boundaries. -1. Mock or stub only what is necessary to isolate the subject; avoid over-mocking that disconnects the test from real behavior. -1. Test contracts and interfaces, not just internal units — what the caller observes is what matters. +1. Use unit tests for isolated logic; use integration tests when behavior crosses boundaries. +1. Mock or stub only what is necessary. +1. Test contracts and interfaces, not just internal units. ## Maintenance 1. Update tests in the same change as the behavior they cover. -1. Remove tests that no longer reflect real behavior rather than commenting them out. -1. Treat flaky tests as bugs; do not merge code with known test reliability issues. +1. Remove tests that no longer reflect real behavior. +1. Treat flaky tests as bugs. diff --git a/src/vstack/_templates/instructions/typescript/template.md b/src/vstack/_templates/instructions/typescript/template.md index c97bcf20..43b29832 100644 --- a/src/vstack/_templates/instructions/typescript/template.md +++ b/src/vstack/_templates/instructions/typescript/template.md @@ -1,16 +1,16 @@ -Use these TypeScript conventions in this project. +Use these TypeScript conventions. ## Type safety -1. Enable and respect strict mode; do not disable strictness per-file without a documented reason. +1. Enable and respect strict mode; do not disable strictness per file without a documented reason. 1. Avoid `any`; prefer `unknown` when the type is genuinely unknown and narrow it explicitly. -1. Prefer `interface` for object shapes that may be extended; use `type` for unions, intersections, and aliases. +1. Prefer `interface` for extendable object shapes; use `type` for unions, intersections, and aliases. 1. Do not use type assertions (`as`) to silence type errors; fix the type instead. ## Design and readability 1. Prefer explicit, domain-meaningful names over abbreviations. -1. Keep functions focused; split functions that mix parsing, I/O, and business rules. +1. Keep functions focused. 1. Prefer straightforward control flow over clever one-liners. 1. Use `const` by default; use `let` only when reassignment is required; never use `var`. diff --git a/src/vstack/_templates/prompts/api-design-review/config.yaml b/src/vstack/_templates/prompts/api-design-review/config.yaml index fe5e583e..ffbccd7c 100644 --- a/src/vstack/_templates/prompts/api-design-review/config.yaml +++ b/src/vstack/_templates/prompts/api-design-review/config.yaml @@ -2,7 +2,6 @@ name: api-design-review description: Review an API design or OpenAPI spec for correctness, completeness, and consistency. argument-hint: "[OpenAPI spec file, design doc, or endpoint scope]" agent: designer -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/api-design-review/template.md b/src/vstack/_templates/prompts/api-design-review/template.md index 6f21b212..29829807 100644 --- a/src/vstack/_templates/prompts/api-design-review/template.md +++ b/src/vstack/_templates/prompts/api-design-review/template.md @@ -1,7 +1,7 @@ Review the provided API design or OpenAPI specification for correctness, completeness, and consistency. -Focus on issues that affect consumers: breaking contracts, ambiguous semantics, missing error cases, and inconsistent conventions. -Do not focus on implementation details or tooling preferences. +Focus on consumer impact: breaking contracts, ambiguous semantics, missing errors, and inconsistent conventions. +Ignore implementation details and tooling preferences. Output exactly in this format: diff --git a/src/vstack/_templates/prompts/architecture-risk/config.yaml b/src/vstack/_templates/prompts/architecture-risk/config.yaml index 2d197547..93d486d0 100644 --- a/src/vstack/_templates/prompts/architecture-risk/config.yaml +++ b/src/vstack/_templates/prompts/architecture-risk/config.yaml @@ -2,7 +2,6 @@ name: architecture-risk description: Identify architectural risks, tradeoffs, and mitigation priorities for a proposed design. argument-hint: "[design doc, ADR, or architecture scope]" agent: architect -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/architecture-risk/template.md b/src/vstack/_templates/prompts/architecture-risk/template.md index bf633545..d668c00c 100644 --- a/src/vstack/_templates/prompts/architecture-risk/template.md +++ b/src/vstack/_templates/prompts/architecture-risk/template.md @@ -1,7 +1,7 @@ Evaluate the provided architecture for delivery and runtime risk. Prioritize issues that could cause outages, data loss, severe operability pain, or major rework. -Do not focus on stylistic preferences. +Ignore stylistic preferences. Output exactly in this format: diff --git a/src/vstack/_templates/prompts/artifact-integrity/config.yaml b/src/vstack/_templates/prompts/artifact-integrity/config.yaml index bf2b4c84..f646d0c3 100644 --- a/src/vstack/_templates/prompts/artifact-integrity/config.yaml +++ b/src/vstack/_templates/prompts/artifact-integrity/config.yaml @@ -2,7 +2,6 @@ name: artifact-integrity description: Check source templates against generated artifacts and identify drift or missing regeneration. argument-hint: "[artifact type, path, or full repo]" agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/artifact-integrity/template.md b/src/vstack/_templates/prompts/artifact-integrity/template.md index e0e98f24..0d9a00b1 100644 --- a/src/vstack/_templates/prompts/artifact-integrity/template.md +++ b/src/vstack/_templates/prompts/artifact-integrity/template.md @@ -1,13 +1,13 @@ -Check source templates against generated artifacts and identify drift or missing regeneration. +Check source templates against generated artifacts and identify drift. -Compare `src/vstack/_templates/` sources against their installed counterparts in `.github/` -and the manifest at `.vstack/vstack.json`. Surface any mismatch, stale output, or gap. +Compare `src/vstack/_templates/` sources with installed artifacts in `.github/` +and the manifest at `.vstack/vstack.json`. Surface mismatches, stale output, or gaps. Output exactly in this format: ## Drift Findings -List every source-to-artifact mismatch detected. +List all source-to-artifact mismatches. For each item: @@ -18,7 +18,7 @@ For each item: ## Regeneration Actions -List the exact commands needed to bring generated artifacts back into sync. +List exact commands needed to bring generated artifacts back into sync. For each action: @@ -28,7 +28,7 @@ For each action: ## Risk If Unfixed -Describe the production risk if drift is left unresolved. +Describe production risk if drift is left unresolved. For each drift item from above: @@ -37,7 +37,7 @@ For each drift item from above: ## Verification Steps -Provide a checklist to confirm the repository is back in a clean state after regeneration. +Provide a checklist to confirm the repository is clean after regeneration. - [ ] `python3 -m vstack install` completes without errors - [ ] `vstack validate` reports no unresolved template tokens diff --git a/src/vstack/_templates/prompts/ci-triage/config.yaml b/src/vstack/_templates/prompts/ci-triage/config.yaml index 3df48e0f..ce2ea6ce 100644 --- a/src/vstack/_templates/prompts/ci-triage/config.yaml +++ b/src/vstack/_templates/prompts/ci-triage/config.yaml @@ -2,7 +2,6 @@ name: ci-triage description: Triage CI failures into root-cause clusters and prioritize the fastest safe recovery path. argument-hint: "[workflow run, failing job, or log scope]" agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/dependency-audit/config.yaml b/src/vstack/_templates/prompts/dependency-audit/config.yaml index 506a9c08..571b4b49 100644 --- a/src/vstack/_templates/prompts/dependency-audit/config.yaml +++ b/src/vstack/_templates/prompts/dependency-audit/config.yaml @@ -2,7 +2,6 @@ name: dependency-audit description: Audit dependencies for vulnerabilities, outdated versions, licence risks, and supply chain hygiene. argument-hint: "[dependency manifest, lockfile, or package scope]" agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/dependency-audit/template.md b/src/vstack/_templates/prompts/dependency-audit/template.md index b4033238..931b69f7 100644 --- a/src/vstack/_templates/prompts/dependency-audit/template.md +++ b/src/vstack/_templates/prompts/dependency-audit/template.md @@ -1,6 +1,6 @@ Audit the provided dependency manifest or lockfile for vulnerabilities, outdated packages, licence risks, and supply chain hygiene. -Prefer evidence from the manifest itself; flag items that require external verification. +Prefer evidence from the manifest itself; flag items that need external verification. Output exactly in this format: @@ -17,8 +17,8 @@ For each item: ## Outdated Packages -List dependencies that are significantly behind their latest stable release and carry meaningful risk. -Do not list minor version differences without impact. +List dependencies significantly behind latest stable releases where risk is meaningful. +Do not list low-impact minor version differences. For each item: @@ -43,8 +43,8 @@ For each item: ## Supply Chain Hygiene -List packages with unusual provenance concerns: abandoned maintainers, single-maintainer with no backup, recent ownership transfers, or typosquatting risk. +List packages with unusual provenance concerns: abandoned maintainers, single-maintainer projects, recent ownership transfers, or typosquatting risk. ## Recommended Actions -Ordered list of actions by priority (critical first). +Ordered action list by priority (critical first). diff --git a/src/vstack/_templates/prompts/incident-timeline/config.yaml b/src/vstack/_templates/prompts/incident-timeline/config.yaml index e542efaa..196baa88 100644 --- a/src/vstack/_templates/prompts/incident-timeline/config.yaml +++ b/src/vstack/_templates/prompts/incident-timeline/config.yaml @@ -2,7 +2,6 @@ name: incident-timeline description: Build a structured, evidence-based incident timeline and action-oriented postmortem summary. argument-hint: "[logs, alerts, timeline notes, or incident ID]" agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/migration-plan/config.yaml b/src/vstack/_templates/prompts/migration-plan/config.yaml index fb398cfb..f95ad7d6 100644 --- a/src/vstack/_templates/prompts/migration-plan/config.yaml +++ b/src/vstack/_templates/prompts/migration-plan/config.yaml @@ -2,7 +2,6 @@ name: migration-plan description: Produce a safe migration plan with sequencing, fallback paths, and verification checkpoints. argument-hint: "[migration scope or affected components]" agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/migration-safety/config.yaml b/src/vstack/_templates/prompts/migration-safety/config.yaml index 1de25cc4..4a7df139 100644 --- a/src/vstack/_templates/prompts/migration-safety/config.yaml +++ b/src/vstack/_templates/prompts/migration-safety/config.yaml @@ -2,7 +2,6 @@ name: migration-safety description: Review database migration safety, rollback strategy, and zero-downtime risk. argument-hint: "[migration files, schema, or rollout plan]" agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/migration-safety/template.md b/src/vstack/_templates/prompts/migration-safety/template.md index 912b7d0a..be7b06cf 100644 --- a/src/vstack/_templates/prompts/migration-safety/template.md +++ b/src/vstack/_templates/prompts/migration-safety/template.md @@ -1,7 +1,7 @@ Review the selected migration plan and code for production safety. Focus on forward compatibility, rollback feasibility, data integrity, and operational risk. -Assume a live system with concurrent reads/writes. +Assume a live system with concurrent reads and writes. Output exactly in this format: diff --git a/src/vstack/_templates/prompts/ops-readiness/config.yaml b/src/vstack/_templates/prompts/ops-readiness/config.yaml index 7f0c6e2f..063ab884 100644 --- a/src/vstack/_templates/prompts/ops-readiness/config.yaml +++ b/src/vstack/_templates/prompts/ops-readiness/config.yaml @@ -2,7 +2,6 @@ name: ops-readiness description: Assess operational readiness across observability, runbooks, failure handling, and supportability. argument-hint: "[service, component, or release scope]" agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/code-review/config.yaml b/src/vstack/_templates/prompts/quick-review/config.yaml similarity index 79% rename from src/vstack/_templates/prompts/code-review/config.yaml rename to src/vstack/_templates/prompts/quick-review/config.yaml index b0bc0753..6ab53b9b 100644 --- a/src/vstack/_templates/prompts/code-review/config.yaml +++ b/src/vstack/_templates/prompts/quick-review/config.yaml @@ -1,8 +1,7 @@ -name: code-review +name: quick-review description: Review a change for bugs, regressions, and missing tests. argument-hint: "[scope or files to review]" agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/code-review/template.md b/src/vstack/_templates/prompts/quick-review/template.md similarity index 100% rename from src/vstack/_templates/prompts/code-review/template.md rename to src/vstack/_templates/prompts/quick-review/template.md diff --git a/src/vstack/_templates/prompts/release-check/config.yaml b/src/vstack/_templates/prompts/release-check/config.yaml index 435f8c6b..2647d972 100644 --- a/src/vstack/_templates/prompts/release-check/config.yaml +++ b/src/vstack/_templates/prompts/release-check/config.yaml @@ -2,7 +2,6 @@ name: release-check description: Evaluate release gate readiness using required reports, artifacts, and sign-off evidence. argument-hint: "[release scope or target branch]" agent: release -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/repo-assessment/config.yaml b/src/vstack/_templates/prompts/repo-assessment/config.yaml index feb1eb7c..8b20b9ec 100644 --- a/src/vstack/_templates/prompts/repo-assessment/config.yaml +++ b/src/vstack/_templates/prompts/repo-assessment/config.yaml @@ -2,7 +2,6 @@ name: repo-assessment description: Assess a repository for production-readiness gaps and prioritized improvements. argument-hint: "[repository scope or component path]" agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/repo-assessment/template.md b/src/vstack/_templates/prompts/repo-assessment/template.md index e7c6012d..9ae04ed9 100644 --- a/src/vstack/_templates/prompts/repo-assessment/template.md +++ b/src/vstack/_templates/prompts/repo-assessment/template.md @@ -1,7 +1,7 @@ -Assess this repository for production-readiness gaps and prioritized improvement opportunities. +Assess this repository for production-readiness gaps and prioritized improvements. -Focus on evidence found in source files, tests, CI configuration, docs, and manifests. -Prefer concrete findings over speculative risks. +Base findings on evidence in source files, tests, CI config, docs, and manifests. +Prefer concrete findings over speculation. Output exactly in this format: @@ -17,8 +17,7 @@ For each item: ## High-ROI Improvements -List high-value improvements that reduce operational risk or developer friction. -Rank by impact relative to effort. +List high-value improvements that reduce operational risk or developer friction, ranked by impact versus effort. For each item: @@ -28,7 +27,7 @@ For each item: ## Testing and Verification Gaps -List behavioral paths that are untested or where test coverage provides false confidence. +List untested behavioral paths or areas where coverage may give false confidence. For each item: @@ -38,8 +37,7 @@ For each item: ## Suggested Next Sprint Backlog -Provide a short, actionable list of tasks suitable for the next sprint. -Order from highest to lowest priority. +Provide a short, actionable next-sprint task list ordered from highest to lowest priority. - task title - owner role (product | architect | designer | engineer | tester | release) diff --git a/src/vstack/_templates/prompts/template-impact/config.yaml b/src/vstack/_templates/prompts/template-impact/config.yaml index 24521fd6..31a3be63 100644 --- a/src/vstack/_templates/prompts/template-impact/config.yaml +++ b/src/vstack/_templates/prompts/template-impact/config.yaml @@ -2,7 +2,6 @@ name: template-impact description: Assess impact of a template change on generated artifacts, tests, and release risk. argument-hint: "[template path or change scope]" agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/test-gaps/config.yaml b/src/vstack/_templates/prompts/test-gaps/config.yaml index 830e2e06..92c6bb1c 100644 --- a/src/vstack/_templates/prompts/test-gaps/config.yaml +++ b/src/vstack/_templates/prompts/test-gaps/config.yaml @@ -2,7 +2,6 @@ name: test-gaps description: Identify missing behavioral coverage and prioritize test additions by production risk. argument-hint: "[component, feature, or repository scope]" agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/upgrade-plan/config.yaml b/src/vstack/_templates/prompts/upgrade-plan/config.yaml index 7975be51..da7302dd 100644 --- a/src/vstack/_templates/prompts/upgrade-plan/config.yaml +++ b/src/vstack/_templates/prompts/upgrade-plan/config.yaml @@ -2,7 +2,6 @@ name: upgrade-plan description: Build a safe upgrade plan with sequencing, compatibility checks, and rollback points. argument-hint: "[target version, component, or full repo]" agent: tester -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/prompts/workflow-check/config.yaml b/src/vstack/_templates/prompts/workflow-check/config.yaml index 74e7af23..0a56dfb6 100644 --- a/src/vstack/_templates/prompts/workflow-check/config.yaml +++ b/src/vstack/_templates/prompts/workflow-check/config.yaml @@ -2,7 +2,6 @@ name: workflow-check description: Review workflow stage flow, gate usage, and handoff integrity across role artifacts. argument-hint: "[workflow scope or stage list]" agent: planner -model: GPT-5.3-Codex (copilot) tools: - read - search diff --git a/src/vstack/_templates/skills/ask/config.yaml b/src/vstack/_templates/skills/ask/config.yaml new file mode 100644 index 00000000..6e536429 --- /dev/null +++ b/src/vstack/_templates/skills/ask/config.yaml @@ -0,0 +1,17 @@ +name: ask +version: 20260618001 +description: | + Read-only technical Q&A for the current codebase. Clarifies ambiguous + questions, gathers evidence from code and docs, and returns concise, + referenced answers without making any changes. Use for "how does this work", + "where is X", "why might this fail", and "what should we do" guidance. +allowed-tools: 'execute read search web vscode' +argument-hint: '[question about code, architecture, behavior, or workflow]' + +license: MIT +compatibility: Requires a skills-compatible agent with repository file access and optional web lookup. +metadata: + owner: vstack + maturity: stable +user-invocable: true +disable-model-invocation: false diff --git a/src/vstack/_templates/skills/ask/template.md b/src/vstack/_templates/skills/ask/template.md new file mode 100644 index 00000000..2f5fcba7 --- /dev/null +++ b/src/vstack/_templates/skills/ask/template.md @@ -0,0 +1,91 @@ +{{SKILL_CONTEXT}} + +# ask — Read-Only Technical Q&A + +Answer questions clearly using evidence from the repository. +Do not edit files, run write operations, or apply changes. + +## Out of scope + +- Implementing fixes or refactors (route to `engineer`) +- Running destructive commands or state-changing operations +- Producing release artifacts (route to `release`) + +## Workflow + +1. Understand the question and classify it: + - code behavior/explanation + - architecture/ownership + - debugging hypothesis + - API usage/contract + - process/tooling guidance +1. Identify what evidence is needed. +1. Gather evidence with focused search and minimal file reads. +1. Ask one clarification question if ambiguity blocks a reliable answer. +1. Respond with direct answer + evidence + actionable next steps. + +## Clarification rule + +If the question is ambiguous, ask exactly one focused question before deeper research. +Use options when useful and include a default assumption. + +Example format: + +- Question: Which path do you mean by "review flow"? +- Options: A) PR review lifecycle | B) code quality skill flow | C) release sign-off flow +- Default if no response: B + +## Research strategy + +Prefer broad-to-narrow exploration: + +1. Find candidate areas quickly. +1. Narrow to specific symbols/functions/configs. +1. Read only files required to answer confidently. + +Recommended commands: + +```bash +rg -n "" src tests docs 2>/dev/null | head -120 +rg --files src tests docs | head -200 +``` + +When needed, inspect relevant runtime evidence: + +```bash +# read-only diagnostics/examples +# terminal output snapshots or test failure summaries can be used as evidence +``` + +## Answer quality rules + +- Lead with the answer, then provide evidence. +- Distinguish verified facts from assumptions. +- Reference concrete files and symbols for code-related questions. +- Keep answers concise but complete for the asked scope. +- If changes are needed, describe them but do not apply them. + +## Output contract + +Use this format: + +```text +## Answer +[Direct answer in plain language] + +## Evidence +- [file/symbol]: [what it shows] +- [file/symbol]: [what it shows] + +## Recommended Next Step +- [single best next action] + +## Confidence +[high/medium/low + one-line reason] +``` + +## Escalation guidance + +- If the question requires implementation, hand off to `engineer` with a scoped summary. +- If it requires deep root-cause investigation, hand off to `debug`. +- If it requires risk/impact comparison, hand off to `analyse`. diff --git a/src/vstack/_templates/skills/explore/config.yaml b/src/vstack/_templates/skills/explore/config.yaml index e2fb9c73..02229ead 100644 --- a/src/vstack/_templates/skills/explore/config.yaml +++ b/src/vstack/_templates/skills/explore/config.yaml @@ -1,11 +1,11 @@ name: explore -version: 20260421015 +version: 20260611001 description: | - Repository and system discovery. Maps the architecture, understands the - codebase, identifies technical debt, and produces a structured onboarding - summary. Use at the start of any engagement with an unfamiliar codebase, - when asked to "understand this codebase", "map the architecture", "explore - the repo", or "what does this service do?". + Fast codebase exploration and technical Q&A. Uses broad-to-narrow search, + parallel context gathering, and depth modes (`quick`, `medium`, `thorough`) + to map architecture, find reusable patterns, and answer targeted questions + without making code changes. Use when asked to "explore the repo", "where is + X implemented", "how does this system work", or "find examples to reuse". allowed-tools: 'execute read search' argument-hint: '[repository or system to explore]' diff --git a/src/vstack/_templates/skills/explore/template.md b/src/vstack/_templates/skills/explore/template.md index 5393987f..d6accf0f 100644 --- a/src/vstack/_templates/skills/explore/template.md +++ b/src/vstack/_templates/skills/explore/template.md @@ -1,170 +1,116 @@ {{SKILL_CONTEXT}} -# explore — Codebase & Architecture Discovery +# explore — Fast Repository Exploration & Reuse Discovery -Map an unfamiliar codebase and produce a structured onboarding summary. -Report findings; do not change code. +Answer codebase questions quickly and accurately. +Map architecture, find reusable patterns, and return targeted evidence. +Do not change files. ## Out of scope -- Fixing issues found during exploration (use `debug` or `verify`) -- Architecture recommendations (use `architecture`) -- Performance analysis (use `performance` or `analyse`) +- Implementing or fixing code (use `engineer`, `debug`, or `verify` workflows) +- Full architecture decisioning (use `architecture`) +- Deep security/performance audits (use `security` or `performance`) -## Phase 1: Project Overview +## Operating modes -```bash -# Identify project type and tech stack -ls -la -cat README.md 2>/dev/null | head -60 || cat README.rst 2>/dev/null | head -60 || true -cat package.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('Name:', d.get('name'), '| Version:', d.get('version'), '| Main:', d.get('main',''))" 2>/dev/null || true -cat pyproject.toml 2>/dev/null | head -20 || true -cat go.mod 2>/dev/null | head -10 || true -cat Cargo.toml 2>/dev/null | head -10 || true -``` - -Record: +Choose depth based on user intent. -- **Project name and purpose** -- **Tech stack** (language, framework, runtime) -- **Project type** (API service, library, CLI, worker, monorepo) +- `quick` (2-5 minutes): answer one focused question with minimal reads. +- `medium` (5-15 minutes): map the relevant subsystem and provide reuse candidates. +- `thorough` (15+ minutes): broader architecture map with risks, dependencies, and integration points. -## Phase 2: Directory Structure - -```bash -# Top-level structure -find . -maxdepth 3 -not -path '*/node_modules/*' -not -path '*/.git/*' \ - -not -path '*/vendor/*' -not -path '*/__pycache__/*' -not -path '*/dist/*' \ - -not -path '*/.venv/*' | sort | head -80 -``` +If the user does not specify a depth, default to `medium`. -Identify: +## Search strategy (broad -> narrow) -- Where source code lives (`src/`, `lib/`, `pkg/`, top-level) -- Where tests live (`test/`, `tests/`, `spec/`, `__tests__/`) -- Where configs live (`config/`, `.env*`, `*config.yaml`) -- CI/CD configuration (`.github/workflows/`, `.gitlab-ci.yml`, etc.) -- Infrastructure code (`k8s/`, `terraform/`, `docker-compose.yml`) +1. Start broad to find candidate areas quickly. +1. Narrow to concrete symbols, endpoints, and call paths. +1. Read only the files needed to answer confidently. +1. Stop when evidence is sufficient; avoid exhaustive sweeps by default. -## Phase 3: Dependencies & External Services - -```bash -# Dependency overview -cat package.json 2>/dev/null | python3 -c " -import sys, json -d = json.load(sys.stdin) -deps = {**d.get('dependencies',{}), **d.get('devDependencies',{})} -print('Dependencies:', len(deps)) -for k,v in list(deps.items())[:20]: print(f' {k}: {v}') -" 2>/dev/null || true - -cat pyproject.toml 2>/dev/null | grep -A 20 '\[tool.poetry.dependencies\]' | head -25 || true -cat go.mod 2>/dev/null | grep -E '^require|^\t' | head -20 || true - -# External services referenced -grep -r -E 'postgres|mysql|redis|mongodb|kafka|rabbitmq|elasticsearch|dynamodb|s3' \ - --include='*.ts' --include='*.py' --include='*.go' --include='*.yaml' --include='*.env*' \ - --exclude-dir=node_modules --exclude-dir=vendor . 2>/dev/null | grep -v test | head -20 -``` - -## Phase 4: API & Service Contracts - -```bash -# Check for API spec files -find . -name 'openapi*.yaml' -o -name 'openapi*.json' -o -name 'swagger*.yaml' \ - -o -name '*.proto' -o -name 'asyncapi*.yaml' 2>/dev/null | head -10 - -# Check for route definitions -grep -r -n '@app.route\|router\.\|@Get\|@Post\|path=' \ - --include='*.ts' --include='*.py' --include='*.go' \ - --exclude-dir=node_modules . 2>/dev/null | head -30 -``` +Prefer parallel discovery for independent branches. +Examples: -## Phase 5: Test Infrastructure +- API layer + data layer + job/worker layer +- frontend feature + backend endpoint +- primary implementation + analogous implementation template -{{RUN_TESTS}} +## Recommended command patterns ```bash -# Test count and coverage setup -find . \( -name '*.test.*' -o -name '*_test.*' -o -name '*spec.*' \) \ - -not -path '*/node_modules/*' -not -path '*/.venv/*' 2>/dev/null | wc -l - -# Coverage config -cat .nycrc 2>/dev/null || cat vitest.config.* 2>/dev/null | head -20 || \ - cat pytest.ini 2>/dev/null | head -20 || true -``` +# 1) Inventory project shape quickly +ls -la +find . -maxdepth 3 \ + -not -path '*/.git/*' -not -path '*/node_modules/*' -not -path '*/vendor/*' \ + -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/.venv/*' \ + -not -path '*/__pycache__/*' | head -120 -## Phase 6: CI/CD Pipeline +# 2) Locate likely implementation areas +rg --files | head -200 +rg -n "router|endpoint|handler|service|repository|controller|usecase|workflow" src tests docs 2>/dev/null | head -120 -```bash -# CI config -ls .github/workflows/ 2>/dev/null | head -10 -cat .github/workflows/*.yml 2>/dev/null | head -80 || true -cat .gitlab-ci.yml 2>/dev/null | head -60 || true +# 3) Find symbol definitions/usages once a likely area is known +rg -n "" src tests docs 2>/dev/null | head -120 ``` -## Phase 7: Technical Debt & Health +Language and contract hints: ```bash -# Check for TODO/FIXME/HACK comments -grep -r -n "TODO\|FIXME\|HACK\|XXX\|DEPRECATED\|BUG" \ - --include='*.ts' --include='*.py' --include='*.go' \ - --exclude-dir=node_modules . 2>/dev/null | head -30 - -# Check for TODOS.md -cat TODOS.md 2>/dev/null | head -40 || true +cat pyproject.toml 2>/dev/null | head -80 || true +cat package.json 2>/dev/null | head -80 || true +cat go.mod 2>/dev/null | head -80 || true +find . \( -name 'openapi*.yaml' -o -name 'openapi*.json' -o -name '*.proto' \) 2>/dev/null | head -40 ``` -## Discovery Report +## Reuse-first discovery -Produce a structured summary: +Always look for an existing analogous implementation before suggesting net-new structure. -```text -## Discovery Report — [project name] — [date] +For each candidate pattern, capture: -### Overview -Purpose: [one paragraph] -Type: [API service / library / CLI / worker / ...] -Stack: [language, framework, runtime versions] +- where it lives (file + symbol) +- why it is analogous +- what can be reused directly +- what must be adapted -### Architecture -[Mermaid diagram of service topology or module structure when possible; ASCII fallback if needed] +When asked to support implementation planning, return at least one "golden path" example and one fallback example. -### Data Stores +## Evidence quality rules -- [Database]: [what it stores, ORM/driver used] -- [Cache]: [what is cached, TTL strategy] +- Prefer explicit evidence over assumptions. +- Cite concrete files and symbols, not only directories. +- Distinguish facts from inferences. +- If confidence is low, say what is missing and what to check next. -### Key External Dependencies +## Output contract -- [Service A]: [purpose, auth method] -- [Service B]: [purpose] +Tailor output to the requested depth, but keep this structure: -### API Surface - -[Summarize endpoints or exported functions] - -### Test Coverage - -- Unit tests: [Y/N, count, coverage %] -- Integration tests: [Y/N] -- Contract tests: [Y/N] +```text +## Exploration Result -### CI/CD +### Answer +[Direct answer to the question in 2-6 sentences] -- CI: [GitHub Actions/GitLab CI/etc] -- Deploy target: [Fly.io/Render/K8s/etc] -- Release process: [manual/automated] +### Evidence +- [file/symbol]: [what it proves] +- [file/symbol]: [what it proves] -### Technical Debt +### Reusable Patterns +- [pattern A]: [why reusable, adaptation notes] +- [pattern B]: [why reusable, adaptation notes] -- [Key items from TODOS.md or code comments] +### Suggested Next Checks +- [targeted check 1] +- [targeted check 2] -### Onboarding Notes +### Confidence +[high/medium/low + one-line reason] +``` -- How to run locally: [command] -- How to run tests: [command] -- Key config: [env vars] -- Gotchas: [anything that surprised me] +For `thorough` mode, append: -``` +- subsystem map +- major dependency boundaries +- main risk hotspots (coupling, missing tests, unclear ownership) diff --git a/src/vstack/_templates/skills/space-setup/template.md b/src/vstack/_templates/skills/space-setup/template.md index ee1211f3..32ff55bb 100644 --- a/src/vstack/_templates/skills/space-setup/template.md +++ b/src/vstack/_templates/skills/space-setup/template.md @@ -18,7 +18,7 @@ Set up a project Space that keeps Copilot context focused, current, and easy to 1. Create or update the Space using GitHub UI (or approved API workflow). 1. Validate discoverability: each key topic maps to at least one source document. 1. Record refresh cadence and owner. -1. Re-check after `vstack install` or release docs updates. +1. Re-check after major context source changes or release docs updates. ## Output format diff --git a/src/vstack/cli/constants.py b/src/vstack/cli/constants.py index a7be2d44..3980c76b 100644 --- a/src/vstack/cli/constants.py +++ b/src/vstack/cli/constants.py @@ -9,6 +9,7 @@ from vstack.skills.config import SKILL_TYPE EXPECTED_CANONICAL_NAMES = [ + "ask", "vision", "architecture", "requirements", @@ -126,7 +127,7 @@ class ArtifactState: "architecture-risk", "artifact-integrity", "ci-triage", - "code-review", + "quick-review", "dependency-audit", "incident-timeline", "migration-plan", diff --git a/src/vstack/cli/init.py b/src/vstack/cli/init.py index 6f5d3949..b41d5355 100644 --- a/src/vstack/cli/init.py +++ b/src/vstack/cli/init.py @@ -13,6 +13,7 @@ from vstack.manifest import ( CURRENT_HASH_ALGORITHM, CURRENT_MANIFEST_VERSION, + ArtifactEntry, Manifest, content_hash, hash_with_algorithm, @@ -180,8 +181,6 @@ def _record_manifest_entry( checksum_algorithm: str, ) -> None: """Append one installed artifact entry to in-memory manifest data.""" - from vstack.manifest import ArtifactEntry - new_entries.setdefault(gen.config.manifest_key, []).append( ArtifactEntry( name=artifact_name, @@ -363,6 +362,124 @@ def _write_manifest( manifest_file.write(manifest) print(f" {colors.DIM}wrote {service.label(manifest_file.path)}{colors.RESET}") + @staticmethod + def _obsolete_candidates( + *, + existing_manifest: Manifest | None, + selected_manifest_keys: set[str], + new_entries, + ) -> list[tuple[str, ArtifactEntry]]: + """Return tracked entries that are no longer produced by current templates. + + Candidates are entries for selected artifact families that existed in the + previous manifest but are absent from the newly built entry set. + """ + if existing_manifest is None: + return [] + + obsolete: list[tuple[str, ArtifactEntry]] = [] + for manifest_key in selected_manifest_keys: + existing_by_name = { + entry.name: entry for entry in existing_manifest.entries_for(manifest_key) + } + kept_names = {entry.name for entry in new_entries.get(manifest_key, [])} + for artifact_name, entry in existing_by_name.items(): + if artifact_name not in kept_names: + obsolete.append((manifest_key, entry)) + return obsolete + + @staticmethod + def _can_prune_obsolete_entry(*, install_dir: Path, entry) -> tuple[bool, str]: + """Return whether an obsolete entry can be removed safely and why.""" + out_file = install_dir / entry.file + if not out_file.exists(): + return True, "file already missing" + + if entry.checksum is None: + return False, "tracked file has no stored checksum" + + checksum_algorithm = (entry.checksum_algorithm or CURRENT_HASH_ALGORITHM).lower() + try: + current = hash_with_algorithm(out_file.read_text(encoding="utf-8"), checksum_algorithm) + except OSError: + return False, "file is unreadable" + except ValueError: + return False, "unknown checksum algorithm" + + if current != entry.checksum: + return False, "local changes detected" + return True, "" + + @staticmethod + def _remove_file_if_present(*, out_file: Path, dry_run: bool) -> None: + """Remove one file and prune an empty parent directory when possible.""" + if dry_run: + return + + out_file.unlink(missing_ok=True) + parent = out_file.parent + try: + if parent.exists() and not any(parent.iterdir()): + parent.rmdir() + except OSError: + pass + + @staticmethod + def _process_obsolete_entry( + *, + install_dir: Path, + manifest_key: str, + type_name: str, + entry: ArtifactEntry, + prune: bool, + dry_run: bool, + colors, + prefix: str, + new_entries, + ) -> tuple[str, bool]: + """Handle one obsolete manifest entry and return (action, was_preserved).""" + selector = f"{type_name}/{entry.name}" + rel = str(entry.file) + + if not prune: + print( + f" {prefix}{colors.YELLOW}?{colors.RESET} {rel}" + f" {colors.DIM}obsolete candidate ({selector}) — run vstack init --prune to remove{colors.RESET}" + ) + Manifest.preserve_existing_entry( + new_entries=new_entries, + manifest_key=manifest_key, + existing_entry=entry, + ) + return "obsolete", False + + removable, reason = InitCommand._can_prune_obsolete_entry( + install_dir=install_dir, + entry=entry, + ) + if not removable: + print( + f" {prefix}{colors.YELLOW}↷{colors.RESET} {rel}" + f" {colors.DIM}obsolete preserved ({selector}) — {reason}{colors.RESET}" + ) + Manifest.preserve_existing_entry( + new_entries=new_entries, + manifest_key=manifest_key, + existing_entry=entry, + ) + return "preserve", True + + reason_suffix = "" if reason == "" else f" — {reason}" + print( + f" {prefix}{colors.CYAN}−{colors.RESET} {rel}" + f" {colors.DIM}removed obsolete tracked artifact ({selector}){reason_suffix}{colors.RESET}" + ) + InitCommand._remove_file_if_present( + out_file=install_dir / entry.file, + dry_run=dry_run, + ) + return "prune", False + @staticmethod def _print_summary( *, @@ -370,6 +487,7 @@ def _print_summary( action_counts: dict[str, int], preserved_selectors: list[str], dry_run: bool, + prune: bool, ) -> None: """Print a readable summary and conflict guidance after an init run.""" installed = action_counts.get("install", 0) @@ -377,10 +495,12 @@ def _print_summary( preserved = action_counts.get("preserve", 0) skipped = action_counts.get("skip", 0) adopted = action_counts.get("adopt", 0) + obsolete = action_counts.get("obsolete", 0) + pruned = action_counts.get("prune", 0) install_label = "installed" summary_title = "Summary (dry-run)" if dry_run else "Summary" - total = installed + updated + preserved + skipped + adopted + total = installed + updated + preserved + skipped + adopted + obsolete print() print(f" {colors.BOLD}{summary_title}{colors.RESET}") @@ -390,6 +510,19 @@ def _print_summary( print(f" preserved : {colors.BOLD}{preserved}{colors.RESET}") print(f" skipped : {colors.BOLD}{skipped}{colors.RESET}") print(f" adopted : {colors.BOLD}{adopted}{colors.RESET}") + print(f" obsolete : {colors.BOLD}{obsolete}{colors.RESET}") + print(f" pruned : {colors.BOLD}{pruned}{colors.RESET}") + + if obsolete and not prune: + print() + print( + f" {colors.YELLOW}⚠{colors.RESET} " + "obsolete candidates were reported and preserved in manifest state." + ) + print(" Next step:") + print( + f" {colors.DIM}vstack init --prune{colors.RESET} remove safe obsolete artifacts" + ) if preserved: noun = "file" if preserved == 1 else "files" @@ -456,8 +589,6 @@ def _prune_planner_when_manual_mode( exists from a previous non-manual mode, remove it when unchanged. Locally modified planner files are preserved and kept tracked. """ - from vstack.manifest import hash_with_algorithm - if gen.config.type_name != "agent": return if getattr(gen, "workflow_mode", "manual") != "manual": @@ -520,6 +651,7 @@ def execute( force_names: list[str] | None = None, adopt_names: list[str] | None = None, update: bool = False, + prune: bool = False, dry_run: bool = False, excluded_names: dict[str, list[str]] | None = None, ) -> int: @@ -552,10 +684,12 @@ def execute( ) break - manifest_file, _, existing_entries, new_entries = InitCommand._load_existing_manifest( - service=service, - install_dir=install_dir, - gens=gens, + manifest_file, existing_manifest, existing_entries, new_entries = ( + InitCommand._load_existing_manifest( + service=service, + install_dir=install_dir, + gens=gens, + ) ) if manifest_file is None or existing_entries is None or new_entries is None: return 1 @@ -615,11 +749,39 @@ def execute( print(f" ERROR [{gen.config.type_name}]: {msg.message}", file=sys.stderr) all_ok = False + selected_manifest_keys = {gen.config.manifest_key for gen in gens} + type_name_by_manifest_key = {gen.config.manifest_key: gen.config.type_name for gen in gens} + for manifest_key, entry in InitCommand._obsolete_candidates( + existing_manifest=existing_manifest, + selected_manifest_keys=selected_manifest_keys, + new_entries=new_entries, + ): + action_counts["obsolete"] = action_counts.get("obsolete", 0) + 1 + type_name = type_name_by_manifest_key.get(manifest_key, manifest_key.rstrip("s")) + obsolete_action, was_preserved = InitCommand._process_obsolete_entry( + install_dir=install_dir, + manifest_key=manifest_key, + type_name=type_name, + entry=entry, + prune=prune, + dry_run=dry_run, + colors=colors, + prefix=prefix, + new_entries=new_entries, + ) + if obsolete_action == "prune": + action_counts["prune"] = action_counts.get("prune", 0) + 1 + elif obsolete_action == "preserve": + action_counts["preserve"] = action_counts.get("preserve", 0) + 1 + if was_preserved: + preserved_selectors.add(f"{type_name}/{entry.name}") + InitCommand._print_summary( colors=colors, action_counts=action_counts, preserved_selectors=sorted(preserved_selectors), dry_run=dry_run, + prune=prune, ) if not dry_run: @@ -650,5 +812,6 @@ def run( force_names=getattr(context.args, "force_names", None), adopt_names=getattr(context.args, "adopt_name", None), update=getattr(context.args, "update", False), + prune=getattr(context.args, "prune", False), dry_run=getattr(context.args, "dry_run", False), ) diff --git a/src/vstack/cli/parser.py b/src/vstack/cli/parser.py index 454b9cb0..a035fab1 100644 --- a/src/vstack/cli/parser.py +++ b/src/vstack/cli/parser.py @@ -249,6 +249,14 @@ def _add_init_command(self, sub: SubparserFactory) -> None: action="store_true", help="Show what would be regenerated without writing files", ) + parser.add_argument( + "--prune", + action="store_true", + help=( + "Remove safe obsolete tracked artifacts that are no longer generated. " + "Without this flag obsolete candidates are reported and preserved." + ), + ) def _add_uninstall_command(self, sub: SubparserFactory) -> None: """Register the ``uninstall`` subcommand.""" diff --git a/src/vstack/hooks/generator.py b/src/vstack/hooks/generator.py index 17d2be7d..10afb656 100644 --- a/src/vstack/hooks/generator.py +++ b/src/vstack/hooks/generator.py @@ -195,7 +195,7 @@ def _generate_json_from_yaml(self, yaml_data: dict) -> str: rendered_actions.append(rendered_action) rendered_hooks[event] = rendered_actions - return json.dumps({"version": 1, "hooks": rendered_hooks}, indent=2) + return json.dumps({"version": 1, "hooks": rendered_hooks}, indent=2) + "\n" def find_extra_files(self, tmpl_dir: Path) -> list[Path]: """Hook templates use a single YAML file and do not copy sidecar files.""" diff --git a/tests/_fixtures/golden/agents/planner.agent.md b/tests/_fixtures/golden/agents/planner.agent.md index 7289bccc..f248f2ff 100644 --- a/tests/_fixtures/golden/agents/planner.agent.md +++ b/tests/_fixtures/golden/agents/planner.agent.md @@ -16,10 +16,6 @@ agents: - engineer - tester - release -model: - - auto - - GPT-5.3-Codex (copilot) - - Claude Sonnet 4.6 (copilot) user-invocable: true target: vscode --- @@ -99,6 +95,23 @@ Signs a request is a focused task (not a pipeline run): When in doubt, ask: "Does this need more than one role to complete?" If not, route directly. +## collaborative planning with user approval + +Before dispatching worker agents for a full pipeline, create a short execution plan with the user. + +1. Propose the initial plan as a compact stage list with: objective, owning role, and dependencies. +1. Ask for confirmation or edits when sequencing, scope, or ownership is ambiguous. +1. Apply user feedback and freeze the plan baseline for this run. +1. Start delegation only after the plan is accepted. + +During execution, the plan may change only when new facts appear. When replanning is needed: + +1. Explain what changed and why the current plan is no longer valid. +1. Propose the minimal plan delta. +1. Ask for approval before continuing with the updated plan. + +The planner owns planning and orchestration decisions. Worker agents execute scoped tasks from the accepted plan. + ## working principles - **Classify before orchestrating.** Determine whether the request is a full pipeline run or a focused task before starting any stage. Starting the pipeline for a focused task is overhead without benefit. @@ -126,6 +139,71 @@ For every ready stage or domain question: If a domain question surfaces mid-orchestration that no stage report has answered, route it to the relevant specialist instead of answering it yourself. +## token efficiency and delegation budget + +Use subagents by default for substantive work, but keep delegation payloads minimal and deterministic. + +1. Set a concise run budget up front: expected number of stages, candidate parallel branches, and escalation points. +1. Delegate only the minimum context needed for the stage: + +- stage objective +- accepted plan slice for this stage +- relevant predecessor outputs only +- explicit done criteria + +1. Prefer delta handoffs. If a stage reruns, pass only what changed since the last attempt. +1. Avoid duplicate calls. Do not invoke a worker again with the same objective and unchanged inputs. +1. Use focused specialist routing instead of broad multi-role fan-out when one role can complete the task. +1. Keep stage reports compact and structured so downstream prompts can reference fields instead of replaying prose. + +Parallelization rule: + +- Run in parallel only when dependencies are fully satisfied and merge criteria are explicit. +- If merge criteria are unclear, run sequentially to avoid rework and token waste. + +Escalation rule: + +- If required context is missing, ask one targeted question before dispatching. +- If uncertainty remains high after one question, pause and request user decision instead of speculative delegation. + +## plan state and persistence + +The execution plan is operational state, not a domain deliverable. + +Planner-run state schema (keep this shape stable across the run): + +```yaml +planner_run_state: + planner_run_id: + plan_version: + stage_status_map: + : ready|blocked|skipped|pending + blockers: + - +``` + +State update protocol: + +1. Initialize `planner_run_state` before first delegation. + +1. Increment `plan_version` only when plan structure or sequencing changes. + +1. Update only the affected keys after each stage (delta update), especially `stage_status_map` and `blockers`. + +1. Keep `planner_run_id` stable for the full run and propagate it to every delegated prompt. + +1. On replan, record a short rationale and changed stages before dispatch continues. + +1. Do not write planner run plans to project docs output paths (for example, docs releases or role-owned artifacts) unless explicitly requested. + +1. Keep active plan state in session-level coordination context and stage execution logs. + +1. If repository memory is available, persist only concise run metadata there (plan version, stage status map, blocker list, planner run id). + +1. Persist plan state updates as deltas, not full rewrites. + +1. Treat persisted plan state as coordination data only; worker artifacts remain owned by worker agents. + ## decision guidelines - If workflow config is missing or invalid, stop and report exactly what is wrong. @@ -176,16 +254,31 @@ Planner run correlation: When invoking a worker stage, require this structured stage report at the end: -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` ## success criteria @@ -231,4 +324,4 @@ that requires changes to upstream items, flag it and trigger a reverse handoff. - `@#analyse` - assess stage impact, skip rationale, and trade-offs - + diff --git a/tests/_fixtures/golden/agents/product.agent.md b/tests/_fixtures/golden/agents/product.agent.md index 16513d4f..7af8e12f 100644 --- a/tests/_fixtures/golden/agents/product.agent.md +++ b/tests/_fixtures/golden/agents/product.agent.md @@ -21,11 +21,6 @@ agents: - engineer - tester - release -model: - - auto - - Claude Sonnet 4.6 (copilot) - - GPT-5.3-Codex (copilot) - - Claude Opus 4.7 (copilot) user-invocable: true target: vscode --- @@ -111,16 +106,31 @@ Planner-coordinated mode (`@planner` invokes this role as a subagent): - Execute product-stage scope only; do not invoke downstream roles unless explicitly asked. - End with a structured stage report using this schema: -Use this exact stage report schema at the end of your response: +Use this exact stage report schema at the end of your response. Keep values short and deterministic. - `status`: `ready` or `blocked` - `changes_made`: `yes` or `no` -- `updated_items`: list of paths (or `none`) -- `blockers`: list (or `none`) +- `updated_items`: list of paths or `none` +- `plan_delta`: short list of plan updates or `none` +- `blockers`: list or `none` +- `token_usage_summary`: `input_tokens`, `output_tokens`, `total_tokens`, and `budget_status` (`within` or `exceeded`) - `next_handoff_summary`: one short paragraph -- `planner_run_id`: value received in `PLANNER_RUN_ID` (or `none` when not provided) -- `model_used`: model identifier used for this stage (or `unknown`) -- `subagents_invoked`: list of delegated subagents called during this stage (or `none`) +- `planner_run_id`: value from `PLANNER_RUN_ID` or `none` +- `model_used`: model identifier or `unknown` +- `subagents_invoked`: list of delegated subagents or `none` + +Example: + +- `status`: `ready` +- `changes_made`: `yes` +- `updated_items`: `docs/architecture/overview.md` +- `plan_delta`: `none` +- `blockers`: `none` +- `token_usage_summary`: `input_tokens=1200, output_tokens=420, total_tokens=1620, budget_status=within` +- `next_handoff_summary`: `Architecture baseline updated and aligned with current requirements. Ready for designer handoff.` +- `planner_run_id`: `20260611T101500Z-a1b2` +- `model_used`: `GPT-5.3-Codex (copilot)` +- `subagents_invoked`: `none` ## how you work @@ -192,4 +202,4 @@ that requires changes to upstream items, flag it and trigger a reverse handoff. - `@#gh-issues` — create and manage GitHub Issues for requirements, tasks, and user stories - + diff --git a/tests/_fixtures/golden/instructions/security.instructions.md b/tests/_fixtures/golden/instructions/security.instructions.md index 0bf57f53..8d481be0 100644 --- a/tests/_fixtures/golden/instructions/security.instructions.md +++ b/tests/_fixtures/golden/instructions/security.instructions.md @@ -3,43 +3,43 @@ name: security description: 'Security policy for all code, configuration, and infrastructure. Use when writing or reviewing any code, configuration, or workflow file.' applyTo: '**/*' --- -Apply these security policies in this project. +Use these security policies. ## Secrets and credentials -1. Never hardcode secrets, tokens, passwords, or private keys in source code, configuration files, tests, or commit messages. -1. Read secrets from environment variables or a secret store at runtime; document which variables are required. -1. Treat any accidental secret exposure as a revocation event — rotate immediately, do not just delete the value. +1. Never hardcode secrets, tokens, passwords, or private keys in source code, config files, tests, or commit messages. +1. Read secrets from environment variables or a secret store at runtime; document required variables. +1. Treat accidental exposure as a revocation event; rotate immediately. ## Input and trust boundaries 1. Validate and sanitize all input that crosses a trust boundary: HTTP requests, CLI arguments, environment variables, files, and inter-service messages. -1. Never trust client-supplied values for authorization decisions; enforce access control server-side. -1. Reject or escape input before it reaches queries, shell commands, template engines, or log sinks. +1. Never trust client-supplied values for authorization decisions. +1. Reject or escape input before it reaches queries, shell commands, template engines, or logs. ## Authentication and authorization -1. Default to deny; require explicit grants for every protected resource or operation. -1. Verify identity and permission separately; do not conflate authentication with authorization. -1. Do not implement custom cryptography or authentication schemes; use established, maintained libraries. +1. Default to deny; require explicit grants for protected resources or operations. +1. Verify identity and permission separately. +1. Use established, maintained libraries; do not implement custom cryptography or auth schemes. ## Dependencies and supply chain 1. Pin dependency versions in manifests; do not use unbounded version ranges in production code. -1. Minimise the dependency surface — do not add a library when the standard library suffices. -1. Treat dependency updates that introduce new transitive dependencies as requiring explicit review. +1. Minimise the dependency surface. +1. Treat updates that add new transitive dependencies as requiring explicit review. ## Error handling and observability 1. Never expose internal stack traces, system paths, or configuration details to external callers. 1. Do not log sensitive data: passwords, tokens, PII, or session identifiers. -1. Fail closed on security errors — deny access when the policy cannot be evaluated, rather than defaulting to allow. +1. Fail closed on security errors. ## Destructive and privileged operations -1. Require explicit confirmation before executing irreversible or destructive operations. -1. Apply least privilege: request only the permissions a component actually needs. -1. Isolate privileged logic; keep it minimal, auditable, and separate from business logic. +1. Require explicit confirmation before irreversible or destructive operations. +1. Apply least privilege. +1. Keep privileged logic minimal, auditable, and separate from business logic. - + diff --git a/tests/_fixtures/golden/instructions/testing.instructions.md b/tests/_fixtures/golden/instructions/testing.instructions.md index 0507e1a7..7664eb3b 100644 --- a/tests/_fixtures/golden/instructions/testing.instructions.md +++ b/tests/_fixtures/golden/instructions/testing.instructions.md @@ -3,44 +3,44 @@ name: testing description: 'Test authoring conventions for any language or framework. Use when writing or reviewing tests, test plans, or test coverage decisions.' applyTo: '**/*' --- -Use these testing conventions in this project. +Use these testing conventions. ## Scope and intent 1. Write tests to verify observable behavior, not internal implementation details. 1. A test that passes when behavior is wrong, or fails when behavior is correct, has negative value. -1. Tests are documentation — a reader should understand what the system does by reading the test. +1. Tests should read like documentation. ## Naming and structure -1. Name tests to describe what they verify: what the subject does, under what condition, and what the expected outcome is. -1. Keep each test focused on one behavior; avoid asserting unrelated outcomes in a single test. -1. Group related tests together; separate unrelated test concerns into distinct test units. +1. Name tests by subject, condition, and expected outcome. +1. Keep each test focused on one behavior. +1. Group related tests together; separate unrelated concerns. ## Coverage and completeness -1. Cover the success path, expected failure paths, and boundary conditions for every behavioral change. -1. Treat missing tests for changed behavior as a defect — a change without tests is not complete. -1. Do not chase a coverage number; cover behaviors that matter rather than lines that exist. +1. Cover success paths, expected failure paths, and boundary conditions for every behavioral change. +1. Treat missing tests for changed behavior as a defect. +1. Cover behaviors that matter rather than lines that exist. ## Test quality -1. Make tests deterministic — a test that passes or fails non-deterministically is unreliable and must be fixed. -1. Keep tests independent; no test should depend on execution order or shared mutable state. -1. Prefer clear, direct assertions over indirect checks; assert the outcome, not the path to it. -1. Avoid logic (loops, conditionals) in tests; if a test needs logic, split it into multiple focused tests. +1. Make tests deterministic. +1. Keep tests independent. +1. Prefer clear, direct assertions. +1. Avoid logic in tests; split tests that need it. ## Test boundaries -1. Use unit tests for isolated logic; use integration tests when behavior crosses component or service boundaries. -1. Mock or stub only what is necessary to isolate the subject; avoid over-mocking that disconnects the test from real behavior. -1. Test contracts and interfaces, not just internal units — what the caller observes is what matters. +1. Use unit tests for isolated logic; use integration tests when behavior crosses boundaries. +1. Mock or stub only what is necessary. +1. Test contracts and interfaces, not just internal units. ## Maintenance 1. Update tests in the same change as the behavior they cover. -1. Remove tests that no longer reflect real behavior rather than commenting them out. -1. Treat flaky tests as bugs; do not merge code with known test reliability issues. +1. Remove tests that no longer reflect real behavior. +1. Treat flaky tests as bugs. - + diff --git a/tests/_fixtures/golden/prompts/api-design-review.prompt.md b/tests/_fixtures/golden/prompts/api-design-review.prompt.md index 8fd41dc8..a909b91f 100644 --- a/tests/_fixtures/golden/prompts/api-design-review.prompt.md +++ b/tests/_fixtures/golden/prompts/api-design-review.prompt.md @@ -3,15 +3,14 @@ description: 'Review an API design or OpenAPI spec for correctness, completeness name: api-design-review argument-hint: '[OpenAPI spec file, design doc, or endpoint scope]' agent: designer -model: GPT-5.3-Codex (copilot) tools: - read - search --- Review the provided API design or OpenAPI specification for correctness, completeness, and consistency. -Focus on issues that affect consumers: breaking contracts, ambiguous semantics, missing error cases, and inconsistent conventions. -Do not focus on implementation details or tooling preferences. +Focus on consumer impact: breaking contracts, ambiguous semantics, missing errors, and inconsistent conventions. +Ignore implementation details and tooling preferences. Output exactly in this format: @@ -55,4 +54,4 @@ List fields or objects that are missing required constraints, descriptions, or e - top priority fix in one sentence - + diff --git a/tests/_fixtures/golden/prompts/code-review.prompt.md b/tests/_fixtures/golden/prompts/quick-review.prompt.md similarity index 85% rename from tests/_fixtures/golden/prompts/code-review.prompt.md rename to tests/_fixtures/golden/prompts/quick-review.prompt.md index ed73e5aa..d0b734e7 100644 --- a/tests/_fixtures/golden/prompts/code-review.prompt.md +++ b/tests/_fixtures/golden/prompts/quick-review.prompt.md @@ -1,9 +1,8 @@ --- description: 'Review a change for bugs, regressions, and missing tests.' -name: code-review +name: quick-review argument-hint: '[scope or files to review]' agent: engineer -model: GPT-5.3-Codex (copilot) tools: - read - search @@ -51,4 +50,4 @@ End with: - Biggest remaining risk: one sentence - + diff --git a/tests/_fixtures/golden/skills/concise.SKILL.md b/tests/_fixtures/golden/skills/concise.SKILL.md index a3539465..2d7d1683 100644 --- a/tests/_fixtures/golden/skills/concise.SKILL.md +++ b/tests/_fixtures/golden/skills/concise.SKILL.md @@ -147,4 +147,4 @@ Current mode unchanged: - [ ] User confirmation/status returned in deterministic format - + diff --git a/tests/_fixtures/golden/skills/verify.SKILL.md b/tests/_fixtures/golden/skills/verify.SKILL.md index 2681dadf..a2e0e3b0 100644 --- a/tests/_fixtures/golden/skills/verify.SKILL.md +++ b/tests/_fixtures/golden/skills/verify.SKILL.md @@ -266,4 +266,4 @@ scope: [path/component/full] ``` - + diff --git a/tests/vstack/agents/test_generation.py b/tests/vstack/agents/test_generation.py index 8f53d2c2..dd64a9f5 100644 --- a/tests/vstack/agents/test_generation.py +++ b/tests/vstack/agents/test_generation.py @@ -13,8 +13,8 @@ class TestAgentGeneration: """Test cases for AgentGeneration.""" - def test_architect_agent_includes_model_and_handoffs(self, tmp_path: Path) -> None: - """Test that architect agent includes model and handoffs.""" + def test_architect_agent_omits_model_and_includes_handoffs(self, tmp_path: Path) -> None: + """Test that architect agent omits model and includes handoffs.""" # Seed a minimal workflow config so handoffs include agent targets. vstack_dir = tmp_path / ".vstack" vstack_dir.mkdir(parents=True, exist_ok=True) @@ -50,12 +50,7 @@ def test_architect_agent_includes_model_and_handoffs(self, tmp_path: Path) -> No parsed = FrontmatterParser.parse(content) assert parsed.metadata.get("name") == "architect" - assert parsed.metadata.get("model") == [ - "auto", - "Claude Sonnet 4.6 (copilot)", - "GPT-5.3-Codex (copilot)", - "Claude Opus 4.7 (copilot)", - ] + assert parsed.metadata.get("model") is None handoffs = parsed.metadata.get("handoffs") assert isinstance(handoffs, list) diff --git a/tests/vstack/artifacts/test_generator.py b/tests/vstack/artifacts/test_generator.py index 805efd24..e97f4648 100644 --- a/tests/vstack/artifacts/test_generator.py +++ b/tests/vstack/artifacts/test_generator.py @@ -27,7 +27,7 @@ class TestGenericArtifactGenerator: r"(?P)" ) _VSTACK_VERSION_FIELD_RE = re.compile(r'("vstack_version"\s*:\s*")[^"]*(")') - _NORMALIZED_VSTACK_VERSION = "" + _NORMALIZED_VSTACK_VERSION = "" @classmethod def _normalize_vstack_version_in_meta_comment(cls, content: str) -> str: @@ -302,21 +302,21 @@ def test_render_agent_product_matches_golden_fixture( artifact_label="agent/product", ) - def test_render_prompt_code_review_matches_golden_fixture( + def test_render_prompt_quick_review_matches_golden_fixture( self, templates_root: Path, prompt_fixture_path: Callable[[str], Path], ) -> None: - """Code-review prompt rendering must remain byte-for-byte stable.""" + """Quick-review prompt rendering must remain byte-for-byte stable.""" templates = templates_root - template_dir = templates / "prompts" / "code-review" - expected_fixture = prompt_fixture_path("code-review") + template_dir = templates / "prompts" / "quick-review" + expected_fixture = prompt_fixture_path("quick-review") artifact = GenericArtifactGenerator(PROMPT_TYPE, templates).render(template_dir) self._assert_matches_golden_fixture( artifact_content=artifact.content, expected_fixture=expected_fixture, - artifact_label="prompt/code-review", + artifact_label="prompt/quick-review", ) def test_render_prompt_api_design_review_matches_golden_fixture( diff --git a/tests/vstack/cli/test_constants.py b/tests/vstack/cli/test_constants.py index 41f4cc55..0a55a212 100644 --- a/tests/vstack/cli/test_constants.py +++ b/tests/vstack/cli/test_constants.py @@ -6,6 +6,7 @@ from vstack.cli.constants import EXPECTED_INPUT_NAMES EXPECTED_CLI_NAMES = [ + "ask", "vision", "architecture", "requirements", diff --git a/tests/vstack/cli/test_init.py b/tests/vstack/cli/test_init.py index 9b52a4b8..bbc00abf 100644 --- a/tests/vstack/cli/test_init.py +++ b/tests/vstack/cli/test_init.py @@ -557,6 +557,7 @@ def test_print_summary_no_conflicts_shows_installed_count( action_counts={"install": 7, "update": 1}, preserved_selectors=[], dry_run=False, + prune=False, ) out = capsys.readouterr().out assert "Summary" in out @@ -579,6 +580,7 @@ def test_print_summary_with_conflicts_shows_guidance( action_counts={"install": 3, "preserve": 2}, preserved_selectors=["agent/engineer", "skill/verify"], dry_run=False, + prune=False, ) out = capsys.readouterr().out assert "Summary" in out @@ -604,6 +606,7 @@ def test_print_summary_single_preserve_uses_singular_noun( action_counts={"install": 1, "preserve": 1}, preserved_selectors=["agent/engineer"], dry_run=False, + prune=False, ) out = capsys.readouterr().out assert "1 file preserved" in out @@ -619,6 +622,7 @@ def test_print_summary_dry_run_marks_header_and_keeps_installed_label( action_counts={"install": 10}, preserved_selectors=[], dry_run=True, + prune=False, ) out = capsys.readouterr().out assert "Summary (dry-run)" in out @@ -636,11 +640,29 @@ def test_print_summary_shows_optional_counts_when_nonzero( action_counts={"install": 2, "skip": 3, "adopt": 1}, preserved_selectors=[], dry_run=False, + prune=False, ) out = capsys.readouterr().out assert "skipped" in out and ": 3" in out assert "adopted" in out and ": 1" in out + def test_print_summary_reports_obsolete_guidance_when_not_pruning( + self, + capsys: pytest.CaptureFixture[str], + ) -> None: + """Obsolete candidates are reported with guidance when --prune is not used.""" + colors = SimpleNamespace(YELLOW="", RESET="", BOLD="", DIM="", GREEN="", CYAN="") + InitCommand._print_summary( + colors=colors, + action_counts={"install": 1, "obsolete": 2}, + preserved_selectors=[], + dry_run=False, + prune=False, + ) + out = capsys.readouterr().out + assert "obsolete" in out and ": 2" in out + assert "vstack init --prune" in out + # ------------------------------------------------------------------ # _install_single_artifact — return value # ------------------------------------------------------------------ @@ -767,7 +789,12 @@ def _fake_execute(*args, **kwargs): context = CommandContext( args=Namespace( - force=True, force_names=["a"], adopt_name=["b"], update=True, dry_run=True + force=True, + force_names=["a"], + adopt_name=["b"], + update=True, + prune=True, + dry_run=True, ), install_dir=tmp_path, only=["skill"], @@ -779,6 +806,7 @@ def _fake_execute(*args, **kwargs): assert captured["kwargs"]["force_names"] == ["a"] assert captured["kwargs"]["adopt_names"] == ["b"] assert captured["kwargs"]["update"] is True + assert captured["kwargs"]["prune"] is True assert captured["kwargs"]["dry_run"] is True assert captured["kwargs"]["only"] == ["skill"] @@ -806,7 +834,12 @@ def _fake_execute(*args, **kwargs): context = CommandContext( args=Namespace( - force=False, force_names=None, adopt_name=None, update=False, dry_run=False + force=False, + force_names=None, + adopt_name=None, + update=False, + prune=False, + dry_run=False, ), install_dir=tmp_path, only=None, @@ -871,7 +904,7 @@ def verify_input(): ) monkeypatch.setattr( "vstack.cli.init.InitCommand._load_existing_manifest", - staticmethod(lambda **_kwargs: (object(), object(), {}, {})), + staticmethod(lambda **_kwargs: (object(), None, {}, {})), ) result = InitCommand.execute( @@ -886,6 +919,324 @@ def verify_input(): out = capsys.readouterr().out assert "excluded by config" in out + def test_obsolete_candidates_uses_missing_names_from_selected_families(self) -> None: + """Candidates include tracked selected-family entries missing from regenerated output.""" + from vstack.manifest import ArtifactEntry, Manifest + + existing_manifest = Manifest( + vstack_version="3.5.2", + installed_at="2026-06-18T00:00:00+00:00", + artifacts={ + "skills": [ + ArtifactEntry(name="verify", file="skills/verify/SKILL.md"), + ArtifactEntry(name="legacy", file="skills/legacy/SKILL.md"), + ] + }, + ) + new_entries = {"skills": [ArtifactEntry(name="verify", file="skills/verify/SKILL.md")]} + + obsolete = InitCommand._obsolete_candidates( + existing_manifest=existing_manifest, + selected_manifest_keys={"skills"}, + new_entries=new_entries, + ) + + assert len(obsolete) == 1 + assert obsolete[0][0] == "skills" + assert obsolete[0][1].name == "legacy" + + def test_process_obsolete_entry_report_only_preserves_manifest_entry( + self, + tmp_path: Path, + ) -> None: + """Report-only mode keeps obsolete entry tracked for future prune runs.""" + from vstack.manifest import ArtifactEntry + + new_entries: dict[str, list[Any]] = {} + entry = ArtifactEntry(name="legacy", file="skills/legacy/SKILL.md") + + action, was_preserved = InitCommand._process_obsolete_entry( + install_dir=tmp_path, + manifest_key="skills", + type_name="skill", + entry=entry, + prune=False, + dry_run=False, + colors=SimpleNamespace(CYAN="", RESET="", DIM="", YELLOW="", GREEN="", BOLD=""), + prefix="", + new_entries=new_entries, + ) + + assert action == "obsolete" + assert was_preserved is False + assert "skills" in new_entries + assert len(new_entries["skills"]) == 1 + + def test_process_obsolete_entry_prunes_when_checksum_matches( + self, + tmp_path: Path, + ) -> None: + """Prune mode removes obsolete tracked files when content is unchanged.""" + from vstack.manifest import ArtifactEntry + + install_dir = tmp_path / ".github" + out_file = install_dir / "skills" / "legacy" / "SKILL.md" + out_file.parent.mkdir(parents=True) + content = "legacy\n" + out_file.write_text(content, encoding="utf-8") + entry = ArtifactEntry( + name="legacy", + file="skills/legacy/SKILL.md", + checksum=content_hash(content), + checksum_algorithm="sha256", + ) + new_entries: dict[str, list[Any]] = {} + + action, was_preserved = InitCommand._process_obsolete_entry( + install_dir=install_dir, + manifest_key="skills", + type_name="skill", + entry=entry, + prune=True, + dry_run=False, + colors=SimpleNamespace(CYAN="", RESET="", DIM="", YELLOW="", GREEN="", BOLD=""), + prefix="", + new_entries=new_entries, + ) + + assert action == "prune" + assert was_preserved is False + assert not out_file.exists() + assert new_entries == {} + + def test_process_obsolete_entry_prune_preserves_when_locally_modified( + self, + tmp_path: Path, + ) -> None: + """Prune mode preserves obsolete files with checksum drift.""" + from vstack.manifest import ArtifactEntry + + install_dir = tmp_path / ".github" + out_file = install_dir / "skills" / "legacy" / "SKILL.md" + out_file.parent.mkdir(parents=True) + out_file.write_text("local edit\n", encoding="utf-8") + entry = ArtifactEntry( + name="legacy", + file="skills/legacy/SKILL.md", + checksum=content_hash("generated\n"), + checksum_algorithm="sha256", + ) + new_entries: dict[str, list[Any]] = {} + + action, was_preserved = InitCommand._process_obsolete_entry( + install_dir=install_dir, + manifest_key="skills", + type_name="skill", + entry=entry, + prune=True, + dry_run=False, + colors=SimpleNamespace(CYAN="", RESET="", DIM="", YELLOW="", GREEN="", BOLD=""), + prefix="", + new_entries=new_entries, + ) + + assert action == "preserve" + assert was_preserved is True + assert out_file.exists() + assert "skills" in new_entries + assert len(new_entries["skills"]) == 1 + + def test_can_prune_obsolete_entry_true_when_file_is_missing(self, tmp_path: Path) -> None: + """Missing files are safe prune targets and treated as already removed.""" + from vstack.manifest import ArtifactEntry + + entry = ArtifactEntry( + name="legacy", + file="skills/legacy/SKILL.md", + checksum=content_hash("x"), + checksum_algorithm="sha256", + ) + removable, reason = InitCommand._can_prune_obsolete_entry(install_dir=tmp_path, entry=entry) + assert removable is True + assert reason == "file already missing" + + def test_can_prune_obsolete_entry_false_when_checksum_missing(self, tmp_path: Path) -> None: + """Tracked obsolete files without checksum metadata are preserved.""" + from vstack.manifest import ArtifactEntry + + out_file = tmp_path / "skills" / "legacy" / "SKILL.md" + out_file.parent.mkdir(parents=True) + out_file.write_text("legacy\n", encoding="utf-8") + entry = ArtifactEntry(name="legacy", file="skills/legacy/SKILL.md") + + removable, reason = InitCommand._can_prune_obsolete_entry(install_dir=tmp_path, entry=entry) + assert removable is False + assert reason == "tracked file has no stored checksum" + + def test_can_prune_obsolete_entry_false_when_file_is_unreadable( + self, + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, + ) -> None: + """Unreadable files are preserved instead of pruned.""" + from vstack.manifest import ArtifactEntry + + out_file = tmp_path / "skills" / "legacy" / "SKILL.md" + out_file.parent.mkdir(parents=True) + out_file.write_text("legacy\n", encoding="utf-8") + entry = ArtifactEntry( + name="legacy", + file="skills/legacy/SKILL.md", + checksum=content_hash("legacy\n"), + checksum_algorithm="sha256", + ) + + def _raise_read_text(self: Path, *, encoding: str = "utf-8") -> str: + del self, encoding + raise OSError("unreadable") + + monkeypatch.setattr(Path, "read_text", _raise_read_text) + + removable, reason = InitCommand._can_prune_obsolete_entry(install_dir=tmp_path, entry=entry) + assert removable is False + assert reason == "file is unreadable" + + def test_can_prune_obsolete_entry_false_for_unknown_checksum_algorithm( + self, + tmp_path: Path, + ) -> None: + """Unknown checksum algorithms are treated as unsafe for prune.""" + from vstack.manifest import ArtifactEntry + + out_file = tmp_path / "skills" / "legacy" / "SKILL.md" + out_file.parent.mkdir(parents=True) + out_file.write_text("legacy\n", encoding="utf-8") + entry = ArtifactEntry( + name="legacy", + file="skills/legacy/SKILL.md", + checksum="abc123", + checksum_algorithm="sha999", + ) + + removable, reason = InitCommand._can_prune_obsolete_entry(install_dir=tmp_path, entry=entry) + assert removable is False + assert reason == "unknown checksum algorithm" + + def test_remove_file_if_present_dry_run_keeps_file(self, tmp_path: Path) -> None: + """Dry-run remove helper should not delete files.""" + out_file = tmp_path / "skills" / "legacy" / "SKILL.md" + out_file.parent.mkdir(parents=True) + out_file.write_text("legacy\n", encoding="utf-8") + + InitCommand._remove_file_if_present(out_file=out_file, dry_run=True) + assert out_file.exists() + + def test_remove_file_if_present_ignores_parent_rmdir_error( + self, + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, + ) -> None: + """Parent cleanup failures are swallowed after file deletion.""" + out_file = tmp_path / "skills" / "legacy" / "SKILL.md" + out_file.parent.mkdir(parents=True) + out_file.write_text("legacy\n", encoding="utf-8") + + def _raise_rmdir(self: Path) -> None: + del self + raise OSError("rmdir blocked") + + monkeypatch.setattr(Path, "rmdir", _raise_rmdir) + + InitCommand._remove_file_if_present(out_file=out_file, dry_run=False) + assert not out_file.exists() + + def test_execute_tracks_obsolete_and_prune_summary_counts( + self, + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, + ) -> None: + """execute() increments obsolete/prune/preserve counters from obsolete processing.""" + from vstack.manifest import ArtifactEntry + + summary_calls: list[dict[str, Any]] = [] + + monkeypatch.setattr( + "vstack.cli.init.InitCommand._write_manifest", + staticmethod(lambda **_kwargs: None), + ) + + def _fake_summary(**kwargs): + summary_calls.append(kwargs) + + monkeypatch.setattr( + "vstack.cli.init.InitCommand._print_summary", + staticmethod(_fake_summary), + ) + + class _FakeGen: + config = SimpleNamespace( + type_name="skill", + manifest_key="skills", + output_subdir="skills", + ) + + @staticmethod + def render_all(): + return [] + + @staticmethod + def verify_input(): + return SimpleNamespace(messages=[]) + + service = cast( + CommandService, + SimpleNamespace( + generators=[_FakeGen()], + label=lambda path: str(path), + manifest_for=lambda _: SimpleNamespace(read=lambda: None, read_error=None), + ), + ) + + monkeypatch.setattr( + "vstack.cli.init.InitCommand._load_existing_manifest", + staticmethod(lambda **_kwargs: (object(), None, {}, {})), + ) + + obsolete_entries = [ + ( + "skills", + ArtifactEntry(name="legacy-one", file="skills/legacy-one/SKILL.md"), + ), + ( + "skills", + ArtifactEntry(name="legacy-two", file="skills/legacy-two/SKILL.md"), + ), + ] + monkeypatch.setattr( + "vstack.cli.init.InitCommand._obsolete_candidates", + staticmethod(lambda **_kwargs: obsolete_entries), + ) + + process_actions = iter([("prune", False), ("preserve", True)]) + + def _fake_process(**_kwargs): + return next(process_actions) + + monkeypatch.setattr( + "vstack.cli.init.InitCommand._process_obsolete_entry", + staticmethod(_fake_process), + ) + + result = InitCommand.execute(service, tmp_path, prune=True) + + assert result == 0 + assert len(summary_calls) == 1 + action_counts = summary_calls[0]["action_counts"] + assert action_counts["obsolete"] == 2 + assert action_counts["prune"] == 1 + assert action_counts["preserve"] == 1 + assert summary_calls[0]["preserved_selectors"] == ["skill/legacy-two"] + class TestWarnUnknownWorkflowRoles: """Tests for InitCommand._warn_unknown_workflow_roles.""" diff --git a/tests/vstack/cli/test_parser.py b/tests/vstack/cli/test_parser.py index f877cb21..0f2dd0ce 100644 --- a/tests/vstack/cli/test_parser.py +++ b/tests/vstack/cli/test_parser.py @@ -115,6 +115,19 @@ def test_install_accepts_adopt_name(self) -> None: assert args.command == "install" assert args.adopt_name == ["vision"] + def test_init_accepts_prune(self) -> None: + """Test that init supports obsolete cleanup via --prune.""" + parser = parser_module.CommandLineParser().build() + args = parser.parse_args(["init", "--prune", "--target", "."]) + assert args.command == "init" + assert args.prune is True + + def test_install_rejects_prune(self) -> None: + """Test that --prune is init-only and rejected on install.""" + parser = parser_module.CommandLineParser().build() + with pytest.raises(SystemExit): + parser.parse_args(["install", "--prune", "--target", "."]) + def test_status_accepts_only_filter(self) -> None: """Test that status supports --only type filters.""" parser = parser_module.CommandLineParser().build()