diff --git a/.gitignore b/.gitignore index 562f5e73..7fca7911 100644 --- a/.gitignore +++ b/.gitignore @@ -52,15 +52,9 @@ coverage.* # app/test/goldens/goldens/{ci,linux}/). app/test/goldens/failures/ -# -- pql per-repo state (clide dogfoods against itself; pql's index lands -# here when running queries locally). `pql.db` is also where the -# `tools/scripts/plan` stopgap writes decisions + tickets (D-040). +# -- pql per-repo state (index + planning DB, rebuilt from markdown) ---- /.pql/ -# -- Python stopgap tooling under tools/scripts/plan ------------------ -tools/scripts/__pycache__/ -tools/scripts/planning/__pycache__/ - # -- SQLite index files (defensive; should never land at repo root) ---- *.sqlite *.sqlite-journal diff --git a/CHANGELOG.md b/CHANGELOG.md index 37fc2ed3..51f277cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,13 @@ heading, and (b) bumping `project.yaml` `version:` in the same commit. ### Added +- pql skill installed via `pql init --with-skill=yes` + (`.claude/skills/pql/SKILL.md`). Covers vault queries and the + planning surface (decisions + tickets). + +- `Bash(pql)` and `Bash(pql *)` permissions in + `.claude/settings.json`. + - Git subsystem in the daemon (`lib/src/git/`). Status parser (`git status --porcelain`), unified-diff parser, and operations (stage, unstage, stage-hunk, discard, commit, stash, log, pull, @@ -270,6 +277,21 @@ heading, and (b) bumping `project.yaml` `version:` in the same commit. updated to reference `decisions/architecture.md` instead of the deleted `docs/ADRs/`. +- `make decisions-validate` rewired from `tools/scripts/plan` to + `pql decisions validate`. + +- Decision discipline guardrail in CLAUDE.md now points at + `pql decisions claim` instead of the Python stopgap. + +### Removed + +- `tools/scripts/plan` — Python stopgap planning scripts, superseded + by `pql` 1.0 native `decisions` and `ticket` subcommands. Sunset + condition from + [`D-040`](decisions/process.md#d-040-python-stopgap-under-toolsscriptsplan) + met; deletion per + [`R-011`](decisions/rejected.md#r-011-permanent-stopgap). + ### Removed - `docs/ADRs/` directory — content lifted into `decisions/` as D/R diff --git a/CLAUDE.md b/CLAUDE.md index 3b054bee..4c9cb2b7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -28,7 +28,7 @@ These are load-bearing. Violating any means the design is wrong, not the rule. - **pql: wrap, don't duplicate, and treat it as a clide subsystem when present.** Pql logic only lives in `lib/src/pql/` (pure shell-outs). Clide owns pql's `ignore_files:` config key; it never touches pql's `.pql/` index/cache data. See [`D-003`](decisions/architecture.md#d-003-pql-as-supporter-tool-clide-wraps-never-duplicates). - **Repo-is-the-workspace.** The git repo root is the workspace — no parallel "vault" concept. Clide dogfoods against its own repo. - **Ignore discipline.** Single knob: `ignore_files:` in `.pql/config.yaml`, ordered layering. Default `[.gitignore]`; clide writes `[.gitignore, .clideignore]` when `.clideignore` exists. See [`D-004`](decisions/architecture.md#d-004-ignore-file-strategy). -- **Decision discipline.** All architectural choices live in `decisions/.md` as `D-NNN` records. Open questions live in `decisions/questions-.md` as `Q-NNN`. Rejected alternatives live in `decisions/rejected.md` as `R-NNN`. Before an architectural change, read the relevant domain file; before disagreeing with a guardrail, propose an amendment to the underlying `D-NNN` rather than a one-off. Claim new IDs via `tools/scripts/plan decisions claim D "title"` (until pql ships planning subcommands — see [`Q-021`](decisions/questions-architecture.md#q-021-pql-absorbs-planning-vs-keeps-separate)). See [`decisions/README.md`](decisions/README.md). +- **Decision discipline.** All architectural choices live in `decisions/.md` as `D-NNN` records. Open questions live in `decisions/questions-.md` as `Q-NNN`. Rejected alternatives live in `decisions/rejected.md` as `R-NNN`. Before an architectural change, read the relevant domain file; before disagreeing with a guardrail, propose an amendment to the underlying `D-NNN` rather than a one-off. Claim new IDs via `pql decisions claim D "title"`. See [`decisions/README.md`](decisions/README.md). ## Tier ordering (don't skip ahead) diff --git a/Makefile b/Makefile index 48031dc2..47ca88f3 100644 --- a/Makefile +++ b/Makefile @@ -174,7 +174,7 @@ security: ## Dart advisory review + ptyc source review (manual — no floating d .PHONY: decisions-validate decisions-validate: ## Parser dry-run over decisions/*.md (cheap pre-push gate). - tools/scripts/plan decisions validate + pql decisions validate .PHONY: push-check push-check: decisions-validate test-core test test-a11y ## Pre-push gate: decisions + core + fast unit + widget + golden + a11y (<90s). diff --git a/app/lib/builtin/decisions/src/extension.dart b/app/lib/builtin/decisions/src/extension.dart index 1202c9f1..7fadbe4d 100644 --- a/app/lib/builtin/decisions/src/extension.dart +++ b/app/lib/builtin/decisions/src/extension.dart @@ -2,9 +2,7 @@ import 'package:clide_app/extension/extension.dart'; /// Tier-reserved stub. Will surface a sidebar tab (filter by domain / /// status, backlinks from current file) + commands (`decisions.open`, -/// `decisions.claim`, `decisions.amend`). Data source: `pql decisions -/// …` once `Q-021` resolves; `tools/scripts/plan decisions …` until -/// then. +/// `decisions.claim`, `decisions.amend`). Data source: `pql decisions …`. class DecisionsExtension extends ClideExtension { @override String get id => 'builtin.decisions'; diff --git a/app/lib/builtin/tickets/src/extension.dart b/app/lib/builtin/tickets/src/extension.dart index 777cdbc4..01113b74 100644 --- a/app/lib/builtin/tickets/src/extension.dart +++ b/app/lib/builtin/tickets/src/extension.dart @@ -2,9 +2,8 @@ import 'package:clide_app/extension/extension.dart'; /// Tier-reserved stub. Will surface a sidebar tab (filtered list) + a /// workspace tab (kanban board) + commands (`tickets.open`, -/// `tickets.new`, `tickets.move`, `tickets.block`). Data source: `pql -/// ticket …` once `Q-021` resolves; `tools/scripts/plan ticket …` until -/// then. Ticket persistence strategy open at `Q-022`. +/// `tickets.new`, `tickets.move`, `tickets.block`). Data source: +/// `pql ticket …`. Ticket persistence strategy open at `Q-022`. class TicketsExtension extends ClideExtension { @override String get id => 'builtin.tickets'; diff --git a/decisions/README.md b/decisions/README.md index 5952c0ac..0f622623 100644 --- a/decisions/README.md +++ b/decisions/README.md @@ -82,26 +82,23 @@ same semantics, no race on concurrent sessions. ## Querying -Stopgap today: `tools/scripts/plan decisions …` reads and writes -`.pql/pql.db` (gitignored; markdown is source of truth). Replaced -by `pql decisions …` when pql ships parity — see -[D-040](process.md#d-040-python-stopgap-under-toolsscriptsplan) and -[R-011](rejected.md#r-011-permanent-stopgap). +`pql decisions …` reads `decisions/*.md` and writes `.pql/pql.db` +(gitignored; markdown is the source of truth). Common queries: ```bash -tools/scripts/plan decisions list --type confirmed --domain architecture -tools/scripts/plan decisions show D-005 --with-refs -tools/scripts/plan decisions coverage # D-records without tickets -tools/scripts/plan decisions validate # pre-push parser gate +pql decisions list --type confirmed --domain architecture +pql decisions show D-005 --with-refs +pql decisions coverage # D-records without tickets +pql decisions validate # pre-push parser gate +pql ticket board # kanban view of tickets ``` ## Adding a decision 1. Edit the appropriate domain file. 2. Follow the record shape above. -3. Run `tools/scripts/plan decisions validate` (also runs in - `make push-check`). +3. Run `pql decisions validate` (also runs in `make push-check`). 4. Commit. The SQLite index rebuilds from markdown on any - `tools/scripts/plan decisions sync`. + `pql decisions sync`. diff --git a/decisions/process.md b/decisions/process.md index b306da52..11c97ada 100644 --- a/decisions/process.md +++ b/decisions/process.md @@ -46,12 +46,13 @@ Q&D record system itself, kanban, commit conventions, changelog. - **Cost:** Planning features don't ship until pql catches up. Mitigated by [D-040](#d-040-python-stopgap-under-toolsscriptsplan). Gated by [Q-021](questions-process.md#q-021-pql-absorbs-planning-vs-keeps-separate). - **Raised by:** 2026-04-21 planning. -### D-040: Python stopgap under `tools/scripts/plan` +### D-040: [SUPERSEDED] Python stopgap under `tools/scripts/plan` - **Date:** 2026-04-21 - **Decision:** A time-limited Python port of settled-reach's `decisions_sync.py` + `ticket` + `decision` scripts lives at `tools/scripts/plan` with support modules under `tools/scripts/planning/`. Writes to `.pql/pql.db` (gitignored). Ticket IDs are `T-NNN` (TEXT PK, reshape from settled-reach's integers). Same schema, same markdown, same verb shape as the eventual `pql` subcommands. - **Sunset:** Delete the stopgap when pql ships `pql decisions sync | validate | list | show | claim | coverage` + `pql ticket new | list | show | status | assign | block | board` with feature parity, and reads the same `.pql/pql.db` file the stopgap wrote. Removal commit shape: [R-011](rejected.md#r-011-permanent-stopgap). - **Rationale:** Planning tooling must work day one. Pql's Go implementation won't land for at least a cycle or two. Without a stopgap, the convention lives on paper; with one, tickets + decisions are queryable from today. Same schema means migration is call-site find-replace (`tools/scripts/plan ` → `pql `), no data migration. - **Cost:** Python dep on contributors' machines (already present on most Linux dists). One time-limited tool to maintain. See [R-010](rejected.md#r-010-python-script-stopgap-at-toolingdb) for why `tools/scripts/plan` and not `tooling/db/`. - **Raised by:** 2026-04-21 planning. +- **Amendment (2026-04-22):** Sunset condition met. pql 1.0.0 ships full feature parity. Stopgap deleted per [R-011](rejected.md#r-011-permanent-stopgap). --- diff --git a/tools/scripts/README.md b/tools/scripts/README.md deleted file mode 100644 index 2d084e85..00000000 --- a/tools/scripts/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# STOPGAP — Planning tooling - -This directory is a **time-limited stopgap**. The Python scripts here -port settled-reach's `decisions_sync.py` + `ticket` + `decision` -scripts, Scrum-stripped, and write to `.pql/pql.db` (gitignored). - -## Sunset clause - -Per [`D-040`](../../decisions/process.md#d-040-python-stopgap-under-toolsscriptsplan) -and [`R-011`](../../decisions/rejected.md#r-011-permanent-stopgap), -this stopgap deletes when pql ships: - -- `pql decisions sync | validate | list | show | claim | coverage` -- `pql ticket new | list | show | status | assign | block | board` - -with feature parity on the same `.pql/pql.db` file this stopgap wrote. - -Migration is a call-site find-replace: - -``` -tools/scripts/plan decisions sync → pql decisions sync -tools/scripts/plan ticket new task "…" → pql ticket new task "…" -tools/scripts/plan ticket board → pql ticket board -``` - -See [`Q-021`](../../decisions/questions-architecture.md#q-021-pql-absorbs-planning-vs-keeps-separate) -for the open gate on whether pql absorbs planning long-term. - -## Entrypoint - -`plan` is a Python executable. Support modules live under `planning/`. - -``` -plan decisions sync | validate | claim D|Q|R [title] | list | show | coverage -plan ticket new "title" | list | show | status | assign -plan ticket block --by | unblock --from -plan ticket team | label add|rm