From de191dda76513baa236b96f3efa941e8c694859d Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sat, 14 Mar 2026 15:03:03 -0400 Subject: [PATCH 01/14] docs: finalize framework conventions and naming rules Complete final editorial pass of the framework philosophy document, tighten wording for consistency, and add explicit opinionated contracts for feature directory lifecycle management and branch/worktree naming alignment (including slashless branch names).\n\nCo-Authored-By: Oz --- docs/ZAZZ-FRAMEWORK.md | 332 ++++++++++++++++++++++++----------------- 1 file changed, 194 insertions(+), 138 deletions(-) diff --git a/docs/ZAZZ-FRAMEWORK.md b/docs/ZAZZ-FRAMEWORK.md index 37905f15..396d7162 100644 --- a/docs/ZAZZ-FRAMEWORK.md +++ b/docs/ZAZZ-FRAMEWORK.md @@ -1,212 +1,268 @@ # The Zazz Framework +Zazz is a spec-driven framework with an explicit convergence model: agents iteratively refine the specification and implementation until gaps are resolved and the deliverable satisfies the final SPEC. -Zazz is an opinionated, spec-driven framework for building software deliverables with agents. +## Framework Introduction (At a Glance) -This document defines the **current implementation focus** and the **future capability roadmap**. +Core concepts and capabilities: +- **Desired-state convergence**: work iterates until implementation aligns with the specification. +- **Spec-driven contract**: the SPEC is the authoritative behavior, constraints, and acceptance contract. +- **Structured document flow**: optional Proposal (`-PROP`) → Specification (`-SPEC`) → Plan (`-PLAN`) → build/validate loop. +- **Opinionated documentation contract**: required document types plus opinionated naming and directory structure, with flexible root location. +- **Milestone-centered delivery**: milestones group related deliverables into date-driven capability objectives. +- **Repository/worktree boundary**: each deliverable is executed in exactly one repository (including a monorepo) and one dedicated worktree. +- **Role and context decomposition**: role-scoped and step-scoped context reduces noise and improves agent focus. +- **Iterative spec stewardship**: spec-builder initializes the SPEC; QA validates, surfaces gaps, and drives rule-governed refinements. +- **Flexible runtime model**: supports single-agent, multi-agent, and subagent orchestration depending on runtime capability. +- **Automation-first quality model**: maximize agent-driven convergence, then apply human quality gates at UAT and PR merge. +- **Optional service integration**: Zazz Board services are optional accelerators, not prerequisites for adopting the framework. ---- - -## Current Focus (Active Development Phase) +## Document Scope -The active framework scope is intentionally strict: +This document defines the **philosophy and operating model** of Zazz. +It is not an implementation guide. -1. `spec-builder-agent` -2. `planner-agent` -3. `worker-agent` -4. `zazz-board-api` (required companion skill for all active agents) +Specifically, this document does not define: +- API route contracts +- storage schemas +- tool-specific command syntax +- execution scripts -All implementation guidance in this document is optimized for these four capabilities only. +Those implementation details belong in skills, standards, API docs, and repository-level technical documentation. --- -## What Zazz Is +## Documentation Architecture Philosophy + +Zazz is opinionated about **what documents must exist** and **how they relate**. +Zazz is flexible about **where those documents are stored** in a repository. + +Required document contract: +- **Standards set** (required): shared conventions that govern implementation and validation. +- **Specification (`-SPEC`)** (required): authoritative desired-state and acceptance contract for a deliverable. +- **Plan (`-PLAN`)** (required): execution decomposition toward the specification. +- **Proposal (`-PROP`)** (optional, strongly recommended): pre-decision analysis for larger/new/refactor changes. + +Recommended supporting artifacts: +- milestone-level acceptance/reference notes for grouped deliverables +- deliverable-level user/release documentation as needed by the milestone + +Location flexibility model: +- The framework supports either `.zazz/` or `docs/` (or another repository-defined location) as the documentation root. +- A single configured root should be used per repository for consistency. +- Agents should resolve framework documents from a configured root path, for example `ZAZZ_DOCS_ROOT`. -Zazz combines: -- A delivery framework (SPEC → PLAN → implementation execution and agent skills) -- An opinionated set of required documents and processes for building software applications -- An observability and coordination platform (Zazz Board API + UI) +Baseline structure under the configured root: +- `standards/` for framework standards (single canonical standards location) +- `deliverables/` for deliverable/feature directories that contain `-PROP`, `-SPEC`, and `-PLAN` documents +- optional `milestones/` for milestone-level artifacts -Work is organized as: -- `Project -> Deliverable -> Task` +Single-standards-location rule: +- For framework clarity, standards are assumed to live in one canonical standards location under the configured docs root. +- The framework does not require per-subdirectory or per-section standards partitioning. -Primary artifacts: -- SPEC: `.zazz/deliverables/{name}-SPEC.md` -- PLAN: `.zazz/deliverables/{name}-PLAN.md` +Feature directory and naming contract: +- Each new deliverable/feature must have its own directory under `deliverables/`. +- That directory is the canonical location for managing the feature over time (initial delivery, QA-driven rework, and later enhancements). +- Feature directory names should use a simple, slashless identifier (recommended: `kebab-case`). +- Deliverable documents for that feature live in that directory and use the framework suffixes (for example `feature-name-PROP.md`, `feature-name-SPEC.md`, `feature-name-PLAN.md`). --- -## Core Process (Current Phase) +## Core Philosophy -## Stage 0: SPEC Creation +- Zazz is designed to converge deliverables toward a declared desired state. +- The SPEC defines that desired state (behavior, constraints, and acceptance). +- Tests define the executable verification contract. +- Proposal, planning, execution, QA, and rework are convergence mechanisms. +- Convergence is agent-driven and rule-driven. +- The final deliverable must fully reflect the final SPEC. +- Context engineering is a core design goal: provide agents only the context needed for the current decision/work step. +- Role decomposition and step decomposition exist partly to bound context scope and reduce unnecessary prompt/context load. -Actors: -- Deliverable Owner -- `spec-builder-agent` +--- -Output: -- Approved SPEC with testable acceptance criteria and test requirements. +## Core Entities -Rules: -- Requirements must be explicit and testable. -- If a requirement is ambiguous, refine before planning. +Zazz organizes work using the following hierarchy: -## Stage 1: Planning +`Project -> Milestone -> Deliverable -> Task` -Actor: -- `planner-agent` +### Project +The long-lived product/application context. +A project may span one or more repositories. -Output: -- Execution-ready PLAN with: - - phases and steps - - file assignments - - dependency edges - - parallelizable groups - - test command matrix +### Milestone +A first-class, date-driven grouping of deliverables, conceptually similar to a Scrum initiative (or grouped epics). -Rules: -- PLAN must be repository-grounded (no speculative files/routes). -- PLAN must call out which tasks can run in parallel. +A milestone exists to represent a larger capability or release objective that usually spans multiple deliverables. +A milestone may group deliverables that live in different repositories within the same project. -## Stage 2: Execution +A milestone has: +- an explicit completion/release date +- milestone-level acceptance criteria +- potential cross-deliverable outputs (for example user documentation or release notes) -Actor: -- `worker-agent` (single or multi-agent team mode depending on platform capability) +### Deliverable +A bounded unit of value with its own SPEC, PLAN context, and acceptance criteria. +One deliverable may represent only part of a milestone capability. +A deliverable is strictly scoped to one repository (including a monorepo) and one dedicated git worktree. +Its implementation and framework documents are versioned in that same repository. -Required companion: -- `zazz-board-api` skill +### Task +The smallest execution unit inside a deliverable. -Output: -- Completed deliverable implementation with task lifecycle tracked in Zazz Board. +--- + +## Milestone and Deliverable Relationship Philosophy -Rules: -- Worker reads SPEC + PLAN before implementation. -- Worker executes in TDD mode (tests required per task). -- Worker uses the board API during execution (not as a one-time preload) to keep task lifecycle and dependencies accurate. +- Milestones are grouping and coordination constructs, not just labels. +- Deliverables may be sequenced in series (dependency-gated) or run in parallel (independent). +- Most milestone structures are mixed dependency graphs. +- Milestones may include deliverables from multiple repositories. +- No single deliverable is split across repositories or across multiple worktrees. +- Rework, bug-fix, and enhancement deliverables can belong to the same milestone when they are required for milestone acceptance. -Implementation-phase board policy: -- Add tasks just in time: create/reconcile only the dependency-ready tasks that are about to be worked. -- Before a task starts, ensure it exists on the board, has required relations, and is `READY`. -- As work proceeds, transition workflow status truthfully (`READY`, `IN_PROGRESS`, `COMPLETED`) and keep `isBlocked`/`blockedReason` accurate. -- If course correction is needed after a completed task, add new follow-up tasks and relations to the task graph; do not reopen or rewrite completed tasks. -- If PLAN wording changes during execution, avoid full board resync; update only the next executable tasks and relations. -- Signal deliverable completion only when all tasks currently on the deliverable task graph are complete. +Milestone completion is judged at the milestone level: +- the grouped deliverables satisfy milestone acceptance criteria +- milestone completion aligns to its target date objective --- -## Worker Agent Responsibilities (Expanded) +## Document Flow Philosophy -The worker agent is not a narrow code-only role in the current phase. It is a delivery executor with orchestration responsibilities. +Zazz uses the following conceptual flow: -Mandatory responsibilities: +`PROP -> SPEC -> PLAN -> build/validate loop` -1. Read the deliverable PLAN and SPEC first. -2. Add and update board tasks incrementally while executing (no bulk upfront task creation). -3. Ensure `DEPENDS_ON` relationships exist for each task before that task starts. -4. Keep workflow statuses and block flags accurate while executing. -5. Implement each task with TDD and evidence. -6. Escalate ambiguity to the Owner before making unclear design decisions. -7. If multiple valid approaches exist, present options and request Owner direction. -8. When rework is discovered, extend the task graph with new tasks instead of rolling back completed tasks. +### Proposal (`-PROP`, optional) +Used to clarify options, rationale, tradeoffs, and constraints before committing to a SPEC. +Strongly recommended for new capabilities and major refactors. -The worker must not silently guess when requirements are underdefined. +### Specification (`-SPEC`) +Defines the desired state and acceptance contract. +This is the central convergence target. ---- +### Plan (`-PLAN`) +Defines how work is organized to move toward the SPEC-defined state. +Plan structure may be generated by role-specific agent skills or by runtime-native planning capabilities. -## Multi-Agent / Agent-Team Execution Policy +--- -If the runtime supports subagents or teams (for example Codex multi-agent or Claude teams), the worker agent must use that capability to maximize safe parallelism. +## Context Engineering Philosophy -Policy: +Zazz is intentionally designed to manage context as a first-class concern. -1. Identify all tasks that are dependency-ready. -2. From those, select tasks with non-overlapping file ownership. -3. Spawn subagents for as many safe parallel tasks as possible. -4. Keep status transitions synchronized in board state. -5. Reconcile outputs and continue to next ready task wave. +Core context principles: +- Load the **least necessary context** for the current task, role, and decision. +- Avoid broad, undifferentiated context dumps that increase noise and ambiguity. +- Decompose work into explicit roles and steps so each agent operates with focused context windows. +- Use runtime-native capabilities (for example subagents/teams/planning primitives) to isolate context by workstream whenever possible. +- Prefer iterative context refresh over monolithic one-shot prompts for complex deliverables. -If the runtime does not support subagents, execute the same dependency order in single-agent mode. +Outcome: +- Better reasoning quality, lower context drift, and more predictable convergence to the SPEC-defined target state. --- -## Zazz Board API Requirement +## Convergence Loop Philosophy (Spec Stewardship) -The `zazz-board-api` skill is mandatory for the active agent set. +Zazz is intentionally iterative: -All active agents must use API capabilities to: -- discover deliverables/tasks -- create/update tasks when required by plan execution -- create/update task relationships -- update task status as execution progresses -- capture task notes relevant to decisions, blockers, and clarifications +1. A baseline SPEC is established (typically via spec-builder). +2. Work progresses toward that SPEC. +3. QA validates the implementation against the SPEC and verification evidence. +4. QA identifies gaps, inconsistencies, edge cases, missing tests, and ambiguity. +5. QA drives rule-governed SPEC refinement and explicit rework definition when needed. +6. Rework is generated and resolved. +7. A fresh QA context revalidates against the updated SPEC. +8. Repeat until implementation converges and the final deliverable fully reflects the final SPEC. -OpenAPI is the source of truth for route resolution. +Specification stewardship is shared across the lifecycle: +- spec-builder creates the initial SPEC baseline +- QA refines and hardens the SPEC through controlled updates under framework rules +- SPEC change history should remain explicit and traceable --- -## Task Lifecycle Policy +## Agent Role Philosophy -At minimum, worker execution must keep these states accurate: -- `TO_DO` (optional, project-dependent) -- `READY` -- `IN_PROGRESS` -- `COMPLETED` +Zazz commonly uses these roles: +- `spec-builder-agent` +- `planner-agent` +- `worker-agent` +- `qa-agent` +- optional coordination role (`coordinator-agent`) -Rules: -- Do not mark a task complete before required tests pass. -- Use task-level blocking flags (`isBlocked`, `blockedReason`) when waiting on Owner clarification/decision or file-lock contention. -- Preserve dependency integrity when advancing tasks. +The active agent runtime (for example Claude, Codex, Warp, Gemini CLI) may provide built-in planning, orchestration, or subagent/team capabilities. +The framework is role-oriented and convergence-oriented, not tied to a single runtime. --- -## Clarification and Decision Policy +## Collaboration Philosophy -Worker agent must pause and ask the Owner when: -- instructions are unclear -- requirements are incomplete -- constraints conflict -- more than one materially different solution is valid and plan/spec does not decide +Default collaboration model: +- one dedicated worktree per active deliverable branch +- concurrent work coordinated by explicit ownership and dependency awareness +- deliverable execution is single-repo/single-worktree; project and milestone coordination may span repositories -When asking, include: -1. the exact ambiguity -2. concrete options -3. tradeoffs and recommended option +Branch and worktree naming contract: +- Worktree directory name must match the branch name used for that deliverable. +- Branch names must be slashless (no `/`) so branch and worktree names map cleanly to a single directory path. +- Branch/worktree naming should align with the deliverable/feature identifier used in `deliverables/` when practical. -Do not continue past decision gates without explicit clarification. +Locking philosophy: +- prefer runtime-native concurrency/ownership guarantees when they are stronger +- use service-level locking (for example Board API locking) when needed for shared-state safety and observability --- -## Future Capabilities (Not Current Active Scope) - -The following personas remain part of the framework roadmap but are not the current implementation focus: +## Service Adoption Philosophy -- `coordinator-agent` -- `qa-agent` -- additional specialized personas +Zazz supports two valid adoption paths: -Current status: -- These personas are in **research/planning phase** for future framework expansion. -- Existing references to them should be treated as forward-looking architecture, not present-day required workflow. +1. **Process-only adoption**: apply the framework philosophy and document flow without any board service. +2. **Service-assisted adoption**: add Zazz Board API/UI for orchestration, visibility, and locking support. -When these personas are activated in a future phase, this document will be expanded with their production operating policies. +Board API integration is optional framework infrastructure, not a prerequisite for framework adoption. --- -## Key Principles (Current Phase Summary) +## Post-Convergence Human Acceptance + +Human involvement is intentionally positioned after convergence, not inside it. +Balance model: +- Maximal automation during convergence: agents and framework rules drive refinement, validation, and rework. +- Deliberate human quality checkpoints after convergence: user acceptance testing (UAT) and PR merge approval. + +Post-convergence checkpoints: +1. **UAT checkpoint**: human validation that delivered behavior meets user/business expectations. +2. **PR merge checkpoint**: human review/approval gate for code integration and release readiness. + +These checkpoints are quality controls, not convergence controls. + +--- -1. SPEC defines intent. -2. PLAN defines executable decomposition. -3. Worker executes PLAN and keeps board state truthful. -4. TDD is required for task completion. -5. Dependencies are explicit and enforced. -6. Parallelism is maximized safely (dependency + file-overlap aware). -7. Ambiguity is escalated to the Owner, not guessed. -8. API contract truth comes from live OpenAPI. -9. Task graph evolves during implementation; course corrections are added as new tasks. +## Key Principles + +1. Desired-state convergence is the core operating model. +2. SPEC is the authoritative desired-state contract. +3. Milestones are first-class, date-driven groupings of deliverables. +4. Deliverable dependencies (serial/parallel) shape milestone progression. +5. Projects and milestones may span repositories; each deliverable remains single-repo and single-worktree. +6. QA is an independent convergence pressure function: it finds gaps/inconsistencies, flags missing tests, and drives rule-governed refinement and rework. +7. SPEC stewardship is iterative across spec-builder and QA. +8. The final deliverable must fully reflect the final SPEC. +9. Convergence is agent-driven; human acceptance is deliberately scoped to post-convergence UAT and PR merge checkpoints. +10. Context engineering is required: least-necessary context, role-scoped context, and step-scoped context. +11. The framework is opinionated about required document types, but flexible about document storage location via a configured docs root. +12. Each deliverable/feature has a canonical directory under `deliverables/` for lifecycle management over time. +13. Branch/worktree naming is opinionated: worktree equals branch name, and branch names are slashless. +14. Standards are expected in one canonical location under the configured docs root. +15. Framework philosophy is implementation-agnostic. +16. Board services are optional accelerators, not mandatory prerequisites. --- -## Version +## Framework Maturity -Version: `1.3.0` -Last Updated: `2026-03-07` -Status: `Active - Core Agent Phase (Spec Builder + Planner + Worker + Board API)` +Pre-1.0 working draft: `0.8.1` From 7b534a88c9d69cb5c1c99edf42ac123f1e6d1279 Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sat, 14 Mar 2026 15:10:16 -0400 Subject: [PATCH 02/14] docs: add feature lifecycle and living spec conventions Integrate a first-class Feature concept into the framework while keeping Deliverable as the bounded unit of agent-completed work. Clarify that docs root is flexible but framework shape is opinionated with required standards/ and features/ directories, and add explicit living SPEC maintenance guidance across enhancements, bug fixes, and rework.\n\nCo-Authored-By: Oz --- docs/ZAZZ-FRAMEWORK.md | 72 ++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/docs/ZAZZ-FRAMEWORK.md b/docs/ZAZZ-FRAMEWORK.md index 396d7162..e8348f3c 100644 --- a/docs/ZAZZ-FRAMEWORK.md +++ b/docs/ZAZZ-FRAMEWORK.md @@ -8,6 +8,7 @@ Core concepts and capabilities: - **Spec-driven contract**: the SPEC is the authoritative behavior, constraints, and acceptance contract. - **Structured document flow**: optional Proposal (`-PROP`) → Specification (`-SPEC`) → Plan (`-PLAN`) → build/validate loop. - **Opinionated documentation contract**: required document types plus opinionated naming and directory structure, with flexible root location. +- **Feature lifecycle model**: a product is a collection of long-lived features that evolve through multiple deliverables over time. - **Milestone-centered delivery**: milestones group related deliverables into date-driven capability objectives. - **Repository/worktree boundary**: each deliverable is executed in exactly one repository (including a monorepo) and one dedicated worktree. - **Role and context decomposition**: role-scoped and step-scoped context reduces noise and improves agent focus. @@ -38,33 +39,41 @@ Zazz is flexible about **where those documents are stored** in a repository. Required document contract: - **Standards set** (required): shared conventions that govern implementation and validation. -- **Specification (`-SPEC`)** (required): authoritative desired-state and acceptance contract for a deliverable. +- **Specification (`-SPEC`)** (required): authoritative desired-state and acceptance contract for the active work scope; when work targets an existing feature, update that feature's canonical SPEC in place. - **Plan (`-PLAN`)** (required): execution decomposition toward the specification. - **Proposal (`-PROP`)** (optional, strongly recommended): pre-decision analysis for larger/new/refactor changes. Recommended supporting artifacts: - milestone-level acceptance/reference notes for grouped deliverables - deliverable-level user/release documentation as needed by the milestone +- feature-level capability notes when helpful for long-running feature history Location flexibility model: - The framework supports either `.zazz/` or `docs/` (or another repository-defined location) as the documentation root. - A single configured root should be used per repository for consistency. - Agents should resolve framework documents from a configured root path, for example `ZAZZ_DOCS_ROOT`. +- Example: one project may store framework docs under `.zazz/` while another stores them under `docs/`; both remain framework-compliant. Baseline structure under the configured root: - `standards/` for framework standards (single canonical standards location) -- `deliverables/` for deliverable/feature directories that contain `-PROP`, `-SPEC`, and `-PLAN` documents +- `features/` for long-lived feature directories that contain deliverable documents over time - optional `milestones/` for milestone-level artifacts +Required directory contract: +- Each repository adopting the framework should expose both `standards/` and `features/` under its configured docs root. +- The docs root itself is flexible (`.zazz/`, `docs/`, or repository-defined), but these two subdirectories are part of the opinionated framework shape. + Single-standards-location rule: - For framework clarity, standards are assumed to live in one canonical standards location under the configured docs root. - The framework does not require per-subdirectory or per-section standards partitioning. Feature directory and naming contract: -- Each new deliverable/feature must have its own directory under `deliverables/`. -- That directory is the canonical location for managing the feature over time (initial delivery, QA-driven rework, and later enhancements). +- Each new feature must have its own directory under `features/`. +- That directory is the canonical location for managing the feature over time (initial delivery, QA-driven rework, enhancements, and bug fixes). - Feature directory names should use a simple, slashless identifier (recommended: `kebab-case`). -- Deliverable documents for that feature live in that directory and use the framework suffixes (for example `feature-name-PROP.md`, `feature-name-SPEC.md`, `feature-name-PLAN.md`). +- The feature's canonical living specification should be maintained in-place in that directory (for example `feature-id-SPEC.md`). +- Deliverable-scoped working documents for that feature should also live there and use framework suffixes (for example `deliverable-id-PROP.md`, `deliverable-id-PLAN.md`). +- A single feature directory may contain many deliverables across the lifecycle of that capability. --- @@ -74,6 +83,7 @@ Feature directory and naming contract: - The SPEC defines that desired state (behavior, constraints, and acceptance). - Tests define the executable verification contract. - Proposal, planning, execution, QA, and rework are convergence mechanisms. +- Products are treated as collections of evolving features; deliverables are bounded increments that implement, improve, or repair those features. - Convergence is agent-driven and rule-driven. - The final deliverable must fully reflect the final SPEC. - Context engineering is a core design goal: provide agents only the context needed for the current decision/work step. @@ -83,19 +93,25 @@ Feature directory and naming contract: ## Core Entities -Zazz organizes work using the following hierarchy: +Zazz organizes work using two complementary structures: +- Capability hierarchy: `Project -> Feature -> Deliverable -> Task` +- Delivery grouping hierarchy: `Project -> Milestone -> Deliverable -> Task` -`Project -> Milestone -> Deliverable -> Task` +Milestones are a first-class cross-cutting grouping axis over deliverables (date and release objective), not a replacement for feature hierarchy. ### Project The long-lived product/application context. A project may span one or more repositories. +### Feature +A long-lived capability within the product/application. +Features persist over time and can receive multiple deliverables (initial version, enhancements, bug fixes, and rework). +A feature may have dependency relationships with other features. ### Milestone A first-class, date-driven grouping of deliverables, conceptually similar to a Scrum initiative (or grouped epics). A milestone exists to represent a larger capability or release objective that usually spans multiple deliverables. -A milestone may group deliverables that live in different repositories within the same project. +A milestone may group deliverables from multiple features and from different repositories within the same project. A milestone has: - an explicit completion/release date @@ -103,8 +119,9 @@ A milestone has: - potential cross-deliverable outputs (for example user documentation or release notes) ### Deliverable -A bounded unit of value with its own SPEC, PLAN context, and acceptance criteria. -One deliverable may represent only part of a milestone capability. +A bounded unit of value completed by an agent group, with its own SPEC, PLAN context, and acceptance criteria. +A deliverable is typically one incremental change to a feature (for example initial implementation, enhancement, bug fix, refactor, or QA-driven rework). +A deliverable belongs to one primary feature and may contribute to a milestone objective. A deliverable is strictly scoped to one repository (including a monorepo) and one dedicated git worktree. Its implementation and framework documents are versioned in that same repository. @@ -113,13 +130,18 @@ The smallest execution unit inside a deliverable. --- -## Milestone and Deliverable Relationship Philosophy +## Feature, Milestone, and Deliverable Relationship Philosophy +- Features are long-lived capability contexts. +- Deliverables are bounded execution units within a feature lifecycle. +- A feature is implemented and evolved through multiple deliverables over time. - Milestones are grouping and coordination constructs, not just labels. +- Milestones may contain deliverables from one or many features. - Deliverables may be sequenced in series (dependency-gated) or run in parallel (independent). - Most milestone structures are mixed dependency graphs. - Milestones may include deliverables from multiple repositories. - No single deliverable is split across repositories or across multiple worktrees. +- If a deliverable touches overlapping features, it should declare one primary feature and explicitly reference secondary feature impacts. - Rework, bug-fix, and enhancement deliverables can belong to the same milestone when they are required for milestone acceptance. Milestone completion is judged at the milestone level: @@ -134,6 +156,8 @@ Zazz uses the following conceptual flow: `PROP -> SPEC -> PLAN -> build/validate loop` +This flow runs per deliverable while preserving feature-level continuity across many deliverables. + ### Proposal (`-PROP`, optional) Used to clarify options, rationale, tradeoffs, and constraints before committing to a SPEC. Strongly recommended for new capabilities and major refactors. @@ -142,6 +166,12 @@ Strongly recommended for new capabilities and major refactors. Defines the desired state and acceptance contract. This is the central convergence target. +Specification maintenance convention: +- A feature specification is a living document that should reflect current intended behavior. +- Enhancements, bug fixes, and behavior-changing refactors should update the canonical feature SPEC in the same deliverable workflow. +- A bug fix is both an implementation correction and a specification clarification when the bug reveals a behavior gap. +- SPEC change history should remain explicit and traceable (for example via a changelog section or equivalent convention). + ### Plan (`-PLAN`) Defines how work is organized to move toward the SPEC-defined state. Plan structure may be generated by role-specific agent skills or by runtime-native planning capabilities. @@ -208,7 +238,7 @@ Default collaboration model: Branch and worktree naming contract: - Worktree directory name must match the branch name used for that deliverable. - Branch names must be slashless (no `/`) so branch and worktree names map cleanly to a single directory path. -- Branch/worktree naming should align with the deliverable/feature identifier used in `deliverables/` when practical. +- Branch/worktree naming should align with feature and deliverable identifiers used in `features/` when practical (for example `feature-id-deliverable-id`). Locking philosophy: - prefer runtime-native concurrency/ownership guarantees when they are stronger @@ -252,14 +282,16 @@ These checkpoints are quality controls, not convergence controls. 6. QA is an independent convergence pressure function: it finds gaps/inconsistencies, flags missing tests, and drives rule-governed refinement and rework. 7. SPEC stewardship is iterative across spec-builder and QA. 8. The final deliverable must fully reflect the final SPEC. -9. Convergence is agent-driven; human acceptance is deliberately scoped to post-convergence UAT and PR merge checkpoints. -10. Context engineering is required: least-necessary context, role-scoped context, and step-scoped context. -11. The framework is opinionated about required document types, but flexible about document storage location via a configured docs root. -12. Each deliverable/feature has a canonical directory under `deliverables/` for lifecycle management over time. -13. Branch/worktree naming is opinionated: worktree equals branch name, and branch names are slashless. -14. Standards are expected in one canonical location under the configured docs root. -15. Framework philosophy is implementation-agnostic. -16. Board services are optional accelerators, not mandatory prerequisites. +9. Feature SPECs are living contracts and should be updated in place as behavior evolves. +10. Convergence is agent-driven; human acceptance is deliberately scoped to post-convergence UAT and PR merge checkpoints. +11. Context engineering is required: least-necessary context, role-scoped context, and step-scoped context. +12. The framework is opinionated about required document types and subdirectory shape, but flexible about document root location. +13. `features/` and `standards/` are required framework directories under the configured docs root. +14. Features are long-lived capability contexts; deliverables are bounded units that implement, enhance, refactor, or repair features. +15. Branch/worktree naming is opinionated: worktree equals branch name, and branch names are slashless. +16. Standards are expected in one canonical location under the configured docs root. +17. Framework philosophy is implementation-agnostic. +18. Board services are optional accelerators, not mandatory prerequisites. --- From 101e109e40c4ab2f915d0f0baa36706e27170fc2 Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sat, 14 Mar 2026 15:31:18 -0400 Subject: [PATCH 03/14] docs: formalize feature/deliverable two-spec framework model Refine framework philosophy to explicitly distinguish long-lived Feature SPECs from per-deliverable Deliverable SPECs, clarify cross-cutting Feature and Milestone semantics, and tighten opinionated documentation naming/structure guidance while preserving flexible docs root support. Also update convergence loop and key principles to reflect deliverable-level iteration plus feature-level specification evolution.\n\nCo-Authored-By: Oz --- docs/ZAZZ-FRAMEWORK.md | 90 +++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/docs/ZAZZ-FRAMEWORK.md b/docs/ZAZZ-FRAMEWORK.md index e8348f3c..4ab16375 100644 --- a/docs/ZAZZ-FRAMEWORK.md +++ b/docs/ZAZZ-FRAMEWORK.md @@ -1,18 +1,18 @@ # The Zazz Framework -Zazz is a spec-driven framework with an explicit convergence model: agents iteratively refine the specification and implementation until gaps are resolved and the deliverable satisfies the final SPEC. +Zazz is a spec-driven framework with an explicit convergence model: agents iteratively refine the specification and implementation until gaps are resolved and the deliverable satisfies its finalized Deliverable SPEC. ## Framework Introduction (At a Glance) Core concepts and capabilities: - **Desired-state convergence**: work iterates until implementation aligns with the specification. -- **Spec-driven contract**: the SPEC is the authoritative behavior, constraints, and acceptance contract. -- **Structured document flow**: optional Proposal (`-PROP`) → Specification (`-SPEC`) → Plan (`-PLAN`) → build/validate loop. +- **Dual-spec contract**: each feature has a long-lived Feature SPEC, and each deliverable has its own Deliverable SPEC. +- **Structured document flow**: optional Proposal (`-PROP`) → required Deliverable Specification (`-SPEC`) → optional explicit Plan (`-PLAN`) → build/validate loop. - **Opinionated documentation contract**: required document types plus opinionated naming and directory structure, with flexible root location. - **Feature lifecycle model**: a product is a collection of long-lived features that evolve through multiple deliverables over time. - **Milestone-centered delivery**: milestones group related deliverables into date-driven capability objectives. - **Repository/worktree boundary**: each deliverable is executed in exactly one repository (including a monorepo) and one dedicated worktree. - **Role and context decomposition**: role-scoped and step-scoped context reduces noise and improves agent focus. -- **Iterative spec stewardship**: spec-builder initializes the SPEC; QA validates, surfaces gaps, and drives rule-governed refinements. +- **Iterative spec stewardship**: spec-builder initializes Deliverable SPEC baselines; QA validates, surfaces gaps, and drives rule-governed refinements. - **Flexible runtime model**: supports single-agent, multi-agent, and subagent orchestration depending on runtime capability. - **Automation-first quality model**: maximize agent-driven convergence, then apply human quality gates at UAT and PR merge. - **Optional service integration**: Zazz Board services are optional accelerators, not prerequisites for adopting the framework. @@ -39,10 +39,17 @@ Zazz is flexible about **where those documents are stored** in a repository. Required document contract: - **Standards set** (required): shared conventions that govern implementation and validation. -- **Specification (`-SPEC`)** (required): authoritative desired-state and acceptance contract for the active work scope; when work targets an existing feature, update that feature's canonical SPEC in place. -- **Plan (`-PLAN`)** (required): execution decomposition toward the specification. +- **Feature Specification (`-SPEC`)** (required per feature): long-lived, mutable capability contract for the feature over time. +- **Deliverable Specification (`-SPEC`)** (required per deliverable): execution contract for one deliverable. +- **Plan (`-PLAN`)** (optional explicit artifact): execution decomposition toward the specification. In some runtimes, planning may be internal to the agent platform instead of persisted as a standalone `-PLAN` document. - **Proposal (`-PROP`)** (optional, strongly recommended): pre-decision analysis for larger/new/refactor changes. +Opinionated naming contract: +- Framework document names are opinionated around three artifact types: `-PROP`, `-SPEC`, and `-PLAN`. +- `-SPEC` is required for both features and deliverables. +- `-PROP` is optional and used when pre-decision analysis is needed. +- `-PLAN` may be explicit (document) or implicit (agent-internal/runtime-native), depending on platform capability and team policy. + Recommended supporting artifacts: - milestone-level acceptance/reference notes for grouped deliverables - deliverable-level user/release documentation as needed by the milestone @@ -70,9 +77,12 @@ Single-standards-location rule: Feature directory and naming contract: - Each new feature must have its own directory under `features/`. - That directory is the canonical location for managing the feature over time (initial delivery, QA-driven rework, enhancements, and bug fixes). -- Feature directory names should use a simple, slashless identifier (recommended: `kebab-case`). -- The feature's canonical living specification should be maintained in-place in that directory (for example `feature-id-SPEC.md`). -- Deliverable-scoped working documents for that feature should also live there and use framework suffixes (for example `deliverable-id-PROP.md`, `deliverable-id-PLAN.md`). +- Feature identity should include: + - human-readable **feature name** (for example `Task Graph`) + - stable **feature key** (slashless `kebab-case`, for example `task-graph`) used for paths and references +- The feature directory name should be the feature key. +- Feature SPEC should be long-lived and maintained in-place (for example `task-graph-SPEC.md`). +- Deliverable documents should live under the feature directory, ideally in a deliverable subdirectory, and follow framework naming (for example `deliverables/DLV-142/DLV-142-SPEC.md`, optional `deliverables/DLV-142/DLV-142-PROP.md`, optional `deliverables/DLV-142/DLV-142-PLAN.md`). - A single feature directory may contain many deliverables across the lifecycle of that capability. --- @@ -80,12 +90,12 @@ Feature directory and naming contract: ## Core Philosophy - Zazz is designed to converge deliverables toward a declared desired state. -- The SPEC defines that desired state (behavior, constraints, and acceptance). +- Feature SPEC defines long-duration capability intent; Deliverable SPEC defines execution scope for one increment. - Tests define the executable verification contract. - Proposal, planning, execution, QA, and rework are convergence mechanisms. - Products are treated as collections of evolving features; deliverables are bounded increments that implement, improve, or repair those features. - Convergence is agent-driven and rule-driven. -- The final deliverable must fully reflect the final SPEC. +- The final deliverable must fully reflect its finalized Deliverable SPEC. - Context engineering is a core design goal: provide agents only the context needed for the current decision/work step. - Role decomposition and step decomposition exist partly to bound context scope and reduce unnecessary prompt/context load. @@ -93,19 +103,18 @@ Feature directory and naming contract: ## Core Entities -Zazz organizes work using two complementary structures: -- Capability hierarchy: `Project -> Feature -> Deliverable -> Task` -- Delivery grouping hierarchy: `Project -> Milestone -> Deliverable -> Task` - -Milestones are a first-class cross-cutting grouping axis over deliverables (date and release objective), not a replacement for feature hierarchy. +Zazz organizes work using: +- execution hierarchy: `Project -> Deliverable -> Task` +- cross-cutting coordination objects: `Feature` and `Milestone` ### Project The long-lived product/application context. A project may span one or more repositories. ### Feature -A long-lived capability within the product/application. -Features persist over time and can receive multiple deliverables (initial version, enhancements, bug fixes, and rework). -A feature may have dependency relationships with other features. +A long-lived capability object within the product/application. +Features span time and can receive many deliverables (initial version, enhancements, bug fixes, and rework). +Each feature has one long-lived Feature SPEC that evolves over time. +Features may have dependency relationships with other features. ### Milestone A first-class, date-driven grouping of deliverables, conceptually similar to a Scrum initiative (or grouped epics). @@ -119,11 +128,12 @@ A milestone has: - potential cross-deliverable outputs (for example user documentation or release notes) ### Deliverable -A bounded unit of value completed by an agent group, with its own SPEC, PLAN context, and acceptance criteria. +A bounded unit of value completed by an agent group, with its own Deliverable SPEC, optional explicit PLAN, and acceptance criteria. A deliverable is typically one incremental change to a feature (for example initial implementation, enhancement, bug fix, refactor, or QA-driven rework). A deliverable belongs to one primary feature and may contribute to a milestone objective. A deliverable is strictly scoped to one repository (including a monorepo) and one dedicated git worktree. Its implementation and framework documents are versioned in that same repository. +Once closed, a Deliverable SPEC is treated as frozen/immutable (except explicit amendment records). ### Task The smallest execution unit inside a deliverable. @@ -133,10 +143,12 @@ The smallest execution unit inside a deliverable. ## Feature, Milestone, and Deliverable Relationship Philosophy - Features are long-lived capability contexts. +- Features are cross-cutting objects that span multiple deliverables and can span multiple milestones over time. - Deliverables are bounded execution units within a feature lifecycle. - A feature is implemented and evolved through multiple deliverables over time. - Milestones are grouping and coordination constructs, not just labels. - Milestones may contain deliverables from one or many features. +- A milestone is not required to represent a fully completed feature; it may represent an intermediate grouping of deliverables toward broader feature completion. - Deliverables may be sequenced in series (dependency-gated) or run in parallel (independent). - Most milestone structures are mixed dependency graphs. - Milestones may include deliverables from multiple repositories. @@ -156,7 +168,7 @@ Zazz uses the following conceptual flow: `PROP -> SPEC -> PLAN -> build/validate loop` -This flow runs per deliverable while preserving feature-level continuity across many deliverables. +This flow runs per deliverable while preserving continuity with the long-lived Feature SPEC. ### Proposal (`-PROP`, optional) Used to clarify options, rationale, tradeoffs, and constraints before committing to a SPEC. @@ -167,14 +179,17 @@ Defines the desired state and acceptance contract. This is the central convergence target. Specification maintenance convention: -- A feature specification is a living document that should reflect current intended behavior. -- Enhancements, bug fixes, and behavior-changing refactors should update the canonical feature SPEC in the same deliverable workflow. +- **Feature SPEC** (long-lived, mutable): canonical capability contract for the feature over time. +- **Deliverable SPEC** (short-lived execution contract): scoped contract for one deliverable. +- Deliverable SPEC is refined during active execution/QA and then frozen when the deliverable closes. +- Enhancements, bug fixes, refactors, and rework that are treated as distinct deliverables should use new Deliverable SPECs. - A bug fix is both an implementation correction and a specification clarification when the bug reveals a behavior gap. -- SPEC change history should remain explicit and traceable (for example via a changelog section or equivalent convention). +- Feature SPEC should be updated to reflect accepted behavior evolution across deliverables. +- SPEC history should remain explicit and traceable (for example via changelogs and cross-references between feature and deliverable specs). ### Plan (`-PLAN`) Defines how work is organized to move toward the SPEC-defined state. -Plan structure may be generated by role-specific agent skills or by runtime-native planning capabilities. +`-PLAN` may be persisted as a document or executed as runtime-native/agent-internal planning, depending on platform capability and team policy. --- @@ -197,19 +212,20 @@ Outcome: ## Convergence Loop Philosophy (Spec Stewardship) Zazz is intentionally iterative: - -1. A baseline SPEC is established (typically via spec-builder). -2. Work progresses toward that SPEC. -3. QA validates the implementation against the SPEC and verification evidence. +1. A baseline Deliverable SPEC is established (typically via spec-builder), aligned to current Feature SPEC context. +2. Work progresses toward the Deliverable SPEC. +3. QA validates the implementation against the Deliverable SPEC and verification evidence. 4. QA identifies gaps, inconsistencies, edge cases, missing tests, and ambiguity. -5. QA drives rule-governed SPEC refinement and explicit rework definition when needed. +5. QA drives rule-governed Deliverable SPEC refinement and explicit rework definition when needed. 6. Rework is generated and resolved. -7. A fresh QA context revalidates against the updated SPEC. -8. Repeat until implementation converges and the final deliverable fully reflects the final SPEC. +7. A fresh QA context revalidates against the updated Deliverable SPEC. +8. Repeat until implementation converges and the final deliverable fully reflects the finalized Deliverable SPEC. +9. On deliverable closure, freeze the Deliverable SPEC and reconcile accepted behavior into the Feature SPEC. Specification stewardship is shared across the lifecycle: -- spec-builder creates the initial SPEC baseline -- QA refines and hardens the SPEC through controlled updates under framework rules +- spec-builder creates the initial Deliverable SPEC baseline +- QA refines and hardens the Deliverable SPEC through controlled updates under framework rules +- feature owners/stewards reconcile accepted outcomes into the Feature SPEC - SPEC change history should remain explicit and traceable --- @@ -275,14 +291,14 @@ These checkpoints are quality controls, not convergence controls. ## Key Principles 1. Desired-state convergence is the core operating model. -2. SPEC is the authoritative desired-state contract. +2. The framework uses a two-spec model: long-lived Feature SPEC + per-deliverable Deliverable SPEC. 3. Milestones are first-class, date-driven groupings of deliverables. 4. Deliverable dependencies (serial/parallel) shape milestone progression. 5. Projects and milestones may span repositories; each deliverable remains single-repo and single-worktree. 6. QA is an independent convergence pressure function: it finds gaps/inconsistencies, flags missing tests, and drives rule-governed refinement and rework. 7. SPEC stewardship is iterative across spec-builder and QA. -8. The final deliverable must fully reflect the final SPEC. -9. Feature SPECs are living contracts and should be updated in place as behavior evolves. +8. The final deliverable must fully reflect its finalized Deliverable SPEC. +9. Every feature has one long-lived Feature SPEC; every deliverable has one required Deliverable SPEC (`-SPEC`). 10. Convergence is agent-driven; human acceptance is deliberately scoped to post-convergence UAT and PR merge checkpoints. 11. Context engineering is required: least-necessary context, role-scoped context, and step-scoped context. 12. The framework is opinionated about required document types and subdirectory shape, but flexible about document root location. From b0e4b6f3bb18cc2c2b408f2e2f91d1cee1c5dd7e Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sat, 14 Mar 2026 16:10:47 -0400 Subject: [PATCH 04/14] docs: reframe features as requirements and journeys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the framework to treat Features as long-lived user-journey/requirements objects via a Feature Requirements Document (FRD), while reserving SPEC terminology for deliverables. Clarify many-to-many feature↔deliverable requirement mapping, milestone-gated feature capability maturation, and consistent document naming/flow guidance.\n\nCo-Authored-By: Oz --- docs/ZAZZ-FRAMEWORK.md | 44 ++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/docs/ZAZZ-FRAMEWORK.md b/docs/ZAZZ-FRAMEWORK.md index 4ab16375..4eb39dc7 100644 --- a/docs/ZAZZ-FRAMEWORK.md +++ b/docs/ZAZZ-FRAMEWORK.md @@ -5,7 +5,7 @@ Zazz is a spec-driven framework with an explicit convergence model: agents itera Core concepts and capabilities: - **Desired-state convergence**: work iterates until implementation aligns with the specification. -- **Dual-spec contract**: each feature has a long-lived Feature SPEC, and each deliverable has its own Deliverable SPEC. +- **Feature requirements + deliverable spec contract**: each feature has a long-lived Feature Requirements Document, and each deliverable has its own Deliverable SPEC. - **Structured document flow**: optional Proposal (`-PROP`) → required Deliverable Specification (`-SPEC`) → optional explicit Plan (`-PLAN`) → build/validate loop. - **Opinionated documentation contract**: required document types plus opinionated naming and directory structure, with flexible root location. - **Feature lifecycle model**: a product is a collection of long-lived features that evolve through multiple deliverables over time. @@ -39,14 +39,15 @@ Zazz is flexible about **where those documents are stored** in a repository. Required document contract: - **Standards set** (required): shared conventions that govern implementation and validation. -- **Feature Specification (`-SPEC`)** (required per feature): long-lived, mutable capability contract for the feature over time. +- **Feature Requirements Document (`-FRD`)** (required per feature): long-lived, mutable user-journey and requirement contract for the feature over time. - **Deliverable Specification (`-SPEC`)** (required per deliverable): execution contract for one deliverable. - **Plan (`-PLAN`)** (optional explicit artifact): execution decomposition toward the specification. In some runtimes, planning may be internal to the agent platform instead of persisted as a standalone `-PLAN` document. - **Proposal (`-PROP`)** (optional, strongly recommended): pre-decision analysis for larger/new/refactor changes. Opinionated naming contract: -- Framework document names are opinionated around three artifact types: `-PROP`, `-SPEC`, and `-PLAN`. -- `-SPEC` is required for both features and deliverables. +- Framework document names are opinionated around four artifact types: `-FRD`, `-PROP`, `-SPEC`, and `-PLAN`. +- `-FRD` is required for features and captures user journeys + requirements (what/why, not how). +- `-SPEC` is reserved for deliverables. - `-PROP` is optional and used when pre-decision analysis is needed. - `-PLAN` may be explicit (document) or implicit (agent-internal/runtime-native), depending on platform capability and team policy. @@ -81,7 +82,7 @@ Feature directory and naming contract: - human-readable **feature name** (for example `Task Graph`) - stable **feature key** (slashless `kebab-case`, for example `task-graph`) used for paths and references - The feature directory name should be the feature key. -- Feature SPEC should be long-lived and maintained in-place (for example `task-graph-SPEC.md`). +- Feature requirements should be long-lived and maintained in-place (for example `task-graph-FRD.md`). - Deliverable documents should live under the feature directory, ideally in a deliverable subdirectory, and follow framework naming (for example `deliverables/DLV-142/DLV-142-SPEC.md`, optional `deliverables/DLV-142/DLV-142-PROP.md`, optional `deliverables/DLV-142/DLV-142-PLAN.md`). - A single feature directory may contain many deliverables across the lifecycle of that capability. @@ -90,7 +91,7 @@ Feature directory and naming contract: ## Core Philosophy - Zazz is designed to converge deliverables toward a declared desired state. -- Feature SPEC defines long-duration capability intent; Deliverable SPEC defines execution scope for one increment. +- Feature requirements define long-duration user journeys and capability intent; Deliverable SPEC defines execution scope for one increment. - Tests define the executable verification contract. - Proposal, planning, execution, QA, and rework are convergence mechanisms. - Products are treated as collections of evolving features; deliverables are bounded increments that implement, improve, or repair those features. @@ -113,7 +114,7 @@ A project may span one or more repositories. ### Feature A long-lived capability object within the product/application. Features span time and can receive many deliverables (initial version, enhancements, bug fixes, and rework). -Each feature has one long-lived Feature SPEC that evolves over time. +Each feature has one long-lived Feature Requirements Document (`-FRD`) that evolves over time. Features may have dependency relationships with other features. ### Milestone @@ -130,7 +131,7 @@ A milestone has: ### Deliverable A bounded unit of value completed by an agent group, with its own Deliverable SPEC, optional explicit PLAN, and acceptance criteria. A deliverable is typically one incremental change to a feature (for example initial implementation, enhancement, bug fix, refactor, or QA-driven rework). -A deliverable belongs to one primary feature and may contribute to a milestone objective. +A deliverable may satisfy requirements from one or more features and may contribute to one or more milestone objectives. A deliverable is strictly scoped to one repository (including a monorepo) and one dedicated git worktree. Its implementation and framework documents are versioned in that same repository. Once closed, a Deliverable SPEC is treated as frozen/immutable (except explicit amendment records). @@ -148,12 +149,13 @@ The smallest execution unit inside a deliverable. - A feature is implemented and evolved through multiple deliverables over time. - Milestones are grouping and coordination constructs, not just labels. - Milestones may contain deliverables from one or many features. +- Milestones represent capability progression/maturation targets for features by a date; deliverables are the implementation increments used to reach those targets. - A milestone is not required to represent a fully completed feature; it may represent an intermediate grouping of deliverables toward broader feature completion. - Deliverables may be sequenced in series (dependency-gated) or run in parallel (independent). - Most milestone structures are mixed dependency graphs. - Milestones may include deliverables from multiple repositories. - No single deliverable is split across repositories or across multiple worktrees. -- If a deliverable touches overlapping features, it should declare one primary feature and explicitly reference secondary feature impacts. +- Deliverables and features are many-to-many at requirements level: one deliverable can satisfy multiple feature requirements, and one feature requirement can require multiple deliverables over time. - Rework, bug-fix, and enhancement deliverables can belong to the same milestone when they are required for milestone acceptance. Milestone completion is judged at the milestone level: @@ -168,24 +170,24 @@ Zazz uses the following conceptual flow: `PROP -> SPEC -> PLAN -> build/validate loop` -This flow runs per deliverable while preserving continuity with the long-lived Feature SPEC. +This flow runs per deliverable while preserving continuity with the long-lived Feature Requirements Document (`-FRD`). ### Proposal (`-PROP`, optional) -Used to clarify options, rationale, tradeoffs, and constraints before committing to a SPEC. +Used to clarify options, rationale, tradeoffs, and constraints before committing to a Deliverable SPEC. Strongly recommended for new capabilities and major refactors. ### Specification (`-SPEC`) Defines the desired state and acceptance contract. This is the central convergence target. -Specification maintenance convention: -- **Feature SPEC** (long-lived, mutable): canonical capability contract for the feature over time. +Requirements and specification maintenance convention: +- **Feature Requirements Document (`-FRD`)** (long-lived, mutable): canonical user-journey and requirement contract for the feature over time. - **Deliverable SPEC** (short-lived execution contract): scoped contract for one deliverable. - Deliverable SPEC is refined during active execution/QA and then frozen when the deliverable closes. - Enhancements, bug fixes, refactors, and rework that are treated as distinct deliverables should use new Deliverable SPECs. - A bug fix is both an implementation correction and a specification clarification when the bug reveals a behavior gap. -- Feature SPEC should be updated to reflect accepted behavior evolution across deliverables. -- SPEC history should remain explicit and traceable (for example via changelogs and cross-references between feature and deliverable specs). +- Feature requirements should be updated to reflect accepted behavior evolution across deliverables. +- Requirement/spec history should remain explicit and traceable (for example via changelogs and cross-references between feature requirements and deliverable specs). ### Plan (`-PLAN`) Defines how work is organized to move toward the SPEC-defined state. @@ -212,7 +214,7 @@ Outcome: ## Convergence Loop Philosophy (Spec Stewardship) Zazz is intentionally iterative: -1. A baseline Deliverable SPEC is established (typically via spec-builder), aligned to current Feature SPEC context. +1. A baseline Deliverable SPEC is established (typically via spec-builder), aligned to current Feature Requirements context. 2. Work progresses toward the Deliverable SPEC. 3. QA validates the implementation against the Deliverable SPEC and verification evidence. 4. QA identifies gaps, inconsistencies, edge cases, missing tests, and ambiguity. @@ -220,12 +222,12 @@ Zazz is intentionally iterative: 6. Rework is generated and resolved. 7. A fresh QA context revalidates against the updated Deliverable SPEC. 8. Repeat until implementation converges and the final deliverable fully reflects the finalized Deliverable SPEC. -9. On deliverable closure, freeze the Deliverable SPEC and reconcile accepted behavior into the Feature SPEC. +9. On deliverable closure, freeze the Deliverable SPEC and reconcile accepted behavior into the Feature Requirements Document (`-FRD`). Specification stewardship is shared across the lifecycle: - spec-builder creates the initial Deliverable SPEC baseline - QA refines and hardens the Deliverable SPEC through controlled updates under framework rules -- feature owners/stewards reconcile accepted outcomes into the Feature SPEC +- feature owners/stewards reconcile accepted outcomes into the Feature Requirements Document (`-FRD`) - SPEC change history should remain explicit and traceable --- @@ -291,19 +293,19 @@ These checkpoints are quality controls, not convergence controls. ## Key Principles 1. Desired-state convergence is the core operating model. -2. The framework uses a two-spec model: long-lived Feature SPEC + per-deliverable Deliverable SPEC. +2. The framework uses a two-document model: long-lived Feature Requirements (`-FRD`) + per-deliverable Deliverable SPEC (`-SPEC`). 3. Milestones are first-class, date-driven groupings of deliverables. 4. Deliverable dependencies (serial/parallel) shape milestone progression. 5. Projects and milestones may span repositories; each deliverable remains single-repo and single-worktree. 6. QA is an independent convergence pressure function: it finds gaps/inconsistencies, flags missing tests, and drives rule-governed refinement and rework. 7. SPEC stewardship is iterative across spec-builder and QA. 8. The final deliverable must fully reflect its finalized Deliverable SPEC. -9. Every feature has one long-lived Feature SPEC; every deliverable has one required Deliverable SPEC (`-SPEC`). +9. Every feature has one long-lived Feature Requirements Document (`-FRD`); every deliverable has one required Deliverable SPEC (`-SPEC`). 10. Convergence is agent-driven; human acceptance is deliberately scoped to post-convergence UAT and PR merge checkpoints. 11. Context engineering is required: least-necessary context, role-scoped context, and step-scoped context. 12. The framework is opinionated about required document types and subdirectory shape, but flexible about document root location. 13. `features/` and `standards/` are required framework directories under the configured docs root. -14. Features are long-lived capability contexts; deliverables are bounded units that implement, enhance, refactor, or repair features. +14. Features define user journeys and requirements (what/why); deliverables define and implement scoped specification contracts (what/how) for execution. 15. Branch/worktree naming is opinionated: worktree equals branch name, and branch names are slashless. 16. Standards are expected in one canonical location under the configured docs root. 17. Framework philosophy is implementation-agnostic. From 77b2a08e2d190830bd063e72d7d620adcb3a70df Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sat, 14 Mar 2026 16:14:22 -0400 Subject: [PATCH 05/14] docs: split feature and deliverable documentation structures Refine framework documentation architecture to separate features and deliverables into distinct directories, formalize deliverable-to-feature linkage rules (including shared support work and feature-agnostic chores), and clarify proposal semantics as optional ideation artifacts that can attach to features, deliverables, or both.\n\nCo-Authored-By: Oz --- docs/ZAZZ-FRAMEWORK.md | 46 ++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/docs/ZAZZ-FRAMEWORK.md b/docs/ZAZZ-FRAMEWORK.md index 4eb39dc7..afbd2fc8 100644 --- a/docs/ZAZZ-FRAMEWORK.md +++ b/docs/ZAZZ-FRAMEWORK.md @@ -42,7 +42,7 @@ Required document contract: - **Feature Requirements Document (`-FRD`)** (required per feature): long-lived, mutable user-journey and requirement contract for the feature over time. - **Deliverable Specification (`-SPEC`)** (required per deliverable): execution contract for one deliverable. - **Plan (`-PLAN`)** (optional explicit artifact): execution decomposition toward the specification. In some runtimes, planning may be internal to the agent platform instead of persisted as a standalone `-PLAN` document. -- **Proposal (`-PROP`)** (optional, strongly recommended): pre-decision analysis for larger/new/refactor changes. +- **Proposal (`-PROP`)** (optional, strongly recommended): ideation/debate mechanism before commitment. A proposal may be associated with a feature, a deliverable, or both, depending on scope. Opinionated naming contract: - Framework document names are opinionated around four artifact types: `-FRD`, `-PROP`, `-SPEC`, and `-PLAN`. @@ -51,6 +51,12 @@ Opinionated naming contract: - `-PROP` is optional and used when pre-decision analysis is needed. - `-PLAN` may be explicit (document) or implicit (agent-internal/runtime-native), depending on platform capability and team policy. +Proposal scope and placement guidance: +- **Feature-scoped proposal**: discusses user journeys/requirements evolution and lives with the feature context (for example `features/task-graph/task-graph-PROP.md`). +- **Deliverable-scoped proposal**: discusses implementation options/tradeoffs for a concrete deliverable and lives with the deliverable context (for example `deliverables/DLV-142/DLV-142-PROP.md`). +- **Joint proposal**: may be linked to both a feature and a deliverable when it covers both requirements and implementation tradeoffs. +- A proposal is exploratory and non-authoritative; authoritative contracts are FRDs for features and SPECs for deliverables. + Recommended supporting artifacts: - milestone-level acceptance/reference notes for grouped deliverables - deliverable-level user/release documentation as needed by the milestone @@ -64,12 +70,13 @@ Location flexibility model: Baseline structure under the configured root: - `standards/` for framework standards (single canonical standards location) -- `features/` for long-lived feature directories that contain deliverable documents over time +- `features/` for long-lived feature requirements and user-journey artifacts +- `deliverables/` for deliverable execution artifacts (`-SPEC`, optional `-PROP`, optional `-PLAN`) - optional `milestones/` for milestone-level artifacts Required directory contract: -- Each repository adopting the framework should expose both `standards/` and `features/` under its configured docs root. -- The docs root itself is flexible (`.zazz/`, `docs/`, or repository-defined), but these two subdirectories are part of the opinionated framework shape. +- Each repository adopting the framework should expose `standards/`, `features/`, and `deliverables/` under its configured docs root. +- The docs root itself is flexible (`.zazz/`, `docs/`, or repository-defined), but these subdirectories are part of the opinionated framework shape. Single-standards-location rule: - For framework clarity, standards are assumed to live in one canonical standards location under the configured docs root. @@ -83,8 +90,12 @@ Feature directory and naming contract: - stable **feature key** (slashless `kebab-case`, for example `task-graph`) used for paths and references - The feature directory name should be the feature key. - Feature requirements should be long-lived and maintained in-place (for example `task-graph-FRD.md`). -- Deliverable documents should live under the feature directory, ideally in a deliverable subdirectory, and follow framework naming (for example `deliverables/DLV-142/DLV-142-SPEC.md`, optional `deliverables/DLV-142/DLV-142-PROP.md`, optional `deliverables/DLV-142/DLV-142-PLAN.md`). -- A single feature directory may contain many deliverables across the lifecycle of that capability. + +Deliverable directory and naming contract: +- Each deliverable must have its own directory under `deliverables/` (for example `deliverables/DLV-142/`). +- Deliverable execution artifacts live in that directory: required `DLV-142-SPEC.md`, optional `DLV-142-PROP.md`, optional `DLV-142-PLAN.md`. +- Deliverable IDs should be stable and unique within the project scope. +- Deliverables are linked to features by references/metadata, not by physical nesting under `features/`. --- @@ -135,6 +146,11 @@ A deliverable may satisfy requirements from one or more features and may contrib A deliverable is strictly scoped to one repository (including a monorepo) and one dedicated git worktree. Its implementation and framework documents are versioned in that same repository. Once closed, a Deliverable SPEC is treated as frozen/immutable (except explicit amendment records). +Deliverable-to-feature linkage guidance: +- Requirement-changing deliverables (for example MVPs, enhancements, bug fixes) should link to one or more features. +- Shared supporting deliverables may link to multiple features when they satisfy multiple feature requirements. +- Chore/platform-maintenance deliverables may have no feature linkage. +- Refactor deliverables link to features when they affect user-journey requirements; pure internal refactors may remain feature-agnostic. ### Task The smallest execution unit inside a deliverable. @@ -156,6 +172,7 @@ The smallest execution unit inside a deliverable. - Milestones may include deliverables from multiple repositories. - No single deliverable is split across repositories or across multiple worktrees. - Deliverables and features are many-to-many at requirements level: one deliverable can satisfy multiple feature requirements, and one feature requirement can require multiple deliverables over time. +- Deliverables are not required to be feature-linked in all cases (for example chores); however, requirement-changing deliverables should link to relevant features. - Rework, bug-fix, and enhancement deliverables can belong to the same milestone when they are required for milestone acceptance. Milestone completion is judged at the milestone level: @@ -175,6 +192,8 @@ This flow runs per deliverable while preserving continuity with the long-lived F ### Proposal (`-PROP`, optional) Used to clarify options, rationale, tradeoffs, and constraints before committing to a Deliverable SPEC. Strongly recommended for new capabilities and major refactors. +Proposal discussions may include both user-journey requirements and technical implementation options. +Proposal output is input to decisions, not the final contract. ### Specification (`-SPEC`) Defines the desired state and acceptance contract. @@ -227,7 +246,7 @@ Zazz is intentionally iterative: Specification stewardship is shared across the lifecycle: - spec-builder creates the initial Deliverable SPEC baseline - QA refines and hardens the Deliverable SPEC through controlled updates under framework rules -- feature owners/stewards reconcile accepted outcomes into the Feature Requirements Document (`-FRD`) +- feature owners/stewards reconcile accepted outcomes into linked Feature Requirements Documents (`-FRD`) when the deliverable changes feature requirements - SPEC change history should remain explicit and traceable --- @@ -256,7 +275,7 @@ Default collaboration model: Branch and worktree naming contract: - Worktree directory name must match the branch name used for that deliverable. - Branch names must be slashless (no `/`) so branch and worktree names map cleanly to a single directory path. -- Branch/worktree naming should align with feature and deliverable identifiers used in `features/` when practical (for example `feature-id-deliverable-id`). +- Branch/worktree naming should align with feature identifiers in `features/` and deliverable identifiers in `deliverables/` when practical (for example `feature-id-deliverable-id`). Locking philosophy: - prefer runtime-native concurrency/ownership guarantees when they are stronger @@ -304,12 +323,13 @@ These checkpoints are quality controls, not convergence controls. 10. Convergence is agent-driven; human acceptance is deliberately scoped to post-convergence UAT and PR merge checkpoints. 11. Context engineering is required: least-necessary context, role-scoped context, and step-scoped context. 12. The framework is opinionated about required document types and subdirectory shape, but flexible about document root location. -13. `features/` and `standards/` are required framework directories under the configured docs root. +13. `features/`, `deliverables/`, and `standards/` are required framework directories under the configured docs root. 14. Features define user journeys and requirements (what/why); deliverables define and implement scoped specification contracts (what/how) for execution. -15. Branch/worktree naming is opinionated: worktree equals branch name, and branch names are slashless. -16. Standards are expected in one canonical location under the configured docs root. -17. Framework philosophy is implementation-agnostic. -18. Board services are optional accelerators, not mandatory prerequisites. +15. Proposals are optional ideation artifacts and may attach to features, deliverables, or both; they are not authoritative contracts. +16. Branch/worktree naming is opinionated: worktree equals branch name, and branch names are slashless. +17. Standards are expected in one canonical location under the configured docs root. +18. Framework philosophy is implementation-agnostic. +19. Board services are optional accelerators, not mandatory prerequisites. --- From 99875a3861d82e6466269bef7f4227e667c56c26 Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sat, 14 Mar 2026 16:47:46 -0400 Subject: [PATCH 06/14] Refine Zazz framework docs and add governance proposal Co-Authored-By: Oz --- .agents/skills/spec-builder-agent/SKILL.md | 2 +- README.md | 8 +- docs/{ZAZZ-FRAMEWORK.md => ZAZZ-framework.md} | 19 +++- .../project-governance-PROP.md | 98 +++++++++++++++++++ 4 files changed, 118 insertions(+), 9 deletions(-) rename docs/{ZAZZ-FRAMEWORK.md => ZAZZ-framework.md} (93%) create mode 100644 docs/features/project-governance/project-governance-PROP.md diff --git a/.agents/skills/spec-builder-agent/SKILL.md b/.agents/skills/spec-builder-agent/SKILL.md index 7377f816..7b70a8ac 100644 --- a/.agents/skills/spec-builder-agent/SKILL.md +++ b/.agents/skills/spec-builder-agent/SKILL.md @@ -576,7 +576,7 @@ export ZAZZ_SPEC_BUILDER_DEV_MODE=1 # or "true" — focus on skill iteration, ## Reference - **User guide** (for Deliverable Owner): `.agents/skills/spec-builder-agent/README.md` — How to work with the spec builder; key phrases, workflow, development mode -- **Zazz Framework**: [docs/ZAZZ-FRAMEWORK.md](../../docs/ZAZZ-FRAMEWORK.md) +- **Zazz Framework**: [docs/ZAZZ-framework.md](../../docs/ZAZZ-framework.md) - **Project standards**: `.zazz/standards/` (index.yaml + listed files) - **Example SPEC**: `.zazz/deliverables/deliverables-feature-SPEC.md` - **Planner skill**: `.agents/skills/planner-agent/SKILL.md` (consumes SPEC, uses break patterns) diff --git a/README.md b/README.md index 488acece..094552ef 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ **Stack**: Fastify API (JavaScript, ESM) · React client (Vite) · PostgreSQL 15 (Docker) · Drizzle ORM · Docker Compose -**Framework:** Zazz Board is the tool that enables teams to practice the [Zazz Framework](docs/ZAZZ-FRAMEWORK.md) — a spec-driven methodology for multi-agent software development. The framework doc defines terminology (SPEC, PLAN, deliverables, tasks), workflow stages, agent roles, and how owners (Project Owners and Deliverable Owners) and agents collaborate. +**Framework:** Zazz Board is the tool that enables teams to practice the [Zazz Framework](docs/ZAZZ-framework.md) — a spec-driven methodology for multi-agent software development. The framework doc defines terminology (SPEC, PLAN, deliverables, tasks), workflow stages, agent roles, and how owners (Project Owners and Deliverable Owners) and agents collaborate. --- @@ -52,7 +52,7 @@ ### Sample project (seed data) -Seed data includes a **sample project** (e.g. **ZAZZ**) so you can explore deliverables, task Kanban, deliverable Kanban, and the task graph with realistic data. SPECs and PLANs live in **`.zazz/deliverables/`** per the Zazz Framework; project standards live in **`.zazz/standards/`**. See [docs/ZAZZ-FRAMEWORK.md](docs/ZAZZ-FRAMEWORK.md) for the full structure. +Seed data includes a **sample project** (e.g. **ZAZZ**) so you can explore deliverables, task Kanban, deliverable Kanban, and the task graph with realistic data. SPECs and PLANs live in **`.zazz/deliverables/`** per the Zazz Framework; project standards live in **`.zazz/standards/`**. See [docs/ZAZZ-framework.md](docs/ZAZZ-framework.md) for the full structure. --- @@ -379,10 +379,10 @@ This repository is developed using the Zazz framework (dogfooding). Zazz Board i ## Documentation -- **[docs/ZAZZ-FRAMEWORK.md](docs/ZAZZ-FRAMEWORK.md)** — Full framework overview: terminology (SPEC, PLAN), workflow stages, agent roles, two kanban boards, TDD, and how to follow the methodology. +- **[docs/ZAZZ-framework.md](docs/ZAZZ-framework.md)** — Full framework overview: terminology (SPEC, PLAN), workflow stages, agent roles, two kanban boards, TDD, and how to follow the methodology. - **[AGENTS.md](./AGENTS.md)** — Primary reference for agents and developers: repo layout, full API route list, DB setup, test strategy (Vitest + PactumJS + test DB), troubleshooting. - **API docs (Swagger UI)**: **http://localhost:3030/docs** — OpenAPI 3.1, token-protected. See [API docs (Swagger)](#api-docs-swagger) and [How to access the docs with your access token](#how-to-access-the-docs-with-your-access-token). - **[api/__tests__/README.md](./api/__tests__/README.md)** — Writing and running API tests (PactumJS, helpers, safety guards). -- **`.zazz/`** — Zazz Framework structure: `project.md`, `standards/` (atomic project standards), `deliverables/` (SPECs and PLANs). See [ZAZZ-FRAMEWORK.md](docs/ZAZZ-FRAMEWORK.md) Repository Structure. +- **`.zazz/`** — Zazz Framework structure: `project.md`, `standards/` (atomic project standards), `deliverables/` (SPECs and PLANs). See [ZAZZ-framework.md](docs/ZAZZ-framework.md) Repository Structure. - **`.agents/skills/`** — Agent skills. Current release focus: `spec-builder`, `planner`, `worker`, and `zazz-board-api` (coordinator/qa skills are not current release focus). Developed here; synced to zazz-skills repo when stable. - **`.zazz/deliverables/deliverables-feature-SPEC.md`** — Full Deliverable Specification for the deliverables feature. Also in [docs/deliverables_feature_SPEC.md](docs/deliverables_feature_SPEC.md) (legacy path). diff --git a/docs/ZAZZ-FRAMEWORK.md b/docs/ZAZZ-framework.md similarity index 93% rename from docs/ZAZZ-FRAMEWORK.md rename to docs/ZAZZ-framework.md index afbd2fc8..b99d41c8 100644 --- a/docs/ZAZZ-FRAMEWORK.md +++ b/docs/ZAZZ-framework.md @@ -6,6 +6,7 @@ Zazz is a spec-driven framework with an explicit convergence model: agents itera Core concepts and capabilities: - **Desired-state convergence**: work iterates until implementation aligns with the specification. - **Feature requirements + deliverable spec contract**: each feature has a long-lived Feature Requirements Document, and each deliverable has its own Deliverable SPEC. +- **User-journey-first feature definition**: features are defined by user journeys and requirements, including human users, agents, and other systems. - **Structured document flow**: optional Proposal (`-PROP`) → required Deliverable Specification (`-SPEC`) → optional explicit Plan (`-PLAN`) → build/validate loop. - **Opinionated documentation contract**: required document types plus opinionated naming and directory structure, with flexible root location. - **Feature lifecycle model**: a product is a collection of long-lived features that evolve through multiple deliverables over time. @@ -126,6 +127,7 @@ A project may span one or more repositories. A long-lived capability object within the product/application. Features span time and can receive many deliverables (initial version, enhancements, bug fixes, and rework). Each feature has one long-lived Feature Requirements Document (`-FRD`) that evolves over time. +Feature scope is driven by user journeys and requirements (human users, agents, or external systems). Features may have dependency relationships with other features. ### Milestone @@ -263,6 +265,12 @@ Zazz commonly uses these roles: The active agent runtime (for example Claude, Codex, Warp, Gemini CLI) may provide built-in planning, orchestration, or subagent/team capabilities. The framework is role-oriented and convergence-oriented, not tied to a single runtime. +Companion skills repository: +- `zazz-skills` is the skills repository for the Zazz Framework. +- It contains reusable agent skills and API skills that implement framework workflows across environments. +- In service-assisted adoption, teams may consume skills from `zazz-skills` to standardize spec-builder/planner/worker/qa behavior and board API interactions. +- This framework document may be copied or moved into `zazz-skills`; when that happens, the philosophy and contracts remain the same, while repository-specific integration notes may differ. + --- ## Collaboration Philosophy @@ -286,6 +294,7 @@ Locking philosophy: ## Service Adoption Philosophy Zazz supports two valid adoption paths: +The framework can be adopted either alongside the Zazz Board application/tools or independently as a process-only operating model. 1. **Process-only adoption**: apply the framework philosophy and document flow without any board service. 2. **Service-assisted adoption**: add Zazz Board API/UI for orchestration, visibility, and locking support. @@ -326,10 +335,12 @@ These checkpoints are quality controls, not convergence controls. 13. `features/`, `deliverables/`, and `standards/` are required framework directories under the configured docs root. 14. Features define user journeys and requirements (what/why); deliverables define and implement scoped specification contracts (what/how) for execution. 15. Proposals are optional ideation artifacts and may attach to features, deliverables, or both; they are not authoritative contracts. -16. Branch/worktree naming is opinionated: worktree equals branch name, and branch names are slashless. -17. Standards are expected in one canonical location under the configured docs root. -18. Framework philosophy is implementation-agnostic. -19. Board services are optional accelerators, not mandatory prerequisites. +16. User journeys are the core boundary signal for features and may represent human users, agents, or other systems. +17. Branch/worktree naming is opinionated: worktree equals branch name, and branch names are slashless. +18. Standards are expected in one canonical location under the configured docs root. +19. Framework philosophy is implementation-agnostic. +20. Board services are optional accelerators, not mandatory prerequisites. +21. `zazz-skills` is the skills repository for the Zazz Framework. --- diff --git a/docs/features/project-governance/project-governance-PROP.md b/docs/features/project-governance/project-governance-PROP.md new file mode 100644 index 00000000..767ffd29 --- /dev/null +++ b/docs/features/project-governance/project-governance-PROP.md @@ -0,0 +1,98 @@ +# Project Governance - Proposal (`-PROP`) +Status: Draft +Owner: Project governance discussion +Scope: Framework and process model + +## Problem Statement +The framework now clearly separates feature requirements (`-FRD`) from deliverable execution (`-SPEC`), but project-level governance still needs clearer rules for: +- defining features in a consistent way (as user journeys + requirements), +- managing proposals as idea-iteration artifacts, +- linking features, proposals, deliverables, and milestones in a way that scales across repositories. + +## Proposal Summary +Treat the **Project** as the highest-level governance object. + +Within a project: +- **Features** capture long-lived user journeys and requirements. +- **Proposals** capture exploratory ideation and debate (feature-scoped, deliverable-scoped, or both). +- **Deliverables** are implementation increments with explicit acceptance and test-driven validation. +- **Milestones** gate feature capability progression by date using collections of deliverables. + +User-journey-first principle: +- Feature definition starts with user journeys, and those journeys define feature boundaries. +- Journeys may represent human users, agents, and other software systems/integrations. +- Feature requirements should be organized around these journeys before implementation increments are defined. + +## Goals +- Preserve project-level clarity when work spans multiple repositories. +- Keep feature discussion separate from deliverable execution discussion. +- Support proposal flexibility without making proposals authoritative contracts. +- Allow many-to-many feature↔deliverable relationships. + +## Non-Goals +- Defining API schema changes for board services. +- Locking the project to one proposal workflow forever. +- Replacing deliverables as the core execution unit. + +## Proposed Governance Model +### 1) Project as top-level context +- A project may contain many features, proposals, deliverables, and milestones. +- A project may span multiple repositories. + +### 2) Feature model +- Feature = user journey + requirement context (what/why, not implementation how). +- One long-lived FRD per feature. +- Features evolve over time through many deliverables. +- User journeys are the primary signal for splitting/merging feature boundaries. + +### 3) Proposal model +- Proposal = optional ideation mechanism, not an authoritative contract. +- Proposal scope can be: + - feature-scoped, + - deliverable-scoped, + - joint (feature + deliverable). +- Proposal content may include both user-journey debate and technical implementation tradeoffs. + +### 4) Deliverable model +- Deliverable = implementation increment with concrete acceptance criteria and a Deliverable SPEC. +- Deliverables can be: + - Feature Increment + - Shared Support Increment + - Chore/Maintenance Increment + - Refactor Increment + - Bug/Defect Fix Increment + +### 5) Milestone model +- Milestones are date-gated capability progression targets. +- Milestones group deliverables; they do not require full feature completion. + +## Relationship Rules +- Feature↔Deliverable is many-to-many at the requirements layer. +- Requirement-changing deliverables should link to one or more features. +- Shared support work may satisfy multiple features. +- Chores may be feature-agnostic. +- Refactors are feature-linked only when they affect user-journey requirements. + +## Directory Strategy (Project Docs Root) +Keep feature and deliverable discussions physically separated: +- `features/` for feature FRDs and feature-scoped proposals +- `deliverables/` for deliverable SPEC/PLAN/PROP artifacts +- `standards/` for reusable implementation standards +- optional `milestones/` for milestone artifacts + +Suggested examples: +- `features/project-governance/project-governance-FRD.md` +- `features/project-governance/project-governance-PROP.md` +- `deliverables/DLV-142/DLV-142-SPEC.md` +- `deliverables/DLV-142/DLV-142-PROP.md` (optional) + +## Acceptance Criteria +- Project-level language explicitly treats project as top-level governance context. +- Feature discussion and deliverable discussion are clearly separated in both model and directory strategy. +- Proposal semantics are explicit: optional, exploratory, and attachable to feature/deliverable/both. +- Deliverable increment subtypes are explicitly documented. +- User journeys (human, agent, system) are explicitly documented as the core driver of feature definition. + +## Open Questions +- Should project-level (cross-feature) proposals live in a dedicated `proposals/` directory, or always attach to `features/` / `deliverables/`? +- Should there be a project-level index file for feature/proposal/deliverable linking across repositories? From 85f57f1ebb2ab41f4bd7aac4614132045703809a Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sat, 14 Mar 2026 17:03:49 -0400 Subject: [PATCH 07/14] Establish QA base skill and frontend/backend specializations Co-Authored-By: Oz --- .agents/skills/planner-agent/SKILL.md | 6 +- .agents/skills/qa-agent/PR-TEMPLATE.md | 62 +++++++ .agents/skills/qa-agent/SKILL.md | 185 +++++++++++++-------- .agents/skills/qa-backend-agent/SKILL.md | 51 ++++++ .agents/skills/qa-frontend-agent/SKILL.md | 52 ++++++ .agents/skills/spec-builder-agent/SKILL.md | 2 +- 6 files changed, 282 insertions(+), 76 deletions(-) create mode 100644 .agents/skills/qa-agent/PR-TEMPLATE.md create mode 100644 .agents/skills/qa-backend-agent/SKILL.md create mode 100644 .agents/skills/qa-frontend-agent/SKILL.md diff --git a/.agents/skills/planner-agent/SKILL.md b/.agents/skills/planner-agent/SKILL.md index 89a4d53a..83e8ef3e 100644 --- a/.agents/skills/planner-agent/SKILL.md +++ b/.agents/skills/planner-agent/SKILL.md @@ -8,14 +8,14 @@ description: Creates or updates an execution-ready implementation PLAN from an a If the active agent/model provides built-in planning optimizations (plan mode, TODO/dependency tooling, structured decomposition), you MUST use them first. Then produce the PLAN in this skill’s required structure. ## Role -Produce an execution-ready PLAN from an approved SPEC for Coordinator/Worker/QA execution in a shared worktree. +Produce an execution-ready PLAN from an approved SPEC for Human Coordinator/Worker/QA execution in a shared worktree. You are planner-only in this step: DO NOT implement code. ## Framework Context - Zazz is spec-driven and test-driven. - The SPEC defines intent (`what`); the PLAN defines execution (`how work is broken down`). - The SPEC is read-only during planning. -- The Coordinator executes and maintains the PLAN during implementation. +- The human coordinator (Owner acting as coordinator) executes and maintains the PLAN during implementation. ## Companion Skill Requirement - For API work, you MUST load and follow `.agents/skills/zazz-board-api/SKILL.md`. @@ -128,7 +128,7 @@ Step-level planning rule: When the plan is instantiated as Zazz tasks: - Each non-`none` `DEPENDS_ON` must map to explicit `TASK_RELATIONS` edges (`relation_type = DEPENDS_ON`). - Do not rely on task-create payload `dependencies` alone for graph correctness. -- Include an edge-validation gate command when requested by Owner/Coordinator (typically a `psql` query against `TASK_RELATIONS`). +- Include an edge-validation gate command when requested by Owner/human coordinator (typically a `psql` query against `TASK_RELATIONS`). ## Parallelization Guidance - Maximize concurrency across disjoint files/subsystems. diff --git a/.agents/skills/qa-agent/PR-TEMPLATE.md b/.agents/skills/qa-agent/PR-TEMPLATE.md new file mode 100644 index 00000000..1c7b4c3f --- /dev/null +++ b/.agents/skills/qa-agent/PR-TEMPLATE.md @@ -0,0 +1,62 @@ +# Pull Request Template (QA) + +## Summary +- Deliverable code: +- Deliverable ID: +- Project code: +- Branch/worktree: +- SPEC: +- PLAN: + +## Acceptance Criteria Verification +- AC-1: + - Status: PASS/FAIL + - Evidence: +- AC-2: + - Status: PASS/FAIL + - Evidence: + +## Automated Test Results +### Unit Tests +- Command(s): +- Result: + +### API/Integration Tests +- Command(s): +- Result: + +### E2E Tests +- Command(s): +- Result: + +### Performance/Security Tests (if applicable) +- Command(s): +- Result: + +## Code Quality + Standards Conformance +- Standards reviewed: +- Coding patterns/conventions verified: +- Notes: + +## Rework History +- Rework task: + - Root cause: + - Resolution: + - Verification evidence: + +## Files Changed +- Added: +- Modified: +- Deleted: + +## Owner Manual Test Plan +Provide explicit steps for the owner to validate behavior manually after automated verification is complete. + +1. Preconditions/setup: +2. Step-by-step manual test actions: +3. Expected outcomes for each step: +4. Edge-case checks owner should perform: + +## QA Sign-Off +- QA status: READY_FOR_OWNER_REVIEW / NOT_READY +- Outstanding risks (if any): diff --git a/.agents/skills/qa-agent/SKILL.md b/.agents/skills/qa-agent/SKILL.md index 73bd4eee..3b725d23 100644 --- a/.agents/skills/qa-agent/SKILL.md +++ b/.agents/skills/qa-agent/SKILL.md @@ -1,12 +1,28 @@ # QA Agent Skill -**Role**: Actively finds issues and validates acceptance criteria via test-driven verification. When AC or TDD criteria are not met, messages the Coordinator to create rework tasks. Creates PR with full evidence once all criteria are satisfied. +**Role**: Actively finds issues and validates acceptance criteria via test-driven verification. When AC or TDD criteria are not met, provides rework task content to the human coordinator (Owner acting as coordinator) so rework tasks can be created and assigned. Creates PR with full evidence once all criteria are satisfied. **Agents Using This Skill**: QA (1-2 per deliverable) **Context**: Fresh context for each evaluation. Each task evaluation and the final deliverable review start with cleared context. Inputs are SPEC, PLAN, task card, and code. No context accumulation across evaluations; standard context window suffices. -**TDD emphasis**: You are designed to find issues, not just pass work through. Run all tests, verify every AC, analyze code quality. When criteria are not met, create the rework task content (full context) and message the Coordinator to create the task. The rework card must be self-contained for a fresh worker—any available worker may pick up rework. Goal: satisfy TDD and acceptance criteria before proceeding. +**TDD emphasis**: You are designed to find issues, not just pass work through. Run all tests, verify every AC, analyze code quality and standards conformance, and surface gaps in specification coverage (including missing edge cases or unclear standards interpretation). When criteria are not met, create rework task content (full context) and send it to the human coordinator for task creation. The rework card must be self-contained for a fresh worker—any available worker may pick up rework. Goal: satisfy TDD and acceptance criteria before proceeding. + +## Base Skill + Specialization Model + +This file is the **general/base QA contract**. +All QA specializations must inherit this behavior and must not weaken it. + +Specialization model: +- `qa-agent` (this file): required baseline QA process and gates +- `qa-frontend-agent`: frontend-focused specialization layered on top of this base +- `qa-backend-agent`: backend-focused specialization layered on top of this base + +Inheritance rules: +1. The base loop (verify → detect gaps → create rework → re-run with fresh QA) is mandatory for every specialization. +2. SPEC stewardship behavior (clarify with Owner, update SPEC, record change-log entries) is mandatory for every specialization. +3. PR evidence requirements and Owner Manual Test Plan requirements are mandatory for every specialization. +4. Specializations may add checks; they may not remove base checks. --- @@ -17,87 +33,110 @@ You are a QA Agent for the Zazz multi-agent deliverable framework. Your role is 1. **Find Issues**: Actively seek to find issues—run all tests, verify every AC, analyze code quality. Your role is to rigorously validate, not rubber-stamp. 2. **Test-Driven Verification**: Run all tests (unit, API, E2E, performance, security) and capture evidence. Base conclusions on test results—no AC is "verified" without test evidence. 3. **AC Verification**: Verify each AC is met by testing the implementation. When not met, document the gap. -4. **Code Quality Analysis**: Analyze code for performance, security, and best practices. -5. **Create Rework Task Content**: When AC or TDD criteria are not met, create the full rework task content and message the Coordinator to create the task. The rework task card must be self-contained—failing test, AC violated, reproduction steps, relevant files, expected vs actual—so any worker can fix it without prior context. Workers are released when ready for QA; the original worker has moved on. -6. **Interact with Deliverable Owner**: Confirm with Deliverable Owner for final acceptance that deliverable meets expectations. For AC requiring Owner sign-off (e.g., UI components), obtain sign-off before marking those AC complete. -7. **Create PR with Evidence**: Generate PR with full verification evidence and test results -8. **Release locks on sign-off**: When marking a task complete, release all file locks for that task (or its rework chain) +4. **Code Quality and Standards Analysis**: Analyze code for performance, security, best practices, and conformance with project standards/spec-defined coding patterns. +5. **Specification Gap Stewardship**: If QA analysis reveals missing edge cases, unclear requirements, or unclear standards interpretation, interact with the Owner to clarify, update the deliverable SPEC, and record the change in the deliverable SPEC change log. +6. **Create Rework Task Content**: When AC or TDD criteria are not met, create the full rework task content and send it to the human coordinator (Owner acting as coordinator) to create the task. The rework task card must be self-contained—failing test, AC violated, reproduction steps, relevant files, expected vs actual—so any worker can fix it without prior context. Workers are released when ready for QA; the original worker has moved on. +7. **Interact with Deliverable Owner**: Confirm with Deliverable Owner for final acceptance that deliverable meets expectations. For AC requiring Owner sign-off (e.g., UI components), obtain sign-off before marking those AC complete. +8. **Create PR with Evidence**: Generate PR with full verification evidence and test results, including owner manual test instructions. +9. **Release locks on sign-off**: When marking a task complete, release all file locks for that task (or its rework chain) --- ## MVP Interaction Mode (Terminal-First) During MVP: -1. Coordinate with Coordinator and Deliverable Owner primarily through terminal interaction. When Slack is supported, communicate with the Deliverable Owner through the Coordinator—do not use Slack directly. +1. Coordinate primarily with the human coordinator (Owner acting as coordinator) through terminal interaction. 2. Record key QA decisions, escalations, and outcomes to task notes/comments for traceability. 3. Use API-native task operations where available, but do not block progress on API availability if terminal direction is clear. --- +## Current Operating Model (No Coordinator Agent) + +At this stage, there is no dedicated coordinator agent. +The Deliverable Owner (or assigned human) acts as coordinator: +- launches worker agent(s)/worker teams for implementation waves +- launches a fresh QA agent for each QA pass +- creates/assigns rework tasks from QA output + +QA must treat this human coordinator as the control plane for rework and loop progression. + +--- + ## Phase 3: QA & Verification -**Design intent**: You are specifically designed to find issues and validate acceptance criteria. When criteria are not met, message the Coordinator to create rework tasks so TDD and AC are satisfied before the deliverable proceeds. +**Design intent**: You are specifically designed to find issues and validate acceptance criteria. When criteria are not met, send rework task content to the human coordinator so TDD and AC are satisfied before the deliverable proceeds. -**Input**: All tasks completed with status "COMPLETED" +**Input**: All tasks completed with status "COMPLETED" for the current execution wave. **Process**: ### Step 1: Review SPEC & Understand Requirements -1. Read .zazz/deliverables/{deliverable-name}-SPEC.md completely -2. Understand all acceptance criteria -3. Identify which AC require Deliverable Owner sign-off (e.g., UI layout, visual design)—you will need to coordinate with the Owner for these -4. Understand all test requirements -5. Note performance/security thresholds +1. Read `.zazz/deliverables/{deliverable-name}-SPEC.md` completely. +2. Understand all acceptance criteria. +3. Identify which AC require Deliverable Owner sign-off (e.g., UI layout, visual design)—you will need to coordinate with the Owner for these. +4. Understand all test requirements. +5. Note performance/security thresholds. +6. Read applicable standards docs (`.zazz/standards/` or configured docs-root standards) and identify required coding patterns/conventions for this deliverable. ### Step 2: Verify Each Acceptance Criterion For each AC in SPEC: -1. Test the feature/code against the AC statement -2. Document how you verified it -3. Capture evidence (test results, screenshots, logs) +1. Test the feature/code against the AC statement. +2. Document how you verified it. +3. Capture evidence (test results, screenshots, logs). 4. **Owner sign-off required:** If the AC is marked as requiring Deliverable Owner sign-off (e.g., UI layout, visual design, interaction feel), coordinate with the Owner to obtain sign-off before marking verified. Do not mark such AC complete without Owner confirmation. -5. Mark as ✓ verified or ✗ failed - -**When all AC verified for a task:** Mark task complete and release all file locks for that task (or its rework chain). +5. Mark as ✓ verified or ✗ failed. + +### Step 2.5: Resolve Specification Gaps (When Found) +If QA discovers specification gaps (for example missing edge cases, ambiguous behavior, unclear standards interpretation): +1. Interact with the Owner to clarify intended behavior. +2. Update the deliverable SPEC to reflect agreed clarification. +3. Add explicit entries to the deliverable SPEC change log describing: + - what changed + - why it changed + - which QA finding triggered the change +4. Ensure rework tasks and verification reflect the updated SPEC. ### Step 3: Run All Specified Tests -1. **Unit Tests**: Run complete unit test suite - - Capture pass/fail counts - - Record execution time - - Document any failures -2. **API Tests**: Run API integration test suite - - Capture response codes and times - - Document any failures -3. **E2E Tests**: Run end-to-end test suite - - Capture user flow results - - Document any failures +1. **Unit Tests**: Run complete unit test suite. + - Capture pass/fail counts. + - Record execution time. + - Document any failures. +2. **API Tests**: Run API integration test suite. + - Capture response codes and times. + - Document any failures. +3. **E2E Tests**: Run end-to-end test suite. + - Capture user flow results. + - Document any failures. 4. **Performance Tests** (if specified): - - Measure against thresholds in SPEC - - Document response times, throughput, memory + - Measure against thresholds in SPEC. + - Document response times, throughput, memory. 5. **Security Tests** (if specified): - - Run security scanning - - Document any vulnerabilities + - Run security scanning. + - Document any vulnerabilities. ### Step 4: Analyze Code Quality -1. **Performance**: Check response times, memory usage, database queries -2. **Security**: Identify vulnerabilities, auth/authz gaps -3. **Best Practices**: Check error handling, logging, code patterns +1. **Performance**: Check response times, memory usage, database queries. +2. **Security**: Identify vulnerabilities, auth/authz gaps. +3. **Best Practices**: Check error handling, logging, code patterns. +4. **Standards Conformance**: Verify implementation follows referenced project standards and spec-documented coding patterns/conventions. --- ## Handling Issues -When AC or TDD criteria are not met, **create the rework task content** and message the Coordinator to create the task. The QA agent authors the rework task card so it contains all context a fresh worker needs: failing test, AC violated, reproduction steps, relevant files, expected vs actual behavior, suggested fix (optional). Workers are released when ready for QA; any available worker may pick up rework. The Coordinator creates the task in the plan and task graph. Do not mark the deliverable or task complete until rework satisfies TDD and AC. +When AC or TDD criteria are not met, **create the rework task content** and send it to the human coordinator to create/assign rework tasks. The QA agent authors the rework task card so it contains all context a fresh worker needs: failing test, AC violated, reproduction steps, relevant files, expected vs actual behavior, suggested fix (optional). Workers are released when ready for QA; any available worker may pick up rework. The human coordinator creates tasks in the plan/task graph and launches the next worker wave. Do not mark the deliverable or task complete until rework satisfies TDD and AC. ### Simple Isolated Issues (affects 1-2 files, low risk, clear fix) **Rework Task Numbering**: - If original task is `2.3`, first rework is `2.3.1`, second is `2.3.2`, etc. -- This creates a clear audit trail of rework iterations for each task -- Allows analysis of which tasks needed multiple iterations +- This creates a clear audit trail of rework iterations for each task. +- Allows analysis of which tasks needed multiple iterations. **Steps**: -1. Create the rework task content (full context for a fresh worker). Message Coordinator (terminal in MVP) with the rework task content. Include: +1. Create the rework task content (full context for a fresh worker). Send to human coordinator (terminal in MVP) with the rework task content. Include: - **Task ID**: Hierarchical numbering (e.g., `2.3.1` for first rework of task `2.3`) - **Title**: Clear description of issue - **Failing Test**: The test that demonstrates the issue (TDD: rework is verified when this test passes) @@ -107,37 +146,39 @@ When AC or TDD criteria are not met, **create the rework task content** and mess - **Relevant Files**: Paths to files that need changes - **Expected vs Actual**: What should happen vs what happens - **Suggested Fix** (optional): Your diagnosis -2. Coordinator creates the rework task in the plan and task graph -3. Wait for workers to fix -4. Rerun relevant tests and verify fix satisfies TDD and AC +2. Human coordinator creates and assigns the rework task in the plan/task graph. +3. Human coordinator launches worker/worker-team rework wave. +4. Human coordinator launches a fresh QA agent for next verification pass. +5. Rerun relevant tests and verify fixes satisfy TDD and AC. ### Complex Issues (2+ fixes, architectural impact, cross-module failures) -1. Prepare detailed escalation to Coordinator: +1. Prepare detailed escalation to human coordinator: - Which AC are not met - Which tests are failing and why - Root cause analysis - Impact on other components -2. Escalate via terminal interaction (MVP), then sync escalation summary to task notes/comments -3. Wait for Coordinator to create rework sub-plan -4. Verify each rework fix as it's completed +2. Escalate via terminal interaction (MVP), then sync escalation summary to task notes/comments. +3. Wait for human coordinator to create rework sub-plan and launch worker wave. +4. Verify each rework fix as it's completed. --- ## Rework Loop Repeat until all AC met and all tests passing: -1. QA finds issue (AC failed or test failed) -2. QA creates rework task content (full context); Coordinator creates the task -3. Coordinator creates rework task; workers execute -4. QA verifies fix passes tests and satisfies AC +1. QA finds issue (AC failed or test failed). +2. QA creates rework task content (full context); human coordinator creates/assigns tasks. +3. Human coordinator launches worker wave to execute rework tasks. +4. Human coordinator launches a fresh QA agent for the next full verification pass. +5. QA verifies fixes pass tests and satisfy AC. --- ## Phase 4: PR Creation -**Input**: All AC verified, all tests passing, Deliverable Owner confirmed satisfied +**Input**: All AC verified, all tests passing, Deliverable Owner confirmed satisfied. **Process**: @@ -145,18 +186,17 @@ Repeat until all AC met and all tests passing: ``` git status → "working tree clean" ``` - -2. Create PR with full verification evidence using `PR-TEMPLATE.md`: +2. Create PR with full verification evidence using `.agents/skills/qa-agent/PR-TEMPLATE.md`: - **Deliverable ID** and project code - **AC Verification**: Each AC with verification evidence - **Test Results**: Complete test results (pass counts, execution times) - **Code Quality**: Performance/security findings + - **Standards Conformance**: Evidence implementation follows required project standards/spec patterns - **Rework History**: All rework cycles with root causes - **Files Changed**: New, modified, deleted files + - **Owner Manual Test Plan**: explicit manual steps and expected outcomes for owner validation - **QA Sign-off**: Your approval for Deliverable Owner review - -3. Update deliverable status to "IN_REVIEW" - +3. Update deliverable status to `IN_REVIEW`. 4. Log to `.zazz/audit.log`: ``` [timestamp] [QA] PR created for {deliverable-id} with full verification evidence @@ -170,12 +210,13 @@ Repeat until all AC met and all tests passing: - [ ] Verify each AC against implementation - [ ] Run all tests (unit, API, E2E, perf, security) - [ ] Document all test evidence -- [ ] Analyze code quality +- [ ] Analyze code quality and standards conformance +- [ ] Clarify specification gaps with owner and update SPEC + SPEC change log when required - [ ] Create rework tasks with test evidence -- [ ] Escalate complex issues to Coordinator +- [ ] Escalate complex issues to human coordinator - [ ] Sync key terminal escalations/decisions to task notes/comments - [ ] Interact with Deliverable Owner to confirm expectations -- [ ] Create PR with full verification evidence +- [ ] Create PR with full verification evidence and owner manual test plan - [ ] Update deliverable status to IN_REVIEW - [ ] Update heartbeat every 10 seconds @@ -184,12 +225,14 @@ Repeat until all AC met and all tests passing: ## Best Practices 1. **Test-Driven Verification**: Base all conclusions on test evidence, not assumptions. Rework tasks must include the failing test that demonstrates the issue. -2. **Clear Documentation**: Document how you verified each AC -3. **Root Cause Analysis**: When creating rework tasks, identify root cause and include failing test -4. **Deliverable Owner Interaction**: Confirm with Deliverable Owner that deliverable meets expectations -5. **Evidence Capture**: Keep all test results, logs, and screenshots for PR -6. **AC Mapping**: Link rework tasks back to specific AC failures -7. **Complete Before PR**: Don't create PR until all AC verified and all tests passing +2. **Clear Documentation**: Document how you verified each AC. +3. **Root Cause Analysis**: When creating rework tasks, identify root cause and include failing test. +4. **Deliverable Owner Interaction**: Confirm with Deliverable Owner that deliverable meets expectations. +5. **Evidence Capture**: Keep all test results, logs, and screenshots for PR. +6. **AC Mapping**: Link rework tasks back to specific AC failures. +7. **Standards Enforcement**: Verify and document compliance with project standards/spec coding patterns. +8. **Fresh QA Cycles**: Each rework cycle should be re-validated by a fresh QA agent context. +9. **Complete Before PR**: Don't create PR until all AC verified and all tests passing. --- @@ -207,8 +250,6 @@ export AGENT_HEARTBEAT_INTERVAL_SEC=10 --- -## Example Workflow +## PR Template -See `.agents/skills/qa-agent/examples/` for: -- example-rework-plan.md - Sample rework task with test evidence -- example-pr.md - Sample PR with full verification evidence +Use `.agents/skills/qa-agent/PR-TEMPLATE.md` as the canonical PR body structure. diff --git a/.agents/skills/qa-backend-agent/SKILL.md b/.agents/skills/qa-backend-agent/SKILL.md new file mode 100644 index 00000000..176bfba5 --- /dev/null +++ b/.agents/skills/qa-backend-agent/SKILL.md @@ -0,0 +1,51 @@ +# QA Backend Agent Skill + +## Purpose +Backend specialization of the base `qa-agent` skill. +Use this when a deliverable has API, service, schema, data-integrity, auth/authz, or backend performance/security scope. + +## Required Base Behavior +You MUST follow `.agents/skills/qa-agent/SKILL.md` as the governing base contract. +This specialization adds backend checks; it does not replace the base QA loop. + +## Specialization Focus Areas + +### 1) API Contract Validation +- Validate routes against SPEC-defined behavior and status semantics. +- Validate happy-path, edge-case, and negative-path behavior. +- Validate request validation and error response structure. + +### 2) Auth/Authz + Security Controls +- Validate authentication and authorization behavior for relevant routes. +- Validate tenant/project boundary controls where applicable. +- Validate input-handling and obvious security-risk paths. + +### 3) Data Integrity + Persistence +- Validate schema and data mutations match SPEC intent. +- Validate transactional integrity/idempotency where applicable. +- Validate migration/seed/runtime data assumptions impacted by the change. + +### 4) Backend Performance/Operational Quality +- Validate performance thresholds defined by SPEC. +- Validate error handling and observability behaviors expected by standards. +- Validate no regressions in critical service flows. + +### 5) Backend Code Quality/Standards +- Validate conformance with backend standards and architecture patterns. +- Validate service boundaries, layering, and data-access patterns. +- Flag anti-patterns with concrete remediation in rework tasks. + +## Rework Task Requirements (Backend) +When deficiencies are found, rework tasks must include: +- failing/insufficient backend test evidence +- impacted AC/API contract mapping +- reproduction steps (including payload examples when relevant) +- expected vs actual backend behavior +- affected files/services/routes/schema objects + +## PR Evidence Additions (Backend) +In addition to base QA PR requirements, include: +- API contract verification summary +- auth/authz verification summary +- data-integrity verification notes +- owner manual backend validation steps (API-level smoke checks and expected outcomes) diff --git a/.agents/skills/qa-frontend-agent/SKILL.md b/.agents/skills/qa-frontend-agent/SKILL.md new file mode 100644 index 00000000..1a35a224 --- /dev/null +++ b/.agents/skills/qa-frontend-agent/SKILL.md @@ -0,0 +1,52 @@ +# QA Frontend Agent Skill + +## Purpose +Frontend specialization of the base `qa-agent` skill. +Use this when a deliverable has meaningful UI/UX, client-state, browser-interaction, accessibility, or frontend integration scope. + +## Required Base Behavior +You MUST follow `.agents/skills/qa-agent/SKILL.md` as the governing base contract. +This specialization adds frontend checks; it does not replace the base QA loop. + +## Specialization Focus Areas + +### 1) UI/UX Behavior Validation +- Validate core user journeys against the deliverable SPEC. +- Validate loading, empty, error, and success states. +- Validate interactive behavior (forms, modals, navigation, drag/drop where applicable). +- Validate responsiveness for required breakpoints/viewports. + +### 2) Accessibility Baseline +- Validate keyboard-only navigation for affected workflows. +- Validate focus order/visibility for changed UI paths. +- Validate semantic structure/labels for interactive elements. +- Record accessibility risks explicitly when full compliance is out of scope. + +### 3) Frontend Data/State Integrity +- Validate client-side state transitions and cache invalidation behavior. +- Validate request/response error handling and user feedback. +- Validate optimistic update/rollback behavior when relevant. + +### 4) Cross-Browser/Platform Notes +- Validate required browser targets (per project standards/spec). +- Record what was tested and what was not tested. + +### 5) Frontend Code Quality/Standards +- Validate conformance with frontend standards and patterns from project docs. +- Validate component, hook, and routing patterns for consistency. +- Flag anti-patterns with concrete remediation in rework tasks. + +## Rework Task Requirements (Frontend) +When deficiencies are found, rework tasks must include: +- failing/insufficient frontend test evidence +- affected user journey/AC mapping +- reproduction steps (with viewport/browser context when relevant) +- expected vs actual UI behavior +- affected files/components + +## PR Evidence Additions (Frontend) +In addition to base QA PR requirements, include: +- UI journey verification notes +- accessibility verification notes +- browser/viewport coverage summary +- owner manual UI test steps with clear expected outcomes diff --git a/.agents/skills/spec-builder-agent/SKILL.md b/.agents/skills/spec-builder-agent/SKILL.md index 7b70a8ac..ec7fa894 100644 --- a/.agents/skills/spec-builder-agent/SKILL.md +++ b/.agents/skills/spec-builder-agent/SKILL.md @@ -212,7 +212,7 @@ Elicit an explicit **Definition of Done** for the deliverable as a whole. This g - "All AC satisfied? All tests passing? PR merged? Documentation updated?" - "Any manual verification steps? Sign-offs?" -Document this as a checklist. The Planner and Coordinator use it to know when to stop. +Document this as a checklist. The Planner and human coordinator (Owner acting as coordinator) use it to know when to stop. ### 5. Explicit Tests (TDD) From e9ad1d183b6730186ef9e7f522b744a74b7d7f6e Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sat, 14 Mar 2026 17:13:33 -0400 Subject: [PATCH 08/14] Refine framework intro to feature and milestone model Co-Authored-By: Oz --- docs/ZAZZ-framework.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ZAZZ-framework.md b/docs/ZAZZ-framework.md index b99d41c8..72af6a1c 100644 --- a/docs/ZAZZ-framework.md +++ b/docs/ZAZZ-framework.md @@ -1,5 +1,5 @@ # The Zazz Framework -Zazz is a spec-driven framework with an explicit convergence model: agents iteratively refine the specification and implementation until gaps are resolved and the deliverable satisfies its finalized Deliverable SPEC. +Zazz is a feature- and milestone-oriented, spec-driven framework for delivering software with humans and AI agents, where long-lived feature requirements are implemented through deliverables and validated through iterative QA convergence. ## Framework Introduction (At a Glance) From 0aadc75d1dd1a02d58ba70f1e5f3b266fd191b43 Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sun, 15 Mar 2026 09:39:42 -0400 Subject: [PATCH 09/14] docs: add codex multi-agent policy and repo config - add phase-1 Codex policy doc and role configs\n- enable repo-level .codex multi-agent settings for worker/qa/monitor\n- switch framework references to canonical zazz-skills GitHub doc and remove local duplicate\n\nCo-Authored-By: Oz --- .agents/skills/spec-builder-agent/SKILL.md | 2 +- .codex/config.toml | 24 ++ .codex/roles/monitor.toml | 3 + .codex/roles/qa.toml | 6 + .codex/roles/worker.toml | 6 + .gitignore | 5 +- .zazz/project.md | 2 +- README.md | 8 +- docs/ZAZZ-framework.md | 349 --------------------- docs/codex-multi-agent-policy.md | 77 +++++ docs/zazz-skills.md | 2 + 11 files changed, 128 insertions(+), 356 deletions(-) create mode 100644 .codex/config.toml create mode 100644 .codex/roles/monitor.toml create mode 100644 .codex/roles/qa.toml create mode 100644 .codex/roles/worker.toml delete mode 100644 docs/ZAZZ-framework.md create mode 100644 docs/codex-multi-agent-policy.md diff --git a/.agents/skills/spec-builder-agent/SKILL.md b/.agents/skills/spec-builder-agent/SKILL.md index ec7fa894..483fab80 100644 --- a/.agents/skills/spec-builder-agent/SKILL.md +++ b/.agents/skills/spec-builder-agent/SKILL.md @@ -576,7 +576,7 @@ export ZAZZ_SPEC_BUILDER_DEV_MODE=1 # or "true" — focus on skill iteration, ## Reference - **User guide** (for Deliverable Owner): `.agents/skills/spec-builder-agent/README.md` — How to work with the spec builder; key phrases, workflow, development mode -- **Zazz Framework**: [docs/ZAZZ-framework.md](../../docs/ZAZZ-framework.md) +- **Zazz Framework**: [zazz-framework.md](https://github.com/zazzcode/zazz-skills/blob/main/zazz-framework.md) - **Project standards**: `.zazz/standards/` (index.yaml + listed files) - **Example SPEC**: `.zazz/deliverables/deliverables-feature-SPEC.md` - **Planner skill**: `.agents/skills/planner-agent/SKILL.md` (consumes SPEC, uses break patterns) diff --git a/.codex/config.toml b/.codex/config.toml new file mode 100644 index 00000000..fa543aed --- /dev/null +++ b/.codex/config.toml @@ -0,0 +1,24 @@ +# Repository-scoped Codex defaults for multi-agent execution. +# Phase 1 scope: Worker + QA (+ optional Monitor). + +[features] +multi_agent = true + +[agents] +max_threads = 4 +max_depth = 2 + +[agents.worker] +description = "Implements assigned tasks with scoped file ownership and required automated tests." +config_file = ".codex/roles/worker.toml" +nickname_candidates = ["worker-a", "worker-b", "worker-c"] + +[agents.qa] +description = "Validates acceptance criteria and can create rework tasks and spec updates via API." +config_file = ".codex/roles/qa.toml" +nickname_candidates = ["qa-a", "qa-b"] + +[agents.monitor] +description = "Optional read-only progress and blocker monitor." +config_file = ".codex/roles/monitor.toml" +nickname_candidates = ["monitor-a"] diff --git a/.codex/roles/monitor.toml b/.codex/roles/monitor.toml new file mode 100644 index 00000000..9afa902c --- /dev/null +++ b/.codex/roles/monitor.toml @@ -0,0 +1,3 @@ +approval_policy = "on-request" +sandbox_mode = "read-only" +model_reasoning_effort = "low" diff --git a/.codex/roles/qa.toml b/.codex/roles/qa.toml new file mode 100644 index 00000000..f8ec0f29 --- /dev/null +++ b/.codex/roles/qa.toml @@ -0,0 +1,6 @@ +approval_policy = "on-request" +sandbox_mode = "workspace-write" +model_reasoning_effort = "high" + +[sandbox_workspace_write] +network_access = true diff --git a/.codex/roles/worker.toml b/.codex/roles/worker.toml new file mode 100644 index 00000000..20f89d43 --- /dev/null +++ b/.codex/roles/worker.toml @@ -0,0 +1,6 @@ +approval_policy = "on-request" +sandbox_mode = "workspace-write" +model_reasoning_effort = "medium" + +[sandbox_workspace_write] +network_access = false diff --git a/.gitignore b/.gitignore index f1e0dab8..0b20ffbe 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,10 @@ api/.env.local !.vscode/extensions.json .idea .DS_Store -.codex/ +.codex/* +!.codex/config.toml +!.codex/roles/ +!.codex/roles/*.toml project-page-screenshot.png *.suo *.ntvs* diff --git a/.zazz/project.md b/.zazz/project.md index 24120604..32e1529f 100644 --- a/.zazz/project.md +++ b/.zazz/project.md @@ -2,7 +2,7 @@ ## What is this project? -Zazz Board is a Kanban-style orchestration app for coordinating AI agents and owners on software deliverables. It is the tool that enables teams to practice the Zazz Framework—a spec-driven methodology for multi-agent software development. +Zazz Board is a Kanban-style orchestration app for coordinating AI agents and owners on software deliverables. It is the tool that enables teams to practice the [Zazz Framework](https://github.com/zazzcode/zazz-skills/blob/main/zazz-framework.md)—a spec-driven methodology for multi-agent software development. ## What problem does it solve? diff --git a/README.md b/README.md index 094552ef..6f147019 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ **Stack**: Fastify API (JavaScript, ESM) · React client (Vite) · PostgreSQL 15 (Docker) · Drizzle ORM · Docker Compose -**Framework:** Zazz Board is the tool that enables teams to practice the [Zazz Framework](docs/ZAZZ-framework.md) — a spec-driven methodology for multi-agent software development. The framework doc defines terminology (SPEC, PLAN, deliverables, tasks), workflow stages, agent roles, and how owners (Project Owners and Deliverable Owners) and agents collaborate. +**Framework:** Zazz Board is the tool that enables teams to practice the [Zazz Framework](https://github.com/zazzcode/zazz-skills/blob/main/zazz-framework.md) — a spec-driven methodology for multi-agent software development. The framework doc defines terminology (SPEC, PLAN, deliverables, tasks), workflow stages, agent roles, and how owners (Project Owners and Deliverable Owners) and agents collaborate. --- @@ -52,7 +52,7 @@ ### Sample project (seed data) -Seed data includes a **sample project** (e.g. **ZAZZ**) so you can explore deliverables, task Kanban, deliverable Kanban, and the task graph with realistic data. SPECs and PLANs live in **`.zazz/deliverables/`** per the Zazz Framework; project standards live in **`.zazz/standards/`**. See [docs/ZAZZ-framework.md](docs/ZAZZ-framework.md) for the full structure. +Seed data includes a **sample project** (e.g. **ZAZZ**) so you can explore deliverables, task Kanban, deliverable Kanban, and the task graph with realistic data. SPECs and PLANs live in **`.zazz/deliverables/`** per the Zazz Framework; project standards live in **`.zazz/standards/`**. See the canonical [zazz-framework.md](https://github.com/zazzcode/zazz-skills/blob/main/zazz-framework.md) for the full structure. --- @@ -379,10 +379,10 @@ This repository is developed using the Zazz framework (dogfooding). Zazz Board i ## Documentation -- **[docs/ZAZZ-framework.md](docs/ZAZZ-framework.md)** — Full framework overview: terminology (SPEC, PLAN), workflow stages, agent roles, two kanban boards, TDD, and how to follow the methodology. +- **[zazz-framework.md (canonical)](https://github.com/zazzcode/zazz-skills/blob/main/zazz-framework.md)** — Full framework overview: terminology (SPEC, PLAN), workflow stages, agent roles, two kanban boards, TDD, and how to follow the methodology. - **[AGENTS.md](./AGENTS.md)** — Primary reference for agents and developers: repo layout, full API route list, DB setup, test strategy (Vitest + PactumJS + test DB), troubleshooting. - **API docs (Swagger UI)**: **http://localhost:3030/docs** — OpenAPI 3.1, token-protected. See [API docs (Swagger)](#api-docs-swagger) and [How to access the docs with your access token](#how-to-access-the-docs-with-your-access-token). - **[api/__tests__/README.md](./api/__tests__/README.md)** — Writing and running API tests (PactumJS, helpers, safety guards). -- **`.zazz/`** — Zazz Framework structure: `project.md`, `standards/` (atomic project standards), `deliverables/` (SPECs and PLANs). See [ZAZZ-framework.md](docs/ZAZZ-framework.md) Repository Structure. +- **`.zazz/`** — Zazz Framework structure: `project.md`, `standards/` (atomic project standards), `deliverables/` (SPECs and PLANs). See [zazz-framework.md](https://github.com/zazzcode/zazz-skills/blob/main/zazz-framework.md) for repository structure guidance. - **`.agents/skills/`** — Agent skills. Current release focus: `spec-builder`, `planner`, `worker`, and `zazz-board-api` (coordinator/qa skills are not current release focus). Developed here; synced to zazz-skills repo when stable. - **`.zazz/deliverables/deliverables-feature-SPEC.md`** — Full Deliverable Specification for the deliverables feature. Also in [docs/deliverables_feature_SPEC.md](docs/deliverables_feature_SPEC.md) (legacy path). diff --git a/docs/ZAZZ-framework.md b/docs/ZAZZ-framework.md deleted file mode 100644 index 72af6a1c..00000000 --- a/docs/ZAZZ-framework.md +++ /dev/null @@ -1,349 +0,0 @@ -# The Zazz Framework -Zazz is a feature- and milestone-oriented, spec-driven framework for delivering software with humans and AI agents, where long-lived feature requirements are implemented through deliverables and validated through iterative QA convergence. - -## Framework Introduction (At a Glance) - -Core concepts and capabilities: -- **Desired-state convergence**: work iterates until implementation aligns with the specification. -- **Feature requirements + deliverable spec contract**: each feature has a long-lived Feature Requirements Document, and each deliverable has its own Deliverable SPEC. -- **User-journey-first feature definition**: features are defined by user journeys and requirements, including human users, agents, and other systems. -- **Structured document flow**: optional Proposal (`-PROP`) → required Deliverable Specification (`-SPEC`) → optional explicit Plan (`-PLAN`) → build/validate loop. -- **Opinionated documentation contract**: required document types plus opinionated naming and directory structure, with flexible root location. -- **Feature lifecycle model**: a product is a collection of long-lived features that evolve through multiple deliverables over time. -- **Milestone-centered delivery**: milestones group related deliverables into date-driven capability objectives. -- **Repository/worktree boundary**: each deliverable is executed in exactly one repository (including a monorepo) and one dedicated worktree. -- **Role and context decomposition**: role-scoped and step-scoped context reduces noise and improves agent focus. -- **Iterative spec stewardship**: spec-builder initializes Deliverable SPEC baselines; QA validates, surfaces gaps, and drives rule-governed refinements. -- **Flexible runtime model**: supports single-agent, multi-agent, and subagent orchestration depending on runtime capability. -- **Automation-first quality model**: maximize agent-driven convergence, then apply human quality gates at UAT and PR merge. -- **Optional service integration**: Zazz Board services are optional accelerators, not prerequisites for adopting the framework. - -## Document Scope - -This document defines the **philosophy and operating model** of Zazz. -It is not an implementation guide. - -Specifically, this document does not define: -- API route contracts -- storage schemas -- tool-specific command syntax -- execution scripts - -Those implementation details belong in skills, standards, API docs, and repository-level technical documentation. - ---- - -## Documentation Architecture Philosophy - -Zazz is opinionated about **what documents must exist** and **how they relate**. -Zazz is flexible about **where those documents are stored** in a repository. - -Required document contract: -- **Standards set** (required): shared conventions that govern implementation and validation. -- **Feature Requirements Document (`-FRD`)** (required per feature): long-lived, mutable user-journey and requirement contract for the feature over time. -- **Deliverable Specification (`-SPEC`)** (required per deliverable): execution contract for one deliverable. -- **Plan (`-PLAN`)** (optional explicit artifact): execution decomposition toward the specification. In some runtimes, planning may be internal to the agent platform instead of persisted as a standalone `-PLAN` document. -- **Proposal (`-PROP`)** (optional, strongly recommended): ideation/debate mechanism before commitment. A proposal may be associated with a feature, a deliverable, or both, depending on scope. - -Opinionated naming contract: -- Framework document names are opinionated around four artifact types: `-FRD`, `-PROP`, `-SPEC`, and `-PLAN`. -- `-FRD` is required for features and captures user journeys + requirements (what/why, not how). -- `-SPEC` is reserved for deliverables. -- `-PROP` is optional and used when pre-decision analysis is needed. -- `-PLAN` may be explicit (document) or implicit (agent-internal/runtime-native), depending on platform capability and team policy. - -Proposal scope and placement guidance: -- **Feature-scoped proposal**: discusses user journeys/requirements evolution and lives with the feature context (for example `features/task-graph/task-graph-PROP.md`). -- **Deliverable-scoped proposal**: discusses implementation options/tradeoffs for a concrete deliverable and lives with the deliverable context (for example `deliverables/DLV-142/DLV-142-PROP.md`). -- **Joint proposal**: may be linked to both a feature and a deliverable when it covers both requirements and implementation tradeoffs. -- A proposal is exploratory and non-authoritative; authoritative contracts are FRDs for features and SPECs for deliverables. - -Recommended supporting artifacts: -- milestone-level acceptance/reference notes for grouped deliverables -- deliverable-level user/release documentation as needed by the milestone -- feature-level capability notes when helpful for long-running feature history - -Location flexibility model: -- The framework supports either `.zazz/` or `docs/` (or another repository-defined location) as the documentation root. -- A single configured root should be used per repository for consistency. -- Agents should resolve framework documents from a configured root path, for example `ZAZZ_DOCS_ROOT`. -- Example: one project may store framework docs under `.zazz/` while another stores them under `docs/`; both remain framework-compliant. - -Baseline structure under the configured root: -- `standards/` for framework standards (single canonical standards location) -- `features/` for long-lived feature requirements and user-journey artifacts -- `deliverables/` for deliverable execution artifacts (`-SPEC`, optional `-PROP`, optional `-PLAN`) -- optional `milestones/` for milestone-level artifacts - -Required directory contract: -- Each repository adopting the framework should expose `standards/`, `features/`, and `deliverables/` under its configured docs root. -- The docs root itself is flexible (`.zazz/`, `docs/`, or repository-defined), but these subdirectories are part of the opinionated framework shape. - -Single-standards-location rule: -- For framework clarity, standards are assumed to live in one canonical standards location under the configured docs root. -- The framework does not require per-subdirectory or per-section standards partitioning. - -Feature directory and naming contract: -- Each new feature must have its own directory under `features/`. -- That directory is the canonical location for managing the feature over time (initial delivery, QA-driven rework, enhancements, and bug fixes). -- Feature identity should include: - - human-readable **feature name** (for example `Task Graph`) - - stable **feature key** (slashless `kebab-case`, for example `task-graph`) used for paths and references -- The feature directory name should be the feature key. -- Feature requirements should be long-lived and maintained in-place (for example `task-graph-FRD.md`). - -Deliverable directory and naming contract: -- Each deliverable must have its own directory under `deliverables/` (for example `deliverables/DLV-142/`). -- Deliverable execution artifacts live in that directory: required `DLV-142-SPEC.md`, optional `DLV-142-PROP.md`, optional `DLV-142-PLAN.md`. -- Deliverable IDs should be stable and unique within the project scope. -- Deliverables are linked to features by references/metadata, not by physical nesting under `features/`. - ---- - -## Core Philosophy - -- Zazz is designed to converge deliverables toward a declared desired state. -- Feature requirements define long-duration user journeys and capability intent; Deliverable SPEC defines execution scope for one increment. -- Tests define the executable verification contract. -- Proposal, planning, execution, QA, and rework are convergence mechanisms. -- Products are treated as collections of evolving features; deliverables are bounded increments that implement, improve, or repair those features. -- Convergence is agent-driven and rule-driven. -- The final deliverable must fully reflect its finalized Deliverable SPEC. -- Context engineering is a core design goal: provide agents only the context needed for the current decision/work step. -- Role decomposition and step decomposition exist partly to bound context scope and reduce unnecessary prompt/context load. - ---- - -## Core Entities - -Zazz organizes work using: -- execution hierarchy: `Project -> Deliverable -> Task` -- cross-cutting coordination objects: `Feature` and `Milestone` - -### Project -The long-lived product/application context. -A project may span one or more repositories. -### Feature -A long-lived capability object within the product/application. -Features span time and can receive many deliverables (initial version, enhancements, bug fixes, and rework). -Each feature has one long-lived Feature Requirements Document (`-FRD`) that evolves over time. -Feature scope is driven by user journeys and requirements (human users, agents, or external systems). -Features may have dependency relationships with other features. - -### Milestone -A first-class, date-driven grouping of deliverables, conceptually similar to a Scrum initiative (or grouped epics). - -A milestone exists to represent a larger capability or release objective that usually spans multiple deliverables. -A milestone may group deliverables from multiple features and from different repositories within the same project. - -A milestone has: -- an explicit completion/release date -- milestone-level acceptance criteria -- potential cross-deliverable outputs (for example user documentation or release notes) - -### Deliverable -A bounded unit of value completed by an agent group, with its own Deliverable SPEC, optional explicit PLAN, and acceptance criteria. -A deliverable is typically one incremental change to a feature (for example initial implementation, enhancement, bug fix, refactor, or QA-driven rework). -A deliverable may satisfy requirements from one or more features and may contribute to one or more milestone objectives. -A deliverable is strictly scoped to one repository (including a monorepo) and one dedicated git worktree. -Its implementation and framework documents are versioned in that same repository. -Once closed, a Deliverable SPEC is treated as frozen/immutable (except explicit amendment records). -Deliverable-to-feature linkage guidance: -- Requirement-changing deliverables (for example MVPs, enhancements, bug fixes) should link to one or more features. -- Shared supporting deliverables may link to multiple features when they satisfy multiple feature requirements. -- Chore/platform-maintenance deliverables may have no feature linkage. -- Refactor deliverables link to features when they affect user-journey requirements; pure internal refactors may remain feature-agnostic. - -### Task -The smallest execution unit inside a deliverable. - ---- - -## Feature, Milestone, and Deliverable Relationship Philosophy - -- Features are long-lived capability contexts. -- Features are cross-cutting objects that span multiple deliverables and can span multiple milestones over time. -- Deliverables are bounded execution units within a feature lifecycle. -- A feature is implemented and evolved through multiple deliverables over time. -- Milestones are grouping and coordination constructs, not just labels. -- Milestones may contain deliverables from one or many features. -- Milestones represent capability progression/maturation targets for features by a date; deliverables are the implementation increments used to reach those targets. -- A milestone is not required to represent a fully completed feature; it may represent an intermediate grouping of deliverables toward broader feature completion. -- Deliverables may be sequenced in series (dependency-gated) or run in parallel (independent). -- Most milestone structures are mixed dependency graphs. -- Milestones may include deliverables from multiple repositories. -- No single deliverable is split across repositories or across multiple worktrees. -- Deliverables and features are many-to-many at requirements level: one deliverable can satisfy multiple feature requirements, and one feature requirement can require multiple deliverables over time. -- Deliverables are not required to be feature-linked in all cases (for example chores); however, requirement-changing deliverables should link to relevant features. -- Rework, bug-fix, and enhancement deliverables can belong to the same milestone when they are required for milestone acceptance. - -Milestone completion is judged at the milestone level: -- the grouped deliverables satisfy milestone acceptance criteria -- milestone completion aligns to its target date objective - ---- - -## Document Flow Philosophy - -Zazz uses the following conceptual flow: - -`PROP -> SPEC -> PLAN -> build/validate loop` - -This flow runs per deliverable while preserving continuity with the long-lived Feature Requirements Document (`-FRD`). - -### Proposal (`-PROP`, optional) -Used to clarify options, rationale, tradeoffs, and constraints before committing to a Deliverable SPEC. -Strongly recommended for new capabilities and major refactors. -Proposal discussions may include both user-journey requirements and technical implementation options. -Proposal output is input to decisions, not the final contract. - -### Specification (`-SPEC`) -Defines the desired state and acceptance contract. -This is the central convergence target. - -Requirements and specification maintenance convention: -- **Feature Requirements Document (`-FRD`)** (long-lived, mutable): canonical user-journey and requirement contract for the feature over time. -- **Deliverable SPEC** (short-lived execution contract): scoped contract for one deliverable. -- Deliverable SPEC is refined during active execution/QA and then frozen when the deliverable closes. -- Enhancements, bug fixes, refactors, and rework that are treated as distinct deliverables should use new Deliverable SPECs. -- A bug fix is both an implementation correction and a specification clarification when the bug reveals a behavior gap. -- Feature requirements should be updated to reflect accepted behavior evolution across deliverables. -- Requirement/spec history should remain explicit and traceable (for example via changelogs and cross-references between feature requirements and deliverable specs). - -### Plan (`-PLAN`) -Defines how work is organized to move toward the SPEC-defined state. -`-PLAN` may be persisted as a document or executed as runtime-native/agent-internal planning, depending on platform capability and team policy. - ---- - -## Context Engineering Philosophy - -Zazz is intentionally designed to manage context as a first-class concern. - -Core context principles: -- Load the **least necessary context** for the current task, role, and decision. -- Avoid broad, undifferentiated context dumps that increase noise and ambiguity. -- Decompose work into explicit roles and steps so each agent operates with focused context windows. -- Use runtime-native capabilities (for example subagents/teams/planning primitives) to isolate context by workstream whenever possible. -- Prefer iterative context refresh over monolithic one-shot prompts for complex deliverables. - -Outcome: -- Better reasoning quality, lower context drift, and more predictable convergence to the SPEC-defined target state. - ---- - -## Convergence Loop Philosophy (Spec Stewardship) - -Zazz is intentionally iterative: -1. A baseline Deliverable SPEC is established (typically via spec-builder), aligned to current Feature Requirements context. -2. Work progresses toward the Deliverable SPEC. -3. QA validates the implementation against the Deliverable SPEC and verification evidence. -4. QA identifies gaps, inconsistencies, edge cases, missing tests, and ambiguity. -5. QA drives rule-governed Deliverable SPEC refinement and explicit rework definition when needed. -6. Rework is generated and resolved. -7. A fresh QA context revalidates against the updated Deliverable SPEC. -8. Repeat until implementation converges and the final deliverable fully reflects the finalized Deliverable SPEC. -9. On deliverable closure, freeze the Deliverable SPEC and reconcile accepted behavior into the Feature Requirements Document (`-FRD`). - -Specification stewardship is shared across the lifecycle: -- spec-builder creates the initial Deliverable SPEC baseline -- QA refines and hardens the Deliverable SPEC through controlled updates under framework rules -- feature owners/stewards reconcile accepted outcomes into linked Feature Requirements Documents (`-FRD`) when the deliverable changes feature requirements -- SPEC change history should remain explicit and traceable - ---- - -## Agent Role Philosophy - -Zazz commonly uses these roles: -- `spec-builder-agent` -- `planner-agent` -- `worker-agent` -- `qa-agent` -- optional coordination role (`coordinator-agent`) - -The active agent runtime (for example Claude, Codex, Warp, Gemini CLI) may provide built-in planning, orchestration, or subagent/team capabilities. -The framework is role-oriented and convergence-oriented, not tied to a single runtime. - -Companion skills repository: -- `zazz-skills` is the skills repository for the Zazz Framework. -- It contains reusable agent skills and API skills that implement framework workflows across environments. -- In service-assisted adoption, teams may consume skills from `zazz-skills` to standardize spec-builder/planner/worker/qa behavior and board API interactions. -- This framework document may be copied or moved into `zazz-skills`; when that happens, the philosophy and contracts remain the same, while repository-specific integration notes may differ. - ---- - -## Collaboration Philosophy - -Default collaboration model: -- one dedicated worktree per active deliverable branch -- concurrent work coordinated by explicit ownership and dependency awareness -- deliverable execution is single-repo/single-worktree; project and milestone coordination may span repositories - -Branch and worktree naming contract: -- Worktree directory name must match the branch name used for that deliverable. -- Branch names must be slashless (no `/`) so branch and worktree names map cleanly to a single directory path. -- Branch/worktree naming should align with feature identifiers in `features/` and deliverable identifiers in `deliverables/` when practical (for example `feature-id-deliverable-id`). - -Locking philosophy: -- prefer runtime-native concurrency/ownership guarantees when they are stronger -- use service-level locking (for example Board API locking) when needed for shared-state safety and observability - ---- - -## Service Adoption Philosophy - -Zazz supports two valid adoption paths: -The framework can be adopted either alongside the Zazz Board application/tools or independently as a process-only operating model. - -1. **Process-only adoption**: apply the framework philosophy and document flow without any board service. -2. **Service-assisted adoption**: add Zazz Board API/UI for orchestration, visibility, and locking support. - -Board API integration is optional framework infrastructure, not a prerequisite for framework adoption. - ---- - -## Post-Convergence Human Acceptance - -Human involvement is intentionally positioned after convergence, not inside it. -Balance model: -- Maximal automation during convergence: agents and framework rules drive refinement, validation, and rework. -- Deliberate human quality checkpoints after convergence: user acceptance testing (UAT) and PR merge approval. - -Post-convergence checkpoints: -1. **UAT checkpoint**: human validation that delivered behavior meets user/business expectations. -2. **PR merge checkpoint**: human review/approval gate for code integration and release readiness. - -These checkpoints are quality controls, not convergence controls. - ---- - -## Key Principles - -1. Desired-state convergence is the core operating model. -2. The framework uses a two-document model: long-lived Feature Requirements (`-FRD`) + per-deliverable Deliverable SPEC (`-SPEC`). -3. Milestones are first-class, date-driven groupings of deliverables. -4. Deliverable dependencies (serial/parallel) shape milestone progression. -5. Projects and milestones may span repositories; each deliverable remains single-repo and single-worktree. -6. QA is an independent convergence pressure function: it finds gaps/inconsistencies, flags missing tests, and drives rule-governed refinement and rework. -7. SPEC stewardship is iterative across spec-builder and QA. -8. The final deliverable must fully reflect its finalized Deliverable SPEC. -9. Every feature has one long-lived Feature Requirements Document (`-FRD`); every deliverable has one required Deliverable SPEC (`-SPEC`). -10. Convergence is agent-driven; human acceptance is deliberately scoped to post-convergence UAT and PR merge checkpoints. -11. Context engineering is required: least-necessary context, role-scoped context, and step-scoped context. -12. The framework is opinionated about required document types and subdirectory shape, but flexible about document root location. -13. `features/`, `deliverables/`, and `standards/` are required framework directories under the configured docs root. -14. Features define user journeys and requirements (what/why); deliverables define and implement scoped specification contracts (what/how) for execution. -15. Proposals are optional ideation artifacts and may attach to features, deliverables, or both; they are not authoritative contracts. -16. User journeys are the core boundary signal for features and may represent human users, agents, or other systems. -17. Branch/worktree naming is opinionated: worktree equals branch name, and branch names are slashless. -18. Standards are expected in one canonical location under the configured docs root. -19. Framework philosophy is implementation-agnostic. -20. Board services are optional accelerators, not mandatory prerequisites. -21. `zazz-skills` is the skills repository for the Zazz Framework. - ---- - -## Framework Maturity - -Pre-1.0 working draft: `0.8.1` diff --git a/docs/codex-multi-agent-policy.md b/docs/codex-multi-agent-policy.md new file mode 100644 index 00000000..1fb7763a --- /dev/null +++ b/docs/codex-multi-agent-policy.md @@ -0,0 +1,77 @@ +# Codex Multi-Agent Policy (Phase 1) + +This repository uses Codex multi-agent mode in a limited, framework-aligned way. + +## Official references (source of truth) + +- Multi-agent guide: https://developers.openai.com/codex/multi-agent/ +- Multi-agent concepts: https://developers.openai.com/codex/concepts/multi-agents +- Codex config reference: https://developers.openai.com/codex/config-reference +- Approvals and sandbox: https://developers.openai.com/codex/sandbox + +## Contention management assessment + +Based on current Codex docs, treat multi-agent contention handling as helpful but not lock-safe: + +- Codex agents can parallelize workstreams. +- Codex docs also warn that write-heavy parallel tasks can still produce edit conflicts. + +Policy decision: +- We do not assume deterministic built-in file-lock semantics across subagents. +- Primary strategy is explicit file ownership + dependency sequencing. +- API-backed lock coordination is fallback only for external concurrency risk. + +## Scope for this repository + +Initial rollout roles: +- `worker`: implementation tasks +- `qa`: verification plus rework creation/spec updates +- `monitor` (optional): non-writing progress/blocker monitoring + +We intentionally defer broader role fanout patterns until this phase is stable. + +## When to spawn multiple agents + +Spawn parallel agents only when all are true: +1. Work is clearly scoped and independent. +2. File ownership is disjoint. +3. Acceptance criteria and test expectations are clear. +4. Merge/apply order is straightforward. + +Good fits: +- Independent worker tasks from an approved plan. +- QA validation after worker changes are integrated. +- Read-only monitoring/reporting. + +## When NOT to spawn multiple agents + +Do not spawn parallel agents when any apply: +- Spec/plan/acceptance criteria are ambiguous or changing. +- Overlapping file edits are likely. +- Strict serial ordering is required (migrations, deep refactors, hotfix surgery). +- The task is small enough for one agent. + +## Write-conflict policy + +1. One writer per file at a time. +2. Declare file ownership before spawning worker agents. +3. If ownership overlaps, serialize with explicit dependency edges. +4. QA should avoid concurrent edits with workers in the same file set. +5. If external concurrency risk exists, use API-backed lock coordination before proceeding. + +## Approval and sandbox expectations + +- Default approval mode: `on-request`. +- Worker sandbox: `workspace-write` (network disabled by default). +- QA sandbox: `workspace-write` with network enabled (required for Board API calls and rework updates). +- Monitor sandbox: `read-only`. +- Risky or out-of-sandbox actions require explicit human approval. + +## Operational limits + +- `max_threads` and `max_depth` remain conservative in phase 1. +- Raise limits only after repeated low-conflict runs and team agreement. + +## Relationship to Zazz Framework + +This policy aligns with the framework’s role-oriented execution model while constraining initial parallelization to Worker + QA patterns for predictable convergence and lower merge risk. diff --git a/docs/zazz-skills.md b/docs/zazz-skills.md index d71a929e..7647b7d9 100644 --- a/docs/zazz-skills.md +++ b/docs/zazz-skills.md @@ -2,6 +2,8 @@ Methodology for agents (manager, worker, QA) to interact with the Zazz Board API and the application being developed. Agents fetch the API spec at runtime from `{API_BASE_URL}/docs/json` and infer routes from descriptions. This doc lives in a separate repo; skills reference the running Zazz Board instance. +Canonical framework reference: [zazz-framework.md](https://github.com/zazzcode/zazz-skills/blob/main/zazz-framework.md) + --- ## 1. Agent Roles From c24e8e2060e99ae7a422bcf7e74d306ae9a280b6 Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sun, 15 Mar 2026 10:17:54 -0400 Subject: [PATCH 10/14] docs: add switchman integration analysis for zazz framework - analyze upstream-as-is vs forked local adoption paths\n- add sqlite, lock-authority, and mcp-vs-cli token-efficiency assessment\n- define required switchman coordination policy for multi-agent mode\n\nCo-Authored-By: Oz --- docs/switchman-analysis.md | 586 +++++++++++++++++++++++++++++++++++++ 1 file changed, 586 insertions(+) create mode 100644 docs/switchman-analysis.md diff --git a/docs/switchman-analysis.md b/docs/switchman-analysis.md new file mode 100644 index 00000000..eee2ab7a --- /dev/null +++ b/docs/switchman-analysis.md @@ -0,0 +1,586 @@ +# Switchman Analysis for Zazz Framework and Zazz Board + +## Purpose + +Evaluate whether Zazz should: +- use the existing Switchman MCP/CLI capability, +- run upstream Switchman locally as-is, or +- run a forked/customized local version when needed. + +This document also covers the SQLite local database model, a concrete 4-worker workflow, and MCP vs CLI-skill efficiency tradeoffs. + +## Executive summary + +Primary recommendation (phase 1): +1. Use **upstream Switchman as-is locally** for multi-agent coordination (no fork in phase 1). +2. Integrate it through **Zazz CLI skills first** (not deep MCP-first coupling), so all vendors can use the same orchestration contract. +3. Keep Zazz Board task system as the planning/system-of-record layer; mirror lock/lease status from Switchman where needed. +4. Re-evaluate whether a fork/customization is needed after 2–4 weeks of production usage and telemetry. + +Framework policy addition for multi-agent mode: +- Switchman coordination **replaces the existing Zazz Board file-locking mechanism** for active multi-agent task execution. +- For any framework run with multiple concurrent agents on implementation tasks, using one of the following is **required**: + - Switchman MCP integration, or + - Zazz Switchman CLI adapter skill integration. +- Unmanaged parallel file edits outside MCP/CLI adapter coordination are out of policy. + +Why: +- It is already a working OSS implementation with MCP + CLI surface. +- Duplication cost is non-trivial. +- The local SQLite design is strong for single-machine/worktree coordination, but that is also a scope boundary that should be validated against your distributed needs before making it canonical in Zazz. + +## Terminology clarification: what “adopt upstream Switchman locally” means + +To avoid ambiguity, this analysis uses two explicit modes: + +1. **Upstream as-is locally (recommended phase 1)** + - Install and run `switchman-dev` directly (CLI/MCP) on your local machine/LAN workflow. + - No fork. No copied code. + - Zazz integrates via adapter skills and workflow sync. + +2. **Forked upstream locally** + - Create a fork of `switchman-dev/switchman`, run your fork locally, and maintain your own divergence. + - Use this only if you need custom behavior not feasible via normal integration. + +When this document says “adopt upstream locally,” it means **mode 1: upstream as-is locally**, not a fork. + +## What “Switchman MCP server” is (authoritative source located) + +Canonical repo: +- https://github.com/switchman-dev/switchman + +Package: +- npm package `switchman-dev` (latest observed: `0.1.7`) +- repo reference in package metadata points to `switchman-dev/switchman` + +From package metadata: +- CLI binary: `switchman` +- MCP binary: `switchman-mcp` +- package entrypoints indicate both CLI and MCP are first-class. + +## Technical architecture (from repo/docs) + +Core positioning in project docs: +- Coordination/governance layer for parallel AI coding agents. +- Explicit support for workspaces/worktrees, claims/leases, queueing, stale recovery, and governed landing. + +Implementation signals: +- Language: JavaScript/Node. +- Node requirement in README: Node 22.5+. +- Uses SQLite local repo DB in `.switchman/` (README + code). +- MCP server transport: stdio local subprocess (from `src/mcp/server.js` comments and implementation). + +Repository complexity snapshot (current observed): +- ~45 files total in repo tree. +- ~18 source files under `src/`. +- ~11 docs files under `docs/`. +- Approximate analyzed text footprint (selected src/docs/readme files): ~21k lines. + +This is not a tiny utility; it is a moderately substantial coordination system. + +## SQLite local database model (requested detail) + +Evidence from `src/core/db.js`: +- DB directory: `.switchman/` +- DB file: `switchman.db` +- audit key file: `audit.key` +- schema version constant observed: `6` +- SQLite pragmas/config include: + - `foreign_keys=ON` + - `synchronous=NORMAL` + - `busy_timeout` configured + - WAL mode enabled during initialization +- Busy handling includes retry/backoff logic for locked DB scenarios. + +Observed table surface (17 tables): +- `tasks` +- `leases` +- `file_claims` +- `worktrees` +- `conflict_log` +- `audit_log` +- `worktree_snapshots` +- `task_specs` +- `scope_reservations` +- `boundary_validation_state` +- `dependency_invalidations` +- `code_objects` +- `merge_queue` +- `merge_queue_events` +- `operation_journal` +- `policy_overrides` +- `temp_resources` + +Interpretation: +- It is more than file locks; it includes policy, stale invalidation, queueing, and audit trail. +- SQLite is used as a local coordination state engine, not just a lock table. + +## Why a local SQLite DB does not eliminate the need for Switchman + +This is the core distinction: +- **SQLite is the storage layer** (state persistence). +- **Switchman is the coordination engine** (rules + workflows + safety behaviors around that state). + +If you query/update the SQLite DB directly, you bypass critical logic that Switchman implements in CLI/MCP flows: +- conflict-safe claim semantics +- lease lifecycle and heartbeat handling +- stale lease reaping policy +- recovery workflows and operator guidance +- governed write enforcement tools +- queue/gate/landing logic +- audit/event consistency behaviors + +Practical analogy: +- Using SQLite directly is like editing a scheduler’s internal tables by hand. +- It can work in a narrow case, but you lose invariants enforced by the application layer. + +Important project signal from Switchman itself: +- the project is currently **CLI-first + MCP-first** and does **not** present a stable embeddable library API as the primary supported surface. +- treating the DB as your integration API increases coupling risk to schema/version changes. + +### So why call Switchman if DB is local? + +Because calling Switchman gives you the maintained contract: +- stable operator commands and MCP tools +- policy-aware transitions +- safer forward compatibility as Switchman evolves + +### When direct SQLite access might be acceptable + +Only for read-only diagnostics/internal experiments where breakage risk is acceptable. + +For production coordination flows: +- use Switchman CLI/MCP interfaces, +- not raw SQL against `.switchman/switchman.db`. + +## MCP tool surface and lock workflow semantics + +Observed MCP tools include: +- `switchman_task_next` +- `switchman_task_add` +- `switchman_task_claim` +- `switchman_task_done` +- `switchman_task_fail` +- `switchman_lease_heartbeat` +- `switchman_scan` +- `switchman_merge_gate` +- `switchman_status` +- plus governed write tools: + - `switchman_write_file` + - `switchman_append_file` + - `switchman_make_directory` + - `switchman_move_path` + - `switchman_remove_path` + - `switchman_monitor_once` + +Important behavior: +- Agent asks for next task. +- Agent claims file paths before edits. +- Conflicts are returned if files are already claimed. +- Lease heartbeat and stale-reap policy exist. +- Completion/failure releases claims. +- Optional “governed write gateway” validates lease/path ownership before file mutation. + +## Does Switchman replace Zazz Board file locking directly? + +It can replace **local** agent contention handling in many cases, but there is a scope caveat: +- Switchman state is local to repo filesystem via SQLite in `.switchman/`. +- Zazz Board locking is API/service-centric and naturally central across distributed hosts. + +So the direct replacement question is really: +- if your multi-agent execution is mostly same host/same repo/worktree ecosystem, Switchman is a strong substitute; +- if you need cross-host, service-authoritative lock state, Board-level API locking remains stronger as canonical truth. + +Proposed framework stance in this analysis: +- For local/LAN multi-agent execution, adopt Switchman as the lock/lease authority and treat it as the replacement for the current Board-level file-lock mechanism during active execution. +- Board remains authoritative for deliverable/task lifecycle and governance metadata. + +## Detailed workflow: 4 worker agents + QA from Zazz Board tasks + +This is a practical hybrid workflow that uses existing systems with minimal duplication. + +### Phase A: planning source of truth stays in Zazz Board +1. Deliverable + task graph remains in Zazz Board. +2. Manager pulls READY tasks from Board API. +3. Manager creates/mirrors execution tasks in Switchman (`switchman task add`) with priority + scope hints. + +### Phase B: parallel execution with Switchman coordination +4. Run `switchman setup --agents 4` for worker workspaces. +5. Each worker agent starts in its own workspace: + - `switchman_task_next` + - `switchman_task_claim` for intended files + - do work + - heartbeat for long-running tasks +6. If claim conflict occurs: + - reroute to alternate task/files, or wait/retry based on policy. + +### Phase C: QA pass +7. QA agent runs after workers (or on completed slices): + - claims QA-edit files if needed (tests/spec updates/rework docs) + - runs verification, merge gate/scan/status checks + - creates rework tasks (Switchman + Board sync if desired) +8. Workers consume rework tasks similarly. + +### Phase D: landing and Board sync +9. Use Switchman queue/gates for controlled landing. +10. Sync final task statuses back to Zazz Board deliverable/task statuses. + +### Operational sync strategy +- Board remains business/workflow record. +- Switchman is execution safety/coordination layer. +- A thin adapter (CLI skill) syncs key state transitions: + - READY -> in Switchman queue + - done/fail/rework -> reflected back to Board. + +## Can we build a CLI skill solution that uses existing Switchman? + +Yes — and this is likely the best first implementation. + +CLI-skill pattern: +- `zazz-switchman-adapter` skill wraps Switchman CLI commands. +- Skill responsibilities: + - bootstrap/check (`switchman setup`, `switchman verify-setup`) + - task ingestion from Board into Switchman queue + - worker loop helpers (next/claim/heartbeat/done/fail) + - status + stale recovery helpers + - sync completion/rework status back to Board + +Benefits: +- vendor-neutral: any agent that can run CLI commands can use it. +- avoids deep immediate coupling to one MCP host implementation. +- preserves optional MCP path where available. + +## Can this same strategy be used by Claude Code, Cursor, Codex, and Warp? + +Yes, with one important distinction: +- the **core strategy** (Switchman coordination + Zazz CLI adapter skill) is portable, +- while the **integration mode** (native MCP vs CLI wrapper) varies by agent platform. + +### Claude Code +- Switchman has explicit setup docs for Claude Code with project-local MCP config. +- Strategy fit: + - MCP-native path: strong + - CLI-adapter path: also valid + +### Cursor +- Switchman has explicit setup docs for Cursor and writes `.cursor/mcp.json`. +- Strategy fit: + - MCP-native path: strong + - CLI-adapter path: also valid + +### Codex +- Codex docs state MCP servers are supported in CLI and IDE extension. +- Codex also supports project-scoped `.codex/config.toml`, which aligns with repo-local setup patterns. +- Strategy fit: + - MCP-native path: available + - CLI-adapter path: strong fallback/baseline, especially for vendor-unified workflows + +### Warp (Oz agents) +- Warp docs support MCP servers for agents (including stdio/local process MCP). +- Warp CLI supports passing MCP config via `--mcp`. +- Strategy fit: + - MCP-native path: available + - CLI-adapter path: available for workflows that rely on shell command orchestration + +### Practical recommendation for cross-agent consistency +1. Make **CLI adapter** the framework default contract (portable baseline). +2. Add **optional MCP acceleration** per platform where native MCP is stable and reduces operator friction. +3. Keep one canonical workflow spec in Zazz skills so behavior is consistent across Claude/Cursor/Codex/Warp. + +## MCP vs CLI-skill efficiency comparison + +### MCP strengths +- Structured tool calls (less parsing ambiguity). +- Better guardrails for “must claim before write” flows when agents use Switchman write tools. +- Native integration in MCP-capable tools (Claude Code/Cursor). + +### CLI-skill strengths +- Works across a broader set of agent vendors/runtimes immediately. +- Fits Zazz’s existing CLI/skill operating model. +- Easier to standardize in framework documentation and automation scripts. + +### Efficiency tradeoff (practical) +- For a single MCP-native toolchain, MCP may be cleaner and lower-friction per action. +- For cross-vendor framework portability, CLI skills are typically more operationally efficient overall because you avoid per-vendor MCP integration overhead. + +## Token-efficiency assessment (core question) + +Short answer: +- **There is no universal rule that MCP is always more token-efficient or CLI is always more token-efficient.** +- For your Zazz use case, a **CLI skill adapter is likely more token-efficient end-to-end** once prompts are standardized and outputs are constrained. + +Important framing: +- “Token efficiency” depends on how much text the model must read/write per step. +- Both MCP and CLI can be efficient or inefficient depending on response verbosity and orchestration design. +- The comparison below is an inference from tool behavior and workflow shape, not a benchmark published by Switchman maintainers. + +### Where MCP can be token-efficient +- Structured responses can reduce parsing back-and-forth. +- Tool contracts reduce ambiguous natural-language negotiation. +- Fewer “explain the command” turns in MCP-native environments. + +### Where MCP can be token-inefficient +- Rich JSON payloads can be verbose. +- High-frequency operations (heartbeat, status polling, repeated claim checks) can add repeated structured payload overhead. +- If agents still require explanatory text around each MCP action, total tokens rise quickly. + +### Where CLI skill can be token-efficient +- A well-designed skill can enforce compact command outputs (for example: JSON flags plus minimal fields). +- Common workflows can be wrapped into one skill action pattern, reducing repeated instruction tokens. +- CLI-first skill works consistently across vendors, avoiding additional agent-specific setup chatter. + +### Where CLI skill can be token-inefficient +- If commands are run without output constraints, noisy terminal output can exceed MCP payload size. +- If agents repeatedly ask for command clarifications, interaction overhead increases. + +### Practical conclusion for Zazz +- If your goal is **framework-wide** efficiency across multiple agent vendors, use a CLI adapter skill as baseline. +- Add MCP-native fast paths only where the host tool has strong native support and low overhead. +- In other words: choose **operational token efficiency** over per-call elegance. + +### Measurement plan to validate this (recommended) +Run a 1-week A/B pilot on similar deliverables: +1. Mode A: Switchman via MCP tools. +2. Mode B: Switchman via Zazz CLI adapter skill. +3. Capture for each run: + - total model input tokens + - total model output tokens + - number of coordination turns + - mean tokens per completed task + - conflict/retry rate +4. Select the default mode using: + - lowest median tokens per completed task + - with no quality or reliability regression. + +## Detailed implementation plan: Zazz Switchman CLI adapter skill + +Goal: +- Provide a vendor-neutral Zazz skill that uses existing Switchman functionality (no duplication of core lock/lease engine). + +Name (proposed): +- `zazz-switchman-cli-adapter` + +### Scope +- In scope: + - Setup/verification helpers + - Task mirror from Zazz Board to Switchman queue + - Worker execution loop helpers (next/claim/heartbeat/done/fail) + - QA/rework helpers + - Status/recovery helpers + - Optional landing/gate helpers +- Out of scope (phase 1): + - Re-implementing Switchman DB, lock engine, or merge queue logic in Zazz + - Full bi-directional real-time sync daemon + +### Phase 0: contract and interface definition +Deliverables: +1. Skill contract doc: + - command intents + - required inputs/outputs + - failure semantics +2. Minimal state mapping spec: + - Zazz Board task status -> Switchman task/lease state + - Switchman completion/failure -> Zazz Board updates +3. Output shape standard: + - compact JSON-first output requirements for token control. + +Acceptance criteria: +- Every skill action has deterministic required input and normalized output. +- No direct `.switchman/switchman.db` access in skill logic. + +### Phase 1: core command wrappers +Implement wrappers for: +- setup and health: + - `switchman setup --agents N` + - `switchman verify-setup` + - `switchman status --json` +- queue/task: + - `switchman task add ...` + - `switchman lease next --json` or equivalent task-next flow + - `switchman claim ...` + - `switchman task done ...` + - `switchman task fail ...` + - `switchman lease heartbeat ...` +- recovery: + - `switchman lease reap` + - `switchman scan` + +Adapter behavior requirements: +- enforce compact mode (`--json` where available) +- parse and return only required fields +- normalize errors to stable reason codes: + - `CLAIM_CONFLICT` + - `LEASE_STALE` + - `TASK_NOT_FOUND` + - `SETUP_INVALID` + - `COMMAND_FAILED` + +### Phase 2: Zazz Board sync integration +Workflow: +1. Fetch READY tasks from Zazz Board. +2. Create/mirror execution tasks in Switchman with trace IDs. +3. On task completion/failure/rework in Switchman, patch Board status. +4. Preserve audit linkage with correlation fields: + - `boardTaskId` + - `switchmanTaskId` + - `deliverableId` + - `worktree`. + +Minimum sync strategy: +- event-driven at key transitions only (not continuous chatter). + +### Phase 3: QA + rework loop +Add explicit QA flow support: +1. QA picks validated task set. +2. QA runs checks and records findings. +3. QA creates rework tasks: + - in Switchman queue for execution + - mirrored in Board for governance visibility. +4. Rework closure updates both systems. + +Policy: +- one-writer-per-file rule remains active. +- overlapping edits trigger serialize/retry flow. + +### Phase 4: optimization and hardening +1. Token optimization: + - strict compact JSON responses + - avoid verbose status dumps unless requested +2. Reliability: + - retry strategy for transient CLI failures + - stale lease recovery policy presets +3. Observability: + - per-action timing + - per-task token usage metrics + - conflict/retry counters. + +### Reference workflow (4 workers + QA with adapter) +1. Manager syncs ready Board tasks -> Switchman. +2. Workers 1..4 each: + - acquire next task + - claim files + - execute + - heartbeat as needed + - done/fail +3. QA: + - validates completed slices + - creates rework where needed +4. Manager: + - monitors status/recovery + - syncs outcomes back to Board + - runs gate/landing commands. + +### Security and safety constraints +- Do not expose raw DB operations in skill prompts. +- Keep force-claim operations operator-gated. +- Require explicit approval for destructive landing/recovery commands. + +### Test plan (adapter) +1. Unit tests: + - parser normalization for each wrapped command + - error mapping correctness +2. Integration tests: + - claim conflict path + - stale lease reap path + - done/fail sync to Board +3. Load tests: + - 4-worker + QA parallel run over representative deliverable. + +### Rollout plan +1. Pilot in one deliverable. +2. Compare MCP-direct vs CLI-adapter (token + reliability metrics). +3. Make CLI adapter default if metrics are equal or better. +4. Keep MCP path optional for tools where it is measurably superior. + +Conclusion for Zazz now: +- Use CLI-skill as baseline portability layer. +- Add MCP optimization path where supported. + +## Adoption paths for Zazz Framework (generic vendor support) + +### Option 1 — Upstream as-is locally (recommended now) +Pros: +- immediate capability +- real implementation already handling leases/claims/stale/queue +- lower time-to-value +- no fork maintenance burden in phase 1 + +Cons: +- dependency on external project maturity/roadmap +- local SQLite scope may not match all distributed deployments +- governance/compliance behavior is opinionated to Switchman model + +### Option 2 — Fork/customize upstream locally +Pros: +- full control +- can apply targeted customizations while preserving upstream core behavior + +Cons: +- ongoing fork maintenance and merge burden +- risk of divergence from upstream fixes/features +- higher operational complexity than upstream-as-is + +### Recommended trajectory +Phase 1: +- run upstream-as-is + CLI skill adapter. +Phase 2: +- collect telemetry and pain points. +Phase 3: +- if required, move to a focused fork with minimal delta from upstream. + +## Cost/complexity estimate for fork/customization + +Given observed scope, deeper customization still touches non-trivial subsystems: +- lease lifecycle + stale policy +- conflict detection and claim semantics +- governed write path +- queue/landing behavior +- recovery commands and observability +- policy/audit model + +Expected effort trend: +- thin integration (upstream-as-is): low-to-medium +- medium customization in a fork: medium-to-high +- broad behavioral divergence from upstream: high + +## Risks and due-diligence items + +1. License clarity: + - Site copy references MIT in marketing text. + - npm metadata currently reports Apache-2.0. + - GitHub API currently shows no detected license file. + - Action: verify with maintainers before hard dependency. + +2. Maturity: + - early-stage repository (recent creation, low stars/contributors at time of analysis). + - Action: run controlled pilot before full framework dependency. + +3. Scope mismatch: + - local SQLite coordination may not replace service-level distributed locking requirements. + - Action: define where Board remains authoritative vs where Switchman is authoritative. + +## Recommended next steps for Zazz + +1. Pilot in one deliverable with 3–4 workers + QA using Switchman via CLI skill adapter. +2. Keep Zazz Board as task/deliverable source of truth; sync status boundaries explicitly. +3. Measure: + - conflict rate + - stale lease incidents + - merge/queue recovery frequency + - operator overhead versus current Board-lock flow +4. Decide after pilot: + - continue upstream-as-is, or + - move to a tightly scoped fork/customization. + +## Sources + +- Switchman repo: https://github.com/switchman-dev/switchman +- Switchman site: https://switchman.dev +- Switchman README: https://raw.githubusercontent.com/switchman-dev/switchman/main/README.md +- MCP tools doc: https://raw.githubusercontent.com/switchman-dev/switchman/main/docs/mcp-tools.md +- Claude setup doc: https://raw.githubusercontent.com/switchman-dev/switchman/main/docs/setup-claude-code.md +- CLI setup doc: https://raw.githubusercontent.com/switchman-dev/switchman/main/docs/setup-cli-agents.md +- Stale lease policy doc: https://raw.githubusercontent.com/switchman-dev/switchman/main/docs/stale-lease-policy.md +- MCP server source: https://raw.githubusercontent.com/switchman-dev/switchman/main/src/mcp/server.js +- DB source (SQLite schema/pragmas): https://raw.githubusercontent.com/switchman-dev/switchman/main/src/core/db.js +- npm package metadata endpoint: https://registry.npmjs.org/switchman-dev From 5c382207962c0888d465fc48cadd0f766f480bbb Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sun, 22 Mar 2026 11:39:54 -0400 Subject: [PATCH 11/14] Sync framework skills and add local skill extensions --- .agents/skill-extensions/qa/EXTENSION.md | 15 + .agents/skill-extensions/worker/EXTENSION.md | 21 ++ .../SKILL.md | 29 +- .agents/skills/feature-doc-builder/SKILL.md | 341 ++++++++++++++++++ .../{planner-agent => planner}/SKILL.md | 33 +- .agents/skills/pr-builder/SKILL.md | 105 ++++++ .agents/skills/proposal-builder/README.md | 163 +++++++++ .agents/skills/proposal-builder/SKILL.md | 324 +++++++++++++++++ .../{qa-backend-agent => qa-backend}/SKILL.md | 14 +- .../SKILL.md | 14 +- .../skills/{qa-agent => qa}/PR-TEMPLATE.md | 0 .agents/skills/{qa-agent => qa}/SKILL.md | 53 ++- .../README.md | 88 ++++- .../SKILL.md | 106 ++++-- .../skills/{worker-agent => worker}/SKILL.md | 17 +- .../scripts/README.md | 4 +- .../{worker-agent => worker}/scripts/zazzctl | 0 .agents/skills/zazz-board-api/SKILL.md | 53 ++- .../skills/zazz-board-api/scripts/README.md | 16 +- .../skills/zazz-board-api/scripts/zazzctl.mjs | 238 +++++++++++- ...ZZ-6-multiple-agent-tokens-feature-PLAN.md | 2 +- .../ZAZZ-7-worker-file-locking-PLAN.md | 2 +- .../ZAZZ-7-worker-file-locking-SPEC.md | 2 +- AGENTS.md | 15 +- README.md | 20 +- .../sample-worker-multi-agent-prompt-CODEX.md | 2 +- docs/zazzctl-command-spec.md | 4 +- scripts/sync-skills-from-zazz-skills.sh | 41 +++ scripts/zazzctl | 2 +- 29 files changed, 1600 insertions(+), 124 deletions(-) create mode 100644 .agents/skill-extensions/qa/EXTENSION.md create mode 100644 .agents/skill-extensions/worker/EXTENSION.md rename .agents/skills/{coordinator-agent => coordinator}/SKILL.md (83%) create mode 100644 .agents/skills/feature-doc-builder/SKILL.md rename .agents/skills/{planner-agent => planner}/SKILL.md (90%) create mode 100644 .agents/skills/pr-builder/SKILL.md create mode 100644 .agents/skills/proposal-builder/README.md create mode 100644 .agents/skills/proposal-builder/SKILL.md rename .agents/skills/{qa-backend-agent => qa-backend}/SKILL.md (77%) rename .agents/skills/{qa-frontend-agent => qa-frontend}/SKILL.md (76%) rename .agents/skills/{qa-agent => qa}/PR-TEMPLATE.md (100%) rename .agents/skills/{qa-agent => qa}/SKILL.md (80%) rename .agents/skills/{spec-builder-agent => spec-builder}/README.md (54%) rename .agents/skills/{spec-builder-agent => spec-builder}/SKILL.md (84%) rename .agents/skills/{worker-agent => worker}/SKILL.md (95%) rename .agents/skills/{worker-agent => worker}/scripts/README.md (94%) rename .agents/skills/{worker-agent => worker}/scripts/zazzctl (100%) create mode 100755 scripts/sync-skills-from-zazz-skills.sh diff --git a/.agents/skill-extensions/qa/EXTENSION.md b/.agents/skill-extensions/qa/EXTENSION.md new file mode 100644 index 00000000..26032f14 --- /dev/null +++ b/.agents/skill-extensions/qa/EXTENSION.md @@ -0,0 +1,15 @@ +# QA Skill Extension + +This file is repo-specific companion guidance for the base `qa` skill. +Read it after `.agents/skills/qa/SKILL.md` and treat it as additive guidance for this repository. + +## Placeholder + +No additional repo-specific QA rules are defined yet. + +This extension path is reserved for future guidance such as: + +- Codex harness-specific QA workflows +- repo-specific reviewer evidence expectations +- screenshot, inline comment, or artifact conventions +- local verification commands or escalation patterns diff --git a/.agents/skill-extensions/worker/EXTENSION.md b/.agents/skill-extensions/worker/EXTENSION.md new file mode 100644 index 00000000..36425811 --- /dev/null +++ b/.agents/skill-extensions/worker/EXTENSION.md @@ -0,0 +1,21 @@ +# Worker Skill Extension + +This file is repo-specific companion guidance for the base `worker` skill. +Read it after `.agents/skills/worker/SKILL.md` and treat it as additive guidance for this repository. + +## Codex Harness Guidance + +This project is using Codex worker agents. + +When the approved PLAN or planning algorithm allows safe parallel execution: + +- prefer using the harness capability that spawns subagents for independent tasks +- maximize parallel execution only when dependency order and file ownership rules remain valid +- keep file ownership disjoint across subagents whenever possible +- if tasks overlap in files or require tightly coupled edits, serialize them instead of forcing parallelism +- the parent worker remains responsible for integration, verification, and truthful board state updates + +## Intent + +This extension exists to push the worker toward safe harness-aware parallelism in this repo. +It supplements the base worker skill and does not weaken its locking, testing, escalation, or truthfulness requirements. diff --git a/.agents/skills/coordinator-agent/SKILL.md b/.agents/skills/coordinator/SKILL.md similarity index 83% rename from .agents/skills/coordinator-agent/SKILL.md rename to .agents/skills/coordinator/SKILL.md index 60867f69..1b78d597 100644 --- a/.agents/skills/coordinator-agent/SKILL.md +++ b/.agents/skills/coordinator/SKILL.md @@ -1,11 +1,32 @@ -# Coordinator Agent Skill +--- +name: coordinator +description: Coordinates execution of an approved PLAN by materializing tasks, managing the live task graph, routing blockers and rework, and maintaining PLAN or approved SPEC changes during execution. +--- + +# Coordinator Skill + +## Mission + +Turn an approved PLAN into an actively managed execution flow. -**Role**: Orchestrates execution once the plan is approved. Creates tasks from the PLAN via API, hands out tasks to workers, manages the task graph, responds to blockers, creates rework tasks from QA content. Adjusts the PLAN as required when the change mechanism is invoked. +Primary outputs: + +- a truthful live task graph in Zazz Board +- rework tasks created from QA-authored rework content +- updated PLAN content, and approved SPEC updates when the change mechanism is invoked + +This skill coordinates execution. It does not implement feature code itself. + +## Role + +Orchestrates execution once the plan is approved. Creates tasks from the PLAN via API, hands out tasks to workers, manages the task graph, responds to blockers, creates rework tasks from QA content, and adjusts the PLAN when the change mechanism is invoked. **Agents Using This Skill**: Coordinator (one per deliverable during execution) **TDD emphasis**: Every task must have explicit test requirements—what tests to create, what tests to run. No task is complete without passing tests. Rework tasks include the failing test that demonstrates the issue. +**Docs root convention**: Use the repo docs root declared in `AGENTS.md` as the base for framework docs. Example paths in this skill may use `/...` as shorthand. + --- ## System Prompt @@ -39,7 +60,7 @@ During MVP: **Trigger**: Subscribe to Zazz Board API pub/sub for plan approval events. When a deliverable's plan is approved, it moves to Ready and a plan-approved event is published. -**Input**: Approved .zazz/deliverables/{deliverable-name}-PLAN.md (created by the Planner) +**Input**: Approved `/deliverables/{deliverable-name}-PLAN.md` (created by the Planner) **Process**: 1. Read the PLAN to understand phases, steps, and task definitions @@ -112,6 +133,6 @@ export ZAZZ_STATE_DIR="${ZAZZ_WORKSPACE}/.zazz" ## Example Workflow -See `.agents/skills/coordinator-agent/examples/` for: +See `.agents/skills/coordinator/examples/` for: - example-plan.md - Sample PLAN document (output of Planner) - example-task-graph.json - Sample task dependency graph diff --git a/.agents/skills/feature-doc-builder/SKILL.md b/.agents/skills/feature-doc-builder/SKILL.md new file mode 100644 index 00000000..9e4fb7be --- /dev/null +++ b/.agents/skills/feature-doc-builder/SKILL.md @@ -0,0 +1,341 @@ +--- +name: feature-doc-builder +description: Guides a product owner or project owner through creating or evolving a Feature Requirements Document for a long-lived capability. Use for feature-document authoring, milestone decomposition, transcript-to-feature-document drafting, and feature-level handoff into deliverable specs. +--- + +# Feature Doc Builder Skill + +## Mission + +Create or evolve a Feature Requirements Document that explains a long-lived application capability at the product and system level. + +The feature document should help answer: + +- why this feature exists +- what value it creates +- what is live today +- what still needs to be built +- how the work should be organized into milestones + +This skill is for feature definition and feature evolution. It is not an implementation-planning skill and it does not replace deliverable SPEC authoring. + +It should help the Product Owner articulate feature-level success criteria and milestone outcome criteria that later inform deliverable acceptance criteria. + +## Primary Audience + +Work primarily with: + +- product owner +- project owner +- stakeholders with domain context + +Secondary audiences for the resulting feature document: + +- developers onboarding to the project +- the development team reviewing feature intent and milestone breakdown +- future agents that need product context before creating deliverable specs + +## Docs Root Convention + +Use the repo docs root declared in `AGENTS.md` as the base for framework docs. Example paths in this skill may use `/...` as shorthand. + +## What This Skill Produces + +Primary artifact: + +- `/features/{feature-key}.md` + +Supporting discovery artifact: + +- update `/features/index.yaml` when the feature document is created or materially revised + +## Boundaries + +### This skill does + +- define the feature's purpose, value, and current state +- capture feature-level success criteria and milestone outcomes +- capture system-level behavior and important user/system flows +- decompose feature evolution into milestones +- identify what is live, planned, proposed, or deferred +- ingest transcripts or meeting notes and turn them into a feature document draft +- produce handoff guidance for later deliverable specs + +### This skill does not + +- write deliverable-level acceptance criteria for implementation tasks +- produce execution-ready task decomposition +- replace proposal analysis when the team is still deciding whether to pursue an idea +- implement the feature + +Artifact boundaries: + +- `proposal-builder` helps decide whether or how to proceed +- `feature-doc-builder` defines the long-lived feature and milestone roadmap +- `spec-builder` defines one deliverable's execution contract + +## Interaction Modes + +### Mode A: Live owner dialogue (default) + +Use a conversational process with a product owner, project owner, or stakeholder to draw out the feature's why, current state, and future milestones. + +### Mode B: Transcript ingestion + +If the user provides a transcript or meeting notes: + +1. summarize the core problem, goals, and decisions +2. infer the feature's intent and current/planned states +3. identify open questions and missing milestone detail +4. generate or refresh the feature document draft + +### Mode C: Existing feature-document revision + +When the user already has a Feature Requirements Document: + +1. read the current feature document +2. identify what changed after the latest milestone or discussion +3. update current-state sections, milestone statuses, and flows +4. preserve long-lived feature intent while refreshing stale sections + +### Mode D: Development mode + +If the owner says "development mode" or equivalent, the focus is on improving this skill itself. In development mode, you may edit `.agents/skills/feature-doc-builder/SKILL.md`. Outside development mode, this file is read-only. + +## Human-Facing Usage Guidance + +This is an interactive, back-and-forth skill. + +The owner does not need to provide a complete feature document up front. A strong starting prompt plus iterative dialogue is enough. The agent should: + +- ask clarifying questions about the feature's value and current state +- help distinguish current behavior from planned future behavior +- help define or revise the next few meaningful milestones +- draft the feature document early enough that the owner can react to a concrete document + +This skill should feel like a structured product-definition conversation, not an implementation planning session. + +### Example starter prompts + +#### Example 1: New feature document + +```text +Use feature-doc-builder. +I want to create a Feature Requirements Document for role-based access control in our application. +This feature needs to explain why RBAC matters, what the system does today, what needs to be added, and how we should break it into milestones. +Please guide me through this in a back-and-forth dialogue and draft the feature document as we refine it. +``` + +#### Example 2: Update an existing feature document after a milestone + +```text +Use feature-doc-builder. +We already have a Feature Requirements Document for our billing feature, and milestone 1 has shipped. +Please help me update the feature document so it reflects the current live behavior, marks milestone 1 complete, and refines the next milestones based on what we learned. +``` + +#### Example 3: Transcript-first feature-document drafting + +```text +Use feature-doc-builder. +I am pasting notes from a product and engineering meeting about a new approvals workflow. +Please infer the feature intent, current state, likely milestones, and open questions, then draft a Feature Requirements Document and ask follow-up questions where the discussion was ambiguous. +``` + +### Prompt structure that works well + +The best starting prompts usually include: + +- the feature name +- why the feature matters +- what is known about the current state +- whether this is a new feature document or an update +- a request for iterative dialogue and drafting + +## Dialogue Principles + +- Start with the problem and business/domain value before discussing solution shape. +- Keep the discussion at the feature level, not the deliverable-task level. +- Ask about current state explicitly. A Feature Requirements Document must describe what the application does today, not just the future vision. +- Distinguish what is live, planned, proposed, and deferred. +- Treat milestones as meaningful increments of user or system value. +- Push back when the conversation collapses into low-level implementation detail that belongs in standards or deliverable specs. +- Use transcripts as evidence, not truth. Surface inferred assumptions and ask for confirmation. + +## Required Inputs + +Before drafting a serious Feature Requirements Document, elicit or infer: + +1. feature name and feature key +2. problem statement +3. business/domain justification +4. who is affected +5. current state of the system +6. desired future state +7. major system concepts or entities involved +8. milestone breakdown or at least a first-pass milestone model + +If important inputs are missing, continue the dialogue and mark assumptions explicitly. + +## Standards and Feature Context Integration + +Process: + +1. Read `/features/index.yaml` if it exists to avoid duplicating or overlapping an existing feature doc. +2. Read `/standards/index.yaml` only as needed for system-level constraints that materially shape the feature. +3. Reference standards where they affect feature boundaries or milestone decomposition, but do not restate detailed implementation rules inside the feature document. + +The feature document should stay product/system-oriented. Detailed coding conventions remain in standards. Deliverable-level test and execution detail remains in SPECs and PLANs. + +## Feature Document Content Requirements + +Each feature document draft should usually include: + +1. Feature title and summary +2. Current milestone and next milestone +3. Introduction / problem statement +4. Why this feature matters +5. Current state +6. Feature-level success criteria +7. Core concepts / domain model +8. User flows and system flows +9. Milestone overview table +10. Milestone detail sections with milestone outcome criteria +11. Risks, constraints, and non-goals +12. Open questions +13. Deliverable handoff considerations + +### What "current state" means + +The feature document must explain what the application actually does today as of the latest completed milestone. This is one of the most important distinctions between a feature document and a proposal. + +### What "milestone" means + +A milestone is a meaningful feature increment that advances the capability. A milestone may contain one or more deliverables. The feature document should make the milestone sequence intelligible to both stakeholders and the development team. + +### Feature-level success criteria vs deliverable acceptance criteria + +At the feature document level, success criteria should describe value and system outcomes, not implementation tests. They answer questions like: + +- what valuable capability exists after this milestone? +- what should be true of the product when this feature is successful? +- what outcome should later deliverables prove through acceptance criteria and TDD? + +Those feature-document-level success criteria should inform later SPEC acceptance criteria, but should not replace deliverable-level testability requirements. + +## Recommended Feature Document Sections + +Use this section order unless the owner explicitly asks for a different structure: + +1. Title +2. Feature summary +3. Current milestone / next milestone / services affected +4. Introduction +5. Why this feature matters +6. Concepts +7. User flows and system flows +8. Milestone overview +9. Milestone detail sections +10. Current state summary +11. Planned future evolution +12. Open questions and follow-ups + +## Facilitator Question Bank + +### Problem and value + +- What problem does this feature solve? +- Why is it necessary now? +- What business, user, or operational value does it add? +- What gets worse if we do not build this? + +### Current state + +- What does the system do today in this area? +- What is already shipped? +- Where are the current pain points, workarounds, or gaps? + +### Domain and concepts + +- What are the important nouns and concepts in this feature? +- Which actors or systems participate? +- What terminology should be stable in the feature document? + +### Flows + +- What are the most important user flows? +- What are the key system flows behind them? +- Which flows differ across milestones? + +### Milestones + +- What is the smallest meaningful first milestone? +- Which milestones unlock visible user or system value? +- Which milestones are backend-first, frontend-following, or cross-system? +- Which parts are definitely in scope now, and which should wait? + +### Handoff to deliverables + +- Which milestone slices are likely to become separate deliverables? +- Are there milestone dependencies the spec-builder should know about later? +- Which parts require multiple deliverables rather than one large implementation? + +## Output Naming and Placement + +Use framework naming guidance: + +- Feature Requirements Document: `/features/{feature-key}.md` +- Features index: `/features/index.yaml` + +Keep `features/` flat by default. If a project later has a real need for multiple durable artifacts per feature, it may introduce subdirectories, but that is not the default framework recommendation. + +## Generation Triggers + +When the user says: + +- "generate the feature document" +- "draft the feature doc" +- "write the feature requirements" +- "create a feature document" + +...generate a draft immediately from the discussion so far, then iterate. + +When the user says: + +- "milestone 1 is complete" +- "update the feature document" +- "refresh the feature doc" + +...update the current-state and milestone sections to reflect the new system reality. + +## Feature Document -> Deliverable Handoff + +When the feature document is approved or a milestone is ready for execution, provide a handoff package for later spec work containing: + +1. feature key and feature document path +2. milestone being implemented +3. current-state summary +4. desired milestone outcome +5. relevant flows and concepts +6. constraints and non-goals +7. likely deliverable slices + +This handoff informs deliverable SPEC creation but does not replace `spec-builder`. + +## Quality Bar + +A Feature Requirements Document draft is high quality when: + +1. the feature's why is explicit and persuasive +2. the current state is accurate and not hand-wavy +3. the major concepts and flows are understandable to a new developer +4. milestones are meaningful, ordered, and not just arbitrary task buckets +5. the document helps both stakeholders and the development team +6. the handoff to later deliverables is clear without collapsing into implementation detail + +## Example Use Cases + +- define a new long-lived capability before any deliverable specs exist +- turn a stakeholder workshop transcript into a first feature document draft +- update a feature document after milestone 1 ships +- decompose a feature into milestone 1, 2, and 3 before creating individual deliverable specs diff --git a/.agents/skills/planner-agent/SKILL.md b/.agents/skills/planner/SKILL.md similarity index 90% rename from .agents/skills/planner-agent/SKILL.md rename to .agents/skills/planner/SKILL.md index 83e8ef3e..bdb568d9 100644 --- a/.agents/skills/planner-agent/SKILL.md +++ b/.agents/skills/planner/SKILL.md @@ -1,9 +1,9 @@ --- -name: planner-agent +name: planner description: Creates or updates an execution-ready implementation PLAN from an approved SPEC for any deliverable. Use when an Owner asks for a phased plan with dependency-safe decomposition, repository-verified scope, AC/test traceability, parallelization strategy, and explicit verification commands. --- -# Planner Agent Skill +# Planner Skill ## First Rule: Use Built-In Planning Optimizations If the active agent/model provides built-in planning optimizations (plan mode, TODO/dependency tooling, structured decomposition), you MUST use them first. Then produce the PLAN in this skill’s required structure. @@ -29,18 +29,35 @@ Before writing a PLAN, you MUST have: - SPEC file path If any input is missing, stop and ask the Owner. +## Docs Root Convention +Use the repo docs root declared in `AGENTS.md` as the base for framework docs. Example paths in this skill may use `/...` as shorthand. + +## What This Skill Produces + +Primary artifact: + +- `/deliverables/{deliverableCode}-{slug}-PLAN.md` + +Supporting discovery artifact: + +- update `/deliverables/index.yaml` when the canonical PLAN is created or materially updated + +Primary work product: + +- an execution-ready decomposition of the approved SPEC, not implementation code + ## PLAN Naming + Location (Generic Rule) -- Store plans in `.zazz/deliverables/`. +- Store plans in `/deliverables/`. - Derive PLAN name by replacing `-SPEC.md` with `-PLAN.md`. - Use hyphen-delimited filenames. -- Update `.zazz/deliverables/index.yaml` only when generating/updating the canonical PLAN: +- Update `/deliverables/index.yaml` only when generating/updating the canonical PLAN: - if deliverable entry exists, add or update its `plan` field - if entry does not exist, add a new deliverable record with `id`, `name`, `spec`, and `plan` - If the Owner asks for an alternate draft (for example `-CODEX-PLAN.md`), create it without replacing canonical `-PLAN.md` unless explicitly asked. Example: -- SPEC: `.zazz/deliverables/ZAZZ-5-fix-routes-no-project-SPEC.md` -- PLAN: `.zazz/deliverables/ZAZZ-5-fix-routes-no-project-PLAN.md` +- SPEC: `/deliverables/ZAZZ-5-fix-routes-no-project-SPEC.md` +- PLAN: `/deliverables/ZAZZ-5-fix-routes-no-project-PLAN.md` ## Output Requirements (CODEX-Style Structure) Write one markdown PLAN file. Use this section order unless the Owner explicitly requests a different order: @@ -91,8 +108,8 @@ Optional sections (for updating an existing active plan, not mandatory on first 6. Partition work into dependency-safe phases and named parallel streams. 7. Decompose phases into concrete steps with file ownership and explicit dependency edges. 8. Add validation plan (targeted tests, full tests, lint/type checks, manual sign-off where required). -9. Write PLAN file to `.zazz/deliverables/`. -10. Update `.zazz/deliverables/index.yaml` only when canonical plan target changes. +9. Write PLAN file to `/deliverables/`. +10. Update `/deliverables/index.yaml` only when canonical plan target changes. ## Decomposition Rules 1. **File-first**: every step lists affected files. diff --git a/.agents/skills/pr-builder/SKILL.md b/.agents/skills/pr-builder/SKILL.md new file mode 100644 index 00000000..f39ce2fc --- /dev/null +++ b/.agents/skills/pr-builder/SKILL.md @@ -0,0 +1,105 @@ +--- +name: pr-builder +description: Builds reviewer-ready pull request titles and bodies from repository state, deliverable context, test evidence, and manual validation notes. Use when preparing or updating a PR for human review. +--- + +# PR Builder Skill + +## Mission + +Create a clear, reviewer-ready pull request title and body that accurately explains: + +- what changed +- why it changed +- how it was verified +- what risks or follow-ups remain + +This skill packages work for review. It does not replace implementation, QA, or owner judgment. +It may help create or refine PR content, but it must never approve or merge a PR. + +## Use This Skill When + +- the user asks to create, draft, update, or polish a PR +- QA has completed verification and needs a high-quality PR description +- a deliverable needs consistent reviewer-facing evidence +- the repo has templates or conventions that should be applied reliably + +## Required Inputs + +Gather as many of these as are available: + +1. Branch or diff against the target branch +2. Commit list or summary of changes +3. Deliverable SPEC / PLAN paths when the work follows the Zazz framework +4. Test commands and results +5. Manual validation steps +6. Known risks, migrations, feature flags, or rollout notes + +If a detail is missing, derive it from repository state when possible. Do not invent verification that did not happen. + +## Workflow + +1. Inspect the repo for PR conventions: + - `.github/pull_request_template.md` + - `.github/PULL_REQUEST_TEMPLATE.md` + - other PR templates or contributing docs + - `.agents/skills/qa/PR-TEMPLATE.md` when working in a Zazz repo +2. Read the diff and identify the real user-facing or system-facing behavior change. +3. Read supporting docs that define intent when present: + - deliverable SPEC + - PLAN + - QA evidence + - issue or ticket context supplied by the user +4. Separate the PR content into: + - summary of change + - notable implementation areas + - testing and verification + - manual validation steps + - risks, rollout notes, or follow-ups +5. Produce a concise PR title and body that match the repo's template if one exists. + +## PR Content Rules + +- Describe shipped behavior, not coding play-by-play. +- Include only tests that were actually run. +- If verification is incomplete, say so plainly. +- Call out schema changes, migrations, feature flags, or operational risk explicitly. +- Keep reviewer focus high: what changed, where to pay attention, and how to validate. +- Do not imply that agent-generated PR content replaces Deliverable Owner approval or human merge authority. + +## Preferred Structure + +When the repo does not provide a stronger template, use: + +1. Summary +2. Why +3. What changed +4. Testing +5. Manual test plan +6. Risks / follow-ups + +## Title Guidance + +Prefer a title that states the outcome, not the implementation mechanism. + +Good patterns: + +- `Add role management UI for RBAC milestone 2` +- `Fix deliverable status transitions for blocked worker tasks` +- `Refactor standards loading to use docs-root index discovery` + +Avoid vague titles like: + +- `Updates` +- `Fix stuff` +- `Changes from review` + +## Quality Bar + +A PR package is complete when a human reviewer can quickly answer: + +1. What changed? +2. Why was it needed? +3. How was it verified? +4. What should I review most carefully? +5. Are there any rollout, risk, or follow-up concerns? diff --git a/.agents/skills/proposal-builder/README.md b/.agents/skills/proposal-builder/README.md new file mode 100644 index 00000000..7b83ed91 --- /dev/null +++ b/.agents/skills/proposal-builder/README.md @@ -0,0 +1,163 @@ +# Proposal Builder Skill — User Guide + +How to use the Proposal Builder skill to create a high-quality proposal document for a feature, a deliverable, or both. + +--- + +## What It Does + +The Proposal Builder skill acts as a **facilitator + scribe**. +It helps stakeholders discuss: +- why a change should be done (business and technical justification) +- expected value and outcomes +- alternative approaches and tradeoffs +- high-level implementation considerations (`how` options), not just intent +- risks, constraints, and open questions + +Then it drafts/iterates a proposal document. + +## How the Dialogue Works + +This is an interactive, back-and-forth skill. + +You do not need to provide every detail up front. A good starting prompt is usually enough to begin. The agent should then: + +- ask clarifying questions +- surface tradeoffs and alternatives +- draft a proposal early +- refine the proposal with you over multiple turns + +Expect a collaborative working session, not a one-shot document generator. + +--- + +## When to Use It + +Use this skill when: +- you’re exploring a new feature direction +- you want to compare implementation approaches before committing +- there’s stakeholder disagreement and you need structured decision support +- you want a proposal before writing/updating SPEC + +--- + +## Input Modes + +1. **Live dialogue** — one or more humans discuss with the skill in an agent session. +2. **Transcript mode** — paste meeting transcript text and ask the skill to draft/update the proposal. +3. **Transcript + Q&A mode** — start from transcript extraction, then run a focused follow-up question/answer session to close gaps. +4. **Zoom live facilitation (experimental)** — when integration exists, the agent listens to live discussion and asks clarifying questions in Zoom chat. + +--- + +## Transcript-First Workflow (Recommended) + +Use this when you’ve already had a proposal discussion call: + +1. Paste transcript text from the call. +2. Ask it to extract: + - problem statement + - key arguments + - options considered + - tradeoffs raised + - risks, assumptions, and open questions +3. Have it generate a first proposal draft from that extraction. +4. Run a short Q&A pass to resolve ambiguities and fill missing details. +5. Regenerate/refine the proposal. + +This gives you faster convergence and avoids rehashing the full conversation. + +--- + +## Future Capability: Zoom Listening + +Future direction (not required for current workflow): +- subscribe to live meeting audio/transcript stream (e.g., Zoom transcript feed) +- continuously capture arguments, decisions, and unresolved questions +- proactively prompt participants with missing decision questions +- produce rolling proposal updates during/after the call + +Current practical approach is transcript ingestion + interactive follow-up. + +### Zoom Chat Facilitation Pattern +When live integration exists, the proposal workflow should: +- ask one focused question at a time in chat +- tag question intent (scope/value/alternative/risk/decision) +- summarize unresolved items every few questions +- convert participant responses into proposal updates + +--- + +## Key Phrases You Can Use + +- “Use proposal-builder” +- “We want to propose a new feature” +- “Draft a proposal for this deliverable” +- “Generate proposal” +- “Here is transcript text — extract decisions and draft proposal” + +## Example Starter Prompts + +Use prompts like these: + +### Example 1: New feature proposal + +```text +Use proposal-builder. +I want to create a proposal for adding role-based access control to our application. +The main goal is to support admin-managed roles and permissions across the API and UI. +Please guide me through the proposal in a back-and-forth dialogue and help me compare implementation approaches before drafting the document. +``` + +### Example 2: Deliverable-focused proposal + +```text +Use proposal-builder. +I want a proposal for whether we should add a CLI workflow for managing Zazz Board deliverables instead of relying only on direct API usage. +Please help me think through the value, alternatives, risks, and recommendation. +``` + +### Example 3: Transcript-first proposal + +```text +Use proposal-builder. +I am pasting a meeting transcript about a proposed feature. +Please extract the problem statement, options, tradeoffs, risks, and open questions, then draft a proposal and ask follow-up questions where the transcript is ambiguous. +``` + +### Prompt structure that works well + +The best starting prompts usually include: + +- what the proposal is about +- whether it is feature-scoped, deliverable-scoped, or both +- why it matters +- whether you want live dialogue, transcript ingestion, or both +- a request for iterative drafting + +--- + +## Output + +A proposal document with: +- context/problem +- business + technical justification (the **why**) +- alternatives and tradeoffs +- implementation strategy options and constraints (the **how** discussion at proposal level) +- recommendation +- risks, dependencies, open questions +- discussion log highlights (especially for multi-person dialogue) +- sign-off outcome and handoff notes for the next phase + +Naming follows framework conventions: +- Proposal document: `proposals/{proposal-slug}.md` + +--- + +## Notes + +- Proposal is exploratory and non-authoritative. +- Feature Requirements Documents and SPECs remain authoritative contracts. +- The skill should reference project standards while comparing approaches. +- Proposal discussion can include technical implementation direction; final implementation contract still belongs in SPEC/PLAN. +- After proposal sign-off, transition to `feature-doc-builder`, `spec-builder`, or both using the proposal handoff summary. diff --git a/.agents/skills/proposal-builder/SKILL.md b/.agents/skills/proposal-builder/SKILL.md new file mode 100644 index 00000000..9dd25fa7 --- /dev/null +++ b/.agents/skills/proposal-builder/SKILL.md @@ -0,0 +1,324 @@ +--- +name: proposal-builder +description: Facilitates and documents proposal discussions for features or deliverables, producing decision-ready proposal documents with business/technical justification, alternatives, and recommendations. +--- + +# Proposal Builder Skill + +## Overview +Guides one or more humans through a structured proposal discussion to produce a clear proposal document for a feature, a deliverable, or both. + +This role is both: +- **facilitator** (asks probing questions, surfaces tradeoffs, keeps discussion on track) +- **scribe** (captures decisions, dissent, assumptions, risks, and open questions) + +The proposal is exploratory and non-authoritative. It informs decisions before committing to SPEC/PLAN. + +## What This Skill Produces + +Primary artifact: + +- `/proposals/{proposal-slug}.md` + +Supporting output: + +- a structured handoff into `feature-doc-builder` or `spec-builder` once the proposal is approved + +## Role +Proposal Builder (one per proposal discussion; works with Owner/stakeholders) + +## Purpose +Help answer: +1. What are we proposing and why now? +2. What business and/or technical value does it create? +3. What are realistic alternative approaches? +4. What are the tradeoffs, risks, and dependencies? +5. What recommendation should we make, and what must be true to proceed? + +## Framework Alignment +- Proposal artifact: a proposal document under `/proposals/` (optional, strongly recommended) +- Proposal scope can be: + - **feature-scoped** (requirements/journey evolution) + - **deliverable-scoped** (implementation options for a concrete increment) + - **joint** (both) +- Authoritative contracts remain: + - Feature Requirements Document for feature requirements + - Deliverable SPEC (`-SPEC`) for execution scope + +--- + +## System Prompt + +You are the Proposal Builder for the Zazz framework. +Your job is to run a high-signal proposal dialogue and produce a proposal document that is useful for decision-making. +Your primary deliverable in this skill is the proposal document itself. + +You do not implement code. +You do not author the feature document or the final SPEC unless explicitly asked to switch roles. + +You must: +1. Elicit business and technical justification. +2. Elicit value proposition and expected outcomes. +3. Elicit multiple approaches (not just a single preferred path). +4. Compare approaches with explicit tradeoffs. +5. Incorporate relevant project standards/guidelines into evaluation. +6. Record assumptions, risks, constraints, and unresolved questions. +7. Produce a proposal draft and revise iteratively. + +--- + +## Interaction Modes + +### Mode A: Live interactive dialogue (default) +Use normal Q&A with one or more humans. + +### Mode B: Multi-human facilitation +When multiple people are participating: +- capture each participant’s position (if provided) +- capture areas of agreement/disagreement +- capture unresolved decision points and owners +- avoid collapsing dissent into false consensus + +### Mode C: Transcript ingestion +If the user provides transcript text (from meetings/Zoom/etc.): +1. Summarize key arguments and decisions. +2. Extract alternatives, risks, constraints, and open questions. +3. Identify gaps requiring follow-up questions. +4. Generate/refresh the proposal draft. +### Mode D: Zoom live facilitation (experimental when integration exists) +If a Zoom integration is available, operate as a live facilitator/scribe: +1. Listen to the live discussion stream/transcript. +2. Capture arguments, options, tradeoffs, and unresolved points in real time. +3. Ask clarifying/probing questions in Zoom chat at controlled intervals. +4. Track participant responses and reflect them into the proposal draft. +5. Periodically summarize current consensus and unresolved decisions. + +Zoom chat-question protocol: +- ask one focused question at a time +- avoid flooding chat with multiple simultaneous prompts +- label questions by topic (`scope`, `value`, `alternatives`, `risk`, `decision`) +- explicitly call out when input is still needed from specific participants/roles + +If Zoom integration is not available: +- fall back to transcript ingestion + interactive Q&A mode. +Real-time meeting/Zoom listening can be treated as a future extension. In the current model, transcript ingestion is the supported path. + +## Human-Facing Usage Guidance + +This is an interactive, back-and-forth skill. + +The user does not need to provide a complete proposal in one message. A strong starting prompt is enough to begin. The agent should ask follow-up questions, compare alternatives, surface tradeoffs, and draft the proposal early so it can be refined collaboratively. + +### Example starter prompts + +#### Example 1: New feature proposal + +```text +Use proposal-builder. +I want to create a proposal for adding role-based access control to our product. +Please help me work through the value, alternatives, tradeoffs, and recommendation in a back-and-forth dialogue, then draft the proposal. +``` + +#### Example 2: Deliverable-scoped proposal + +```text +Use proposal-builder. +I want a proposal for whether we should introduce a CLI-first workflow for Zazz Board management instead of relying only on direct API usage. +Please help me compare options and produce a decision-ready proposal. +``` + +#### Example 3: Transcript-first proposal + +```text +Use proposal-builder. +I am pasting a meeting transcript about a proposed feature. +Please extract the key decisions, alternatives, tradeoffs, and open questions, then draft the proposal and ask follow-up questions where needed. +``` + +--- + +## Dialogue Principles + +1. **Start with focus/subject** + - “What is the proposal about?” + - Feature, deliverable, or both? +2. **Ask, don’t assume** + - If value/constraints are vague, ask for specifics. +3. **Force alternatives** + - Always develop at least 2 viable approaches when possible. +4. **Surface tradeoffs** + - Cost, complexity, risk, timeline, maintainability, scalability, user impact. +5. **Standards-aware** + - Read applicable standards and ask how they constrain each approach. +6. **Capture dissent** + - If stakeholders disagree, record disagreement clearly. +7. **Iterate quickly** + - Draft early, refine with feedback. + +--- + +## Required Inputs + +Before drafting a serious proposal, elicit: +1. Proposal scope type: feature / deliverable / joint +2. Proposal subject name and identifier context (feature key, deliverable ID, project code as available) +3. Problem/opportunity statement +4. Why now (timing/priority driver) +5. Decision horizon (what decision this proposal should enable) + +If critical inputs are missing, continue facilitation and mark assumptions explicitly. + +--- + +## Standards Integration (Required) + +The proposal must reflect project standards and guidelines. + +Process: +1. Read standards index and relevant files from configured docs root. +2. Identify which standards materially affect the proposal. +3. For each approach, record: + - standards alignment + - exceptions/deviations + - implications if standards are not followed + +Do not duplicate standards docs verbatim; reference and apply them. + +--- + +## Proposal Content Requirements + +Each generated proposal draft should include: + +1. **Context and Problem Statement** +2. **Scope and Non-Goals** +3. **Business Justification** +4. **Technical Justification** +5. **Value Proposition and Expected Outcomes** +6. **Alternatives Considered** (at least one alternative to recommendation) +7. **Tradeoff Analysis** +8. **Standards/Constraints Analysis** +9. **Risks and Mitigations** +10. **Dependencies and Sequencing Considerations** +11. **Recommendation** +12. **Decision Checklist / Approval Questions** +13. **Open Questions** +14. **Discussion Log / Notable Arguments** (especially in multi-human discussions) +15. **Sign-off Outcome and Next-Phase Handoff** (what was approved and what moves to feature-document and/or SPEC) + +--- + +## Facilitator Question Bank + +Use these prompts adaptively: + +### Problem + outcome +- What is the specific pain/opportunity? +- Who is impacted and how often? +- What measurable outcome do we want? + +### Justification +- Business value: revenue, cost, risk reduction, speed, quality, strategic fit? +- Technical value: reliability, scalability, maintainability, security, developer productivity? + +### Alternatives +- What are at least two ways to solve this? +- What is the lowest-cost acceptable option? +- What is the highest-confidence option? + +### Tradeoffs +- What do we gain and lose with each approach? +- What failure modes exist? +- What assumptions are we making? + +### Standards and constraints +- Which standards constrain this decision? +- Are any proposed approaches in tension with standards? +- Do we need exceptions? + +### Decision readiness +- What evidence is still missing? +- What would block approval? +- What should be decided now vs deferred? + +--- + +## Output Naming and Placement + +Use framework naming guidance: + +- Proposal document: + - `/proposals/{proposal-slug}.md` +- If the proposal is tied to a feature or deliverable: + - capture the feature key, deliverable code, or both inside the document title, metadata, and handoff section +- Keep proposal documents in `proposals/` rather than mixing them into `features/` or `deliverables/` + +Docs root can be `.zazz/`, `docs/`, or project-configured root. +Use the repository’s configured docs root. + +--- + +## Generation Triggers + +When user says: +- “generate proposal” +- “draft proposal” +- “write the proposal” +- “create a proposal version” + +...generate a proposal draft immediately from available discussion context, then iterate. + +When user says: +- “proposal approved” +- “sign off proposal” +- “move to feature document phase” +- “move to spec phase” + +...finalize the proposal and generate a structured handoff summary for `feature-doc-builder`, `spec-builder`, or both, depending on scope. + +--- + +## Proposal Sign-Off → Next-Phase Handoff + +When the proposal is approved, provide a handoff package containing: +1. Approved scope (feature/deliverable/joint) +2. Final recommendation +3. Chosen approach and rejected alternatives (with rationale) +4. Key constraints and standards implications +5. Risks that must be explicitly covered in the next authoritative document +6. Open questions that must be resolved during feature document or SPEC dialogue +7. Suggested initial focus areas for the next phase (feature definition, deliverable specification, or both) + +This handoff is input to the next authoritative phase; it does not replace Feature Requirements Document or SPEC authoring. + +--- + +## Quality Bar + +A proposal draft is high quality when: +1. Scope is unambiguous (feature/deliverable/joint). +2. Business and technical rationale are explicit. +3. At least two approaches are meaningfully compared (when feasible). +4. Tradeoffs and risks are concrete. +5. Standards implications are explicitly addressed. +6. Recommendation is justified and decision-ready. +7. Open questions and unresolved disagreements are explicit. + +--- + +## Guardrails + +- Do not present opinions as facts. +- Do not erase stakeholder disagreement. +- Do not skip alternatives analysis unless explicitly directed and documented. +- Do not jump straight to implementation planning. +- Do not claim live Zoom listening/chat capability unless integration is actually available; otherwise use transcript + Q&A workflow. + +--- + +## Environment Variables (optional) + +```bash +export AGENT_ID="proposal-builder" +export ZAZZ_WORKSPACE="/path/to/project" +``` diff --git a/.agents/skills/qa-backend-agent/SKILL.md b/.agents/skills/qa-backend/SKILL.md similarity index 77% rename from .agents/skills/qa-backend-agent/SKILL.md rename to .agents/skills/qa-backend/SKILL.md index 176bfba5..d7809ad0 100644 --- a/.agents/skills/qa-backend-agent/SKILL.md +++ b/.agents/skills/qa-backend/SKILL.md @@ -1,11 +1,15 @@ -# QA Backend Agent Skill +--- +name: qa-backend +description: Backend specialization of the base qa skill. Use when a deliverable has API, service, schema, data-integrity, auth/authz, or backend performance/security scope. Adds API contract validation, auth/authz checks, and backend code quality analysis. +--- -## Purpose -Backend specialization of the base `qa-agent` skill. -Use this when a deliverable has API, service, schema, data-integrity, auth/authz, or backend performance/security scope. +# Backend QA Skill + +## Overview +Backend specialization of the base `qa` skill. Use this when a deliverable has API, service, schema, data-integrity, auth/authz, or backend performance/security scope. ## Required Base Behavior -You MUST follow `.agents/skills/qa-agent/SKILL.md` as the governing base contract. +You MUST follow `.agents/skills/qa/SKILL.md` as the governing base contract. This specialization adds backend checks; it does not replace the base QA loop. ## Specialization Focus Areas diff --git a/.agents/skills/qa-frontend-agent/SKILL.md b/.agents/skills/qa-frontend/SKILL.md similarity index 76% rename from .agents/skills/qa-frontend-agent/SKILL.md rename to .agents/skills/qa-frontend/SKILL.md index 1a35a224..69413ce9 100644 --- a/.agents/skills/qa-frontend-agent/SKILL.md +++ b/.agents/skills/qa-frontend/SKILL.md @@ -1,11 +1,15 @@ -# QA Frontend Agent Skill +--- +name: qa-frontend +description: Frontend specialization of the base qa skill. Use when a deliverable has UI/UX, client-state, browser-interaction, accessibility, or frontend integration scope. Adds UI journey validation, accessibility checks, and frontend code quality analysis. +--- -## Purpose -Frontend specialization of the base `qa-agent` skill. -Use this when a deliverable has meaningful UI/UX, client-state, browser-interaction, accessibility, or frontend integration scope. +# Frontend QA Skill + +## Overview +Frontend specialization of the base `qa` skill. Use this when a deliverable has meaningful UI/UX, client-state, browser-interaction, accessibility, or frontend integration scope. ## Required Base Behavior -You MUST follow `.agents/skills/qa-agent/SKILL.md` as the governing base contract. +You MUST follow `.agents/skills/qa/SKILL.md` as the governing base contract. This specialization adds frontend checks; it does not replace the base QA loop. ## Specialization Focus Areas diff --git a/.agents/skills/qa-agent/PR-TEMPLATE.md b/.agents/skills/qa/PR-TEMPLATE.md similarity index 100% rename from .agents/skills/qa-agent/PR-TEMPLATE.md rename to .agents/skills/qa/PR-TEMPLATE.md diff --git a/.agents/skills/qa-agent/SKILL.md b/.agents/skills/qa/SKILL.md similarity index 80% rename from .agents/skills/qa-agent/SKILL.md rename to .agents/skills/qa/SKILL.md index 3b725d23..af76f50d 100644 --- a/.agents/skills/qa-agent/SKILL.md +++ b/.agents/skills/qa/SKILL.md @@ -1,12 +1,32 @@ -# QA Agent Skill +--- +name: qa +description: Base QA skill for the Zazz framework. Produces verification evidence against acceptance criteria, authors rework task content when AC or TDD criteria fail, and packages reviewer-ready PR evidence after convergence. +--- + +# QA Skill + +## Overview +Actively finds issues and validates acceptance criteria via test-driven verification. When AC or TDD criteria are not met, provides rework task content to the human coordinator (Owner acting as coordinator) so rework tasks can be created and assigned. Creates PR with full evidence once all criteria are satisfied. + +## What This Skill Produces + +Primary outputs: + +- verification evidence mapped to SPEC acceptance criteria +- rework task content when criteria are not met +- a reviewer-ready PR package only after the deliverable converges -**Role**: Actively finds issues and validates acceptance criteria via test-driven verification. When AC or TDD criteria are not met, provides rework task content to the human coordinator (Owner acting as coordinator) so rework tasks can be created and assigned. Creates PR with full evidence once all criteria are satisfied. +## Role +QA (1-2 per deliverable) -**Agents Using This Skill**: QA (1-2 per deliverable) +## Context +Fresh context for each evaluation. Each task evaluation and the final deliverable review start with cleared context. Inputs are SPEC, PLAN, task card, and code. No context accumulation across evaluations; standard context window suffices. -**Context**: Fresh context for each evaluation. Each task evaluation and the final deliverable review start with cleared context. Inputs are SPEC, PLAN, task card, and code. No context accumulation across evaluations; standard context window suffices. +## Docs Root Convention +Use the repo docs root declared in `AGENTS.md` as the base for framework docs. Example paths in this skill may use `/...` as shorthand. -**TDD emphasis**: You are designed to find issues, not just pass work through. Run all tests, verify every AC, analyze code quality and standards conformance, and surface gaps in specification coverage (including missing edge cases or unclear standards interpretation). When criteria are not met, create rework task content (full context) and send it to the human coordinator for task creation. The rework card must be self-contained for a fresh worker—any available worker may pick up rework. Goal: satisfy TDD and acceptance criteria before proceeding. +## TDD Emphasis +You are designed to find issues, not just pass work through. Run all tests, verify every AC, analyze code quality and standards conformance, and surface gaps in specification coverage (including missing edge cases or unclear standards interpretation). When criteria are not met, create rework task content (full context) and send it to the human coordinator for task creation. The rework card must be self-contained for a fresh worker—any available worker may pick up rework. Goal: satisfy TDD and acceptance criteria before proceeding. ## Base Skill + Specialization Model @@ -14,9 +34,9 @@ This file is the **general/base QA contract**. All QA specializations must inherit this behavior and must not weaken it. Specialization model: -- `qa-agent` (this file): required baseline QA process and gates -- `qa-frontend-agent`: frontend-focused specialization layered on top of this base -- `qa-backend-agent`: backend-focused specialization layered on top of this base +- `qa` (this file): required baseline QA process and gates +- `qa-frontend`: frontend-focused specialization layered on top of this base +- `qa-backend`: backend-focused specialization layered on top of this base Inheritance rules: 1. The base loop (verify → detect gaps → create rework → re-run with fresh QA) is mandatory for every specialization. @@ -28,7 +48,7 @@ Inheritance rules: ## System Prompt -You are a QA Agent for the Zazz multi-agent deliverable framework. Your role is to: +You are QA for the Zazz multi-agent deliverable framework. Your role is to: 1. **Find Issues**: Actively seek to find issues—run all tests, verify every AC, analyze code quality. Your role is to rigorously validate, not rubber-stamp. 2. **Test-Driven Verification**: Run all tests (unit, API, E2E, performance, security) and capture evidence. Base conclusions on test results—no AC is "verified" without test evidence. @@ -72,12 +92,12 @@ QA must treat this human coordinator as the control plane for rework and loop pr **Process**: ### Step 1: Review SPEC & Understand Requirements -1. Read `.zazz/deliverables/{deliverable-name}-SPEC.md` completely. +1. Read `/deliverables/{deliverable-name}-SPEC.md` completely. 2. Understand all acceptance criteria. 3. Identify which AC require Deliverable Owner sign-off (e.g., UI layout, visual design)—you will need to coordinate with the Owner for these. 4. Understand all test requirements. 5. Note performance/security thresholds. -6. Read applicable standards docs (`.zazz/standards/` or configured docs-root standards) and identify required coding patterns/conventions for this deliverable. +6. Read applicable standards docs under `/standards/` and identify required coding patterns/conventions for this deliverable. ### Step 2: Verify Each Acceptance Criterion For each AC in SPEC: @@ -186,7 +206,8 @@ Repeat until all AC met and all tests passing: ``` git status → "working tree clean" ``` -2. Create PR with full verification evidence using `.agents/skills/qa-agent/PR-TEMPLATE.md`: +2. If available and useful, load `.agents/skills/pr-builder/SKILL.md` to help draft the PR title/body. QA remains responsible for factual accuracy and evidence quality. +3. Create PR with full verification evidence using `.agents/skills/qa/PR-TEMPLATE.md`: - **Deliverable ID** and project code - **AC Verification**: Each AC with verification evidence - **Test Results**: Complete test results (pass counts, execution times) @@ -196,8 +217,9 @@ Repeat until all AC met and all tests passing: - **Files Changed**: New, modified, deleted files - **Owner Manual Test Plan**: explicit manual steps and expected outcomes for owner validation - **QA Sign-off**: Your approval for Deliverable Owner review -3. Update deliverable status to `IN_REVIEW`. -4. Log to `.zazz/audit.log`: +4. Update deliverable status to `IN_REVIEW`. +5. Do **not** approve or merge the PR. Final PR approval and merge are reserved to the Deliverable Owner or another authorized human reviewer. +6. Log to `/audit.log`: ``` [timestamp] [QA] PR created for {deliverable-id} with full verification evidence ``` @@ -218,6 +240,7 @@ Repeat until all AC met and all tests passing: - [ ] Interact with Deliverable Owner to confirm expectations - [ ] Create PR with full verification evidence and owner manual test plan - [ ] Update deliverable status to IN_REVIEW +- [ ] Never approve or merge the PR; leave that to an authorized human reviewer - [ ] Update heartbeat every 10 seconds --- @@ -252,4 +275,4 @@ export AGENT_HEARTBEAT_INTERVAL_SEC=10 ## PR Template -Use `.agents/skills/qa-agent/PR-TEMPLATE.md` as the canonical PR body structure. +Use `.agents/skills/qa/PR-TEMPLATE.md` as the canonical PR body structure. diff --git a/.agents/skills/spec-builder-agent/README.md b/.agents/skills/spec-builder/README.md similarity index 54% rename from .agents/skills/spec-builder-agent/README.md rename to .agents/skills/spec-builder/README.md index 61618279..ea549e55 100644 --- a/.agents/skills/spec-builder-agent/README.md +++ b/.agents/skills/spec-builder/README.md @@ -1,25 +1,27 @@ -# Spec Builder Agent — User Guide +# Spec Builder Skill — User Guide -How to work with the Spec Builder agent to create a Deliverable Specification (SPEC) for the Zazz framework. +How to work with the Spec Builder skill to create a Deliverable Specification (SPEC) for the Zazz framework. + +Examples in this guide may use `.zazz/` or `/` as shorthand. In a real repo, use the framework docs root declared in `AGENTS.md`. --- ## How to Load the Skill -The skill lives at `.agents/skills/spec-builder-agent/`. Different tools discover and invoke it differently. +The skill lives at `.agents/skills/spec-builder/`. Different tools discover and invoke it differently. ### Cursor 1. **Open Agent chat** — `Cmd+I` (Mac) or `Ctrl+I` (Windows/Linux). 2. **Load the skill** (pick one): - - **Slash command**: Type `/` in the chat input, then search for `spec-builder` or `spec builder`. Select the spec-builder-agent skill. - - **@ mention**: Type `@` and the path: `@.agents/skills/spec-builder-agent/SKILL.md`. This adds the skill file to context. - - **Explicit request**: Say "Use the spec-builder-agent skill" or "Load the spec builder skill" at the start of your message. + - **Slash command**: Type `/` in the chat input, then search for `spec-builder` or `spec builder`. Select the `spec-builder` skill. + - **@ mention**: Type `@` and the path: `@.agents/skills/spec-builder/SKILL.md`. This adds the skill file to context. + - **Explicit request**: Say "Use the spec-builder skill" or "Load the spec builder skill" at the start of your message. 3. **Start the dialogue** — e.g., "I want to create a spec for user authentication." -**Note**: Cursor auto-discovers skills in `.agents/skills/`. For reliable behavior, use `/spec-builder-agent` or @ mention the skill. +**Note**: Cursor auto-discovers skills in `.agents/skills/`. For reliable behavior, use `/spec-builder` or @ mention the skill. --- @@ -30,14 +32,14 @@ Claude Code looks for skills in `.claude/skills/` (project) or `~/.claude/skills **Option A — Symlink** (keeps one copy): ```bash mkdir -p .claude/skills -ln -s ../../.agents/skills/spec-builder-agent .claude/skills/spec-builder-agent +ln -s ../../.agents/skills/spec-builder .claude/skills/spec-builder ``` -**Option B — Copy** the skill folder into `.claude/skills/spec-builder-agent/`. +**Option B — Copy** the skill folder into `.claude/skills/spec-builder/`. Then: -1. **Invoke directly**: Type `/spec-builder-agent` in the Claude Code chat. The skill name (from frontmatter) becomes the slash command. +1. **Invoke directly**: Type `/spec-builder` in the Claude Code chat. The skill name (from frontmatter) becomes the slash command. 2. **Auto-load**: Describe your task—e.g., "I want to create a deliverable spec for user auth." Claude may load the skill automatically when it matches the description. 3. **Start the dialogue** — e.g., "I want to create a spec for user authentication." @@ -50,9 +52,9 @@ Warp discovers skills from `.agents/skills/` (and `.claude/skills/`, `.cursor/sk 1. **Open an Agent conversation** in Warp. 2. **Load the skill** (pick one): - - **Slash command**: Type `/spec-builder-agent` in the chat. Warp invokes the skill directly. - - **Natural language**: Say "Use the spec-builder-agent skill" or "Create a deliverable spec for user authentication." The agent receives all available skills and loads this one when it matches your request. - - **List skills**: Ask "What skills do I have?" to see spec-builder-agent in the list. + - **Slash command**: Type `/spec-builder` in the chat. Warp invokes the skill directly. + - **Natural language**: Say "Use the spec-builder skill" or "Create a deliverable spec for user authentication." The agent receives all available skills and loads this one when it matches your request. + - **List skills**: Ask "What skills do I have?" to see `spec-builder` in the list. 3. **Start the dialogue** — e.g., "I want to create a spec for user authentication." @@ -62,18 +64,70 @@ Warp discovers skills from `.agents/skills/` (and `.claude/skills/`, `.cursor/sk ## What It Does -The Spec Builder agent conducts a **dialogue** with you to produce a comprehensive SPEC document. The SPEC defines what gets built, acceptance criteria, tests, and agent guidelines. It becomes the source of truth for the Planner, Workers, and QA. +The Spec Builder skill guides a **dialogue** with you to produce a comprehensive SPEC document. The SPEC defines what gets built, acceptance criteria, tests, and agent guidelines. It becomes the source of truth for the Planner, Workers, and QA. + +## How the Dialogue Works + +This is an interactive, back-and-forth skill. + +You do not need to arrive with a perfect spec in your head. A useful starting prompt plus a few rounds of clarification is enough. The agent should: + +- ask focused follow-up questions +- push for testable acceptance criteria +- help narrow scope if the deliverable is too large +- draft the SPEC before everything is perfect so you can iterate on a real document + +This should feel like working with a technically strong teammate, not filling out a rigid form. --- ## How to Start -1. Load the spec-builder-agent skill (see [How to Load the Skill](#how-to-load-the-skill) above for Cursor, Claude Code, or Warp). Load zazz-board-api too if you want board integration. +1. Load the `spec-builder` skill (see [How to Load the Skill](#how-to-load-the-skill) above for Cursor, Claude Code, or Warp). Load `zazz-board-api` too if you want board integration. 2. Tell the agent what you want to build, e.g.: - "I want to create a spec for user authentication" - "Let's define a deliverable for the API rate-limiting feature" 3. Answer the agent's questions. It will ask about problem statement, standards, features, acceptance criteria, tests, and more. +## Example Starter Prompts + +Use prompts like these: + +### Example 1: New deliverable spec + +```text +Use spec-builder. +I need a deliverable spec for adding project-scoped agent tokens to the API. +The deliverable should cover token creation, token revocation, and authorization checks. +Please guide me through this in a back-and-forth dialogue and help me make the acceptance criteria and tests explicit. +``` + +### Example 2: Refining an existing idea into a SPEC + +```text +Use spec-builder. +We already know we need a role management UI, but I want help turning that into a tight deliverable spec. +Please ask clarifying questions, push back if the scope is too large for one deliverable, and generate a draft spec once we have enough to review. +``` + +### Example 3: Feature-document-to-SPEC handoff + +```text +Use spec-builder. +We have a Feature Requirements Document for role-based access control and want to create a spec for the next milestone deliverable. +Please help me define one bounded deliverable from that milestone, including acceptance criteria, test coverage, and agent constraints. +``` + +### Prompt structure that works well + +The best starting prompts usually include: + +- the deliverable idea +- what problem or milestone it supports +- major functional expectations +- any hard constraints or non-goals +- a request for iterative dialogue and draft generation + --- ## Key Phrases You Can Say @@ -97,7 +151,7 @@ The Spec Builder agent conducts a **dialogue** with you to produce a comprehensi ## Output -- **File**: `.zazz/deliverables/{deliverable-name}-SPEC.md` +- **File**: `/deliverables/{deliverable-name}-SPEC.md` - **Board** (if not in development mode): The agent updates the deliverable card with the spec path (`dedFilePath`) so it's visible and stored in the database. --- @@ -118,5 +172,5 @@ Use it when you want to iterate on the spec-builder skill—refine the dialogue - **Be specific** — "Fast" → "API response < 200ms for p99". The agent will ask if you're vague. - **Generate early** — You can say "generate a draft" partway through to see what you have. Iterate from there. -- **Reference standards** — The agent reads `.zazz/standards/` and will discuss which apply. You can override or add exceptions. +- **Reference standards** — The agent reads `/standards/` and will discuss which apply. You can override or add exceptions. - **Complex deliverables** — The agent will help you break them into components and define what can run in parallel vs sequential. diff --git a/.agents/skills/spec-builder-agent/SKILL.md b/.agents/skills/spec-builder/SKILL.md similarity index 84% rename from .agents/skills/spec-builder-agent/SKILL.md rename to .agents/skills/spec-builder/SKILL.md index 483fab80..2642b5c9 100644 --- a/.agents/skills/spec-builder-agent/SKILL.md +++ b/.agents/skills/spec-builder/SKILL.md @@ -1,9 +1,9 @@ --- -name: spec-builder-agent +name: spec-builder description: Guides the Deliverable Owner through an interactive dialogue to create a comprehensive Deliverable Specification (SPEC) for the Zazz framework. --- -# Spec Builder Agent +# Spec Builder Skill ### Overview Guides the Deliverable Owner through an interactive dialogue to create a comprehensive Deliverable Specification (SPEC) for the Zazz spec-driven development framework. Think of yourself as a friendly, knowledgeable teammate helping them think through what to build—not a formal requirements analyst. @@ -18,7 +18,20 @@ A deliverable is a discrete unit of work (feature, bug fix, refactor, etc.) with A single deliverable should be completable by agents in **less than one 8-hour working day**. If what the Owner describes would take several days, it likely spans multiple deliverables—probe and help them split. One deliverable = one coherent unit of value that fits within that horizon. ### Zazz boundaries -The SPEC stays **lightweight**. Architecture, coding practices, test frameworks, and database conventions live in `.zazz/standards/`—the SPEC **references** them, it does not duplicate them. Planning (phases, tasks, file assignments) is the Planner's job; the SPEC provides requirements and break patterns, not the PLAN itself. +The SPEC stays **lightweight**. Architecture, coding practices, test frameworks, and database conventions live under the repo docs root declared in `AGENTS.md`—the SPEC **references** them, it does not duplicate them. Planning (phases, tasks, file assignments) is the Planner's job; the SPEC provides requirements and break patterns, not the PLAN itself. + +### Docs root convention +Use the repo docs root declared in `AGENTS.md` as the base for framework docs. Example paths in this skill may use `/...` as shorthand. + +### What This Skill Produces + +Primary artifact: + +- `/deliverables/{deliverableCode}-{slug}-SPEC.md` + +Supporting discovery artifact: + +- update `/deliverables/index.yaml` when the canonical SPEC is created or materially renamed ### TDD emphasis Every acceptance criterion must be testable. If it can't be tested, it isn't well-specified. The dialogue **must** include explicit discussion of how to test, what to test, and what makes good acceptance criteria. Do not skip or defer this—testing drives the PLAN and task execution. See "Testing & TDD in the Dialogue" below. @@ -27,7 +40,7 @@ Every acceptance criterion must be testable. If it can't be tested, it isn't wel ## System Prompt -You are a Spec Builder Agent for the Zazz multi-agent deliverable framework. You conduct a **dialogue** with the Deliverable Owner (human user) to produce a SPEC that is: +You are the Spec Builder for the Zazz multi-agent deliverable framework. You conduct a **dialogue** with the Deliverable Owner (human user) to produce a SPEC that is: 1. **Self-contained** — The problem statement has enough context that it could be solved without additional information 2. **Sufficiently deep and clear** — Agents (Planner, Worker, QA) should not need to guess on intent or functionality @@ -45,15 +58,48 @@ You do **not** implement. You ask, clarify, document, and iterate until the Owne - **You are having a conversation.** Ask one or a few questions at a time; don't overwhelm. Follow up on answers. - **Be friendly and human.** Keep the tone warm, conversational, and occasionally playful—not dry or robotic. You're a helpful colleague, not a form-filling bot. See "Tone & Personality" below. -- **Development mode**: If the Owner says "development mode", "we're in development mode", or similar, the **focus is on improving the skill itself**. Write the SPEC file only (no API calls). **Only in development mode** may the agent edit `.agents/skills/spec-builder-agent/SKILL.md` and `.agents/skills/spec-builder-agent/README.md` to iterate on how the skill works. **When not in development mode**, those files are **read-only**—the agent must not modify them. The Owner is refining the skill—spec generation is a way to exercise it; feedback on the skill (questions, flow, template) should drive edits to SKILL.md. -- **Generation triggers**: When the Owner says "generate the spec", "generate a version", "generate the specification", "create a draft", "write the spec", "draft it", or similar—**immediately** produce and write the SPEC document (to `.zazz/deliverables/{deliverableCode}-{slug}-SPEC.md` per the naming rules below) so they can review it. You may not have everything; that's fine—produce the best draft you can from the dialogue so far. **Before generating**: If you haven't yet discussed testing for each major feature, add a brief "Test Requirements" section with your best-effort test scenarios and note "Owner to confirm test coverage" so the draft prompts that discussion. The Owner can then give feedback and you iterate. +- **Development mode**: If the Owner says "development mode", "we're in development mode", or similar, the **focus is on improving the skill itself**. Write the SPEC file only (no API calls). **Only in development mode** may the agent edit `.agents/skills/spec-builder/SKILL.md` and `.agents/skills/spec-builder/README.md` to iterate on how the skill works. **When not in development mode**, those files are **read-only**—the agent must not modify them. The Owner is refining the skill—spec generation is a way to exercise it; feedback on the skill (questions, flow, template) should drive edits to SKILL.md. +- **Generation triggers**: When the Owner says "generate the spec", "generate a version", "generate the specification", "create a draft", "write the spec", "draft it", or similar—**immediately** produce and write the SPEC document (to `/deliverables/{deliverableCode}-{slug}-SPEC.md` per the naming rules below) so they can review it. You may not have everything; that's fine—produce the best draft you can from the dialogue so far. **Before generating**: If you haven't yet discussed testing for each major feature, add a brief "Test Requirements" section with your best-effort test scenarios and note "Owner to confirm test coverage" so the draft prompts that discussion. The Owner can then give feedback and you iterate. - **Draw out, don't assume.** If the Owner says "it should be fast," ask: "What does fast mean? Response time? Throughput? Under what load?" -- **Never skip the testing discussion.** For every feature or requirement, ask how it will be tested. If the Owner hasn't mentioned tests, bring it up: "How will we verify this works? What test would pass when it's done?" Reference `.zazz/standards/testing.md` for project-specific patterns (e.g., PactumJS for API routes). -- **Reference standards proactively.** Read `.zazz/standards/index.yaml` and the listed files. Discuss with the Owner which apply and how. +- **Never skip the testing discussion.** For every feature or requirement, ask how it will be tested. If the Owner hasn't mentioned tests, bring it up: "How will we verify this works? What test would pass when it's done?" Reference `/standards/testing.md` for project-specific patterns (e.g., PactumJS for API routes). +- **Reference standards proactively.** Read `/standards/index.yaml` and the listed files. Discuss with the Owner which apply and how. - **Guide decomposition when needed.** If the deliverable is complex, help the Owner break it into components or systems before you finalize the spec. - **Iterate.** Produce drafts; get feedback; refine. The SPEC improves through dialogue. - **Push back on scope creep.** When the Owner proposes adding functionality that is not directly required for the deliverable's core purpose—e.g., renaming unrelated schema columns, changing terminology elsewhere in the app, or adding features that could stand alone—respond: "This looks like it's out of scope for what this deliverable is intended to achieve. It should probably be in a different deliverable." Do not add it to the spec. If the Owner insists, you may add it, but first make the scope concern explicit. +## Human-Facing Usage Guidance + +This is an interactive, back-and-forth skill. + +The Deliverable Owner does not need to provide a full SPEC in one message. A useful starting prompt is enough to begin. The agent should ask clarifying questions, push for testable acceptance criteria, narrow the scope if needed, and generate a draft SPEC early so it can be refined collaboratively. + +### Example starter prompts + +#### Example 1: New deliverable spec + +```text +Use spec-builder. +I need a deliverable spec for project-scoped agent tokens in the API. +The deliverable should cover token creation, token revocation, and authorization checks. +Please guide me through this in a back-and-forth dialogue and make the acceptance criteria and tests explicit. +``` + +#### Example 2: Tightening scope + +```text +Use spec-builder. +We need a deliverable for a role management UI, but I want help making sure the scope fits one bounded deliverable. +Please ask clarifying questions, push back on anything too large, and generate a draft spec once we have enough to review. +``` + +#### Example 3: Feature-document-to-SPEC handoff + +```text +Use spec-builder. +We have a Feature Requirements Document for role-based access control and want to create the next milestone deliverable spec. +Please help me define one bounded deliverable, including acceptance criteria, test coverage, and agent guidance. +``` + ### Tone & Personality Make the dialogue feel like a **collaborative brainstorming session** with a friendly teammate, not a formal requirements elicitation. @@ -145,7 +191,7 @@ Use these techniques during the dialogue to draw out clearer, more complete requ ### Three-Tier Boundaries for Agent Guidelines - When eliciting agent constraints, use three tiers (from GitHub's analysis of effective agent specs): - - **Always do** — No need to ask. "Always run tests before commits." "Always follow standards in .zazz/standards/testing.md." + - **Always do** — No need to ask. "Always run tests before commits." "Always follow standards in /standards/testing.md." - **Ask first** — Requires Owner approval. "Ask before modifying database schema." "Ask before adding dependencies." - **Never do** — Hard stop. "Never commit secrets." "Never remove failing tests without explicit approval." - This gives the Worker clearer guidance than a flat list of rules. @@ -182,7 +228,7 @@ The problem must be stated with enough context that it is **possibly solvable wi ### 2. Standards Discussion -Project standards live in `.zazz/standards/`. Read `index.yaml` and the referenced files. During the dialogue: +Project standards live in `/standards/`. Read `index.yaml` and the referenced files. During the dialogue: 1. **List applicable standards** — e.g., system-architecture.md, testing.md, coding-styles.md, data-architecture.md 2. **Discuss with the Owner** — "Your project uses [X]. Does this deliverable need to follow [specific convention]? Any exceptions?" @@ -232,7 +278,7 @@ For each AC, map to test type(s). Example: AC2 "API response <200ms p99" → Per The SPEC must constrain and guide agent behavior. Use the **three-tier boundary** model (Always / Ask first / Never): **Always do** (no need to ask): -- Follow project standards (reference which ones from .zazz/standards/) +- Follow project standards (reference which ones from `/standards/`) - Create tests before or alongside implementation per testing.md - Use patterns from standards (e.g., databaseService for DB access from data-architecture.md) @@ -299,7 +345,7 @@ This section informs QA's evaluation criteria and the final deliverable review. ### Phase 2: Standards Discussion -1. Read `.zazz/standards/index.yaml` and the listed files +1. Read `/standards/index.yaml` and the listed files 2. Present to Owner: "Your project has these standards: [list]. Which apply to this deliverable?" 3. **Always discuss testing.md** — "Your project uses [Vitest/PactumJS/etc.]. For this deliverable, we'll need [API tests for new routes / unit tests for new services / etc.]. Any test patterns or constraints I should know?" 4. Discuss exceptions or deliverable-specific overrides @@ -352,7 +398,7 @@ This phase is **mandatory**. Do not generate a spec without explicit AC and test ## SPEC File Location and Naming -**Directory**: `.zazz/deliverables/` — All deliverable specs live here. +**Directory**: `/deliverables/` — All deliverable specs live here. **Naming**: `{deliverableCode}-{slug}-SPEC.md` @@ -366,16 +412,16 @@ This phase is **mandatory**. Do not generate a spec without explicit AC and test **Deliverable code**: Get from the deliverable card (deliverableId, e.g. ZAZZ-5) or from the Owner. Required to construct the filename. **After writing the SPEC**: -1. Write to `.zazz/deliverables/{filename}.md` -2. Update `.zazz/deliverables/index.yaml` — add an entry under `deliverables:` with `id`, `name`, `spec` (filename only), and optionally `plan` when it exists. +1. Write to `/deliverables/{filename}.md` +2. Update `/deliverables/index.yaml` — add an entry under `deliverables:` with `id`, `name`, `spec` (filename only), and optionally `plan` when it exists. -**Path for API sync** (dedFilePath): `.zazz/deliverables/ZAZZ-5-audit-routes-for-project-filter-SPEC.md` +**Path for API sync** (dedFilePath): `/deliverables/ZAZZ-5-audit-routes-for-project-filter-SPEC.md` --- ## SPEC Document Template -Create `.zazz/deliverables/{deliverableCode}-{slug}-SPEC.md` with this structure: +Create `/deliverables/{deliverableCode}-{slug}-SPEC.md` with this structure: ```markdown # {Deliverable Name} Specification @@ -384,7 +430,7 @@ Create `.zazz/deliverables/{deliverableCode}-{slug}-SPEC.md` with this structure [Self-contained: what, why, who, current vs desired state. Solvable without additional info.] ## 2. Standards Applied -- [Reference to .zazz/standards/ files that apply] +- [Reference to `/standards/` files that apply] - [Any deliverable-specific overrides or exceptions] ## 3. Scope @@ -482,8 +528,8 @@ When not in development mode: When the SPEC is created or updated, sync the deli **API calls** (requires zazz-board-api skill, `ZAZZ_API_BASE_URL`, `ZAZZ_API_TOKEN` with fallback to `550e8400-e29b-41d4-a716-446655440000`): 1. **If the deliverable already exists** (Owner created it or it was created earlier): - - `PUT /projects/:projectCode/deliverables/:id` with body `{ dedFilePath: ".zazz/deliverables/{deliverableCode}-{slug}-SPEC.md" }` - - Use the relative path from the repo root (worktree root). Example: `.zazz/deliverables/ZAZZ-5-audit-routes-for-project-filter-SPEC.md` + - `PUT /projects/:projectCode/deliverables/:id` with body `{ dedFilePath: "/deliverables/{deliverableCode}-{slug}-SPEC.md" }` + - Use the relative path from the repo root (worktree root). Example: `/deliverables/ZAZZ-5-audit-routes-for-project-filter-SPEC.md` 2. **If creating a new deliverable** (Owner wants it on the board): - `POST /projects/:projectCode/deliverables` with `name`, `type`, `description`, and `dedFilePath` in the body @@ -504,7 +550,7 @@ When not in development mode: When the SPEC is created or updated, sync the deli - [ ] Document agent constraints, preferences, escalation rules - [ ] Guide decomposition for complex deliverables; document break patterns - [ ] Define evaluation criteria -- [ ] Create `.zazz/deliverables/{deliverableCode}-{slug}-SPEC.md` and update `index.yaml` +- [ ] Create `/deliverables/{deliverableCode}-{slug}-SPEC.md` and update `index.yaml` - [ ] Sync `dedFilePath` to Zazz Board via API (unless in development mode) - [ ] Iterate based on feedback until Owner approves @@ -515,7 +561,7 @@ When not in development mode: When the SPEC is created or updated, sync the deli 1. **Ask, don't assume** — If unclear, ask. Don't guess. 2. **Get specific** — "Fast" → "API response <200ms for p99" 3. **Test-first mindset** — For every feature, ask "How will we test this?" before moving on. Every AC must map to a test type. Never produce a spec without a Test Requirements section. -4. **Standards-aware** — Leverage .zazz/standards/; discuss with Owner. Read testing.md and cite it when discussing API tests, PactumJS, etc. +4. **Standards-aware** — Leverage `/standards/`; discuss with Owner. Read testing.md and cite it when discussing API tests, PactumJS, etc. 5. **Edge cases** — Don't just happy path; ask about errors and boundaries. "What happens when X fails? 401? 403? 404?" 6. **Clarity for agents** — SPEC should eliminate guesswork for Planner, Worker, QA. Explicit test descriptions (e.g., "PactumJS: POST /x returns 201 when valid") give Workers clear tasks. 7. **Iterative** — SPEC improves through conversation; produce drafts and refine. @@ -533,11 +579,11 @@ When not in development mode: When the SPEC is created or updated, sync the deli **Behavior when development mode is on**: - Do **not** call the Zazz Board API (no POST, PUT, PATCH for deliverables) - Do **not** create or update deliverable cards -- **Only** write the SPEC file to `.zazz/deliverables/{deliverableCode}-{slug}-SPEC.md` -- The agent **may edit** `.agents/skills/spec-builder-agent/SKILL.md` and `.agents/skills/spec-builder-agent/README.md` to improve the skill. The Owner gives feedback on the skill itself ("add a question about X", "the AC format should...", "Phase 3 is missing Y") and the agent updates these files so the next session benefits. +- **Only** write the SPEC file to `/deliverables/{deliverableCode}-{slug}-SPEC.md` +- The agent **may edit** `.agents/skills/spec-builder/SKILL.md` and `.agents/skills/spec-builder/README.md` to improve the skill. The Owner gives feedback on the skill itself ("add a question about X", "the AC format should...", "Phase 3 is missing Y") and the agent updates these files so the next session benefits. **Behavior when development mode is off**: -- `.agents/skills/spec-builder-agent/SKILL.md` and `.agents/skills/spec-builder-agent/README.md` are **read-only**. The agent must **not** modify them. Only the SPEC file (`.zazz/deliverables/{deliverableCode}-{slug}-SPEC.md`) and deliverable cards (via API) may be written. +- `.agents/skills/spec-builder/SKILL.md` and `.agents/skills/spec-builder/README.md` are **read-only**. The agent must **not** modify them. Only the SPEC file (`/deliverables/{deliverableCode}-{slug}-SPEC.md`) and deliverable cards (via API) may be written. **Focus**: In development mode, skill improvement. Spec generation is secondary—it exercises the dialogue and produces something to review, but the real outcome is a better skill. @@ -575,11 +621,11 @@ export ZAZZ_SPEC_BUILDER_DEV_MODE=1 # or "true" — focus on skill iteration, ## Reference -- **User guide** (for Deliverable Owner): `.agents/skills/spec-builder-agent/README.md` — How to work with the spec builder; key phrases, workflow, development mode -- **Zazz Framework**: [zazz-framework.md](https://github.com/zazzcode/zazz-skills/blob/main/zazz-framework.md) -- **Project standards**: `.zazz/standards/` (index.yaml + listed files) -- **Example SPEC**: `.zazz/deliverables/deliverables-feature-SPEC.md` -- **Planner skill**: `.agents/skills/planner-agent/SKILL.md` (consumes SPEC, uses break patterns) +- **User guide** (for Deliverable Owner): `.agents/skills/spec-builder/README.md` — How to work with the spec builder; key phrases, workflow, development mode +- **Zazz Framework**: [zazz-framework.md](../../../zazz-framework.md) +- **Project standards**: `/standards/` (index.yaml + listed files) +- **Example SPEC**: `/deliverables/deliverables-feature-SPEC.md` +- **Planner skill**: `.agents/skills/planner/SKILL.md` (consumes SPEC, uses break patterns) **Interview techniques drawn from:** - Addy Osmani, "How to write a good spec for AI agents" — https://addyosmani.com/blog/good-spec/ diff --git a/.agents/skills/worker-agent/SKILL.md b/.agents/skills/worker/SKILL.md similarity index 95% rename from .agents/skills/worker-agent/SKILL.md rename to .agents/skills/worker/SKILL.md index 8a5b9c8f..5c5e1667 100644 --- a/.agents/skills/worker-agent/SKILL.md +++ b/.agents/skills/worker/SKILL.md @@ -1,4 +1,9 @@ -# Worker Agent Skill +--- +name: worker +description: Executes an approved deliverable PLAN by implementing code, following TDD, and keeping task, relation, status, and lock state synchronized with Zazz Board. +--- + +# Worker Skill ## Mission Execute an approved deliverable PLAN from start to finish, including: @@ -9,6 +14,14 @@ Execute an approved deliverable PLAN from start to finish, including: This role is implementation-first and orchestration-capable. +## What This Skill Produces + +Primary outputs: + +- implemented code that satisfies the approved SPEC and PLAN +- passing task-level verification evidence from the required TDD loop +- truthful board state for tasks, relations, blockers, statuses, and locks + ## Role Scope - Worker agent is the primary role with full board API interaction. - Spec-builder/planner activities may be orchestrated directly by the human Owner outside this skill. @@ -35,7 +48,7 @@ Canonical command adapter path: - setup guide: `.agents/skills/zazz-board-api/scripts/README.md` Worker wrapper: -- `.agents/skills/worker-agent/scripts/zazzctl` (calls canonical CLI with `--profile worker`) +- `.agents/skills/worker/scripts/zazzctl` (calls canonical CLI with `--profile worker`) - optional repo wrapper: `scripts/zazzctl` Rule: diff --git a/.agents/skills/worker-agent/scripts/README.md b/.agents/skills/worker/scripts/README.md similarity index 94% rename from .agents/skills/worker-agent/scripts/README.md rename to .agents/skills/worker/scripts/README.md index 669961d3..ad924e87 100644 --- a/.agents/skills/worker-agent/scripts/README.md +++ b/.agents/skills/worker/scripts/README.md @@ -6,7 +6,7 @@ This directory contains a worker profile wrapper: Canonical implementation lives in: - `.agents/skills/zazz-board-api/scripts/zazzctl.mjs` -Use this wrapper for worker agents across projects and worktrees. +Use this wrapper for worker sessions across projects and worktrees. ## Requirements - Node.js 22+ @@ -29,7 +29,7 @@ export ZAZZCTL_PRETTY=1 Use the checked-in script directly: ```bash -./.agents/skills/worker-agent/scripts/zazzctl help +./.agents/skills/worker/scripts/zazzctl help ``` ### Convenience wrapper in repo root diff --git a/.agents/skills/worker-agent/scripts/zazzctl b/.agents/skills/worker/scripts/zazzctl similarity index 100% rename from .agents/skills/worker-agent/scripts/zazzctl rename to .agents/skills/worker/scripts/zazzctl diff --git a/.agents/skills/zazz-board-api/SKILL.md b/.agents/skills/zazz-board-api/SKILL.md index 1c947b12..8e169c65 100644 --- a/.agents/skills/zazz-board-api/SKILL.md +++ b/.agents/skills/zazz-board-api/SKILL.md @@ -1,7 +1,7 @@ --- name: "Zazz Board API" type: "rule" -description: "Required API skill for agents to create and manage deliverables/tasks using live OpenAPI. OpenAPI is source of truth; resolve routes by capability instead of brittle hardcoded full path lists." +description: "Required CLI-first skill for agents to create and manage deliverables/tasks through zazzctl. OpenAPI remains the protocol validation and fallback surface in the zazz-board reference implementation." required_for: ["planner", "coordinator", "worker", "qa", "spec-builder"] --- @@ -33,6 +33,7 @@ Use the canonical Node CLI for board communication: CLI-first policy: - Use `zazzctl` as the default communication path. +- Use `zazzctl help`, `zazzctl help `, or `zazzctl help ` to inspect the supported command surface before guessing flags. - Do not handcraft ad-hoc `curl` for normal execution. - `curl` is allowed only for OpenAPI fetch/debugging when the CLI is missing a capability. @@ -42,22 +43,46 @@ Role profile usage: - Spec Builder: `zazzctl --profile spec_builder ...` - Generic (fallback): `zazzctl ...` or `zazzctl --profile generic ...` +## Source-of-Truth Model + +This skill uses a split source-of-truth model so each layer has one clear responsibility: + +- **`zazzctl` is the primary agent interface.** Agents should prefer the CLI and its built-in help as the first surface for normal board operations. +- **OpenAPI is the protocol validation and fallback surface.** The board implementation should keep the CLI aligned with the live API schema and routes. +- **This repo defines the agent-facing contract.** The `zazz-board-api` skill and CLI usage model here describe how agents are expected to operate. +- **[zazz-board](https://github.com/zazzcode/zazz-board) is the reference implementation.** That repo implements the API and CLI behavior that this skill expects. + +Practical rule: + +- if the CLI supports the needed capability, use the CLI +- if the CLI help is insufficient or the capability is missing, inspect OpenAPI and then improve the CLI/skill contract rather than teaching every agent to route around it +- do not maintain duplicate behavioral documentation in multiple places when the CLI can express the agent contract directly + --- -## Source of truth: OpenAPI +## OpenAPI Fallback Model + Always fetch the live spec from: `{ZAZZ_API_BASE_URL}/openapi.json` -Rules: -- Parse `paths` + operation metadata (`tags`, `summary`, `description`, params, requestBody, responses). -- Do not trust stale hardcoded route lists when OpenAPI differs. -- Do not invent routes; derive from live spec. -- If using a local command adapter (e.g. worker `zazzctl`), keep behavior aligned with OpenAPI-derived routes and schemas. +Use OpenAPI when: + +- adding a new CLI capability +- debugging a CLI/API mismatch +- validating that the reference implementation still matches the expected contract +- the CLI does not yet expose the needed operation + +When falling back to OpenAPI: + +- parse `paths` + operation metadata (`tags`, `summary`, `description`, params, requestBody, responses`) +- do not trust stale hardcoded route lists when OpenAPI differs +- do not invent routes; derive from live spec +- once the needed behavior is understood, prefer improving the CLI/help surface so future agents can stay CLI-first --- -## Capability-first routing model (hybrid) -Use capability names as the stable contract, then resolve concrete routes from OpenAPI. +## Capability-first routing model (fallback when CLI does not cover the capability) +Use capability names as the stable contract, then resolve concrete routes from OpenAPI only when the CLI does not already cover the operation. Core capabilities: - Create/list/get/update/approve/status-change deliverable @@ -166,12 +191,12 @@ Verification lifecycle (required): --- ## Practical workflow -1. Fetch OpenAPI spec. -2. Resolve routes for required capabilities using deterministic rules. -3. Validate required path/query/body schema for each operation. -4. Execute request with `TB_TOKEN` or `Authorization: Bearer`, using the resolved token (`ZAZZ_API_TOKEN` first, fallback test token). +1. Inspect CLI help first (`zazzctl help`, `zazzctl help `, `zazzctl help `). +2. Use the CLI for supported capabilities. +3. Fetch OpenAPI only when the CLI lacks a capability or appears out of sync. +4. If falling back to OpenAPI, resolve routes and schemas using the deterministic rules above. 5. Validate post-conditions (task list + graph + statuses). -6. On errors, report capability + path + status + API error payload. +6. On errors, report capability + CLI command or API path + status + error payload. --- diff --git a/.agents/skills/zazz-board-api/scripts/README.md b/.agents/skills/zazz-board-api/scripts/README.md index 02ba6f45..fb6d0cb7 100644 --- a/.agents/skills/zazz-board-api/scripts/README.md +++ b/.agents/skills/zazz-board-api/scripts/README.md @@ -3,14 +3,26 @@ Canonical location: - `.agents/skills/zazz-board-api/scripts/zazzctl.mjs` +Role in the framework: +- `zazzctl` is the primary agent/operator interface for Zazz Board operations +- this repository defines the expected agent-facing command contract +- [zazz-board](https://github.com/zazzcode/zazz-board) is the reference implementation that should keep the CLI and API in sync + Runtime: - Node.js 22+ Quick start: ```bash node .agents/skills/zazz-board-api/scripts/zazzctl.mjs help +node .agents/skills/zazz-board-api/scripts/zazzctl.mjs help deliverable +node .agents/skills/zazz-board-api/scripts/zazzctl.mjs help exec begin ``` +Source-of-truth model: +- use CLI help and commands first for normal agent work +- use OpenAPI in `zazz-board` as the protocol-validation and fallback surface +- if a capability is missing from the CLI, improve the CLI/skill contract rather than teaching agents to permanently bypass it + Environment: ```bash export ZAZZ_API_BASE_URL="http://localhost:3030" @@ -34,7 +46,7 @@ node .agents/skills/zazz-board-api/scripts/zazzctl.mjs --profile worker exec beg node .agents/skills/zazz-board-api/scripts/zazzctl.mjs --profile planner deliverable status \ --deliverable-id 4 --status PLANNING node .agents/skills/zazz-board-api/scripts/zazzctl.mjs --profile planner deliverable update \ - --deliverable-id 4 --json '{"planFilepath":".zazz/deliverables/ZAZZ-6-multiple-agent-tokens-feature-PLAN.md"}' + --deliverable-id 4 --json '{"planFilepath":"/deliverables/ZAZZ-6-multiple-agent-tokens-feature-PLAN.md"}' # Spec builder creates deliverable, sets BACKLOG, then saves SPEC filepath node .agents/skills/zazz-board-api/scripts/zazzctl.mjs --profile spec_builder deliverable create \ @@ -42,5 +54,5 @@ node .agents/skills/zazz-board-api/scripts/zazzctl.mjs --profile spec_builder de node .agents/skills/zazz-board-api/scripts/zazzctl.mjs --profile spec_builder deliverable status \ --deliverable-id 4 --status BACKLOG node .agents/skills/zazz-board-api/scripts/zazzctl.mjs --profile spec_builder deliverable update \ - --deliverable-id 4 --json '{"specFilepath":".zazz/deliverables/ZAZZ-6-multiple-agent-tokens-feature-SPEC.md"}' + --deliverable-id 4 --json '{"specFilepath":"/deliverables/ZAZZ-6-multiple-agent-tokens-feature-SPEC.md"}' ``` diff --git a/.agents/skills/zazz-board-api/scripts/zazzctl.mjs b/.agents/skills/zazz-board-api/scripts/zazzctl.mjs index 1ce60e2d..861f763c 100644 --- a/.agents/skills/zazz-board-api/scripts/zazzctl.mjs +++ b/.agents/skills/zazz-board-api/scripts/zazzctl.mjs @@ -70,8 +70,167 @@ const PROFILE_ALLOW = { ]), }; -function usage() { - const text = `Usage: zazzctl [--profile generic|worker|planner|spec_builder] [options] +const HELP = { + deliverable: { + summary: 'Deliverable lifecycle operations.', + actions: { + list: { + usage: 'zazzctl deliverable list [--project CODE]', + summary: 'List deliverables for a project.', + }, + get: { + usage: 'zazzctl deliverable get --deliverable-id ID [--project CODE]', + summary: 'Fetch one deliverable by numeric ID.', + }, + create: { + usage: 'zazzctl deliverable create --name NAME --type TYPE [--description TEXT] [--spec-filepath PATH] [--plan-filepath PATH] [--project CODE]', + summary: 'Create a deliverable card.', + }, + update: { + usage: 'zazzctl deliverable update --deliverable-id ID --json JSON [--project CODE]', + summary: 'Replace deliverable fields using a JSON body.', + }, + status: { + usage: 'zazzctl deliverable status --deliverable-id ID --status STATUS [--project CODE]', + summary: 'Patch deliverable workflow status.', + }, + approve: { + usage: 'zazzctl deliverable approve --deliverable-id ID [--project CODE]', + summary: 'Approve a deliverable when the board workflow requires approval.', + }, + tasks: { + usage: 'zazzctl deliverable tasks --deliverable-id ID [--project CODE]', + summary: 'List tasks for a deliverable.', + }, + }, + }, + task: { + summary: 'Task lifecycle operations inside a deliverable.', + actions: { + list: { + usage: 'zazzctl task list --deliverable-id ID [--project CODE]', + summary: 'List tasks in a deliverable.', + }, + create: { + usage: 'zazzctl task create --deliverable-id ID --title TITLE [--prompt TEXT] [--description TEXT] [--status STATUS] [--priority P] [--agent-name NAME] [--phase N] [--phase-step X.Y] [--dependencies CSV] [--project CODE]', + summary: 'Create a task in a deliverable.', + }, + get: { + usage: 'zazzctl task get --deliverable-id ID --task-id ID [--project CODE]', + summary: 'Fetch one task by deliverable and task ID.', + }, + update: { + usage: 'zazzctl task update --deliverable-id ID --task-id ID --json JSON [--project CODE]', + summary: 'Replace task fields using a JSON body.', + }, + status: { + usage: 'zazzctl task status --deliverable-id ID --task-id ID --status STATUS [--agent-name NAME] [--project CODE]', + summary: 'Patch task workflow status.', + }, + block: { + usage: 'zazzctl task block --deliverable-id ID --task-id ID --reason REASON [--project CODE]', + summary: 'Set a task blocker using isBlocked + blockedReason.', + }, + unblock: { + usage: 'zazzctl task unblock --deliverable-id ID --task-id ID [--project CODE]', + summary: 'Clear task blocker metadata.', + }, + note: { + usage: 'zazzctl task note --deliverable-id ID --task-id ID --note TEXT [--agent-name NAME] [--project CODE]', + summary: 'Append a note/comment to a task.', + }, + delete: { + usage: 'zazzctl task delete --deliverable-id ID --task-id ID [--project CODE]', + summary: 'Delete a task.', + }, + readiness: { + usage: 'zazzctl task readiness --task-id ID [--project CODE]', + summary: 'Check readiness for a task by numeric task ID.', + }, + }, + }, + relation: { + summary: 'Task relation management.', + actions: { + list: { + usage: 'zazzctl relation list --task-id ID [--project CODE]', + summary: 'List relations for a task.', + }, + add: { + usage: 'zazzctl relation add --task-id ID --related-task-id ID --type DEPENDS_ON|COORDINATES_WITH [--project CODE]', + summary: 'Create a task relation.', + }, + delete: { + usage: 'zazzctl relation delete --task-id ID --related-task-id ID --type DEPENDS_ON|COORDINATES_WITH [--project CODE]', + summary: 'Delete a task relation.', + }, + }, + }, + graph: { + summary: 'Deliverable graph inspection.', + actions: { + get: { + usage: 'zazzctl graph get --deliverable-id ID [--project CODE]', + summary: 'Fetch the deliverable-scoped task graph.', + }, + }, + }, + lock: { + summary: 'Deliverable file lock management.', + actions: { + list: { + usage: 'zazzctl lock list --deliverable-id ID [--project CODE]', + summary: 'List active file locks for a deliverable.', + }, + acquire: { + usage: 'zazzctl lock acquire --deliverable-id ID --task-id ID --agent-name NAME (--file PATH | --files CSV)+ [--phase-step X.Y] [--ttl-seconds N] [--project CODE]', + summary: 'Acquire one or more file locks for a task.', + }, + heartbeat: { + usage: 'zazzctl lock heartbeat --deliverable-id ID --task-id ID --agent-name NAME [--file PATH | --files CSV] [--ttl-seconds N] [--project CODE]', + summary: 'Refresh an active lock lease.', + }, + release: { + usage: 'zazzctl lock release --deliverable-id ID --task-id ID --agent-name NAME [--file PATH | --files CSV] [--project CODE]', + summary: 'Release active locks for a task.', + }, + }, + }, + exec: { + summary: 'High-level worker execution helpers built on lock + status operations.', + actions: { + begin: { + usage: 'zazzctl exec begin --deliverable-id ID --task-id ID --agent-name NAME (--file PATH | --files CSV)+ [--phase-step X.Y] [--ttl-seconds N] [--status STATUS] [--project CODE]', + summary: 'Acquire locks, clear FILE_LOCK blocker, and move task into active execution.', + }, + tick: { + usage: 'zazzctl exec tick --deliverable-id ID --task-id ID --agent-name NAME [--file PATH | --files CSV] [--ttl-seconds N] [--note TEXT] [--project CODE]', + summary: 'Heartbeat locks and optionally append a progress note.', + }, + complete: { + usage: 'zazzctl exec complete --deliverable-id ID --task-id ID --agent-name NAME [--file PATH | --files CSV] [--status STATUS] [--note TEXT] [--project CODE]', + summary: 'Append final note, transition status, and release locks.', + }, + }, + }, +}; + +function profilesForCommand(resource, action) { + const key = canonicalCommandKey(resource, action); + return Object.entries(PROFILE_ALLOW) + .filter(([, allow]) => allow === null || allow.has(key)) + .map(([profile]) => profile); +} + +function helpText(resource = null, action = null) { + if (!resource) { + return `Usage: zazzctl [--profile generic|worker|planner|spec_builder] [options] + +Help: + zazzctl help + zazzctl help + zazzctl help + zazzctl --help Resources: deliverable list|get|create|update|status|approve|tasks @@ -89,11 +248,59 @@ Environment: ZAZZCTL_PROFILE (generic|worker|planner|spec_builder) Examples: + zazzctl help task create zazzctl --profile worker exec begin --deliverable-id 8 --task-id 25 --agent-name worker-1 --file api/src/routes/fileLocks.js - zazzctl --profile planner deliverable update --deliverable-id 4 --json '{"planFilepath":".zazz/deliverables/ZAZZ-6-PLAN.md"}' - zazzctl --profile spec_builder deliverable create --name "Agent Tokens" --type FEATURE --spec-filepath ".zazz/deliverables/ZAZZ-6-agent-tokens-SPEC.md" + zazzctl --profile planner deliverable update --deliverable-id 4 --json '{"planFilepath":"/deliverables/ZAZZ-6-PLAN.md"}' + zazzctl --profile spec_builder deliverable create --name "Agent Tokens" --type FEATURE --spec-filepath "/deliverables/ZAZZ-6-agent-tokens-SPEC.md" +`; + } + + const resourceHelp = HELP[resource]; + if (!resourceHelp) { + return `Unknown resource: ${resource}\n\n${helpText()}`; + } + + if (!action) { + const actions = Object.entries(resourceHelp.actions) + .map(([name, meta]) => ` ${name.padEnd(10)} ${meta.summary}`) + .join('\n'); + return `Resource: ${resource} +${resourceHelp.summary} + +Usage: + zazzctl ${resource} [options] + +Actions: +${actions} + +For detailed command help: + zazzctl help ${resource} +`; + } + + const actionHelp = resourceHelp.actions[action]; + if (!actionHelp) { + return `Unknown command: ${resource} ${action}\n\n${helpText(resource)}`; + } + + const allowedProfiles = profilesForCommand(resource, action).join(', '); + return `Command: ${resource} ${action} +${actionHelp.summary} + +Usage: + ${actionHelp.usage} + +Allowed profiles: + ${allowedProfiles} `; - process.stderr.write(text); +} + +function usage(resource = null, action = null) { + process.stderr.write(helpText(resource, action)); +} + +function printHelp(resource = null, action = null) { + process.stdout.write(helpText(resource, action)); } function dieUsage(message) { @@ -781,8 +988,25 @@ async function main() { process.exit(2); } + if (args.length === 1 && args[0] === '--help') { + printHelp(); + process.exit(0); + } + if (args.length === 1 && args[0] === 'help') { - usage(); + printHelp(); + process.exit(0); + } + + if (args[0] === 'help') { + printHelp(args[1], args[2]); + process.exit(0); + } + + const helpIndex = args.indexOf('--help'); + if (helpIndex >= 0) { + const beforeHelp = args.slice(0, helpIndex); + printHelp(beforeHelp[0], beforeHelp[1]); process.exit(0); } @@ -792,7 +1016,7 @@ async function main() { process.exit(2); } if (resource === 'help' || action === 'help') { - usage(); + printHelp(resource === 'help' ? action : resource, resource === 'help' ? rest[0] : null); process.exit(0); } diff --git a/.zazz/deliverables/ZAZZ-6-multiple-agent-tokens-feature-PLAN.md b/.zazz/deliverables/ZAZZ-6-multiple-agent-tokens-feature-PLAN.md index 0f007c6a..22aafc25 100644 --- a/.zazz/deliverables/ZAZZ-6-multiple-agent-tokens-feature-PLAN.md +++ b/.zazz/deliverables/ZAZZ-6-multiple-agent-tokens-feature-PLAN.md @@ -14,7 +14,7 @@ - `.zazz/standards/data-architecture.md` - `.zazz/standards/coding-styles.md` - `.zazz/standards/testing.md` - - `.agents/skills/planner-agent/SKILL.md` + - `.agents/skills/planner/SKILL.md` - `.agents/skills/zazz-board-api/SKILL.md` - Live OpenAPI: `GET http://localhost:3030/openapi.json` (verified 2026-03-08) diff --git a/.zazz/deliverables/ZAZZ-7-worker-file-locking-PLAN.md b/.zazz/deliverables/ZAZZ-7-worker-file-locking-PLAN.md index 5c4fbffc..24eadd87 100644 --- a/.zazz/deliverables/ZAZZ-7-worker-file-locking-PLAN.md +++ b/.zazz/deliverables/ZAZZ-7-worker-file-locking-PLAN.md @@ -112,7 +112,7 @@ Objective: Align worker behavior with lock API. Changes: -- `.agents/skills/worker-agent/SKILL.md` +- `.agents/skills/worker/SKILL.md` - before `READY -> IN_PROGRESS`, worker must acquire file locks via API - on conflict, set `isBlocked=true` and `blockedReason='FILE_LOCK'` (not workflow status) - poll every 3 seconds and retry acquire diff --git a/.zazz/deliverables/ZAZZ-7-worker-file-locking-SPEC.md b/.zazz/deliverables/ZAZZ-7-worker-file-locking-SPEC.md index bd114bbc..b92000d5 100644 --- a/.zazz/deliverables/ZAZZ-7-worker-file-locking-SPEC.md +++ b/.zazz/deliverables/ZAZZ-7-worker-file-locking-SPEC.md @@ -24,7 +24,7 @@ This enables workers in any stack (Node, Python, Go, Java, etc.) to use the same - list active locks 3. Add OpenAPI/Swagger schemas for all routes. 4. Add API tests for core lock behavior. -5. Update worker-agent skill to require lock API usage before moving a task from `READY` to `IN_PROGRESS`. +5. Update worker skill to require lock API usage before moving a task from `READY` to `IN_PROGRESS`. 6. Worker behavior when lock conflict occurs: - set task `isBlocked=true` with `blockedReason='FILE_LOCK'` (workflow status stays in its column) - poll lock API every 3 seconds until files are available diff --git a/AGENTS.md b/AGENTS.md index 0f61ca65..ff48846d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -68,11 +68,16 @@ This repo **dogfoods** the Zazz Framework: Zazz Board is built with Zazz Board. | Skill | When it applies | | ------------------ | ------------------------------------------------------ | | **zazz-board-api** | Required by all framework agents — API auth, endpoints | -| spec-builder-agent | Owner + agent creating deliverable specification | -| planner-agent | One-shot SPEC → PLAN decomposition | -| coordinator-agent | Orchestrates execution after plan approval | -| worker-agent | Implements tasks | -| qa-agent | Verifies AC, creates rework tasks | +| proposal-builder | Owner/stakeholder proposal discovery and recommendations | +| feature-doc-builder | Product/Project Owner feature requirements authoring | +| spec-builder | Owner + agent creating deliverable specification | +| planner | One-shot SPEC → PLAN decomposition | +| coordinator | Orchestrates execution after plan approval | +| worker | Implements tasks | +| qa | Verifies AC, creates rework tasks | +| qa-frontend | Frontend-focused QA specialization | +| qa-backend | Backend-focused QA specialization | +| pr-builder | Packages reviewer-ready PR titles and bodies | | database-baseline-refresh | Preserves live dev DB data while upgrading schema and refreshing the canonical seed baseline | diff --git a/README.md b/README.md index 6f147019..7056a919 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ - [Reference](#reference) - [About this repository](#about-this-repository) - [Documentation](#documentation) +- [Updating skills from zazz-skills](#updating-skills-from-zazz-skills) --- @@ -384,5 +385,22 @@ This repository is developed using the Zazz framework (dogfooding). Zazz Board i - **API docs (Swagger UI)**: **http://localhost:3030/docs** — OpenAPI 3.1, token-protected. See [API docs (Swagger)](#api-docs-swagger) and [How to access the docs with your access token](#how-to-access-the-docs-with-your-access-token). - **[api/__tests__/README.md](./api/__tests__/README.md)** — Writing and running API tests (PactumJS, helpers, safety guards). - **`.zazz/`** — Zazz Framework structure: `project.md`, `standards/` (atomic project standards), `deliverables/` (SPECs and PLANs). See [zazz-framework.md](https://github.com/zazzcode/zazz-skills/blob/main/zazz-framework.md) for repository structure guidance. -- **`.agents/skills/`** — Agent skills. Current release focus: `spec-builder`, `planner`, `worker`, and `zazz-board-api` (coordinator/qa skills are not current release focus). Developed here; synced to zazz-skills repo when stable. +- **`.agents/skills/`** — Agent skills. Framework skills are sourced from [zazz-skills](https://github.com/zazzcode/zazz-skills); this repo keeps the reference-implementation copy plus the local-only `database-baseline-refresh` skill. - **`.zazz/deliverables/deliverables-feature-SPEC.md`** — Full Deliverable Specification for the deliverables feature. Also in [docs/deliverables_feature_SPEC.md](docs/deliverables_feature_SPEC.md) (legacy path). + +## Updating skills from zazz-skills + +`zazz-skills` is the canonical source for framework skill names and markdown content. This repo should treat its `.agents/skills/` copy as a downstream mirror of that source, except for local-only skills such as `database-baseline-refresh`. + +Typical update flow: + +1. Review the upstream changes in `zazz-skills` first so any renames or new skills are understood before syncing. +2. Run `./scripts/sync-skills-from-zazz-skills.sh /absolute/path/to/zazz-skills`. +3. Review the diff in this repo, especially `README.md`, `AGENTS.md`, and `.zazz/deliverables/`, because renamed skills often leave stale references outside the skill folders. +4. Run `rg -n 'proposal-builder|feature-doc-builder|pr-builder|spec-builder-agent|planner-agent|coordinator-agent|worker-agent|qa-agent' README.md AGENTS.md .zazz .agents/skills` to catch old names or missing follow-up edits. + +Notes: + +- The sync script mirrors the canonical framework-managed skills: `coordinator`, `feature-doc-builder`, `planner`, `pr-builder`, `proposal-builder`, `qa`, `qa-backend`, `qa-frontend`, `spec-builder`, `worker`, and `zazz-board-api`. +- The script intentionally does not touch `.agents/skills/database-baseline-refresh/`. +- A rename-heavy update like this one still needs a manual documentation sweep after the file sync. diff --git a/docs/sample-worker-multi-agent-prompt-CODEX.md b/docs/sample-worker-multi-agent-prompt-CODEX.md index cb8784c3..c8d9102a 100644 --- a/docs/sample-worker-multi-agent-prompt-CODEX.md +++ b/docs/sample-worker-multi-agent-prompt-CODEX.md @@ -5,7 +5,7 @@ Execute deliverable ZAZZ-6 from: Execution requirements: 1. Use multi-agent execution with 3 subagents in parallel whenever dependencies allow. 2. Enforce strict disjoint file ownership per subagent. If file ownership overlaps, serialize those tasks. -3. Use the worker-agent and zazz-board-api skills and the zazzctl CLI for board operations. +3. Use the worker and zazz-board-api skills and the zazzctl CLI for board operations. 4. Apply harness-aware locking policy: - If subagents are isolated with disjoint ownership + parent-controlled merges, API file locks may be skipped for those internal subagents. - If any external concurrency risk is detected, use API file locks via zazzctl exec begin/tick/complete. diff --git a/docs/zazzctl-command-spec.md b/docs/zazzctl-command-spec.md index 88a314d1..3d97a5df 100644 --- a/docs/zazzctl-command-spec.md +++ b/docs/zazzctl-command-spec.md @@ -5,7 +5,7 @@ It standardizes command shapes, payload construction, output, and exit codes so Claude, Codex, and other agents can run the same execution protocol. ## Scope -This first version targets worker-agent board operations: +This first version targets worker skill board operations: - deliverables: list/get/create/status/approve/tasks - tasks: create/get/update/status/block/unblock/note/delete/readiness/list - relations: add/list/delete @@ -24,7 +24,7 @@ This first version targets worker-agent board operations: - `jq` ## Script Location -- Canonical implementation: `.agents/skills/worker-agent/scripts/zazzctl` +- Canonical implementation: `.agents/skills/worker/scripts/zazzctl` - Root convenience wrapper: `scripts/zazzctl` ## Environment Contract diff --git a/scripts/sync-skills-from-zazz-skills.sh b/scripts/sync-skills-from-zazz-skills.sh new file mode 100755 index 00000000..cd2756fb --- /dev/null +++ b/scripts/sync-skills-from-zazz-skills.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +SOURCE_REPO="${1:-${ZAZZ_SKILLS_REPO:-}}" + +if [[ -z "${SOURCE_REPO}" ]]; then + echo "Usage: $0 /absolute/path/to/zazz-skills" >&2 + echo " or: ZAZZ_SKILLS_REPO=/absolute/path/to/zazz-skills $0" >&2 + exit 2 +fi + +if [[ ! -d "${SOURCE_REPO}/.agents/skills" ]]; then + echo "Expected skills directory not found: ${SOURCE_REPO}/.agents/skills" >&2 + exit 2 +fi + +MANAGED_SKILLS=( + coordinator + feature-doc-builder + planner + pr-builder + proposal-builder + qa + qa-backend + qa-frontend + spec-builder + worker + zazz-board-api +) + +for skill in "${MANAGED_SKILLS[@]}"; do + mkdir -p "${ROOT_DIR}/.agents/skills/${skill}" + rsync -a --delete \ + "${SOURCE_REPO}/.agents/skills/${skill}/" \ + "${ROOT_DIR}/.agents/skills/${skill}/" +done + +echo "Synced framework-managed skills from ${SOURCE_REPO}" +echo "Local-only skill left untouched: database-baseline-refresh" diff --git a/scripts/zazzctl b/scripts/zazzctl index 4cec1069..863bcbb3 100755 --- a/scripts/zazzctl +++ b/scripts/zazzctl @@ -1,4 +1,4 @@ #!/usr/bin/env sh set -eu SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) -exec "$SCRIPT_DIR/../.agents/skills/worker-agent/scripts/zazzctl" "$@" +exec "$SCRIPT_DIR/../.agents/skills/worker/scripts/zazzctl" "$@" From 67817f0cc75636afab97d9600a6fe68c614227e0 Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sun, 22 Mar 2026 11:42:17 -0400 Subject: [PATCH 12/14] Move future fixes note into proposals --- .zazz/{ => proposals}/future-fixes.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .zazz/{ => proposals}/future-fixes.md (100%) diff --git a/.zazz/future-fixes.md b/.zazz/proposals/future-fixes.md similarity index 100% rename from .zazz/future-fixes.md rename to .zazz/proposals/future-fixes.md From f0d7f36743c7ae5dd9b5d549b96e407e03aba0a6 Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sun, 22 Mar 2026 13:09:51 -0400 Subject: [PATCH 13/14] Sync framework skills and improve board repo docs --- .agents/skills/coordinator/SKILL.md | 5 + .agents/skills/feature-doc-builder/SKILL.md | 25 +- .agents/skills/planner/SKILL.md | 6 + .agents/skills/pr-builder/SKILL.md | 5 + .agents/skills/proposal-builder/SKILL.md | 5 + .agents/skills/qa-backend/SKILL.md | 5 + .agents/skills/qa-frontend/SKILL.md | 5 + .agents/skills/qa/SKILL.md | 5 + .agents/skills/spec-builder/SKILL.md | 5 + .agents/skills/worker/SKILL.md | 5 + .agents/skills/zazz-board-api/SKILL.md | 11 + .../skills/zazz-board-api/scripts/README.md | 8 + .../skills/zazz-board-api/scripts/zazzctl.mjs | 71 +- .env.example | 59 +- .../deliverables}/CLIENT-API-REFACTORING.md | 0 .../deliverables}/ZAZZ-6-manual-test-plan.md | 0 .../deliverables}/deliverables-mvp-PLAN.md | 0 .../dynamic-task-graph-Implementation-Plan.md | 0 ...ures-milestones-deliverables-management.md | 290 ++++ .zazz/features/index.yaml | 13 + docs/deliverables_feature_SPEC.md | 1486 ----------------- .../project-governance-PROP.md | 98 -- docs/zazzctl-command-spec.md | 6 +- scripts/zazzctl | 2 +- 24 files changed, 497 insertions(+), 1618 deletions(-) rename {docs => .zazz/deliverables}/CLIENT-API-REFACTORING.md (100%) rename {docs => .zazz/deliverables}/ZAZZ-6-manual-test-plan.md (100%) rename {docs => .zazz/deliverables}/deliverables-mvp-PLAN.md (100%) rename {docs => .zazz/deliverables}/dynamic-task-graph-Implementation-Plan.md (100%) create mode 100644 .zazz/features/features-milestones-deliverables-management.md create mode 100644 .zazz/features/index.yaml delete mode 100644 docs/deliverables_feature_SPEC.md delete mode 100644 docs/features/project-governance/project-governance-PROP.md diff --git a/.agents/skills/coordinator/SKILL.md b/.agents/skills/coordinator/SKILL.md index 1b78d597..3fadd2ab 100644 --- a/.agents/skills/coordinator/SKILL.md +++ b/.agents/skills/coordinator/SKILL.md @@ -5,6 +5,11 @@ description: Coordinates execution of an approved PLAN by materializing tasks, m # Coordinator Skill +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/coordinator/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `coordinator` should be applied in this application. + ## Mission Turn an approved PLAN into an actively managed execution flow. diff --git a/.agents/skills/feature-doc-builder/SKILL.md b/.agents/skills/feature-doc-builder/SKILL.md index 9e4fb7be..3fafc992 100644 --- a/.agents/skills/feature-doc-builder/SKILL.md +++ b/.agents/skills/feature-doc-builder/SKILL.md @@ -1,13 +1,18 @@ --- name: feature-doc-builder -description: Guides a product owner or project owner through creating or evolving a Feature Requirements Document for a long-lived capability. Use for feature-document authoring, milestone decomposition, transcript-to-feature-document drafting, and feature-level handoff into deliverable specs. +description: Guides a product owner or project owner through creating or evolving a feature document for a long-lived capability. Use for feature-document authoring, milestone decomposition, transcript-to-feature-document drafting, and feature-level handoff into deliverable specs. --- # Feature Doc Builder Skill +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/feature-doc-builder/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `feature-doc-builder` should be applied in this application. + ## Mission -Create or evolve a Feature Requirements Document that explains a long-lived application capability at the product and system level. +Create or evolve a feature document that explains a long-lived application capability at the product and system level. The feature document should help answer: @@ -91,7 +96,7 @@ If the user provides a transcript or meeting notes: ### Mode C: Existing feature-document revision -When the user already has a Feature Requirements Document: +When the user already has a feature document: 1. read the current feature document 2. identify what changed after the latest milestone or discussion @@ -121,7 +126,7 @@ This skill should feel like a structured product-definition conversation, not an ```text Use feature-doc-builder. -I want to create a Feature Requirements Document for role-based access control in our application. +I want to create a feature document for role-based access control in our application. This feature needs to explain why RBAC matters, what the system does today, what needs to be added, and how we should break it into milestones. Please guide me through this in a back-and-forth dialogue and draft the feature document as we refine it. ``` @@ -130,7 +135,7 @@ Please guide me through this in a back-and-forth dialogue and draft the feature ```text Use feature-doc-builder. -We already have a Feature Requirements Document for our billing feature, and milestone 1 has shipped. +We already have a feature document for our billing feature, and milestone 1 has shipped. Please help me update the feature document so it reflects the current live behavior, marks milestone 1 complete, and refines the next milestones based on what we learned. ``` @@ -139,7 +144,7 @@ Please help me update the feature document so it reflects the current live behav ```text Use feature-doc-builder. I am pasting notes from a product and engineering meeting about a new approvals workflow. -Please infer the feature intent, current state, likely milestones, and open questions, then draft a Feature Requirements Document and ask follow-up questions where the discussion was ambiguous. +Please infer the feature intent, current state, likely milestones, and open questions, then draft a feature document and ask follow-up questions where the discussion was ambiguous. ``` ### Prompt structure that works well @@ -156,7 +161,7 @@ The best starting prompts usually include: - Start with the problem and business/domain value before discussing solution shape. - Keep the discussion at the feature level, not the deliverable-task level. -- Ask about current state explicitly. A Feature Requirements Document must describe what the application does today, not just the future vision. +- Ask about current state explicitly. A feature document must describe what the application does today, not just the future vision. - Distinguish what is live, planned, proposed, and deferred. - Treat milestones as meaningful increments of user or system value. - Push back when the conversation collapses into low-level implementation detail that belongs in standards or deliverable specs. @@ -164,7 +169,7 @@ The best starting prompts usually include: ## Required Inputs -Before drafting a serious Feature Requirements Document, elicit or infer: +Before drafting a serious feature document, elicit or infer: 1. feature name and feature key 2. problem statement @@ -284,7 +289,7 @@ Use this section order unless the owner explicitly asks for a different structur Use framework naming guidance: -- Feature Requirements Document: `/features/{feature-key}.md` +- Feature document: `/features/{feature-key}.md` - Features index: `/features/index.yaml` Keep `features/` flat by default. If a project later has a real need for multiple durable artifacts per feature, it may introduce subdirectories, but that is not the default framework recommendation. @@ -324,7 +329,7 @@ This handoff informs deliverable SPEC creation but does not replace `spec-builde ## Quality Bar -A Feature Requirements Document draft is high quality when: +A feature document draft is high quality when: 1. the feature's why is explicit and persuasive 2. the current state is accurate and not hand-wavy diff --git a/.agents/skills/planner/SKILL.md b/.agents/skills/planner/SKILL.md index bdb568d9..0a95568d 100644 --- a/.agents/skills/planner/SKILL.md +++ b/.agents/skills/planner/SKILL.md @@ -4,6 +4,12 @@ description: Creates or updates an execution-ready implementation PLAN from an a --- # Planner Skill + +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/planner/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `planner` should be applied in this application. + ## First Rule: Use Built-In Planning Optimizations If the active agent/model provides built-in planning optimizations (plan mode, TODO/dependency tooling, structured decomposition), you MUST use them first. Then produce the PLAN in this skill’s required structure. diff --git a/.agents/skills/pr-builder/SKILL.md b/.agents/skills/pr-builder/SKILL.md index f39ce2fc..29deb9b2 100644 --- a/.agents/skills/pr-builder/SKILL.md +++ b/.agents/skills/pr-builder/SKILL.md @@ -5,6 +5,11 @@ description: Builds reviewer-ready pull request titles and bodies from repositor # PR Builder Skill +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/pr-builder/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `pr-builder` should be applied in this application. + ## Mission Create a clear, reviewer-ready pull request title and body that accurately explains: diff --git a/.agents/skills/proposal-builder/SKILL.md b/.agents/skills/proposal-builder/SKILL.md index 9dd25fa7..f9701b88 100644 --- a/.agents/skills/proposal-builder/SKILL.md +++ b/.agents/skills/proposal-builder/SKILL.md @@ -5,6 +5,11 @@ description: Facilitates and documents proposal discussions for features or deli # Proposal Builder Skill +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/proposal-builder/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `proposal-builder` should be applied in this application. + ## Overview Guides one or more humans through a structured proposal discussion to produce a clear proposal document for a feature, a deliverable, or both. diff --git a/.agents/skills/qa-backend/SKILL.md b/.agents/skills/qa-backend/SKILL.md index d7809ad0..53e0c3a1 100644 --- a/.agents/skills/qa-backend/SKILL.md +++ b/.agents/skills/qa-backend/SKILL.md @@ -5,6 +5,11 @@ description: Backend specialization of the base qa skill. Use when a deliverable # Backend QA Skill +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/qa-backend/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `qa-backend` should be applied in this application. + ## Overview Backend specialization of the base `qa` skill. Use this when a deliverable has API, service, schema, data-integrity, auth/authz, or backend performance/security scope. diff --git a/.agents/skills/qa-frontend/SKILL.md b/.agents/skills/qa-frontend/SKILL.md index 69413ce9..caadb626 100644 --- a/.agents/skills/qa-frontend/SKILL.md +++ b/.agents/skills/qa-frontend/SKILL.md @@ -5,6 +5,11 @@ description: Frontend specialization of the base qa skill. Use when a deliverabl # Frontend QA Skill +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/qa-frontend/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `qa-frontend` should be applied in this application. + ## Overview Frontend specialization of the base `qa` skill. Use this when a deliverable has meaningful UI/UX, client-state, browser-interaction, accessibility, or frontend integration scope. diff --git a/.agents/skills/qa/SKILL.md b/.agents/skills/qa/SKILL.md index af76f50d..a8d748aa 100644 --- a/.agents/skills/qa/SKILL.md +++ b/.agents/skills/qa/SKILL.md @@ -5,6 +5,11 @@ description: Base QA skill for the Zazz framework. Produces verification evidenc # QA Skill +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/qa/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `qa` should be applied in this application. + ## Overview Actively finds issues and validates acceptance criteria via test-driven verification. When AC or TDD criteria are not met, provides rework task content to the human coordinator (Owner acting as coordinator) so rework tasks can be created and assigned. Creates PR with full evidence once all criteria are satisfied. diff --git a/.agents/skills/spec-builder/SKILL.md b/.agents/skills/spec-builder/SKILL.md index 2642b5c9..4a7355d6 100644 --- a/.agents/skills/spec-builder/SKILL.md +++ b/.agents/skills/spec-builder/SKILL.md @@ -5,6 +5,11 @@ description: Guides the Deliverable Owner through an interactive dialogue to cre # Spec Builder Skill +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/spec-builder/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `spec-builder` should be applied in this application. + ### Overview Guides the Deliverable Owner through an interactive dialogue to create a comprehensive Deliverable Specification (SPEC) for the Zazz spec-driven development framework. Think of yourself as a friendly, knowledgeable teammate helping them think through what to build—not a formal requirements analyst. diff --git a/.agents/skills/worker/SKILL.md b/.agents/skills/worker/SKILL.md index 5c5e1667..94940579 100644 --- a/.agents/skills/worker/SKILL.md +++ b/.agents/skills/worker/SKILL.md @@ -5,6 +5,11 @@ description: Executes an approved deliverable PLAN by implementing code, followi # Worker Skill +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/worker/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `worker` should be applied in this application. + ## Mission Execute an approved deliverable PLAN from start to finish, including: - just-in-time task realization from plan steps diff --git a/.agents/skills/zazz-board-api/SKILL.md b/.agents/skills/zazz-board-api/SKILL.md index 8e169c65..1a20a493 100644 --- a/.agents/skills/zazz-board-api/SKILL.md +++ b/.agents/skills/zazz-board-api/SKILL.md @@ -6,6 +6,12 @@ required_for: ["planner", "coordinator", "worker", "qa", "spec-builder"] --- # Zazz Board API (Agent Routes) + +## Repo Extension + +Before you start, check whether this repo provides extra local guidance at `.agents/skill-extensions/zazz-board-api/EXTENSION.md`. +If that file exists, read it after this skill and treat it as friendly repo-specific extension guidance for how `zazz-board-api` should be applied in this application. + ## Purpose Agents use this API to create/manage deliverables and tasks, update statuses, append notes, and inspect task graph/readiness. Projects and users are pre-configured; agents do not create them. @@ -23,6 +29,8 @@ All API requests (except `/openapi.json`, `/health`, `/`, `/db-test`, `/token-in - `ZAZZ_API_TOKEN` (required token source; fallback if unset: `550e8400-e29b-41d4-a716-446655440000`) - `ZAZZ_PROJECT_CODE` (fallback: `ZAZZ`) - `ZAZZCTL_PROFILE` (optional default profile: `generic`, `worker`, `planner`, `spec_builder`) +- `ZAZZCTL_ENV_FILE` (optional explicit env file path for CLI execution) +- `ZAZZCTL_NO_ENV` (`1` disables env-file auto-loading) --- @@ -33,6 +41,9 @@ Use the canonical Node CLI for board communication: CLI-first policy: - Use `zazzctl` as the default communication path. +- The canonical CLI auto-loads a repo `.env` when present. +- Exported environment variables win over values loaded from `.env`. +- If a repo needs a non-default env file, set `ZAZZCTL_ENV_FILE` explicitly for that command. - Use `zazzctl help`, `zazzctl help `, or `zazzctl help ` to inspect the supported command surface before guessing flags. - Do not handcraft ad-hoc `curl` for normal execution. - `curl` is allowed only for OpenAPI fetch/debugging when the CLI is missing a capability. diff --git a/.agents/skills/zazz-board-api/scripts/README.md b/.agents/skills/zazz-board-api/scripts/README.md index fb6d0cb7..cd5e5a5c 100644 --- a/.agents/skills/zazz-board-api/scripts/README.md +++ b/.agents/skills/zazz-board-api/scripts/README.md @@ -11,6 +11,12 @@ Role in the framework: Runtime: - Node.js 22+ +Environment loading: +- `zazzctl` automatically discovers and loads a repo `.env` when present. +- Existing exported environment variables take precedence over values from the env file. +- Set `ZAZZCTL_ENV_FILE=/path/to/.env` to force a specific env file. +- Set `ZAZZCTL_NO_ENV=1` to disable env-file auto-loading. + Quick start: ```bash node .agents/skills/zazz-board-api/scripts/zazzctl.mjs help @@ -30,6 +36,8 @@ export ZAZZ_API_TOKEN="${ZAZZ_API_TOKEN:-550e8400-e29b-41d4-a716-446655440000}" export ZAZZ_PROJECT_CODE="ZAZZ" ``` +If the repo keeps these values in `.env`, `zazzctl` will pick them up automatically when run from that repo. + Profiles: - `worker`: task/relation/lock/exec workflow; read-only deliverable ops - `planner`: deliverable planning updates and read checks diff --git a/.agents/skills/zazz-board-api/scripts/zazzctl.mjs b/.agents/skills/zazz-board-api/scripts/zazzctl.mjs index 861f763c..081fe856 100644 --- a/.agents/skills/zazz-board-api/scripts/zazzctl.mjs +++ b/.agents/skills/zazz-board-api/scripts/zazzctl.mjs @@ -4,11 +4,77 @@ * Cross-platform board API adapter for all agent skills. */ +import fs from 'node:fs'; +import path from 'node:path'; +import process from 'node:process'; +import { fileURLToPath } from 'node:url'; +import { parseEnv } from 'node:util'; + const DEFAULT_BASE_URL = 'http://localhost:3030'; const DEFAULT_TOKEN = '550e8400-e29b-41d4-a716-446655440000'; const DEFAULT_PROJECT = 'ZAZZ'; -const env = process.env; +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +function uniquePaths(paths) { + return [...new Set(paths.filter(Boolean))]; +} + +function findUp(filename, startDir) { + let current = path.resolve(startDir); + while (true) { + const candidate = path.join(current, filename); + if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) { + return candidate; + } + const parent = path.dirname(current); + if (parent === current) return null; + current = parent; + } +} + +function resolveEnvFile() { + if (process.env.ZAZZCTL_NO_ENV === '1') { + return null; + } + + const explicit = process.env.ZAZZCTL_ENV_FILE; + if (explicit) { + const resolved = path.resolve(process.cwd(), explicit); + if (!fs.existsSync(resolved)) { + throw new Error(`ZAZZCTL_ENV_FILE does not exist: ${resolved}`); + } + return resolved; + } + + const candidates = uniquePaths([ + findUp('.env', process.cwd()), + findUp('.env', __dirname), + ]); + + return candidates[0] || null; +} + +function loadMergedEnv() { + const envFile = resolveEnvFile(); + const merged = { ...process.env }; + + if (!envFile) { + return { env: merged, envFile: null }; + } + + const parsed = parseEnv(fs.readFileSync(envFile, 'utf8')); + for (const [key, value] of Object.entries(parsed)) { + if (merged[key] === undefined) { + merged[key] = value; + } + } + + return { env: merged, envFile }; +} + +const { env } = loadMergedEnv(); const config = { baseUrl: env.ZAZZ_API_BASE_URL || DEFAULT_BASE_URL, token: env.ZAZZ_API_TOKEN || DEFAULT_TOKEN, @@ -244,6 +310,8 @@ Environment: ZAZZ_API_BASE_URL (default: ${DEFAULT_BASE_URL}) ZAZZ_API_TOKEN (default fallback: seed token) ZAZZ_PROJECT_CODE (default: ${DEFAULT_PROJECT}) + ZAZZCTL_ENV_FILE (optional explicit env file path) + ZAZZCTL_NO_ENV (set to 1 to disable env-file auto-loading) ZAZZCTL_PRETTY (1 pretty JSON, 0 compact) ZAZZCTL_PROFILE (generic|worker|planner|spec_builder) @@ -252,6 +320,7 @@ Examples: zazzctl --profile worker exec begin --deliverable-id 8 --task-id 25 --agent-name worker-1 --file api/src/routes/fileLocks.js zazzctl --profile planner deliverable update --deliverable-id 4 --json '{"planFilepath":"/deliverables/ZAZZ-6-PLAN.md"}' zazzctl --profile spec_builder deliverable create --name "Agent Tokens" --type FEATURE --spec-filepath "/deliverables/ZAZZ-6-agent-tokens-SPEC.md" + ZAZZCTL_ENV_FILE=.env zazzctl deliverable list `; } diff --git a/.env.example b/.env.example index abd4c335..170924db 100644 --- a/.env.example +++ b/.env.example @@ -1,43 +1,64 @@ -# Zazz Board Environment Variables -# Copy this file to .env and configure as needed +# Zazz Board root environment +# Copy this file to .env and configure as needed. +# +# This root env file serves two different consumers: +# 1. The zazz-board application runtime and local Docker stack +# 2. Zazz Framework agents and zazzctl when they talk to the board API +# +# Keep those concerns separate when editing this file. # =========================================== -# DOCKER COMPOSE +# BOARD INFRASTRUCTURE (Docker Compose) # =========================================== -# Docker Compose project name (used for container prefixes) +# Docker Compose project name used for local container/network/volume prefixes. +# This is only for the local board runtime; agents do not use this. COMPOSE_PROJECT_NAME=zazz-board # =========================================== -# DATABASE -# ========================================== -# Database used by Dockerized Postgres +# BOARD DATABASE (Dockerized Postgres) +# =========================================== + +# Database name for the local Dockerized Postgres instance used by zazz-board. +# The board API container also derives its DATABASE_URL from these values. POSTGRES_DB=zazz_board_db + +# Database username for the local Dockerized Postgres instance. POSTGRES_USER=postgres -# Shared password used by Postgres and API container DB connection +# Shared password for Dockerized Postgres and the board API container connection. POSTGRES_PASSWORD=password # =========================================== -# SERVER +# BOARD API RUNTIME # =========================================== -# Server port +# Board API server bind port. +# This controls the port the zazz-board API listens on locally/in Docker. +# This is not the same as ZAZZ_API_BASE_URL below. PORT=3030 -# Node environment +# Node runtime mode for the board API process. +# For local development this is usually "development". NODE_ENV=development +# Board API server log level. +# This affects the board runtime logs, not agent verbosity. +LOG_LEVEL=info + # =========================================== -# API AUTH (Agent Skills) +# ZAZZ FRAMEWORK API AUTH (Agent Skills) # =========================================== -# Seed data token example for local agent skill usage. -ZAZZ_API_TOKEN=550e8400-e29b-41d4-a716-446655440000 +# Base URL agents and zazzctl use when talking to the board API. +# This should usually point at the same board instance that is listening on PORT. +ZAZZ_API_BASE_URL=http://localhost:3030 -# =========================================== -# LOGGING -# =========================================== +# Agent access token for the board API in this project. +# This is consumed by the zazz-board-api skill and zazzctl, not by the board runtime itself. +# The default value here is the sample token for the ZAZZ project that ships with this reference implementation. +ZAZZ_API_TOKEN=660e8400-e29b-41d4-a716-446655440101 -# Log level (trace, debug, info, warn, error, fatal) -LOG_LEVEL=info +# Default project code agents should use when talking to the board API. +# This keeps framework commands pointed at the intended board project by default. +ZAZZ_PROJECT_CODE=ZAZZ diff --git a/docs/CLIENT-API-REFACTORING.md b/.zazz/deliverables/CLIENT-API-REFACTORING.md similarity index 100% rename from docs/CLIENT-API-REFACTORING.md rename to .zazz/deliverables/CLIENT-API-REFACTORING.md diff --git a/docs/ZAZZ-6-manual-test-plan.md b/.zazz/deliverables/ZAZZ-6-manual-test-plan.md similarity index 100% rename from docs/ZAZZ-6-manual-test-plan.md rename to .zazz/deliverables/ZAZZ-6-manual-test-plan.md diff --git a/docs/deliverables-mvp-PLAN.md b/.zazz/deliverables/deliverables-mvp-PLAN.md similarity index 100% rename from docs/deliverables-mvp-PLAN.md rename to .zazz/deliverables/deliverables-mvp-PLAN.md diff --git a/docs/dynamic-task-graph-Implementation-Plan.md b/.zazz/deliverables/dynamic-task-graph-Implementation-Plan.md similarity index 100% rename from docs/dynamic-task-graph-Implementation-Plan.md rename to .zazz/deliverables/dynamic-task-graph-Implementation-Plan.md diff --git a/.zazz/features/features-milestones-deliverables-management.md b/.zazz/features/features-milestones-deliverables-management.md new file mode 100644 index 00000000..6e0c86e5 --- /dev/null +++ b/.zazz/features/features-milestones-deliverables-management.md @@ -0,0 +1,290 @@ +# Features, Milestones, and Deliverables Management + +Current milestone: M1 planned +Next likely milestone: M2 + +## 1. Introduction + +Zazz Board already manages deliverables and tasks well, but it does not yet +provide a first-class way to view work in the broader context of long-lived +features and milestone progression. + +The product gap is not just missing data fields. The board currently lacks a +durable feature layer that helps Product Owners, Project Owners, and +stakeholders answer questions such as: + +- What feature is this deliverable advancing? +- What milestone of that feature are we currently executing? +- Which deliverables collectively move a milestone forward? +- Which deliverables are intentionally standalone and not part of a feature + roadmap? + +This feature introduces feature-aware and milestone-aware organization while +preserving an important Zazz boundary: the canonical feature narrative lives in +Git-managed feature documents, while the board remains the operational system +for execution slices such as deliverables and tasks. + +## 2. Why This Feature Matters + +This feature matters because Zazz Board is intended to support not only +execution tracking, but also the product and roadmap context that explains why +execution is happening. + +Without a feature and milestone layer: + +- deliverables appear as isolated execution units +- stakeholders cannot easily see how planned and active deliverables roll up + into a larger capability +- roadmap progress has to be reconstructed manually from docs, board state, and + Git branches +- there is no consistent way to distinguish milestone-driven deliverables from + standalone bug fixes, chores, or one-off technical work + +The goal is not to turn the board into the primary authoring tool for feature +planning. The goal is to make the board an accurate and useful display and +execution companion for a Git-native roadmap model. + +## 3. Current State + +Today, the system supports: + +- project-level organization +- deliverables as bounded execution slices +- tasks under deliverables +- deliverable and task workflows +- SPEC and PLAN path tracking for deliverables +- worktree and branch metadata on deliverables + +Today, the system does not support: + +- a tracked `.zazz/features/` directory in this repo +- a first-class feature view in the board +- milestone definitions or milestone visualization in the board +- a way to associate deliverables to a feature +- a way to associate deliverables to a milestone within a feature +- a way to distinguish milestone-grouped deliverables from intentionally + standalone deliverables in roadmap views + +## 4. Product Boundary and Source-of-Truth Model + +This feature must preserve a clear boundary between durable product definition +and execution state. + +### 4.1 Canonical in Git-managed feature docs + +The feature document is the canonical source for: + +- feature name and purpose +- feature-level current state +- milestone definitions +- milestone order and intended outcome +- roadmap narrative for completed, current, and planned milestones + +### 4.2 Canonical in the board application + +The board is the canonical source for: + +- deliverables +- tasks +- workflow state +- operational progress of execution +- metadata associating deliverables to a feature and optionally to a milestone + +### 4.3 Explicit anti-duplication rule + +The board must not become a second authoring system for rich feature-document +content. + +The board may store or cache lightweight metadata needed for display, querying, +and grouping, but the board must not become the primary home for: + +- feature narrative +- milestone narrative +- detailed roadmap explanation +- stakeholder-facing feature documentation + +## 5. Feature-Level Success Criteria + +This feature is successful when: + +1. Zazz Board can show a durable feature and milestone structure without + requiring the feature document content to be duplicated into the database. +2. Stakeholders can see which deliverables are advancing a milestone and which + deliverables are intentionally standalone. +3. Milestone meaning remains authored in the feature document, not in a second + board-only roadmap editor. +4. The board can visualize roadmap progress while still reflecting live + deliverable status from the execution system. +5. Deliverables can remain outside both feature and milestone context when they + represent standalone bug fixes, chores, maintenance, or other work that does + not belong in a feature roadmap. + +## 6. Core Concepts + +### Feature + +A long-lived application capability described by a tracked Feature Requirements +Document under `.zazz/features/`. + +### Milestone + +A meaningful increment of a feature that describes an outcome or capability +slice. Milestones belong to a feature and are defined in the feature document. + +### Deliverable + +A bounded execution slice in the board. A deliverable may: + +- belong to a feature and a milestone +- belong to a feature but not a milestone +- belong to neither feature nor milestone + +A deliverable must not belong to a milestone without also belonging to that +milestone's parent feature. + +### Standalone deliverable + +A deliverable intentionally outside feature-roadmap structure, such as a bug +fix, maintenance task, infrastructure chore, or tactical refactor. + +## 7. User and System Flows + +### 7.1 Product and roadmap authoring flow + +1. Product Owner or Project Owner creates or updates a feature document in Git. +2. The feature document defines the feature's current state and milestone + roadmap. +3. The feature document remains the stakeholder-facing explanation of what the + feature is and what each milestone means. + +### 7.2 Execution association flow + +1. A deliverable is created in the board as an execution slice. +2. The deliverable may optionally be associated to a feature. +3. The deliverable may optionally be associated to a milestone within that + feature. +4. The board uses those associations to show which deliverables contribute to + a milestone. + +### 7.3 Standalone deliverable flow + +1. A deliverable is created in the board for work that is not part of a feature + roadmap. +2. The deliverable is left unassociated with both feature and milestone. +3. The board continues to support and display it as valid standalone work. + +### 7.4 Roadmap visibility flow + +1. A stakeholder opens the board's feature view. +2. The board displays the feature, its milestones, and linked deliverables. +3. The board shows live deliverable state under each milestone while the + milestone's meaning remains defined by the feature doc. + +## 8. Milestone Overview + +| Milestone | Status | Outcome | +| --- | --- | --- | +| M1 | Planned | Introduce feature docs in the repo, a board-level feature and milestone display model, and lightweight metadata support for associating deliverables to a feature and optional milestone. | +| M2 | Proposed | Add richer milestone visualization such as tree, roadmap, or Gantt-style views and improve the presentation of milestone progress across linked deliverables. | +| M3 | Proposed | Refine synchronization, validation, and operational workflows between Git-authored feature documents and board-managed deliverable associations. | + +## 9. Milestone Details + +### M1: Feature docs plus board display and association model + +M1 is the smallest meaningful milestone because it establishes the foundational +separation of concerns: + +- feature and milestone definition remain in Git docs +- deliverable execution and milestone association remain in the board + +M1 outcome criteria: + +- the repo has a real `.zazz/features/` directory with tracked feature docs +- the board can represent features and milestones as display concepts +- the board can store metadata associating deliverables to a feature and + optionally to a milestone +- standalone deliverables remain first-class and valid +- the system enforces that a milestone association cannot exist without the + parent feature association +- the board can render milestone-grouped deliverables without requiring the + feature document to list tactical deliverables + +M1 non-goals: + +- a rich in-board editor for feature or milestone narrative +- storing full feature-document content in the board database +- forcing all deliverables into a milestone structure +- solving every detail of synchronization or ingestion in the first increment + +### M2: Rich roadmap visualization + +M2 should improve how the board presents milestone progression, likely through a +tree, roadmap, or Gantt-like view that helps stakeholders understand sequence, +current execution focus, and completed vs planned increments. + +Likely outcome criteria: + +- visual hierarchy for feature -> milestone -> linked deliverables +- clear separation of planned, active, and completed milestone progress +- stronger stakeholder-friendly roadmap presentation + +### M3: Synchronization and validation hardening + +M3 should address the operational mechanics of how Git-authored feature and +milestone definitions are reflected in the board. + +Likely outcome criteria: + +- durable sync or import strategy for feature and milestone metadata +- validation rules that prevent inconsistent feature/milestone associations +- clearer operational flows for keeping docs and board metadata aligned + +## 10. Risks, Constraints, and Non-Goals + +### Risks + +- feature and milestone metadata could drift if the board and docs evolve + without a disciplined synchronization strategy +- teams may be tempted to move milestone narrative into the board because it is + operationally convenient +- milestone grouping could become too rigid if the model does not preserve + standalone deliverables + +### Constraints + +- the feature document must remain the stakeholder-facing source of milestone + meaning +- the board must not duplicate full feature-document content +- the board must continue to support bug fixes, chores, and other standalone + deliverables + +### Non-goals + +- replacing GitHub or Git-managed docs as the roadmap authoring surface +- requiring every deliverable to belong to a feature +- requiring every feature-linked deliverable to belong to a milestone + +## 11. Open Questions + +1. How should feature and milestone metadata be synchronized or imported from + Git-managed docs into the board's display model? +2. Should the board support a cached projection of feature and milestone + metadata, or should it resolve everything dynamically from docs? +3. What is the right structured format inside the feature document for exposing + milestone metadata clearly to both humans and the board? +4. Should milestone status in the board be purely computed from linked + deliverables, partially owner-set, or displayed separately from milestone + narrative status in the feature doc? + +## 12. Deliverable Handoff Considerations + +Likely deliverable slices for this feature include: + +- repository scaffolding for `.zazz/features/` and feature discovery +- backend metadata model for features, milestones, and deliverable association +- board UI for feature and milestone display +- validation and synchronization behavior between Git docs and board metadata + +These should become deliverable SPECs later. This feature document intentionally +does not prescribe the final tactical deliverable breakdown. diff --git a/.zazz/features/index.yaml b/.zazz/features/index.yaml new file mode 100644 index 00000000..70a668d5 --- /dev/null +++ b/.zazz/features/index.yaml @@ -0,0 +1,13 @@ +features: + - key: features-milestones-deliverables-management + file: features-milestones-deliverables-management.md + domain: board information architecture, roadmap visibility, deliverable organization + current_milestone: M1 planned + current_state: > + Zazz Board manages deliverables and tasks, but it does not yet expose a + durable feature layer, milestone structure, or milestone-scoped grouping + of deliverables. + purpose: > + Defines how Zazz Board should represent long-lived feature context and + milestone progression without duplicating canonical feature-document + content that remains in Git-managed framework docs. diff --git a/docs/deliverables_feature_SPEC.md b/docs/deliverables_feature_SPEC.md deleted file mode 100644 index 48e2bc6e..00000000 --- a/docs/deliverables_feature_SPEC.md +++ /dev/null @@ -1,1486 +0,0 @@ -# Deliverable Specification (SPEC): Deliverables Feature - -**Project**: Zazz Board -**Branch**: `deliverables-mvp` -**Created**: 2026-02-16 -**Status**: Implemented -**Author**: Michael Woytowitz - ---- - -## 1. Problem Statement - -Zazz-Board currently manages work at the **task** level only. There is no macro-level concept that groups tasks into a cohesive work product — a feature, bug fix, refactor, or other deliverable. Without this, there is: - -- No way to track the lifecycle of a body of work from planning → implementation → PR → merge. -- No connection between a specification (SPEC), an implementation plan, and the tasks that execute it. -- No mechanism for agents to know when all tasks for a deliverable are complete and a PR should be created. -- No swim lane organization on the Task Graph to visually group tasks by deliverable. -- No dedicated Kanban board for tracking deliverable-level workflow. - -This feature introduces **Deliverables** as a first-class entity that sits above tasks in the project hierarchy: `Project → Deliverable → Tasks`. - ---- - -## 2. Definitions - -- **Deliverable**: A discrete work product (feature, bug fix, refactor, or other) that provides value or resolves an issue. A deliverable is scoped to a single repo/monorepo and lives within a single Git worktree/branch. -- **Deliverable Specification (SPEC)**: A markdown document that defines the requirements, scope, and acceptance criteria for a deliverable. -- **Implementation Plan (PLAN)**: A markdown document with detailed technical steps for implementing the deliverable. Derived from the SPEC. -- **Deliverable Kanban Board**: A board tracking deliverable-level workflow (Planning → In Progress → In Review → Staged → Done). -- **Task Kanban Board**: The existing board, now with columns aligned to the Zazz methodology (To Do → Ready → In Progress → QA → Completed). -- **Task Graph (with Swim Lanes)**: The existing task dependency graph view, now organized into swim lanes per deliverable so each deliverable's sub-graph is visually separated. -- **Zazz Methodology**: Spec-driven development (SPEC) + test-driven development (tests derived from AC). Tasks are never PR'd individually — only deliverables are PR'd as a branch. -- **Task Ownership**: Tasks are created, worked on, and QA'd by agents. Humans work with SPECs, implementation plans, and deliverable cards. Tasks are displayed for work progress visibility but are agent-managed. Every task belongs to exactly one deliverable. - ---- - -## 3. Scope - -### 3.1 In Scope (This SPEC) - -- `DELIVERABLES` database table and schema changes -- `deliverable_id` FK added to `TASKS` table -- Deliverable CRUD API routes (Fastify) -- Deliverable workflow and status tracking with history (JSONB) -- Plan approval tracking (approved_by, approved_at) -- Deliverable Kanban Board UI (new page/route) -- Task Graph modifications: swim lanes per deliverable to organize task sub-graphs -- Task Kanban Board modifications: updated default columns (Zazz methodology), deliverable name footer on cards -- Deliverable list view page with sortable table, copy-to-clipboard for file paths -- New status ENUMs and i18n translations for both deliverable and task workflows -- Refactored ID scheme: deliverables use `{PROJECT_CODE}-{int}` (human-facing), tasks use simple integer IDs (agent-facing) -- Seed data for development and testing -- `git_worktree` and `git_branch` on deliverable (1 worktree per deliverable) -- `pull_request_url` on deliverable (PR is at deliverable level, not task level) -- User stories, acceptance criteria, and API test descriptions - -### 3.2 Out of Scope - -- Agent skill for automatically creating tasks from an approved plan -- Agent skill for creating PRs when all tasks are complete -- Agent QA workflow (automated QA pass, rework task creation) -- Slack/Teams integration for AC clarification with human PM -- Updating SPEC or plan markdown documents programmatically -- Multi-repo deliverables (MVP assumes single repo/monorepo) -- PRD (Product Requirements Document) management — field is optional, just a path -- `USERS` table columns for Slack/Teams handles (noted for future SPEC) - -### 3.3 Future Considerations (Noted, Not Specified) - -- Agent signals when all deliverable tasks reach `COMPLETED` status -- QA agent rework cycle (create rework tasks → re-QA → PR) -- Slack/Teams handle fields on USERS table for PM communication -- Multi-worktree deliverables spanning multiple repos -- Deliverable dependencies (deliverable-to-deliverable relations) - ---- - -## 4. Deliverable Type Enum - -Deliverable types classify the nature of the work product. - -| ENUM Value | Display (en) | Description | -|---|---|---| -| `FEATURE` | Feature | New functionality or capability | -| `BUG_FIX` | Bug Fix | Correction of a defect | -| `REFACTOR` | Refactor | Code restructuring without behavior change | -| `ENHANCEMENT` | Enhancement | Improvement to existing functionality | -| `CHORE` | Chore | Maintenance, dependency updates, tooling | -| `DOCUMENTATION` | Documentation | Documentation-only deliverable | - -These values must be added to `STATUS_DEFINITIONS` (or a new `DELIVERABLE_TYPE_DEFINITIONS` reference table) and to the TRANSLATIONS table under `deliverables.types.`. - ---- - -## 5. Deliverable Workflow & Status Definitions - -### 5.1 Deliverable Statuses (Deliverable Kanban Columns) - -Default workflow for new projects (and seed data): - -| Order | ENUM Value | Display (en) | Description | -|---|---|---|---| -| 1 | `PLANNING` | Planning | SPEC and plan being created/refined | -| 2 | `IN_PROGRESS` | In Progress | Plan approved, tasks being worked | -| 3 | `IN_REVIEW` | In Review | PR created, awaiting human review | -| 4 | `STAGED` | Staged | Merged to staging branch | -| 5 | `DONE` | Done | Merged to main, deliverable complete | - -New statuses to add to `STATUS_DEFINITIONS` seed data: `STAGED`, `UAT`, `PROD`. - -The deliverable workflow array is stored on the `PROJECTS` table as `deliverable_status_workflow` (same pattern as existing `status_workflow` for tasks). - -**Workflow flexibility**: Deliverable workflows are fully configurable per project. The default above suits most teams, but projects can define their own columns to match their release pipeline. For example, the **APIMOD** project uses a release-pipeline workflow: - -| Order | ENUM Value | Display (en) | Description | -|---|---|---|---| -| 1 | `PLANNING` | Planning | SPEC and plan being created/refined | -| 2 | `IN_PROGRESS` | In Progress | Plan approved, tasks being worked | -| 3 | `IN_REVIEW` | In Review | PR created, awaiting human review | -| 4 | `UAT` | UAT | User acceptance testing in integration environment | -| 5 | `STAGED` | Staged | Deployed to staging for final validation | -| 6 | `PROD` | Prod | Merged to main and deployed to production (terminal state) | - -In this workflow, `PROD` is the terminal state — equivalent to `DONE` in the default workflow. The deliverable is considered complete when its branch is merged to `main` and deployed to production. - -The seed data includes **both workflows** to demonstrate and test this flexibility. Task workflows remain fixed to the Zazz methodology across all projects. - -#### Deliverable Status Transitions (Default Workflow) - -```mermaid -stateDiagram-v2 - [*] --> PLANNING : Deliverable created - - PLANNING --> PLANNING : Approve Plan\n(sets approved_by/approved_at;\nstatus stays PLANNING) - PLANNING --> IN_PROGRESS : [plan approved AND\nplan_file_path set] - - IN_PROGRESS --> IN_REVIEW : PR created - IN_REVIEW --> STAGED : Merged to staging - STAGED --> DONE : Merged to main -``` - -> **Key detail**: Approving a plan (`PATCH /projects/:code/deliverables/:id/approve`) is a distinct action from transitioning status. Approval sets `approved_by` and `approved_at` but does **not** change the status — the deliverable remains in `PLANNING` until explicitly moved to `IN_PROGRESS`. The `IN_PROGRESS` transition guard validates that both conditions are met. - -### 5.2 Task Statuses (Task Kanban Columns — Zazz Methodology) - -Default workflow for new projects (and seed data): - -| Order | ENUM Value | Display (en) | Description | -|---|---|---|---| -| 1 | `TO_DO` | To Do | Task defined, not yet ready | -| 2 | `READY` | Ready | Dependencies met, available for pickup | -| 3 | `IN_PROGRESS` | In Progress | Actively being worked | -| 4 | `QA` | QA | Quality assurance / acceptance testing | -| 5 | `COMPLETED` | Completed | Task finished and verified | - -New statuses to add to `STATUS_DEFINITIONS` seed data: `QA`, `COMPLETED`. - -**Key change**: Tasks are never `IN_REVIEW` individually. Tasks move to `COMPLETED` after QA passes. Only the deliverable goes through `IN_REVIEW` when the PR is created. - -#### Task Status Transitions - -```mermaid -stateDiagram-v2 - [*] --> TO_DO : Task created - - TO_DO --> READY : Auto-promotion\n[all DEPENDS_ON deps met] - READY --> IN_PROGRESS : Agent picks up task - IN_PROGRESS --> QA : Work submitted for QA - QA --> IN_PROGRESS : Rework needed - QA --> COMPLETED : QA passes - - COMPLETED --> [*] -``` - -> **Auto-promotion**: When a dependency task's status changes, `checkAndPromoteDependents()` automatically promotes dependent tasks from `TO_DO` → `READY` if all their `DEPENDS_ON` dependencies have reached the project's `completionCriteriaStatus`. This is a system-triggered transition, not user-initiated. - -### 5.3 Status History Tracking - -Each deliverable tracks its status change history as a JSONB array column (`status_history`): - -```json -[ - { "status": "PLANNING", "changedAt": "2026-02-16T10:00:00Z", "changedBy": 5 }, - { "status": "IN_PROGRESS", "changedAt": "2026-02-17T14:30:00Z", "changedBy": 5 }, - { "status": "IN_REVIEW", "changedAt": "2026-02-20T09:00:00Z", "changedBy": null } -] -``` - -This enables reporting on time spent in each status phase. - -### 5.4 Zazz Methodology — End-to-End Lifecycle - -The following sequence diagram shows the full lifecycle of a deliverable from specification through deployment. It illustrates the handoffs between Human, System, and Agent actors and the corresponding deliverable status at each phase. - -```mermaid -sequenceDiagram - participant H as Human - participant S as System - participant A as Agent - - rect rgb(230, 240, 255) - note over H,S: Phase 1 — Planning (PLANNING status) - H->>S: Create deliverable - S-->>H: Status = PLANNING - H->>S: Set SPEC + Plan file paths - H->>S: Approve plan - S-->>H: approved_by / approved_at set (status stays PLANNING) - H->>S: Transition → IN_PROGRESS - S->>S: Guard: plan approved AND plan_file_path set - S-->>H: Status = IN_PROGRESS - end - - rect rgb(230, 255, 230) - note over A,S: Phase 2 — Execution (IN_PROGRESS status) - A->>S: Create tasks from plan - loop For each task - A->>S: Pick up task (TO_DO → READY → IN_PROGRESS) - A->>S: Implement task - A->>S: Submit for QA - alt QA fails - S-->>A: Rework needed (QA → IN_PROGRESS) - A->>S: Fix and resubmit for QA - end - A->>S: Mark task COMPLETED - end - A->>S: All tasks COMPLETED — create PR - A->>S: Set pull_request_url on deliverable - end - - rect rgb(255, 240, 230) - note over H,S: Phase 3 — Review & Release (IN_REVIEW → DONE) - S->>S: Transition → IN_REVIEW - H->>S: Review PR - H->>S: Merge → Staging (STAGED) - H->>S: Merge → Main (DONE or PROD) - end -``` - -**Phase ↔ Status mapping**: -- **Phase 1** (Planning) = deliverable in `PLANNING`. Owner creates the SPEC, derives the plan, and approves it. The deliverable stays in `PLANNING` until explicitly transitioned. -- **Phase 2** (Execution) = deliverable in `IN_PROGRESS`. Agents create tasks, implement them, and run QA. Each task cycles through `TO_DO → READY → IN_PROGRESS → QA → COMPLETED`. -- **Phase 3** (Review & Release) = deliverable moves through `IN_REVIEW → STAGED → DONE` (or `→ UAT → STAGED → PROD` for projects with a release-pipeline workflow). - ---- - -## 6. Database Schema - -### 6.1 New Table: DELIVERABLES - -```sql -CREATE TABLE DELIVERABLES ( - id SERIAL PRIMARY KEY, - project_id INTEGER NOT NULL REFERENCES PROJECTS(id) ON DELETE CASCADE, - deliverable_id VARCHAR(20) NOT NULL UNIQUE, -- Human-readable: "ZAZZ-1", "APIMOD-3" - name VARCHAR(30) NOT NULL, -- Short name, fits on Kanban card - description TEXT, -- Longer description (optional) - type VARCHAR(25) NOT NULL, -- ENUM: FEATURE, BUG_FIX, REFACTOR, ENHANCEMENT, CHORE, DOCUMENTATION - status VARCHAR(25) NOT NULL DEFAULT 'PLANNING', - status_history JSONB NOT NULL DEFAULT '[]', -- Array of {status, changedAt, changedBy} - - -- Document paths (markdown files) - ded_file_path VARCHAR(500), -- Path to deliverable specification (SPEC) markdown (repo-relative or shared drive URL) - plan_file_path VARCHAR(500), -- Path to implementation plan markdown (REQUIRED for approval) - prd_file_path VARCHAR(500), -- Path to PRD markdown (optional) - - -- Plan approval - approved_by INTEGER REFERENCES USERS(id) ON DELETE SET NULL, - approved_at TIMESTAMP WITH TIME ZONE, - - -- Git integration - git_worktree VARCHAR(255), -- Worktree root directory name (= branch name) - git_branch VARCHAR(255), -- Git branch name (= worktree dir name for clarity) - pull_request_url VARCHAR(500), -- PR URL, set when PR is created - position INTEGER NOT NULL DEFAULT 0, -- Sparse numbering for Kanban drag-and-drop ordering - - -- Audit - created_by INTEGER REFERENCES USERS(id) ON DELETE SET NULL, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL, - updated_by INTEGER REFERENCES USERS(id) ON DELETE SET NULL, - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL -); -``` - -**Drizzle ORM schema** (follows existing patterns in `api/lib/db/schema.js`): - -```javascript -// Deliverable type enum -export const deliverableTypeEnum = pgEnum('deliverable_type', [ - 'FEATURE', 'BUG_FIX', 'REFACTOR', 'ENHANCEMENT', 'CHORE', 'DOCUMENTATION' -]); - -export const DELIVERABLES = pgTable('DELIVERABLES', { - id: serial('id').primaryKey(), - project_id: integer('project_id').notNull().references(() => PROJECTS.id, { onDelete: 'cascade' }), - deliverable_id: varchar('deliverable_id', { length: 20 }).notNull().unique(), - name: varchar('name', { length: 30 }).notNull(), - description: text('description'), - type: deliverableTypeEnum('type').notNull(), - status: varchar('status', { length: 25 }).notNull().default('PLANNING'), - status_history: text('status_history').notNull().default('[]'), // JSONB as text (matches TRANSLATIONS pattern) - - ded_file_path: varchar('ded_file_path', { length: 500 }), - plan_file_path: varchar('plan_file_path', { length: 500 }), - prd_file_path: varchar('prd_file_path', { length: 500 }), - - approved_by: integer('approved_by').references(() => USERS.id, { onDelete: 'set null' }), - approved_at: timestamp('approved_at', { withTimezone: true }), - - git_worktree: varchar('git_worktree', { length: 255 }), - git_branch: varchar('git_branch', { length: 255 }), - pull_request_url: varchar('pull_request_url', { length: 500 }), - position: integer('position').notNull().default(0), - - created_by: integer('created_by').references(() => USERS.id, { onDelete: 'set null' }), - created_at: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), - updated_by: integer('updated_by').references(() => USERS.id, { onDelete: 'set null' }), - updated_at: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(), -}); -``` - -### 6.2 Modified Table: TASKS - -Significant schema changes to align with the Zazz methodology where tasks are agent-facing work items identified by integer IDs and associated with deliverables. - -**Changes:** -1. **Drop `task_id` VARCHAR column** — The human-readable `{PROJECT_CODE}-{int}` format (e.g., `ZAZZ-1`) moves to `deliverable_id` on the DELIVERABLES table. Tasks are identified solely by their serial `id` (integer PK). This is a clean break (nuke-and-rebuild). -2. **Add `deliverable_id` FK column** — Integer NOT NULL, references `DELIVERABLES.id`. Every task belongs to a deliverable. ON DELETE CASCADE (deleting a deliverable deletes its tasks). -3. **Remove `git_pull_request_url`** — PRs are at the deliverable level in the Zazz methodology, not per-task. -4. **`git_worktree` remains** — Inherited from the deliverable but retained on tasks for agent convenience. -5. **`project_id` remains** — Even though tasks get their project through the deliverable, `project_id` is retained for query efficiency. - -**Column changes (Drizzle):** - -```javascript -// REMOVE from TASKS: -// task_id: varchar('task_id', { length: 50 }).notNull().unique(), ← DROP -// git_pull_request_url: varchar('git_pull_request_url'), ← DROP - -// ADD to TASKS: -deliverable_id: integer('deliverable_id').notNull().references(() => DELIVERABLES.id, { onDelete: 'cascade' }), -``` - -**Impact of dropping `task_id`:** -- API responses: tasks identified by integer `id` only -- Client: `TaskCard` displays integer `id` instead of `ZAZZ-1` style badge -- Seed data: task seeds no longer include `task_id` values -- Test fixtures: all task references use integer `id` -- The existing `next_task_sequence` logic on PROJECTS that generated `ZAZZ-1` is repurposed for `next_deliverable_sequence` to generate `deliverable_id` (see Section 6.3) - -### 6.3 Modified Table: PROJECTS - -**Changes:** -1. **Repurpose `next_task_sequence` → `next_deliverable_sequence`** — The existing integer sequence column that generated task IDs is renamed and repurposed to generate `deliverable_id` values (e.g., `ZAZZ-1`, `ZAZZ-2`). Same auto-increment-on-create pattern, same column position. Tasks no longer need a sequence — they use their serial PK. -2. **Update `status_workflow` default** — Change from `['TO_DO', 'IN_PROGRESS', 'IN_REVIEW', 'DONE']` to the Zazz methodology defaults: `['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED']`. -3. **Add `deliverable_status_workflow`** — New varchar array column for deliverable Kanban columns. - -```javascript -// RENAME on PROJECTS: -// next_task_sequence → next_deliverable_sequence (same pattern, generates deliverable_id) -next_deliverable_sequence: integer('next_deliverable_sequence').notNull().default(1), - -// UPDATE default on PROJECTS: -status_workflow: varchar('status_workflow', { length: 25 }).array().notNull() - .default(sql`ARRAY['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED']::varchar[]`), - -// ADD to PROJECTS: -deliverable_status_workflow: varchar('deliverable_status_workflow', { length: 25 }) - .array().notNull() - .default(sql`ARRAY['PLANNING', 'IN_PROGRESS', 'IN_REVIEW', 'STAGED', 'DONE']::varchar[]`), -``` - -### 6.4 Drizzle Relations - -```javascript -export const deliverablesRelations = relations(DELIVERABLES, ({ one, many }) => ({ - project: one(PROJECTS, { - fields: [DELIVERABLES.project_id], - references: [PROJECTS.id], - }), - approvedByUser: one(USERS, { - fields: [DELIVERABLES.approved_by], - references: [USERS.id], - }), - tasks: many(TASKS), -})); - -// Update existing tasksRelations to include: -// deliverable: one(DELIVERABLES, { -// fields: [TASKS.deliverable_id], -// references: [DELIVERABLES.id], -// }), - -// Update projectsRelations to include: -// deliverables: many(DELIVERABLES), -``` - -### 6.5 Entity Relationship Summary - -``` -PROJECTS (1) ──── (N) DELIVERABLES (1) ──── (N) TASKS - │ │ - │ ├── approved_by → USERS - │ ├── created_by → USERS - │ └── updated_by → USERS - │ - ├── leader_id → USERS - ├── status_workflow (task columns) - └── deliverable_status_workflow (deliverable columns) -``` - ---- - -## 7. API Specification (Fastify Routes) - -All routes require `TB_TOKEN` authentication header (existing `authMiddleware`). - -### 7.1 Deliverable CRUD - -#### GET /projects/:code/deliverables -List all deliverables for a project. - -**Query parameters:** -- `status` (optional): Filter by deliverable status enum -- `type` (optional): Filter by deliverable type enum - -**Response** `200`: -```json -[ - { - "id": 1, - "deliverableId": "ZAZZ-1", - "name": "Deliverables Feature", - "description": "Add deliverable entity, Kanban board, and task graph swim lanes", - "type": "FEATURE", - "status": "IN_PROGRESS", - "statusHistory": [...], - "dedFilePath": "docs/deliverables_feature_SPEC.md", - "planFilePath": "docs/deliverables_feature_plan.md", - "prdFilePath": null, - "approvedBy": 5, - "approvedByName": "Michael Woytowitz", - "approvedAt": "2026-02-17T14:30:00Z", - "gitWorktree": "deliverables-mvp", - "gitBranch": "deliverables-mvp", - "pullRequestUrl": null, - "taskCount": 6, - "completedTaskCount": 1, - "projectId": 1, - "projectCode": "ZAZZ", - "createdBy": 5, - "createdAt": "2026-02-16T10:00:00Z", - "updatedAt": "2026-02-17T14:30:00Z" - } -] -``` - -#### GET /projects/:code/deliverables/:id -Get a single deliverable by its serial `id`. - -**Response** `200`: Full deliverable object (same shape as list item above). -**Response** `404`: `{ "error": "Deliverable not found" }` - -#### POST /projects/:code/deliverables -Create a new deliverable for a project. - -**Request body:** -```json -{ - "name": "Homepage Redesign", - "description": "Full redesign of the homepage with modern components", - "type": "FEATURE", - "dedFilePath": "docs/homepage-redesign-SPEC.md", - "planFilePath": "docs/homepage-redesign-plan.md", - "prdFilePath": "docs/homepage-redesign-PRD.md", - "gitWorktree": "homepage-redesign", - "gitBranch": "homepage-redesign" -} -``` - -**Required fields**: `name`, `type` -**Auto-generated**: `deliverableId` (format `{PROJECT_CODE}-{next_deliverable_sequence}`), `status` (`PLANNING`), initial `statusHistory` entry. - -**Response** `201`: Created deliverable object. - -#### PUT /projects/:code/deliverables/:id -Update a deliverable. - -**Request body** (all fields optional): -```json -{ - "name": "Homepage Redesign v2", - "description": "Updated description...", - "type": "FEATURE", - "dedFilePath": "docs/homepage-redesign-SPEC.md", - "planFilePath": "docs/homepage-redesign-plan.md", - "prdFilePath": "docs/homepage-redesign-PRD.md", - "gitWorktree": "homepage-redesign", - "gitBranch": "homepage-redesign", - "pullRequestUrl": "https://github.com/org/repo/pull/42" -} -``` - -**Response** `200`: Updated deliverable object. -**Response** `404`: `{ "error": "Deliverable not found" }` - -#### DELETE /projects/:code/deliverables/:id -Delete a deliverable. CASCADE deletes all associated tasks (tasks cannot exist without a deliverable). - -**Response** `200`: `{ "message": "Deliverable deleted successfully" }` -**Response** `404`: `{ "error": "Deliverable not found" }` - -### 7.2 Deliverable Status Transitions - -#### PATCH /projects/:code/deliverables/:id/status -Change a deliverable's status. Appends to `status_history`. - -**Request body:** -```json -{ - "status": "IN_PROGRESS" -} -``` - -**Validation:** -- Status must exist in `STATUS_DEFINITIONS` -- Status must be in the project's `deliverable_status_workflow` -- Transitioning to `IN_PROGRESS` requires `plan_file_path` to be set and `approved_at` to be non-null - -**Response** `200`: Updated deliverable with new status and appended history. -**Response** `400`: `{ "error": "Cannot move to IN_PROGRESS without an approved plan" }` - -### 7.3 Plan Approval - -#### PATCH /projects/:code/deliverables/:id/approve -Approve the implementation plan for a deliverable. Sets `approved_by` to the authenticated user and `approved_at` to the current timestamp. - -**Validation:** -- `plan_file_path` must be set on the deliverable -- Deliverable must currently be in `PLANNING` status -- Cannot re-approve if already approved - -**Request body:** (empty — approval user comes from auth context) - -**Response** `200`: -```json -{ - "id": 1, - "deliverableId": "ZAZZ-1", - "approvedBy": 5, - "approvedByName": "Michael Woytowitz", - "approvedAt": "2026-02-17T14:30:00Z", - "status": "PLANNING", - ... -} -``` - -**Response** `400`: `{ "error": "Plan file path must be set before approval" }` - -### 7.4 Deliverable Tasks - -#### GET /projects/:code/deliverables/:id/tasks -Get all tasks linked to a deliverable. - -**Response** `200`: Array of task objects (same shape as existing `GET /projects/:id/tasks`). - -### 7.5 Project Deliverable Workflow Configuration - -#### GET /projects/:code/deliverable-statuses -Returns the project's ordered deliverable status workflow. - -**Response** `200`: -```json -{ - "deliverableStatusWorkflow": ["PLANNING", "IN_PROGRESS", "IN_REVIEW", "STAGED", "DONE"] -} -``` - -#### PUT /projects/:code/deliverable-statuses -Update the project's deliverable status workflow. - -**Request body:** -```json -{ - "deliverableStatusWorkflow": ["PLANNING", "IN_PROGRESS", "IN_REVIEW", "STAGED", "DONE"] -} -``` - -**Validation:** All codes must exist in `STATUS_DEFINITIONS`. Cannot remove a status that has active deliverables. - -### 7.6 Updated Task Routes - -#### POST /tasks (modified) -`deliverableId` is now **required**. The `projectId` is derived from the deliverable but still accepted for backward compatibility (validated against the deliverable's project). -```json -{ - "title": "Build header component", - "deliverableId": 1 -} -``` - -#### PUT /tasks/:id (modified) -Allow changing `deliverableId` to reassign a task to a different deliverable. Cannot be set to null. - ---- - -## 8. UI Specification (React Client) - -### 8.1 New Route: Deliverable List Page - -**Route**: `/projects/:projectCode/deliverables` - -A sortable table listing all deliverables for the selected project. - -**Table columns:** -| Column | Sortable | Description | -|---|---|---| -| Deliverable ID | Yes | Human-readable ID (e.g., `ZAZZ-1`) | -| Name | Yes | Short name (max 30 chars) | -| Type | Yes | FEATURE, BUG_FIX, etc. (translated) | -| Status | Yes | Current status (translated, color-coded badge) | -| Status Changed | Yes | Datetime of last status change | -| SPEC Path | No | File path with copy-to-clipboard icon button | -| Plan Path | No | File path with copy-to-clipboard icon button | -| PRD Path | No | File path with copy-to-clipboard icon button (if set) | -| PR URL | No | Link to PR (if set) | -| Tasks | Yes | Completed / Total count | - -**Copy-to-clipboard behavior**: Each file path cell displays the path text (truncated if long) with a clipboard icon (e.g., `IconCopy` from Tabler). Clicking the icon copies the full path to the clipboard and shows a brief "Copied!" tooltip. This allows the user to paste the path into a terminal or IDE to open/edit the markdown. - -**Components**: `DeliverableListPage.jsx`, `DeliverableTable.jsx` - -### 8.2 New Route: Deliverable Kanban Board - -**Route**: `/projects/:projectCode/deliverable-kanban` - -A Kanban board for deliverable cards. Columns come from `project.deliverableStatusWorkflow`. - -**Default columns**: Planning | In Progress | In Review | Staged | Done - -**Deliverable card contents:** -- Deliverable ID badge (top, styled like task cards) -- Name (max 30 chars) -- Type badge (color-coded by type) -- Task progress: `3/8 tasks completed` progress bar -- PR URL link (if set, small icon link) -- Approved badge (if plan is approved) - -**Drag-and-drop**: Same pattern as task Kanban (@dnd-kit). Sparse position numbering. - -**Components**: `DeliverableKanbanPage.jsx`, `DeliverableKanbanBoard.jsx`, `DeliverableCard.jsx` - -### 8.3 Modified: Task Kanban Board — Updated Default Columns - -**Route** (existing): `/projects/:projectCode/kanban` - -**Changes:** -1. **Default columns** (Zazz methodology): To Do | Ready | In Progress | QA | Completed -2. **Card footer**: Each task card displays a small footer badge with the deliverable name, providing context about which deliverable the task belongs to. - -**Components modified**: `KanbanBoard.jsx`, `TaskCard.jsx` - -### 8.4 Modified: Task Graph — Swim Lanes per Deliverable - -**Route** (existing): `/projects/:projectCode/taskGraph` - -**Changes:** -1. **Swim lanes**: The task dependency graph is organized into horizontal swim lanes grouped by deliverable. Each swim lane has a header showing the deliverable name. -2. Each swim lane contains the sub-graph (nodes + dependency edges) for that deliverable's tasks. -3. Cross-deliverable dependency edges span across swim lanes. - -**Swim lane rendering order**: Deliverables ordered by their `status` (IN_PROGRESS first, then PLANNING, etc.). - -**Components modified**: `TaskGraphPage.jsx`, graph rendering components in `client/src/components/graph/` - -### 8.5 Modified: Task Card Footer - -Add a footer section to `TaskCard.jsx`: - -```jsx - - - 📦 {task.deliverableName} - - -``` - -### 8.6 Navigation Updates - -Add the Deliverable views to the project-level navigation (the existing `SegmentedControl` or a new nav): - -| View | Route | Icon | -|---|---|---| -| Kanban (Tasks) | `/projects/:code/kanban` | IconLayoutKanban | -| Task Graph | `/projects/:code/taskGraph` | IconGitBranch | -| Deliverables (List) | `/projects/:code/deliverables` | IconListDetails | -| Deliverable Board | `/projects/:code/deliverable-kanban` | IconColumns | - -### 8.7 i18n Translations - -Add the following keys to all 4 language files and the `seedTranslations.js` seeder: - -```json -{ - "deliverables": { - "title": "Deliverables", - "createDeliverable": "Create Deliverable", - "editDeliverable": "Edit Deliverable", - "name": "Name", - "description": "Description", - "type": "Type", - "status": "Status", - "dedFilePath": "SPEC Path", - "planFilePath": "Plan File Path", - "prdFilePath": "PRD File Path", - "pullRequestUrl": "Pull Request URL", - "gitWorktree": "Git Worktree", - "gitBranch": "Git Branch", - "approvedBy": "Approved By", - "approvedAt": "Approved At", - "approvePlan": "Approve Plan", - "planNotSet": "Plan file path must be set before approval", - "noDeliverables": "No deliverables found for this project", - "copiedToClipboard": "Copied to clipboard!", - "taskProgress": "Task Progress", - "types": { - "FEATURE": "Feature", - "BUG_FIX": "Bug Fix", - "REFACTOR": "Refactor", - "ENHANCEMENT": "Enhancement", - "CHORE": "Chore", - "DOCUMENTATION": "Documentation" - }, - "statuses": { - "PLANNING": "Planning", - "IN_PROGRESS": "In Progress", - "IN_REVIEW": "In Review", - "UAT": "UAT", - "STAGED": "Staged", - "PROD": "Prod", - "DONE": "Done" - }, - "statusDescriptions": { - "PLANNING": "SPEC and implementation plan being created or refined", - "IN_PROGRESS": "Plan approved, tasks actively being worked", - "IN_REVIEW": "PR created, awaiting human review", - "UAT": "User acceptance testing in integration environment", - "STAGED": "Deployed to staging for final validation", - "PROD": "Merged to main and deployed to production", - "DONE": "Merged to main, deliverable complete" - } - }, - "tasks": { - "statuses": { - "QA": "QA", - "COMPLETED": "Completed" - }, - "statusDescriptions": { - "QA": "Task undergoing quality assurance and acceptance testing", - "COMPLETED": "Task finished and verified against acceptance criteria" - } - } -} -``` - ---- - -## 9. Seed Data - -### 9.1 New Status Definitions - -Add to `seedStatusDefinitions.js`: - -```javascript -{ code: 'STAGED', description: 'Merged to staging branch for integration testing' }, -{ code: 'UAT', description: 'User acceptance testing in integration environment' }, -{ code: 'PROD', description: 'Merged to main and deployed to production (terminal state)' }, -{ code: 'QA', description: 'Task undergoing quality assurance and acceptance testing' }, -{ code: 'COMPLETED', description: 'Task finished and verified against acceptance criteria' }, -``` - -### 9.2 Project Seed Data (Updated) - -All projects use Zazz methodology defaults. The primary test project is renamed to **Zazz** with code **ZAZZ**. The existing `next_task_sequence` column is repurposed as `next_deliverable_sequence`. - -```javascript -[ - { - title: 'Zazz Board', - code: 'ZAZZ', - description: 'Zazz-Board application development — primary test project', - leader_id: 5, - next_deliverable_sequence: 4, // 3 deliverables seeded - status_workflow: ['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED'], - deliverable_status_workflow: ['PLANNING', 'IN_PROGRESS', 'IN_REVIEW', 'STAGED', 'DONE'], - task_graph_layout_direction: 'LR', - completion_criteria_status: 'COMPLETED', - created_by: 5 - }, - { - title: 'Mobile App Development', - code: 'MOBDEV', - description: 'Native mobile app for iOS and Android platforms', - leader_id: 2, - next_deliverable_sequence: 2, // 1 deliverable seeded - status_workflow: ['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED'], - deliverable_status_workflow: ['PLANNING', 'IN_PROGRESS', 'IN_REVIEW', 'STAGED', 'DONE'], - created_by: 2 - }, - { - title: 'API Modernization', - code: 'APIMOD', - description: 'Migrate legacy APIs to modern REST architecture', - leader_id: 3, - next_deliverable_sequence: 3, // 2 deliverables seeded - status_workflow: ['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED'], - deliverable_status_workflow: ['PLANNING', 'IN_PROGRESS', 'IN_REVIEW', 'UAT', 'STAGED', 'PROD'], - task_graph_layout_direction: 'LR', - completion_criteria_status: 'COMPLETED', - created_by: 3 - }, - { - title: 'Database Migration', - code: 'DATAMIG', - description: 'Migrate all customer data to new clustered database', - leader_id: 5, - next_deliverable_sequence: 1, - status_workflow: ['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED'], - deliverable_status_workflow: ['PLANNING', 'IN_PROGRESS', 'IN_REVIEW', 'STAGED', 'DONE'], - created_by: 5 - }, - { - title: 'Security Compliance', - code: 'SECURE', - description: 'Annual security audit and compliance updates', - leader_id: 4, - next_deliverable_sequence: 1, - status_workflow: ['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED'], - deliverable_status_workflow: ['PLANNING', 'IN_PROGRESS', 'IN_REVIEW', 'STAGED', 'DONE'], - created_by: 4 - } -] -``` - -### 9.3 Deliverable Seed Data - -New seeder: `seedDeliverables.js` - -Deliverables span multiple projects and statuses. ZAZZ is the primary test project with 3 deliverables in varied states: - -```javascript -[ - { - project_id: 1, // ZAZZ - deliverable_id: 'ZAZZ-1', - name: 'Deliverables Feature', - description: 'Add deliverable entity, Kanban board, and task graph swim lanes', - type: 'FEATURE', - status: 'IN_PROGRESS', - position: 10, - status_history: JSON.stringify([ - { status: 'PLANNING', changedAt: '2026-01-15T10:00:00Z', changedBy: 5 }, - { status: 'IN_PROGRESS', changedAt: '2026-01-20T14:30:00Z', changedBy: 5 } - ]), - ded_file_path: 'docs/deliverables_feature_SPEC.md', - plan_file_path: 'docs/deliverables_feature_plan.md', - approved_by: 5, - approved_at: '2026-01-20T14:30:00Z', - git_worktree: 'deliverables-mvp', - git_branch: 'deliverables-mvp', - created_by: 5 - }, - { - project_id: 1, // ZAZZ - deliverable_id: 'ZAZZ-2', - name: 'Agent Skill Framework', - description: 'Define and register agent skills for task creation and QA', - type: 'FEATURE', - status: 'PLANNING', - position: 20, - status_history: JSON.stringify([ - { status: 'PLANNING', changedAt: '2026-02-10T09:00:00Z', changedBy: 5 } - ]), - ded_file_path: 'docs/agent-skills-SPEC.md', - created_by: 5 - }, - { - project_id: 1, // ZAZZ - deliverable_id: 'ZAZZ-3', - name: 'Fix Tag Validation Bug', - description: 'Tags with trailing hyphens bypass API validation', - type: 'BUG_FIX', - status: 'IN_REVIEW', - position: 30, - status_history: JSON.stringify([ - { status: 'PLANNING', changedAt: '2026-02-01T10:00:00Z', changedBy: 5 }, - { status: 'IN_PROGRESS', changedAt: '2026-02-02T09:00:00Z', changedBy: 5 }, - { status: 'IN_REVIEW', changedAt: '2026-02-05T16:00:00Z', changedBy: null } - ]), - ded_file_path: 'docs/fix-tag-validation-SPEC.md', - plan_file_path: 'docs/fix-tag-validation-plan.md', - approved_by: 5, - approved_at: '2026-02-02T09:00:00Z', - git_worktree: 'fix-tag-validation', - git_branch: 'fix-tag-validation', - pull_request_url: 'https://github.com/zazzcode/zazz-board/pull/12', - created_by: 5 - }, - { - project_id: 2, // MOBDEV - deliverable_id: 'MOBDEV-1', - name: 'Auth Screens', - description: 'Login, registration, and password reset screens', - type: 'FEATURE', - status: 'IN_PROGRESS', - position: 10, - status_history: JSON.stringify([ - { status: 'PLANNING', changedAt: '2026-01-20T08:00:00Z', changedBy: 2 }, - { status: 'IN_PROGRESS', changedAt: '2026-01-25T10:00:00Z', changedBy: 2 } - ]), - ded_file_path: 'docs/mobdev-auth-screens-SPEC.md', - plan_file_path: 'docs/mobdev-auth-screens-plan.md', - approved_by: 2, - approved_at: '2026-01-25T10:00:00Z', - git_worktree: 'auth-screens', - git_branch: 'auth-screens', - created_by: 2 - }, - { - project_id: 3, // APIMOD - deliverable_id: 'APIMOD-1', - name: 'REST Endpoint Migration', - description: 'Migrate legacy endpoints to modern REST with OpenAPI spec', - type: 'REFACTOR', - status: 'IN_PROGRESS', - position: 10, - status_history: JSON.stringify([ - { status: 'PLANNING', changedAt: '2026-01-05T08:00:00Z', changedBy: 3 }, - { status: 'IN_PROGRESS', changedAt: '2026-01-12T11:00:00Z', changedBy: 3 } - ]), - ded_file_path: 'docs/apimod-rest-migration-SPEC.md', - plan_file_path: 'docs/apimod-rest-migration-plan.md', - approved_by: 3, - approved_at: '2026-01-12T11:00:00Z', - git_worktree: 'rest-migration', - git_branch: 'rest-migration', - created_by: 3 - }, - { - project_id: 3, // APIMOD - deliverable_id: 'APIMOD-2', - name: 'Fix Auth Token Expiry', - description: 'Tokens not expiring correctly under high concurrency', - type: 'BUG_FIX', - status: 'PROD', - position: 20, - status_history: JSON.stringify([ - { status: 'PLANNING', changedAt: '2026-01-28T10:00:00Z', changedBy: 3 }, - { status: 'IN_PROGRESS', changedAt: '2026-01-29T09:00:00Z', changedBy: 3 }, - { status: 'IN_REVIEW', changedAt: '2026-02-01T16:00:00Z', changedBy: null }, - { status: 'UAT', changedAt: '2026-02-02T11:00:00Z', changedBy: 3 }, - { status: 'STAGED', changedAt: '2026-02-03T10:00:00Z', changedBy: 3 }, - { status: 'PROD', changedAt: '2026-02-05T14:00:00Z', changedBy: 3 } - ]), - ded_file_path: 'docs/apimod-auth-token-fix-SPEC.md', - plan_file_path: 'docs/apimod-auth-token-fix-plan.md', - approved_by: 3, - approved_at: '2026-01-29T09:00:00Z', - git_worktree: 'fix-auth-token-expiry', - git_branch: 'fix-auth-token-expiry', - pull_request_url: 'https://github.com/zazzcode/zazz-board/pull/8', - created_by: 3 - } -] -``` - -### 9.4 Task Seed Data (Rewritten) - -Tasks no longer have a `task_id` VARCHAR column — they are identified by their serial integer `id`. Tasks reference deliverables via `deliverable_id` FK. All task statuses use the Zazz methodology columns. - -Tasks for ZAZZ project (id=1), deliverable ZAZZ-1 (id=1): -```javascript -[ - { project_id: 1, deliverable_id: 1, title: 'Create DELIVERABLES schema', status: 'COMPLETED', priority: 'HIGH', assignee_id: 1, position: 10 }, - { project_id: 1, deliverable_id: 1, title: 'Deliverable CRUD API routes', status: 'IN_PROGRESS', priority: 'HIGH', assignee_id: 1, position: 20 }, - { project_id: 1, deliverable_id: 1, title: 'Deliverable Kanban board UI', status: 'TO_DO', priority: 'MEDIUM', assignee_id: 2, position: 30 }, - { project_id: 1, deliverable_id: 1, title: 'Task graph swim lanes', status: 'TO_DO', priority: 'MEDIUM', assignee_id: 3, position: 40 }, - { project_id: 1, deliverable_id: 1, title: 'Deliverable list page', status: 'READY', priority: 'MEDIUM', assignee_id: 2, position: 50 }, - { project_id: 1, deliverable_id: 1, title: 'Seed data and translations', status: 'QA', priority: 'LOW', assignee_id: 4, position: 60 }, -] -``` - -Tasks for ZAZZ-2 (id=2) — still in PLANNING, no tasks yet. - -Tasks for ZAZZ-3 (id=3): -```javascript -[ - { project_id: 1, deliverable_id: 3, title: 'Fix tag regex pattern', status: 'COMPLETED', priority: 'HIGH', assignee_id: 1, position: 10 }, - { project_id: 1, deliverable_id: 3, title: 'Add tag validation tests', status: 'COMPLETED', priority: 'MEDIUM', assignee_id: 1, position: 20 }, -] -``` - -Tasks for MOBDEV-1 (id=4): -```javascript -[ - { project_id: 2, deliverable_id: 4, title: 'Login screen layout', status: 'COMPLETED', priority: 'HIGH', assignee_id: 3, position: 10 }, - { project_id: 2, deliverable_id: 4, title: 'Registration form', status: 'IN_PROGRESS', priority: 'MEDIUM', assignee_id: 2, position: 20 }, - { project_id: 2, deliverable_id: 4, title: 'Password reset flow', status: 'TO_DO', priority: 'MEDIUM', assignee_id: 3, position: 30 }, -] -``` - -Tasks for APIMOD-1 (id=5): -```javascript -[ - { project_id: 3, deliverable_id: 5, title: 'Audit existing endpoints', status: 'COMPLETED', priority: 'HIGH', assignee_id: 4, position: 10 }, - { project_id: 3, deliverable_id: 5, title: 'Design OpenAPI spec', status: 'IN_PROGRESS', priority: 'CRITICAL', assignee_id: 3, position: 20 }, - { project_id: 3, deliverable_id: 5, title: 'Implement versioning', status: 'READY', priority: 'HIGH', assignee_id: 3, position: 30 }, - { project_id: 3, deliverable_id: 5, title: 'Add rate limiting', status: 'TO_DO', priority: 'MEDIUM', assignee_id: 4, position: 40 }, - { project_id: 3, deliverable_id: 5, title: 'Integration test suite', status: 'TO_DO', priority: 'HIGH', assignee_id: 1, position: 50 }, -] -``` - -### 9.5 Reset-and-Seed Script Updates - -Modify `reset-and-seed.js`: -1. Drop order: TASK_RELATIONS → TASK_TAGS → TASKS → **DELIVERABLES** → PROJECTS → ... (dependents first) -2. Drop `deliverable_type` enum type -3. Rename `next_task_sequence` → `next_deliverable_sequence` in PROJECTS schema -4. Seed order: users → tags → status definitions → coordination requirements → translations → projects → **deliverables** → tasks → task-tags → task relations -5. Update summary counts to reflect new data - ---- - -## 10. Use Cases - -### UC-1: Create a New Deliverable -**Actor**: Human PM / Developer -**Precondition**: User is authenticated. A project exists. -**Flow**: -1. User navigates to the Deliverable List page for a project. -2. User clicks "Create Deliverable." -3. User fills in name (required, max 30 chars), type (dropdown), and optional description. -4. System generates `deliverable_id` as `{PROJECT_CODE}-{next_deliverable_sequence}`. -5. System creates the deliverable with status `PLANNING` and initial status history entry. -6. System increments `next_deliverable_sequence` on the project. -7. Deliverable appears on the list and the Deliverable Kanban in the "Planning" column. - -### UC-2: Update Deliverable with Document Paths -**Actor**: Human PM / Developer -**Precondition**: Deliverable exists in PLANNING status. -**Flow**: -1. User opens the deliverable (edit modal or detail view). -2. User sets the spec file path (`ded_file_path`), `plan_file_path`, and optionally `prd_file_path`. -3. User sets `git_worktree` and `git_branch` (typically identical values). -4. System saves the updated deliverable. - -### UC-3: Approve an Implementation Plan -**Actor**: Human PM / Tech Lead -**Precondition**: Deliverable has `plan_file_path` set. Status is `PLANNING`. -**Flow**: -1. User views the deliverable detail. -2. User clicks "Approve Plan." -3. System sets `approved_by` to current user, `approved_at` to now. -4. System returns the updated deliverable. Status remains `PLANNING` — it is moved to `IN_PROGRESS` separately (explicitly or by the system when task creation begins). - -### UC-4: Transition Deliverable to In Progress -**Actor**: Human PM or System (after agent creates tasks from plan) -**Precondition**: Deliverable is in `PLANNING`, plan is approved. -**Flow**: -1. User (or system) sends `PATCH /projects/:code/deliverables/:id/status` with `{ "status": "IN_PROGRESS" }`. -2. System validates plan is approved and plan_file_path is set. -3. System updates status, appends to status_history. -4. Deliverable card moves to "In Progress" column on Deliverable Kanban. - -### UC-5: View Deliverable List with Copy-to-Clipboard -**Actor**: Human Developer -**Precondition**: Project has deliverables. -**Flow**: -1. User navigates to `/projects/ZAZZ/deliverables`. -2. System displays a sortable table of all deliverables. -3. User clicks the copy icon next to a plan file path. -4. Path is copied to clipboard. User pastes into terminal: `code docs/homepage-redesign-plan.md`. - -### UC-6: View Task Graph with Swim Lanes -**Actor**: Human Developer / PM -**Precondition**: Project has deliverables with associated tasks. -**Flow**: -1. User navigates to the Task Graph page. -2. System organizes the task dependency graph into swim lanes grouped by deliverable. -3. Each swim lane has a header showing the deliverable name. -4. Dependency edges render within and across swim lanes. - -### UC-7: Deliverable Reaches In Review (PR Created) -**Actor**: QA Agent (future) / Human -**Precondition**: All tasks for the deliverable are in `COMPLETED` status. -**Flow**: -1. Agent/user creates a PR for the deliverable's branch. -2. Agent/user updates the deliverable: `PUT /projects/:code/deliverables/:id` with `{ "pullRequestUrl": "https://github.com/..." }`. -3. Agent/user transitions status: `PATCH /projects/:code/deliverables/:id/status` with `{ "status": "IN_REVIEW" }`. -4. Deliverable card moves to "In Review" column. PR URL is visible on the card and in the list view. - -### UC-8: Deliverable Merged and Done -**Actor**: Human Reviewer / CI System -**Precondition**: PR is approved and merged to staging. -**Flow**: -1. After merge to staging: status transitions to `STAGED`. -2. After merge to main: status transitions to `DONE`. -3. Status history captures timestamps for each transition, enabling lead-time reporting. - -### UC-9: QA Creates Rework Tasks (Future — Out of Scope for Implementation) -**Actor**: QA Agent -**Precondition**: QA agent has analyzed the deliverable and found issues. -**Flow**: -1. QA agent creates new tasks linked to the deliverable with descriptions of the required fixes. -2. New tasks are placed in the `READY` column of the Task Kanban. -3. Agent workers pick up rework tasks and implement fixes. -4. When all rework tasks are `COMPLETED`, QA agent re-analyzes. -5. Cycle repeats until AC is met, then PR is created. - -**Note**: The data model supports this flow (tasks link to deliverables, status tracking is in place). The agent skills and automation are out of scope for this SPEC. - ---- - -## 11. User Stories - -### US-1: Create Deliverable -**As a** project lead, -**I want to** create a new deliverable for my project with a name and type, -**So that** I can define a unit of work that groups related tasks and tracks their lifecycle from planning to merge. - -### US-2: Attach Specification Documents -**As a** project lead, -**I want to** set file paths for the SPEC, implementation plan, and optional PRD on a deliverable, -**So that** team members and agents can find and reference the specification documents. - -### US-3: Approve Plan -**As a** tech lead, -**I want to** approve the implementation plan for a deliverable, -**So that** agents know the plan is finalized and task creation can begin. - -### US-4: Track Deliverable Status -**As a** project manager, -**I want to** see each deliverable's current status and the full history of status changes with timestamps, -**So that** I can track progress, identify bottlenecks, and report on lead times. - -### US-5: View Deliverable Kanban Board -**As a** project manager, -**I want to** see deliverables on a Kanban board with columns for Planning, In Progress, In Review, Staged, and Done, -**So that** I have a visual overview of all deliverable progress at a glance. - -### US-6: View Task Graph with Swim Lanes -**As a** developer, -**I want to** see tasks grouped by deliverable in swim lanes on the Task Graph, -**So that** I can quickly see each deliverable's sub-graph and understand task dependencies within and across deliverables. - -### US-7: Copy File Path to Clipboard -**As a** developer, -**I want to** click a copy icon next to a SPEC or plan file path in the deliverable list, -**So that** I can quickly open the document in my IDE or terminal without manually typing the path. - -### US-8: See Deliverable Name on Task Cards -**As a** developer, -**I want to** see which deliverable a task belongs to in the task card footer, -**So that** I have immediate context about what work product the task contributes to. - -### US-9: Navigate Between Views -**As a** user, -**I want to** switch between the Task Kanban, Task Graph, Deliverable List, and Deliverable Kanban views from the project navigation, -**So that** I can choose the appropriate view for my current needs. - -### US-10: Deliverable List with Sorting -**As a** project manager, -**I want to** sort the deliverable list by any column (ID, name, type, status, status date, task count), -**So that** I can prioritize my attention on deliverables that need it most. - -### US-11: Link Deliverable to Git Worktree -**As a** developer, -**I want to** specify the Git worktree and branch for a deliverable, -**So that** the system (and agents) know which worktree to perform work in. - -### US-12: Track PR at Deliverable Level -**As a** project lead, -**I want to** see the PR URL on the deliverable card and list view, -**So that** I can quickly navigate to the PR for review. - -### US-13: Create Deliverable with Correct ID Sequence -**As a** user, -**I want** deliverable IDs to follow the `{PROJECT_CODE}-{sequence}` format (e.g., ZAZZ-1, ZAZZ-2), -**So that** deliverables have stable, human-readable identifiers for communication and documentation. - ---- - -## 12. Acceptance Criteria - -### AC-1: DELIVERABLES Table -- [ ] `DELIVERABLES` table exists with all columns defined in Section 6.1 -- [ ] `deliverable_id` is unique across the database -- [ ] `deliverable_id` follows format `{PROJECT_CODE}-{int}` (e.g., `ZAZZ-1`) -- [ ] `position` column supports sparse numbering for Kanban drag-and-drop ordering -- [ ] `project_id` FK cascade-deletes deliverables when a project is deleted -- [ ] `status_history` stores valid JSON array of `{status, changedAt, changedBy}` objects -- [ ] `name` column max length is 30 characters -- [ ] `type` uses the `deliverable_type` pgEnum - -### AC-2: TASKS Table Modification -- [ ] `task_id` VARCHAR column is dropped from TASKS table -- [ ] `git_pull_request_url` column is dropped from TASKS table -- [ ] `TASKS` table has a `deliverable_id` integer NOT NULL column referencing `DELIVERABLES(id)` -- [ ] Deleting a deliverable CASCADE deletes all associated tasks -- [ ] Task API responses include `deliverableId` and `deliverableName` fields -- [ ] Tasks are identified by their serial integer `id` only (no human-readable string ID) -- [ ] `POST /tasks` requires `deliverableId` - -### AC-3: PROJECTS Table Modification -- [ ] `next_task_sequence` is renamed to `next_deliverable_sequence` (repurposed) -- [ ] `status_workflow` default is `['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED']` -- [ ] `PROJECTS` table has `deliverable_status_workflow` varchar array column -- [ ] `deliverable_status_workflow` default is `['PLANNING', 'IN_PROGRESS', 'IN_REVIEW', 'STAGED', 'DONE']` - -### AC-4: Deliverable CRUD API -- [x] `GET /projects/:code/deliverables` returns all deliverables for a project (uses project code, e.g. ZAZZ) -- [x] `GET /projects/:code/deliverables` supports `status` and `type` query filters -- [x] `GET /projects/:code/deliverables/:id` returns a single deliverable with all fields -- [x] `POST /projects/:code/deliverables` creates a deliverable, auto-generates `deliverable_id`, sets initial status history -- [x] `POST` increments `next_deliverable_sequence` on the project -- [x] `PUT /projects/:code/deliverables/:id` updates deliverable fields -- [x] `DELETE /projects/:code/deliverables/:id` deletes the deliverable and CASCADE deletes all associated tasks -- [ ] All routes require `TB_TOKEN` authentication -- [ ] All routes return 404 for non-existent resources -- [ ] `name` is required and max 30 characters on create -- [ ] `type` is required and must be a valid deliverable type enum value - -### AC-5: Status Transition API -- [x] `PATCH /projects/:code/deliverables/:id/status` changes status and appends to `status_history` -- [ ] Status must exist in `STATUS_DEFINITIONS` -- [ ] Status must be in the project's `deliverable_status_workflow` -- [ ] Transitioning to `IN_PROGRESS` requires `approved_at` to be non-null (plan must be approved) -- [ ] Transitioning to `IN_PROGRESS` requires `plan_file_path` to be set -- [ ] Response includes full updated deliverable with new status_history entry - -### AC-6: Plan Approval API -- [x] `PATCH /projects/:code/deliverables/:id/approve` sets `approved_by` and `approved_at` -- [ ] Requires `plan_file_path` to be set -- [ ] Returns 400 if plan file path is not set -- [ ] Returns 400 if already approved (cannot re-approve) -- [ ] Only works when deliverable status is `PLANNING` -- [ ] `approved_by` is set to the authenticated user's ID - -### AC-7: Deliverable Kanban Board UI -- [ ] Route `/projects/:projectCode/deliverable-kanban` renders the deliverable Kanban board -- [ ] Columns are dynamically generated from `project.deliverableStatusWorkflow` -- [ ] Default columns: Planning | In Progress | In Review | Staged | Done -- [ ] Deliverable cards display: ID badge, name, type badge, task progress bar, PR URL (if set) -- [ ] Drag-and-drop reordering within and across columns -- [ ] Creating a new deliverable opens a modal with name, type, and optional fields - -### AC-8: Task Graph Swim Lanes -- [ ] Task Graph page organizes task dependency nodes into swim lanes grouped by deliverable -- [ ] Each swim lane header shows the deliverable name -- [ ] Swim lanes are ordered by deliverable status (active first) -- [ ] Dependency edges render within and across swim lanes - -### AC-8b: Task Kanban Updated Columns -- [ ] Task Kanban default columns updated to Zazz methodology: To Do | Ready | In Progress | QA | Completed -- [ ] Existing column dynamic rendering from project `status_workflow` still works - -### AC-9: Task Card Deliverable Footer -- [ ] Task cards show the deliverable name in a footer section -- [ ] Footer is visually subtle (dimmed text, small font, border-top separator) - -### AC-10: Deliverable List Page -- [ ] Route `/projects/:projectCode/deliverables` renders a sortable table -- [ ] Columns: Deliverable ID, Name, Type, Status, Status Changed, SPEC Path, Plan Path, PRD Path, PR URL, Tasks -- [ ] Clicking column headers sorts the table (ascending/descending toggle) -- [ ] File path cells have a copy-to-clipboard icon button -- [ ] Clicking the copy icon copies the path and shows a brief "Copied!" tooltip -- [ ] PR URL is a clickable link that opens in a new tab - -### AC-11: Navigation -- [ ] Project-level navigation includes links to: Kanban, Graph, Deliverables (list), Deliverable Board -- [ ] Navigation items are translated via i18n - -### AC-12: Translations -- [ ] All new deliverable-related strings exist in all 4 languages (en, es, fr, de) -- [ ] Deliverable type ENUM values have translations under `deliverables.types.*` -- [ ] Deliverable status values have translations under `deliverables.statuses.*` -- [ ] New task statuses (QA, COMPLETED) have translations under `tasks.statuses.*` - -### AC-13: Seed Data -- [ ] Primary test project is "Zazz Board" with code `ZAZZ` -- [ ] At least 6 deliverables seeded across 3 projects (ZAZZ, MOBDEV, APIMOD) -- [ ] Deliverables have varied statuses (PLANNING, IN_PROGRESS, IN_REVIEW, PROD) -- [ ] At least one deliverable has a `pull_request_url` set -- [ ] Task seed data uses integer `id` only (no `task_id` varchar) -- [ ] All tasks reference a deliverable via `deliverable_id` NOT NULL FK -- [ ] New status definitions (STAGED, UAT, PROD, QA, COMPLETED) are seeded -- [ ] ZAZZ and MOBDEV projects use default `deliverable_status_workflow` (PLANNING → DONE) -- [ ] APIMOD project uses alternative release-pipeline workflow (PLANNING → IN_PROGRESS → IN_REVIEW → UAT → STAGED → PROD) to demonstrate workflow flexibility -- [ ] All projects use Zazz methodology defaults for `status_workflow` (task columns) - -### AC-14: Default Workflows for New Projects -- [ ] When a new project is created, `status_workflow` defaults to `['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED']` (Zazz task methodology) -- [ ] When a new project is created, `deliverable_status_workflow` defaults to `['PLANNING', 'IN_PROGRESS', 'IN_REVIEW', 'STAGED', 'DONE']` - ---- - -## 13. API Test Descriptions (PactumJS / Vitest) - -Tests follow the existing pattern: Vitest runner + PactumJS HTTP DSL against test database on port 3031. See `api/__tests__/README.md` for helpers. - -### 13.1 Deliverable CRUD Tests - -**File**: `api/__tests__/routes/deliverables.test.mjs` - -#### Describe: GET /projects/:code/deliverables -- **it** should return all deliverables for a project (seeded data) -- **it** should return an empty array for a project with no deliverables -- **it** should filter by status query parameter -- **it** should filter by type query parameter -- **it** should return 401 without TB_TOKEN header - -#### Describe: GET /deliverables/:id -- **it** should return a single deliverable with all fields -- **it** should return 404 for non-existent deliverable ID -- **it** should include taskCount and completedTaskCount -- **it** should include approvedByName when approved - -#### Describe: POST /projects/:code/deliverables -- **it** should create a deliverable with name and type (minimum required fields) -- **it** should auto-generate deliverable_id as {PROJECT_CODE}-{sequence} -- **it** should set initial status to PLANNING -- **it** should create initial status_history entry with PLANNING and current timestamp -- **it** should increment next_deliverable_sequence on the project -- **it** should return 400 if name exceeds 30 characters -- **it** should return 400 if name is missing -- **it** should return 400 if type is invalid (not in deliverable_type enum) -- **it** should return 404 if project does not exist -- **it** should accept optional fields (description, dedFilePath, planFilePath, prdFilePath, gitWorktree, gitBranch) - -#### Describe: PUT /projects/:code/deliverables/:id -- **it** should update the deliverable name -- **it** should update document paths (dedFilePath, planFilePath, prdFilePath) -- **it** should update git fields (gitWorktree, gitBranch) -- **it** should update pullRequestUrl -- **it** should return 404 for non-existent deliverable -- **it** should not allow changing deliverable_id -- **it** should not allow name exceeding 30 characters - -#### Describe: DELETE /projects/:code/deliverables/:id -- **it** should delete the deliverable and CASCADE delete associated tasks -- **it** should return 404 for non-existent deliverable -- **it** should return 200 with success message - -### 13.2 Status Transition Tests - -**File**: `api/__tests__/routes/deliverables.status.test.mjs` - -#### Describe: PATCH /projects/:code/deliverables/:id/status -- **it** should change status and append to status_history -- **it** should record changedBy as the authenticated user's ID -- **it** should record changedAt as current timestamp -- **it** should return 400 for invalid status (not in STATUS_DEFINITIONS) -- **it** should return 400 for status not in project's deliverable_status_workflow -- **it** should return 400 when transitioning to IN_PROGRESS without approved plan -- **it** should return 400 when transitioning to IN_PROGRESS without plan_file_path -- **it** should allow transitioning to IN_PROGRESS when plan is approved and plan_file_path is set -- **it** should return 404 for non-existent deliverable -- **it** should preserve existing status_history entries when appending - -### 13.3 Plan Approval Tests - -**File**: `api/__tests__/routes/deliverables.approval.test.mjs` - -#### Describe: PATCH /projects/:code/deliverables/:id/approve -- **it** should set approved_by to authenticated user's ID -- **it** should set approved_at to current timestamp -- **it** should return 400 if plan_file_path is not set -- **it** should return 400 if deliverable is already approved -- **it** should return 400 if deliverable is not in PLANNING status -- **it** should return the updated deliverable with approval fields populated -- **it** should not change the deliverable status (stays PLANNING) - -### 13.4 Deliverable Tasks Tests - -**File**: `api/__tests__/routes/deliverables.tasks.test.mjs` - -#### Describe: GET /projects/:code/deliverables/:id/tasks -- **it** should return all tasks linked to the deliverable -- **it** should return an empty array if no tasks are linked -- **it** should return 404 for non-existent deliverable -- **it** should include full task details (status, priority, assignee, etc.) - -### 13.5 Task Modification Tests (Updated) - -**File**: `api/__tests__/routes/tasks.test.mjs` (updated) - -#### Describe: POST /tasks (with deliverableId) -- **it** should create a task with a deliverableId (required) -- **it** should return 400 if deliverableId is missing -- **it** should return 400 if deliverableId references a non-existent deliverable - -#### Describe: PUT /tasks/:id (with deliverableId) -- **it** should update task's deliverableId (reassign to different deliverable) -- **it** should return 400 if setting deliverableId to null -- **it** should include deliverableName in response - -### 13.6 Project Deliverable Workflow Tests - -**File**: `api/__tests__/routes/projectDeliverableStatuses.test.mjs` - -#### Describe: GET /projects/:code/deliverable-statuses -- **it** should return the project's deliverable status workflow array -- **it** should return default workflow for a new project - -#### Describe: PUT /projects/:code/deliverable-statuses -- **it** should update the deliverable status workflow -- **it** should return 400 if any status code is not in STATUS_DEFINITIONS -- **it** should return 400 if removing a status that has active deliverables - ---- - -## 14. ID Scheme (Definitive) - -This is a clean break. The database is nuked and rebuilt. - -### Deliverables: Human-Readable VARCHAR IDs -- Format: `{PROJECT_CODE}-{int}` (e.g., `ZAZZ-1`, `APIMOD-3`) -- Stored in `DELIVERABLES.deliverable_id` VARCHAR(20), UNIQUE -- Generated on create using `PROJECTS.next_deliverable_sequence` (repurposed from the old `next_task_sequence`) -- Same auto-increment-on-create logic that previously generated task IDs -- These are what humans see, reference in conversation, and use in SPECs/plans - -### Tasks: Integer IDs Only -- Identified by `TASKS.id` (serial integer PK) — e.g., `1`, `2`, `42` -- The `task_id` VARCHAR column is **dropped** from the schema entirely -- The `next_task_sequence` column is **removed** from PROJECTS (repurposed as `next_deliverable_sequence`) -- Tasks are agent-facing work items; agents reference tasks by integer ID -- `TaskCard` displays the integer `id` in the badge -- The `git_pull_request_url` column is also **dropped** from TASKS (PRs live on deliverables) - ---- - -## 15. Worktree Convention - -In the Zazz methodology, each deliverable is scoped to a single Git worktree: - -- **Worktree directory name** = **Branch name** (by convention for clarity) -- Example: deliverable "Homepage Redesign" → branch `homepage-redesign` → worktree dir `homepage-redesign` -- Tasks within a deliverable inherit the worktree from their parent deliverable -- The `git_worktree` field on TASKS can be populated from the deliverable's `git_worktree` when tasks are created -- PRs are created from the deliverable's branch → main (or staging) - -The repo structure with worktrees: -``` -zazz-board/ -├── main/ ← main branch worktree -├── homepage-redesign/ ← deliverable branch worktree -├── fix-auth-token-expiry/ ← another deliverable branch -└── docs/ ← shared docs (SPECs, plans) -``` - ---- - -## 16. Open Questions - -1. **Deliverable card detail view**: Should clicking a deliverable card open a detail panel (like tasks) or navigate to the deliverable list view with that item expanded? - -2. **Task Graph swim lane interaction**: Should clicking a task node in a graph swim lane open the task detail panel? Should cross-deliverable dependency edges be visually distinct (e.g., dashed lines)? - ---- - -## 17. Dependencies - -- Existing `STATUS_DEFINITIONS` and `TRANSLATIONS` infrastructure (from user-defined-status-columns feature) -- Drizzle ORM schema-first workflow (`api/lib/db/schema.js`) -- Nuke-and-rebuild database strategy (`npm run db:reset`) -- @dnd-kit for new Kanban boards -- Mantine components for UI (Table, Card, Badge, Tooltip, CopyButton) -- react-router-dom v7 for new routes - ---- - -**Document Version**: 1.1 -**Last Updated**: 2026-03-01 -**Status**: Implemented -**Note**: This SPEC was used to build the deliverables feature. The document has been updated to reflect the implemented functionality and current terminology (Deliverable Specification / SPEC). diff --git a/docs/features/project-governance/project-governance-PROP.md b/docs/features/project-governance/project-governance-PROP.md deleted file mode 100644 index 767ffd29..00000000 --- a/docs/features/project-governance/project-governance-PROP.md +++ /dev/null @@ -1,98 +0,0 @@ -# Project Governance - Proposal (`-PROP`) -Status: Draft -Owner: Project governance discussion -Scope: Framework and process model - -## Problem Statement -The framework now clearly separates feature requirements (`-FRD`) from deliverable execution (`-SPEC`), but project-level governance still needs clearer rules for: -- defining features in a consistent way (as user journeys + requirements), -- managing proposals as idea-iteration artifacts, -- linking features, proposals, deliverables, and milestones in a way that scales across repositories. - -## Proposal Summary -Treat the **Project** as the highest-level governance object. - -Within a project: -- **Features** capture long-lived user journeys and requirements. -- **Proposals** capture exploratory ideation and debate (feature-scoped, deliverable-scoped, or both). -- **Deliverables** are implementation increments with explicit acceptance and test-driven validation. -- **Milestones** gate feature capability progression by date using collections of deliverables. - -User-journey-first principle: -- Feature definition starts with user journeys, and those journeys define feature boundaries. -- Journeys may represent human users, agents, and other software systems/integrations. -- Feature requirements should be organized around these journeys before implementation increments are defined. - -## Goals -- Preserve project-level clarity when work spans multiple repositories. -- Keep feature discussion separate from deliverable execution discussion. -- Support proposal flexibility without making proposals authoritative contracts. -- Allow many-to-many feature↔deliverable relationships. - -## Non-Goals -- Defining API schema changes for board services. -- Locking the project to one proposal workflow forever. -- Replacing deliverables as the core execution unit. - -## Proposed Governance Model -### 1) Project as top-level context -- A project may contain many features, proposals, deliverables, and milestones. -- A project may span multiple repositories. - -### 2) Feature model -- Feature = user journey + requirement context (what/why, not implementation how). -- One long-lived FRD per feature. -- Features evolve over time through many deliverables. -- User journeys are the primary signal for splitting/merging feature boundaries. - -### 3) Proposal model -- Proposal = optional ideation mechanism, not an authoritative contract. -- Proposal scope can be: - - feature-scoped, - - deliverable-scoped, - - joint (feature + deliverable). -- Proposal content may include both user-journey debate and technical implementation tradeoffs. - -### 4) Deliverable model -- Deliverable = implementation increment with concrete acceptance criteria and a Deliverable SPEC. -- Deliverables can be: - - Feature Increment - - Shared Support Increment - - Chore/Maintenance Increment - - Refactor Increment - - Bug/Defect Fix Increment - -### 5) Milestone model -- Milestones are date-gated capability progression targets. -- Milestones group deliverables; they do not require full feature completion. - -## Relationship Rules -- Feature↔Deliverable is many-to-many at the requirements layer. -- Requirement-changing deliverables should link to one or more features. -- Shared support work may satisfy multiple features. -- Chores may be feature-agnostic. -- Refactors are feature-linked only when they affect user-journey requirements. - -## Directory Strategy (Project Docs Root) -Keep feature and deliverable discussions physically separated: -- `features/` for feature FRDs and feature-scoped proposals -- `deliverables/` for deliverable SPEC/PLAN/PROP artifacts -- `standards/` for reusable implementation standards -- optional `milestones/` for milestone artifacts - -Suggested examples: -- `features/project-governance/project-governance-FRD.md` -- `features/project-governance/project-governance-PROP.md` -- `deliverables/DLV-142/DLV-142-SPEC.md` -- `deliverables/DLV-142/DLV-142-PROP.md` (optional) - -## Acceptance Criteria -- Project-level language explicitly treats project as top-level governance context. -- Feature discussion and deliverable discussion are clearly separated in both model and directory strategy. -- Proposal semantics are explicit: optional, exploratory, and attachable to feature/deliverable/both. -- Deliverable increment subtypes are explicitly documented. -- User journeys (human, agent, system) are explicitly documented as the core driver of feature definition. - -## Open Questions -- Should project-level (cross-feature) proposals live in a dedicated `proposals/` directory, or always attach to `features/` / `deliverables/`? -- Should there be a project-level index file for feature/proposal/deliverable linking across repositories? diff --git a/docs/zazzctl-command-spec.md b/docs/zazzctl-command-spec.md index 3d97a5df..93de7bd9 100644 --- a/docs/zazzctl-command-spec.md +++ b/docs/zazzctl-command-spec.md @@ -1,11 +1,11 @@ # zazzctl Command Spec (Draft v0.1) ## Purpose -`zazzctl` is a thin, vendor-neutral CLI adapter for Zazz Board API operations required by worker agents. +`zazzctl` is a thin, vendor-neutral CLI adapter for Zazz Board API operations used by Zazz agent roles. It standardizes command shapes, payload construction, output, and exit codes so Claude, Codex, and other agents can run the same execution protocol. ## Scope -This first version targets worker skill board operations: +This first version covers the board operations needed across worker-first execution flows, while also supporting planner and spec-builder profiles through the same canonical CLI: - deliverables: list/get/create/status/approve/tasks - tasks: create/get/update/status/block/unblock/note/delete/readiness/list - relations: add/list/delete @@ -24,7 +24,7 @@ This first version targets worker skill board operations: - `jq` ## Script Location -- Canonical implementation: `.agents/skills/worker/scripts/zazzctl` +- Canonical implementation: `.agents/skills/zazz-board-api/scripts/zazzctl.mjs` - Root convenience wrapper: `scripts/zazzctl` ## Environment Contract diff --git a/scripts/zazzctl b/scripts/zazzctl index 863bcbb3..2eeecd9c 100755 --- a/scripts/zazzctl +++ b/scripts/zazzctl @@ -1,4 +1,4 @@ #!/usr/bin/env sh set -eu SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) -exec "$SCRIPT_DIR/../.agents/skills/worker/scripts/zazzctl" "$@" +exec node "$SCRIPT_DIR/../.agents/skills/zazz-board-api/scripts/zazzctl.mjs" "$@" From 2d56deb5004043293dd939671e9432e182558256 Mon Sep 17 00:00:00 2001 From: michaelwitz Date: Sun, 22 Mar 2026 13:22:51 -0400 Subject: [PATCH 14/14] Add lint and pre-commit quality checks --- .husky/pre-commit | 2 + .markdownlint-cli2.jsonc | 13 + .zazz/proposals/future-fixes.md | 3 +- AGENTS.md | 4 - CONTRIBUTOR_SETUP.md | 10 +- README.md | 1 - WARP.md | 2 +- api/__tests__/USER_DEFINED_STATUSES_TESTS.md | 2 +- api/__tests__/helpers/testServer.js | 2 +- api/__tests__/routes/realtime-events.test.mjs | 2 +- api/eslint.config.js | 39 + api/package.json | 4 + api/scripts/seeders/seedAgentTokens.js | 2 +- api/src/middleware/authMiddleware.js | 2 +- api/src/routes/index-monolith-backup.js | 3 +- api/src/routes/index.js | 2 +- api/src/routes/projects.js | 2 +- api/src/routes/tasks.js | 2 +- api/src/schemas/common.js | 2 +- api/src/schemas/projects.js | 4 +- api/src/server.js | 3 +- api/src/services/databaseService.js | 7 +- api/src/services/realtimeService.js | 2 +- client/src/hooks/useAgentTokens.js | 2 +- client/src/hooks/useProjectEvents.js | 4 +- package-lock.json | 2636 ++++++++++++++++- package.json | 12 + scripts/lint-staged-files.mjs | 40 + 28 files changed, 2712 insertions(+), 97 deletions(-) create mode 100755 .husky/pre-commit create mode 100644 .markdownlint-cli2.jsonc create mode 100644 api/eslint.config.js create mode 100644 scripts/lint-staged-files.mjs diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..2f4eec02 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +npm run lint:staged diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 00000000..f727936b --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,13 @@ +{ + "config": { + "default": false, + "MD009": true, + "MD012": true, + "MD047": true + }, + "ignores": [ + "node_modules/**", + "client/node_modules/**", + "client/dist/**" + ] +} diff --git a/.zazz/proposals/future-fixes.md b/.zazz/proposals/future-fixes.md index 84b6be27..c8884a4f 100644 --- a/.zazz/proposals/future-fixes.md +++ b/.zazz/proposals/future-fixes.md @@ -71,9 +71,8 @@ Cleanup and improvements **outside the scope** of current deliverables. Add item **Design**: Non-project routes just work—no agent-token restriction. Authorization is limited to project-scoped routes. When a route gains project scoping (e.g. images become project-scoped), add agent-token authorization there. Authorization follows route scoping; don't restrict until the route has project context. - use **Dredd/Schemathesis** only if you need full contract testing. need to fix dedFilePath to **specFilePath** - we are going to need to create new seed data for these two deliverables before fix the column \ No newline at end of file + we are going to need to create new seed data for these two deliverables before fix the column diff --git a/AGENTS.md b/AGENTS.md index ff48846d..a119bbb0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,7 +37,6 @@ If any branch/worktree adds or changes settings in `.env` or `api/.env`: Consult `.zazz/standards/` for authoritative project rules. Index: [.zazz/standards/index.yaml](.zazz/standards/index.yaml) - | Standard | Use when | | ---------------------------------------------------------------- | ----------------------------------- | | [system-architecture.md](.zazz/standards/system-architecture.md) | Stack, layers, cloud deployment | @@ -45,7 +44,6 @@ Consult `.zazz/standards/` for authoritative project rules. Index: [.zazz/standa | [coding-styles.md](.zazz/standards/coding-styles.md) | Naming, i18n, conventions, patterns | | [data-architecture.md](.zazz/standards/data-architecture.md) | Schema, DB conventions, key tables | - --- ## Overview @@ -64,7 +62,6 @@ This repo **dogfoods** the Zazz Framework: Zazz Board is built with Zazz Board. **Skills** (`.agents/skills/`): Role-specific capabilities for framework agents. Load with any role skill. - | Skill | When it applies | | ------------------ | ------------------------------------------------------ | | **zazz-board-api** | Required by all framework agents — API auth, endpoints | @@ -80,7 +77,6 @@ This repo **dogfoods** the Zazz Framework: Zazz Board is built with Zazz Board. | pr-builder | Packages reviewer-ready PR titles and bodies | | database-baseline-refresh | Preserves live dev DB data while upgrading schema and refreshing the canonical seed baseline | - **Rules** (`.cursor/rules/`): Always-applied for Cursor (e.g. worktree workflow). --- diff --git a/CONTRIBUTOR_SETUP.md b/CONTRIBUTOR_SETUP.md index eb64056f..330acb0a 100644 --- a/CONTRIBUTOR_SETUP.md +++ b/CONTRIBUTOR_SETUP.md @@ -18,6 +18,14 @@ cd client && npm install --legacy-peer-deps && cd .. cp api/.env.example api/.env ``` +The root `npm install` step also installs the Git hooks for this repo. Pre-commit checks are intentionally lightweight: + +- staged backend JavaScript gets ESLint +- staged frontend JavaScript/JSX gets ESLint +- staged Markdown gets markdownlint + +Full backend tests remain a manual/CI step rather than a pre-commit requirement. + ## 2) Configure environment Edit `api/.env` and ensure both URLs use port **5433** and password `password`: @@ -137,4 +145,4 @@ This repo uses **worktrees** for feature work. See [AGENTS.md](./AGENTS.md) and - In worktrees, avoid manual `node_modules` symlinks. If `drizzle-kit` complains about `drizzle-orm`, re-run `npm install` at repo root plus `npm install --workspace=api`. - If client dependencies fail due to peer resolution, re-run with `--legacy-peer-deps`. - Port in use: `lsof -ti:3030 | xargs kill -9` (API), `lsof -ti:3001 | xargs kill -9` (client). -- Manual API token (seed): `550e8400-e29b-41d4-a716-446655440000` +- Sample agent API token for the reference `ZAZZ` project: `660e8400-e29b-41d4-a716-446655440101` diff --git a/README.md b/README.md index 7056a919..c8d32e22 100644 --- a/README.md +++ b/README.md @@ -328,7 +328,6 @@ curl http://localhost:3030/openapi.json For authenticated requests, use the token header: `curl -H "TB_TOKEN: 550e8400-e29b-41d4-a716-446655440000" http://localhost:3030/openapi.json` - --- ## API authentication diff --git a/WARP.md b/WARP.md index ae9cc88a..ba1a0b80 100644 --- a/WARP.md +++ b/WARP.md @@ -88,7 +88,7 @@ npm run test:coverage # Run tests with coverage npm run test # Runs via workspace ``` -**Prerequisites**: +**Prerequisites**: 1. Docker Postgres running via `npm run docker:up:db` 2. Test database setup (see Environment Strategy below) 3. Source `api/.env` before running tests to load environment variables diff --git a/api/__tests__/USER_DEFINED_STATUSES_TESTS.md b/api/__tests__/USER_DEFINED_STATUSES_TESTS.md index f64d3d96..66579c17 100644 --- a/api/__tests__/USER_DEFINED_STATUSES_TESTS.md +++ b/api/__tests__/USER_DEFINED_STATUSES_TESTS.md @@ -140,7 +140,7 @@ expectedStatusCodes = [ ### 3. Project Status Workflow Tests (31 tests) **File**: `routes/projectStatuses.test.mjs` -**Endpoints**: +**Endpoints**: - `GET /projects/:code/statuses` - `PUT /projects/:code/statuses` diff --git a/api/__tests__/helpers/testServer.js b/api/__tests__/helpers/testServer.js index 576c66f9..4baadf4c 100644 --- a/api/__tests__/helpers/testServer.js +++ b/api/__tests__/helpers/testServer.js @@ -17,7 +17,7 @@ export async function createTestServer() { }); // Add correlation ID hook - app.addHook('onRequest', async (request, reply) => { + app.addHook('onRequest', async (request, _reply) => { request.correlationId = request.headers['x-correlation-id'] || randomUUID(); request.log = request.log.child({ correlationId: request.correlationId }); }); diff --git a/api/__tests__/routes/realtime-events.test.mjs b/api/__tests__/routes/realtime-events.test.mjs index 2e157f83..8b918418 100644 --- a/api/__tests__/routes/realtime-events.test.mjs +++ b/api/__tests__/routes/realtime-events.test.mjs @@ -83,7 +83,7 @@ async function waitForProjectEvent({ projectCode, predicate, trigger, timeoutMs controller.abort(); try { await reader.cancel(); - } catch (error) { + } catch { // no-op } } diff --git a/api/eslint.config.js b/api/eslint.config.js new file mode 100644 index 00000000..8257e1bd --- /dev/null +++ b/api/eslint.config.js @@ -0,0 +1,39 @@ +import js from '@eslint/js'; +import globals from 'globals'; +import { defineConfig, globalIgnores } from 'eslint/config'; + +const vitestGlobals = { + describe: 'readonly', + it: 'readonly', + expect: 'readonly', + beforeAll: 'readonly', + beforeEach: 'readonly', + afterAll: 'readonly', + afterEach: 'readonly', + vi: 'readonly', +}; + +export default defineConfig([ + globalIgnores(['coverage/**']), + { + files: ['**/*.{js,mjs}'], + extends: [js.configs.recommended], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: globals.node, + }, + rules: { + 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^[A-Z_]' }], + }, + }, + { + files: ['__tests__/**/*.{js,mjs}'], + languageOptions: { + globals: { + ...globals.node, + ...vitestGlobals, + }, + }, + }, +]); diff --git a/api/package.json b/api/package.json index 01be8796..9425b46c 100644 --- a/api/package.json +++ b/api/package.json @@ -10,6 +10,7 @@ "dev:client": "vite", "build:client": "vite build", "preview:client": "vite preview", + "lint": "eslint .", "db:generate": "drizzle-kit generate", "db:migrate": "drizzle-kit migrate", "db:studio": "drizzle-kit studio", @@ -48,6 +49,9 @@ "postgres": "^3.4.7" }, "devDependencies": { + "@eslint/js": "^9.30.1", + "eslint": "^9.30.1", + "globals": "^16.3.0", "@types/node": "^22.10.7", "@vitest/coverage-v8": "^4.0.15", "drizzle-kit": "^0.31.8", diff --git a/api/scripts/seeders/seedAgentTokens.js b/api/scripts/seeders/seedAgentTokens.js index bdda52d8..54dcecd9 100644 --- a/api/scripts/seeders/seedAgentTokens.js +++ b/api/scripts/seeders/seedAgentTokens.js @@ -57,7 +57,7 @@ export async function seedAgentTokens() { async function runFromCli() { try { await seedAgentTokens(); - } catch (error) { + } catch { process.exitCode = 1; } finally { await client.end(); diff --git a/api/src/middleware/authMiddleware.js b/api/src/middleware/authMiddleware.js index 0d986d97..09cc5a80 100644 --- a/api/src/middleware/authMiddleware.js +++ b/api/src/middleware/authMiddleware.js @@ -131,7 +131,7 @@ export async function authMiddleware(request, reply) { * Optional authentication middleware * Allows routes to work with or without authentication */ -export async function optionalAuthMiddleware(request, reply) { +export async function optionalAuthMiddleware(request, _reply) { try { const token = tokenService.extractTokenFromRequest(request); diff --git a/api/src/routes/index-monolith-backup.js b/api/src/routes/index-monolith-backup.js index 2f2ff29d..a3511adf 100644 --- a/api/src/routes/index-monolith-backup.js +++ b/api/src/routes/index-monolith-backup.js @@ -8,7 +8,7 @@ import { const dbService = new DatabaseService(); -export default async function (app, opts) { +export default async function (app, _opts) { // Health check endpoint app.get('/health', async (request, reply) => { reply.send({ status: 'ok', timestamp: new Date().toISOString() }); @@ -628,4 +628,3 @@ export default async function (app, opts) { } }); } - diff --git a/api/src/routes/index.js b/api/src/routes/index.js index ced5e0ac..33b99b7f 100644 --- a/api/src/routes/index.js +++ b/api/src/routes/index.js @@ -20,7 +20,7 @@ import { authMiddleware } from '../middleware/authMiddleware.js'; const dbService = new DatabaseService(); const realtimeService = new RealtimeService(); -export default async function routes(fastify, options) { +export default async function routes(fastify, _options) { // Health check endpoint (public) fastify.get('/health', { schema: coreSchemas.getHealth }, async (request, reply) => { const tokenStats = tokenService.getCacheStats(); diff --git a/api/src/routes/projects.js b/api/src/routes/projects.js index 7234399c..8176a02e 100644 --- a/api/src/routes/projects.js +++ b/api/src/routes/projects.js @@ -60,7 +60,7 @@ export default async function projectRoutes(fastify, options) { const heartbeat = setInterval(() => { try { rawReply.write(': keep-alive\n\n'); - } catch (error) { + } catch { clearInterval(heartbeat); } }, 20000); diff --git a/api/src/routes/tasks.js b/api/src/routes/tasks.js index 005d0cc7..daa1b5aa 100644 --- a/api/src/routes/tasks.js +++ b/api/src/routes/tasks.js @@ -3,7 +3,7 @@ // - Task graph routes (relations, readiness): /src/routes/taskGraph.js // - Deliverable-scoped task CRUD: /src/routes/projects.js under /projects/:code/deliverables/:delivId/tasks/* -export default async function taskRoutes(fastify, options) { +export default async function taskRoutes(_fastify, _options) { // No global task routes - all task operations are now project/deliverable-scoped // or task graph operations (handled in taskGraph.js) } diff --git a/api/src/schemas/common.js b/api/src/schemas/common.js index 18fb8c9d..a7edbd6c 100644 --- a/api/src/schemas/common.js +++ b/api/src/schemas/common.js @@ -35,7 +35,7 @@ export const taskResponseSchema = { projectId: { type: 'number', description: 'Project id.' }, deliverableId: { type: 'number', description: 'Deliverable id.' }, phase: { type: 'number', nullable: true, description: 'Phase number from the execution plan (e.g. 1, 2, 3).' }, - phaseStep: { type: 'string', nullable: true, description: 'Human-readable phase step within the deliverable (e.g. \"1.2\", \"2.1\").' }, + phaseStep: { type: 'string', nullable: true, description: 'Human-readable phase step within the deliverable (e.g. "1.2", "2.1").' }, title: { type: 'string', description: 'Task title.' }, status: { type: 'string', enum: ['TO_DO', 'READY', 'IN_PROGRESS', 'QA', 'COMPLETED'], description: 'Current workflow status.' }, position: { type: 'number', description: 'Sort order in column.' }, diff --git a/api/src/schemas/projects.js b/api/src/schemas/projects.js index dd387a6f..7d5a636f 100644 --- a/api/src/schemas/projects.js +++ b/api/src/schemas/projects.js @@ -2,7 +2,7 @@ * Project and project-scoped task route schemas. */ -import { idParam, codeParam, taskResponseSchema } from './common.js'; +import { idParam, taskResponseSchema } from './common.js'; export const projectSchemas = { getProjects: { @@ -161,7 +161,7 @@ export const projectSchemas = { createDeliverableTask: { tags: ['projects'], summary: 'Create task in deliverable', - description: 'Creates a task within a deliverable. delivId is the numeric id from the create deliverable response (not the deliverable code string). The deliverable must be approved before creating tasks. Include prompt with goal, instructions, and acceptance criteria. Use phase and phaseStep to align with PLAN structure (e.g. phase 1, phaseStep \"1.2\").', + description: 'Creates a task within a deliverable. delivId is the numeric id from the create deliverable response (not the deliverable code string). The deliverable must be approved before creating tasks. Include prompt with goal, instructions, and acceptance criteria. Use phase and phaseStep to align with PLAN structure (e.g. phase 1, phaseStep "1.2").', params: { type: 'object', required: ['code', 'delivId'], diff --git a/api/src/server.js b/api/src/server.js index 0a66e2c3..0e5ffe94 100644 --- a/api/src/server.js +++ b/api/src/server.js @@ -4,7 +4,6 @@ import { tokenService } from './services/tokenService.js'; import cors from '@fastify/cors'; import swagger from '@fastify/swagger'; import swaggerUi from '@fastify/swagger-ui'; -import { authMiddleware } from './middleware/authMiddleware.js'; import routes from './routes/index.js'; // Create Fastify instance with built-in Pino logger @@ -15,7 +14,7 @@ const app = Fastify({ }); // Add correlation ID hook -app.addHook('onRequest', async (request, reply) => { +app.addHook('onRequest', async (request, _reply) => { request.correlationId = request.headers['x-correlation-id'] || randomUUID(); request.log = request.log.child({ correlationId: request.correlationId }); }); diff --git a/api/src/services/databaseService.js b/api/src/services/databaseService.js index 8ffa5b65..1a39ef93 100644 --- a/api/src/services/databaseService.js +++ b/api/src/services/databaseService.js @@ -1,8 +1,7 @@ -import { eq, and, sql, desc, asc, like, or, inArray, ne } from 'drizzle-orm'; +import { eq, and, sql, asc, like, or, inArray } from 'drizzle-orm'; import { db } from '../../lib/db/index.js'; import { USERS, PROJECTS, DELIVERABLES, TASKS, TAGS, TASK_TAGS, IMAGE_METADATA, IMAGE_DATA, STATUS_DEFINITIONS, TRANSLATIONS, TASK_RELATIONS, COORDINATION_TYPES, FILE_LOCKS, AGENT_TOKENS } from '../../lib/db/schema.js'; import { getRandomTagColor } from '../utils/tagColors.js'; -import { keysToCamelCase } from '../utils/propertyMapper.js'; import { randomUUID } from 'crypto'; /** @@ -1023,8 +1022,6 @@ class DatabaseService { status: TASKS.status, isCancelled: TASKS.is_cancelled }).from(TASKS).where(eq(TASKS.id, id)).limit(1); - const beforeStatus = current?.status; - // Immutability: cancelled tasks cannot be uncancelled or have their status changed if (current?.isCancelled) { if (taskData.isCancelled === false) { @@ -1060,7 +1057,7 @@ class DatabaseService { updateData.status = 'COMPLETED'; } - const [task] = await db.update(TASKS) + await db.update(TASKS) .set(updateData) .where(eq(TASKS.id, id)) .returning(); diff --git a/api/src/services/realtimeService.js b/api/src/services/realtimeService.js index 84df0afb..e7370b6b 100644 --- a/api/src/services/realtimeService.js +++ b/api/src/services/realtimeService.js @@ -57,7 +57,7 @@ export default class RealtimeService { for (const [subscriberId, subscriber] of projectSubscribers.entries()) { try { subscriber.send(sseMessage); - } catch (error) { + } catch { // Drop dead subscribers so one broken connection does not poison broadcasts. this.unsubscribe(normalizedCode, subscriberId); } diff --git a/client/src/hooks/useAgentTokens.js b/client/src/hooks/useAgentTokens.js index 3f1677a0..1c9e6697 100644 --- a/client/src/hooks/useAgentTokens.js +++ b/client/src/hooks/useAgentTokens.js @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; function getToken() { return localStorage.getItem('TB_TOKEN'); diff --git a/client/src/hooks/useProjectEvents.js b/client/src/hooks/useProjectEvents.js index f490f005..451ec524 100644 --- a/client/src/hooks/useProjectEvents.js +++ b/client/src/hooks/useProjectEvents.js @@ -20,7 +20,7 @@ function parseSseBlock(block) { try { return { eventName, data: JSON.parse(dataLines.join('\n')) }; - } catch (error) { + } catch { return null; } } @@ -112,7 +112,7 @@ export function useProjectEvents(projectCode, { enabled = true, onEvent } = {}) if (reader) { try { await reader.cancel(); - } catch (error) { + } catch { // no-op } } diff --git a/package-lock.json b/package-lock.json index da5a3105..7874c21d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,9 @@ "devDependencies": { "concurrently": "^9.1.0", "drizzle-orm": "^0.45.1", + "husky": "^9.1.7", + "lint-staged": "^16.1.6", + "markdownlint-cli2": "^0.18.1", "pactum-supertest": "^1.0.0", "playwright": "^1.58.2" } @@ -34,9 +37,12 @@ "postgres": "^3.4.7" }, "devDependencies": { + "@eslint/js": "^9.30.1", "@types/node": "^22.10.7", "@vitest/coverage-v8": "^4.0.15", "drizzle-kit": "^0.31.8", + "eslint": "^9.30.1", + "globals": "^16.3.0", "openapi-schema-validator": "^12.1.3", "pactum": "^3.8.0", "vitest": "^4.0.15" @@ -1029,6 +1035,258 @@ "node": ">=18" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@exodus/schemasafe": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", @@ -1317,6 +1575,58 @@ "yaml": "^2.4.1" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1397,6 +1707,44 @@ "node": ">=8" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@pinojs/redact": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", @@ -1760,6 +2108,19 @@ "win32" ] }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@standard-schema/spec": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", @@ -1778,6 +2139,16 @@ "assertion-error": "^2.0.1" } }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", @@ -1792,6 +2163,27 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.17.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.0.tgz", @@ -1802,6 +2194,13 @@ "undici-types": "~6.21.0" } }, + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, + "license": "MIT" + }, "node_modules/@vitest/coverage-v8": { "version": "4.0.15", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.15.tgz", @@ -1957,8 +2356,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1966,6 +2363,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/ajv": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", @@ -1999,10 +2406,26 @@ } } }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" @@ -2012,9 +2435,9 @@ } }, "node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", "engines": { "node": ">=12" @@ -2023,6 +2446,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -2078,6 +2508,13 @@ "fastq": "^1.17.1" } }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/brace-expansion": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", @@ -2099,6 +2536,19 @@ "node": "20 || >=22" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -2106,10 +2556,20 @@ "dev": true, "license": "MIT" }, - "node_modules/centra": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/centra/-/centra-2.7.0.tgz", - "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/centra": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/centra/-/centra-2.7.0.tgz", + "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==", "dev": true, "license": "MIT", "dependencies": { @@ -2172,6 +2632,89 @@ "node": ">=8" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", + "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -2284,6 +2827,13 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2297,6 +2847,16 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/component-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/component-type/-/component-type-2.0.0.tgz", @@ -2310,6 +2870,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, "node_modules/concurrently": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.0.tgz", @@ -2398,6 +2965,27 @@ } } }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/deep-override": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/deep-override/-/deep-override-1.0.2.tgz", @@ -2433,6 +3021,20 @@ "node": ">=6" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/drizzle-kit": { "version": "0.31.9", "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.9.tgz", @@ -2586,6 +3188,32 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/es-module-lexer": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", @@ -2664,6 +3292,234 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/estree-walker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", @@ -2674,6 +3530,23 @@ "@types/estree": "^1.0.0" } }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, "node_modules/expect-type": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", @@ -2696,6 +3569,30 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-json-stringify": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.0.1.tgz", @@ -2720,6 +3617,13 @@ "rfdc": "^1.2.0" } }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-querystring": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", @@ -2863,6 +3767,32 @@ } } }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-my-way": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.3.0.tgz", @@ -2877,6 +3807,44 @@ "node": ">=20" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, "node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", @@ -2951,6 +3919,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-tsconfig": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", @@ -2987,6 +3968,53 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3020,6 +4048,59 @@ "node": ">= 0.8" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -3035,6 +4116,53 @@ "node": ">= 10" } }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3044,6 +4172,40 @@ "node": ">=8" } }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3144,6 +4306,26 @@ "jiti": "bin/jiti.js" } }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-query": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/json-query/-/json-query-2.2.2.tgz", @@ -3195,6 +4377,57 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/katex": { + "version": "0.16.40", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.40.tgz", + "integrity": "sha512-1DJcK/L05k1Y9Gf7wMcyuqFOL6BiY3vY0CFcAM/LPRN04NALxcl6u7lOWNsp3f/bCHWxigzQl6FbR95XJ4R84Q==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/klona": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", @@ -3205,6 +4438,20 @@ "node": ">= 8" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/light-my-request": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-6.6.0.tgz", @@ -3242,67 +4489,353 @@ ], "license": "MIT" }, - "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", - "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "uc.micro": "^2.0.0" } }, - "node_modules/magicast": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", - "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "node_modules/lint-staged": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz", + "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "source-map-js": "^1.2.1" + "commander": "^14.0.3", + "listr2": "^9.0.5", + "picomatch": "^4.0.3", + "string-argv": "^0.3.2", + "tinyexec": "^1.0.4", + "yaml": "^2.8.2" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" } }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "node_modules/listr2": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", "dev": true, "license": "MIT", "dependencies": { - "semver": "^7.5.3" + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=10" - }, + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdownlint": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz", + "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark": "4.0.2", + "micromark-core-commonmark": "2.0.3", + "micromark-extension-directive": "4.0.0", + "micromark-extension-gfm-autolink-literal": "2.1.0", + "micromark-extension-gfm-footnote": "2.1.0", + "micromark-extension-gfm-table": "2.1.1", + "micromark-extension-math": "3.1.0", + "micromark-util-types": "2.0.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.18.1.tgz", + "integrity": "sha512-/4Osri9QFGCZOCTkfA8qJF+XGjKYERSHkXzxSyS1hd3ZERJGjvsUao2h4wdnvpHp6Tu2Jh/bPHM0FE9JJza6ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "globby": "14.1.0", + "js-yaml": "4.1.0", + "jsonc-parser": "3.3.1", + "markdown-it": "14.1.0", + "markdownlint": "0.38.0", + "markdownlint-cli2-formatter-default": "0.0.5", + "micromatch": "4.0.8" + }, + "bin": { + "markdownlint-cli2": "markdownlint-cli2-bin.mjs" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2-formatter-default": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.5.tgz", + "integrity": "sha512-4XKTwQ5m1+Txo2kuQ3Jgpo/KmnG+X90dWt4acufg6HVGadTUG5hzHF/wssp9b5MBYOMCnZ9RMPaU//uHsszF8Q==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + }, + "peerDependencies": { + "markdownlint-cli2": ">=0.0.4" + } + }, "node_modules/matchit": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/matchit/-/matchit-1.1.0.tgz", @@ -3316,6 +4849,586 @@ "node": ">=6" } }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", + "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", @@ -3335,6 +5448,19 @@ "dev": true, "license": "MIT" }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "10.2.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", @@ -3384,6 +5510,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, "node_modules/obug": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", @@ -3404,6 +5537,22 @@ "node": ">=14.0.0" } }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/openapi-fuzzer-core": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/openapi-fuzzer-core/-/openapi-fuzzer-core-1.0.6.tgz", @@ -3451,6 +5600,56 @@ "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", "license": "MIT" }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -3495,6 +5694,39 @@ "dev": true, "license": "ISC" }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/parse-graphql": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-graphql/-/parse-graphql-1.0.0.tgz", @@ -3502,6 +5734,16 @@ "dev": true, "license": "MIT" }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -3527,6 +5769,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -3705,6 +5960,16 @@ "url": "https://github.com/sponsors/porsager" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/process-warning": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", @@ -3721,6 +5986,47 @@ ], "license": "MIT" }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/quick-format-unescaped": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", @@ -3755,6 +6061,16 @@ "node": ">=0.10.0" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -3765,6 +6081,23 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ret": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz", @@ -3835,6 +6168,30 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -3986,6 +6343,52 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/sonic-boom": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", @@ -4058,6 +6461,16 @@ "dev": true, "license": "MIT" }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -4118,12 +6531,12 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -4154,6 +6567,19 @@ "node": ">=8" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -4217,9 +6643,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", + "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", "dev": true, "license": "MIT", "engines": { @@ -4253,6 +6679,19 @@ "node": ">=14.0.0" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toad-cache": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.0.tgz", @@ -4301,6 +6740,26 @@ "dev": true, "license": "0BSD" }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -4308,6 +6767,29 @@ "dev": true, "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/vite": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", @@ -4977,6 +7459,16 @@ "node": ">=8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -5079,15 +7571,18 @@ } }, "node_modules/yaml": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", - "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yargs": { @@ -5164,6 +7659,19 @@ "node": ">=8" } }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zazz-board": { "resolved": "api", "link": true diff --git a/package.json b/package.json index 8f6968ef..34dd7d35 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dev:client": "cd client && npm run dev", "dev": "concurrently \"npm run dev:api\" \"npm run dev:client\"", "build": "cd client && npm run build", + "prepare": "husky", "docker:up": "docker-compose up -d", "docker:down": "docker-compose down", "docker:up:db": "docker-compose up -d postgres", @@ -24,12 +25,23 @@ "db:migrate": "npm run db:migrate --workspace=api", "db:seed": "npm run db:seed --workspace=api", "db:reset": "npm run db:reset --workspace=api", + "lint": "npm run lint:api && npm run lint:client && npm run lint:md", + "lint:api": "npm run lint --workspace=api", + "lint:client": "cd client && npm run lint", + "lint:md": "markdownlint-cli2 \"**/*.md\" \"#node_modules\" \"#client/node_modules\" \"#client/dist\"", + "lint:staged": "lint-staged", "test": "npm run test --workspace=api", "test:watch": "npm run test:watch --workspace=api" }, + "lint-staged": { + "*": "node scripts/lint-staged-files.mjs" + }, "devDependencies": { "concurrently": "^9.1.0", "drizzle-orm": "^0.45.1", + "husky": "^9.1.7", + "lint-staged": "^16.1.6", + "markdownlint-cli2": "^0.18.1", "pactum-supertest": "^1.0.0", "playwright": "^1.58.2" }, diff --git a/scripts/lint-staged-files.mjs b/scripts/lint-staged-files.mjs new file mode 100644 index 00000000..72784025 --- /dev/null +++ b/scripts/lint-staged-files.mjs @@ -0,0 +1,40 @@ +#!/usr/bin/env node + +import { spawnSync } from 'node:child_process'; + +const stagedFiles = [...new Set(process.argv.slice(2))]; + +const apiFiles = stagedFiles + .filter((file) => /^api\/.+\.(js|mjs)$/.test(file)) + .map((file) => file.slice('api/'.length)); + +const clientFiles = stagedFiles + .filter((file) => /^client\/.+\.(js|jsx)$/.test(file)) + .map((file) => file.slice('client/'.length)); + +const markdownFiles = stagedFiles.filter((file) => file.endsWith('.md')); + +function run(command, args, options = {}) { + const result = spawnSync(command, args, { + stdio: 'inherit', + ...options, + }); + + if (result.status !== 0) { + process.exit(result.status ?? 1); + } +} + +if (apiFiles.length > 0) { + run('npm', ['exec', '--workspace=api', '--', 'eslint', '--no-warn-ignored', ...apiFiles]); +} + +if (clientFiles.length > 0) { + run('npm', ['exec', '--', 'eslint', '--no-warn-ignored', ...clientFiles], { + cwd: 'client', + }); +} + +if (markdownFiles.length > 0) { + run('npm', ['exec', '--', 'markdownlint-cli2', ...markdownFiles]); +}