Migrates the project's decisions + ticketing system off the bespoke SQLite tooling
(tooling/db/*, settledreach.db) onto pql — the markdown-vault + planning tool
that was itself productized from this repo's planning structures. Phases 0-5 of pql-migration.md. Big-bang cutover behind a verification gate; legacy tooling stays
intact as the rollback path until a separate Phase-6 follow-up.
What changed
Decisions -> governance/{decisions,questions,rejected}/<domain>.md (pql DQR tree).
357 records (237 D / 108 Q / 12 R), sync broken: 0. Fixed two real id collisions
(D-035 dup -> shadowcasting renumbered D-238; R-011 triple -> deduped).
Tickets -> git-tracked .pql/changelog/ (1013 tickets, 481 deps, 16 history, 90
labels incl. milestone->phase:4). T-N == legacy #N bijection; full pql plan rebuild parity verified. Replaces the binary-DB-plus-backup ritual.
Cutover: hooks folded into .config/hooks/* (pre-commit export+validate;
post-merge/checkout/rewrite replay), Makefile + ticket-cli.md + CLAUDE.md + skills
(whats-next/ticket/pr-process/bug-report) + settings all on pql.
Provenance: decision_refs frontmatter on workshop outcomes.
Migration scripts under tooling/pql-migrate/; pql-requirements.md is feedback to
the pql team (the "Critical" seeded-id blocker dissolved — pql kept our max-id counter).
Deep analysis of migrating decisions + ticketing from the SQLite CLI to pql:
- pql-migration.md: phased branch-only plan (decisions→DQR tree, ticket changelog
seed with T-N≡#N, #N→T-N find-replace, big-bang consumer cutover, docs/workshops/
wiki fold-in, SQLite retirement) + verification gate + benefits.
- pql-requirements.md: 9 surfaced gaps for the pql team (critical: seeded ticket
ids + counter-advance; high: dup-id detection, core.hooksPath awareness, changelog
seed-format docs).
Key finding: milestones are vestigial (milestone_deps empty, 42/1013 tickets
linked) → mapped to a label, dropped as an entity.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The blanket `.pql/` ignore would have hidden `.pql/changelog/` — pql's durable,
git-versioned planning state — making the whole migration's output invisible to
git. Narrow to ignore only the rebuildable DBs (index/pql .db + WAL/SHM) and
track config.yaml + changelog/.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 0 of the pql migration: the decision markdown had two genuine
canonical-ID integrity bugs that pql decisions sync silently LWW-collapses.
- D-035 was defined twice: a content.md tag-taxonomy record and a
perception.md shadowcasting/LOS record, both dated the same day. The
tag-taxonomy record keeps D-035; the shadowcasting record is renumbered
to D-238 (freshly claimed) with a Renumbered note preserving the history.
Inbound refs repointed in architecture.md (x4), questions-architecture.md,
and the README perception index row.
- R-011 (single currency for Phase 2) was defined three times: once
canonically in rejected.md and twice identically in economics.md. The two
economics.md copies are removed; rejected.md absorbs the Proposal/Raised-by
lines and gains a dedupe note. The economics.md dissent link now points at
rejected.md and the footer count drops the rejected-alternative clause.
Verified: tooling/db/decision check-dupes reports 0 duplicates;
pql decisions validate returns ok.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 1 of the pql migration. Moves the flat decisions/*.md layout into
governance/{decisions,questions,rejected}/<domain>.md — the tree pql's
`decisions sync` parses natively (record type from subdir, domain from
filename stem). Proven against pql 1.6.2: sync reports 357 records
(237 D / 108 Q / 12 R), 1057 refs, broken: 0; validate ok.
- 6 D-domain files -> governance/decisions/ (git renames)
- 5 questions-<domain>.md -> governance/questions/<domain>.md (prefix dropped)
- rejected.md split by domain -> governance/rejected/{architecture(R-001..010),
economics(R-011),perception(R-012)}.md
- decisions/README.md + questions.md index folded into governance/README.md;
pql's `decisions sync` now auto-maintains the record index appended below
the hand-written domain guidance (no more manual ID-list table upkeep).
- .pql/config.yaml: canonical vault config (tracked, not ignored).
Link rewrites are token-preserving: only the relative `foo.md` path portion
changes (e.g. `rejected.md#r-011` -> `../rejected/economics.md#r-011`); every
`[D-NNN]` bracket text and `#anchor` stays byte-identical, so pql's reference
extraction is unaffected. The one-shot transform is committed at
tooling/pql-migrate/restructure_decisions.py for provenance.
Codebase path references to decisions/ (CLAUDE.md, rules, skills, docs) are
updated in a follow-up commit.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 1 follow-up: update the active instruction layer (CLAUDE.md, project
structure rule, DECISIONS.md redirect, agent personalities, skill docs) to
reference governance/{decisions,questions,rejected}/<domain>.md instead of the
retired flat decisions/*.md layout.
Path references only — command-surface references (tooling/db/decision*,
decisions-sync, Makefile targets, clerk) are repointed to the pql CLI in the
Phase 4 consumer cutover. Historical archives (docs/sprints, docs/discussions,
docs/workshops) keep their point-in-time decisions/ paths; the separate
whatsinagame/ template distribution is untouched. Agent-memory is gitignored
and out of scope.
The agent/skill repath was applied by tooling/pql-migrate/repath_references.py
(ordered, meaning-preserving replacements; bare-dir rule uses a negative
lookbehind so it can't corrupt a freshly-created governance/decisions/ path),
committed for provenance. CLAUDE.md, project-structure.md, and DECISIONS.md
were hand-edited (structural tree/table changes).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
One-way ticket data migration from the legacy settledreach.db into pql's
git-tracked changelog. Establishes the T-N == #N id bijection (old #440 -> T-440)
so thousands of #NNN git-commit references stay a trivial mapping.
Migrated (verified by full `pql plan rebuild` from changelog):
- 1013 tickets (status + type distributions match source exactly)
- 481 dependencies
- 16 history rows (deterministic content hash so ON CONFLICT(hash) dedups)
- 90 labels = 48 source + 42 milestone-derived
(active "Phase 4" milestone -> phase:4; "Process Rewire" ->
milestone:process-rewire; milestone_deps was empty/vestigial)
Transforms: ids T-prefixed, sprint_id dropped (legacy/archival), decision_ref
and the one 'server,client' comma-team (#575) kept verbatim, deleted_at NULL,
canonical_version 1. Seeded rows carry hash=NULL on tickets/deps/labels — proven
safe: PK-based ON CONFLICT, updated_at drives LWW, and replay is idempotent.
Key finding that dissolves pql-requirements item #1 ("Critical"): seeding via
direct-INSERT does NOT require explicit ticket ids from `ticket new`. The id
counter derives from max(id), so after seeding T-1..T-1021 the next native
`pql ticket new` mints T-1022 — no recycling, no collision. The blocker only
applied to the `ticket new --id` path we never use for bulk seeding.
Scaffolding: .pql/changelog/<table>/0000-schema.sql (canonical pql 1.6.2 schema,
byte-identical across the 4 table dirs) + .gitattributes union-merge driver so
changelog SQL never produces binary-style merge conflicts. Seed is reproducible
via tooling/pql-migrate/seed_tickets.py (read-only on the source, idempotent).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pql was developed off the lessons of this repo's own planning structures, so the
"requirements" are feedback to a descendant, not gaps in a foreign tool — and some
items are deliberate simplifications to adopt rather than ask pql to re-add.
- Item #1 (seeded ids) downgraded Critical -> Resolved: Phase 2 proved direct-INSERT
seeding + pql's max-id counter (inherited from our own CLI) mints T-1022 after
T-1021, so there is no recycling/collision. The --id flag is a low-priority nicety.
- Item #9 (milestones): pql's omission of the milestone entity validates our
vestigial finding; labels-as-milestones is the right call and we adopt it.
- Intro reframed around the lineage.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adopts the T-NNN convention (T-N == old #N == pql ticket id) across the active
operational layer: governance/ decision records, .claude/{rules,agents,skills},
CLAUDE.md, DECISIONS.md. 283 references rewritten.
Guarded against false positives (17 correctly skipped, each logged):
- PR references kept (PR #136/#138/... — PRs are a separate #-namespace)
- non-ticket numbers kept (#4122; the "#1 process failure" idiom; "task #3")
- only #N where N is an actual ticket id is rewritten; the 1-4 digit word-bounded
match also excludes 6-digit hex colours in the visual decision records
Git history is NOT rewritten (a commit's #N already equals T-N numerically), and
historical archives (docs/sprints, docs/discussions, docs/workshops) keep their
point-in-time #N. The /pr-process ticket-ID extraction logic moves to T-NNN in the
Phase 4 consumer cutover.
Verified: pql decisions validate ok; sync 357 records / 1057 refs / broken 0 (the
prose edits don't affect decision parsing or the tickets.decision_ref linkage).
Transform committed at tooling/pql-migrate/retag_ticket_refs.py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Folds pql's planning logic into the version-controlled .config/hooks/* (pql's own
.pql/hooks installer is dead under core.hooksPath=.config/hooks):
- pre-commit: + `pql decisions validate` (decision-ID/format gate, supersedes the
never-built check-decision-ids TODO) and `pql plan export --stage` (flush ticket
mutations to the git-tracked changelog and stage them into the commit). Both
guarded by `command -v pql`; export is a clean no-op when nothing changed.
- post-merge: `pql plan import` + `pql decisions sync` (replay incoming changelog,
re-sync markdown decisions).
- post-checkout (branch only): `pql plan rebuild` + `decisions sync`.
- post-rewrite (rebase/amend): `pql plan rebuild`.
- install-hooks chmods the three new hooks.
Makefile decision targets repointed to pql: decisions-sync -> `pql decisions sync`,
decisions-active -> `pql decisions list --type confirmed`, new decisions-validate ->
`pql decisions validate`. Dropped the SQLite-query conveniences (coverage/orphan/
orphan-tickets); per-decision coverage is `pql decisions show <id> --with-tickets`.
db-backup/db-install and SR_DB_PATH are intentionally kept until Phase 6 so the
legacy SQLite store stays intact as the migration rollback path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rewrites the canonical command reference (.claude/rules/ticket-cli.md) and CLAUDE.md
to the pql CLI: `pql ticket`/`pql plan`/`pql decisions` replace `tooling/db/ticket`,
`sqlite-query`/`sqlite-exec`, and `tooling/db/decision`. Documents T-NNN ids, the
markdown-sourced governance decision tree, the rebuildable changelog-backed pql.db,
and labels-as-milestones (phase:4) in place of the removed milestone entity.
Maps the old surface accurately: ticket new (positional type+title), show
--with-context/--with-blockers, block --by / unblock --from, label add/remove,
decisions claim/list/show/validate/sync, plan whatsnext/review/status.
Behavioral/command cutover only — the legacy tooling/db/* and SR_DB_PATH stay as the
rollback path until Phase 6.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Repoints the kanban workflow skills from tooling/db/* to the pql CLI:
- /whats-next: milestone queries -> `pql ticket list --label phase:4 --unblocked`
(--unblocked does the dependency walk, collapsing the old milestone + per-ticket
deps + milestone_deps steps); WIP via `pql ticket list --status in_progress` (pql
doesn't enforce the limit — warn manually); refinement append via `pql ticket append`;
activation via `pql ticket status`.
- /ticket: full reference rewritten to `pql ticket`/`pql plan`; milestone subcommands
-> phase labels; points at .claude/rules/ticket-cli.md.
- /pr-process: step 8 extracts T-NNN (maps bare #NNN -> T-NNN) and calls
`pql ticket status T-<id> review`.
- /bug-report: bug creation via `pql ticket new bug`.
- clerk: decisions-sync mechanism line -> `pql decisions sync` (factual fix only; the
agent's review logic stays for the #965 re-enable).
- workshop-start IMPROVEMENTS: the old `decision claim` non-idempotency footgun no
longer applies — `pql decisions claim` is side-effect-free.
pr-review/git-commit needed only the Phase-1 path repoint (no command refs); the
settledreach.db.backup exclusion in pr-review stays until Phase 6.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Workshop -> decision provenance was prose-only. Adds a `decision_refs:` YAML
frontmatter list (the confirmed D-records each workshop-outcomes.md touches,
filtered against the governance decision set) to all 17 workshop outcomes; the two
that lacked frontmatter (commodity-catalog, system-economic-specialization) get a
minimal block. pql indexes the list and `SELECT fm.decision_refs` round-trips it, so
"which workshops touch D-NNN" is answerable via SELECT + filter or `pql search`.
decision_refs is a relevance signal (decisions a workshop discusses/produces), not a
strict authorship claim — historical bare refs aren't disambiguated. Generated wiki
read-only sections are left untouched.
Noted in pql-requirements #5: 1.6.2 has no working DSL operator for frontmatter
list-membership (`~`/`contains` error, `in` matches nothing), so membership queries
need a client-side filter for now.
Reproducible via tooling/pql-migrate/add_workshop_provenance.py (idempotent).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Completes the Phase 4 consumer cutover: adds Bash(pql) / Bash(pql *) to
.claude/settings.json so the pql workflow runs without prompts. Added manually by
the lead — the auto-mode classifier blocks an agent from self-widening wildcard Bash
permissions even via /update-config (a deliberate security boundary).
SR_DB_PATH and the Bash(tooling/db/*) allowlist stay until Phase 6 (rollback path).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Multi-agent review — Tyre (architecture) + Hoshe (QA).
Tyre (Architecture): REQUEST_CHANGES
Cutover is architecturally correct — big-bang with preserved rollback, the text
changelog kills the binary-DB conflict class, governance cross-references are sound,
and the hooks are guarded and idempotent. One real bug + one low-severity note:
#
File
Issue
1
.gitattributes:1
Glob too shallow..pql/changelog/*.sql matches nothing — changelog files live at .pql/changelog/<table>/<YYYY-MM>.sql, one level deeper. git check-attr merge → unspecified. This defeats the union-merge guarantee that is the core value of the text changelog. Fix: .pql/changelog/**/*.sql merge=union.
2
tooling/pql-migrate/*.py
Hardcoded REPO=.../main — re-running seed_tickets.py from a worktree writes pql.db to the wrong place (low severity: pql.db is gitignored, the committed changelog is correct). Derive the root from git rev-parse --show-toplevel.
Hoshe (QA): APPROVE
All seven QA checks pass: decision parity exact (357 records / 237 confirmed / 108
question / 12 rejected; validate ok; no duplicate IDs), ticket parity exact (1013
tickets / 481 deps / 16 history / 90 labels after plan rebuild; T-N bijection
confirmed), link integrity clean (correct ../decisions/ prefixes; no governance/governance/ corruption; PR refs + hex colours intact), command cutover
complete (no residual tooling/db/* invocations outside labelled rollback prose),
all four hooks guarded with command -v pql, migration scripts ruff-clean +
read-only on the source DB + idempotent.
Verdict: CHANGES REQUESTED
Both Tyre comments accepted (no pushback). Fixes incoming on the branch.
## Review: pql-migration → main (type: code)
Multi-agent review — Tyre (architecture) + Hoshe (QA).
### Tyre (Architecture): REQUEST_CHANGES
Cutover is architecturally correct — big-bang with preserved rollback, the text
changelog kills the binary-DB conflict class, governance cross-references are sound,
and the hooks are guarded and idempotent. One real bug + one low-severity note:
| # | File | Issue |
|---|------|-------|
| 1 | `.gitattributes:1` | **Glob too shallow.** `.pql/changelog/*.sql` matches nothing — changelog files live at `.pql/changelog/<table>/<YYYY-MM>.sql`, one level deeper. `git check-attr merge` → `unspecified`. This defeats the union-merge guarantee that is the core value of the text changelog. Fix: `.pql/changelog/**/*.sql merge=union`. |
| 2 | `tooling/pql-migrate/*.py` | Hardcoded `REPO=.../main` — re-running `seed_tickets.py` from a worktree writes `pql.db` to the wrong place (low severity: `pql.db` is gitignored, the committed changelog is correct). Derive the root from `git rev-parse --show-toplevel`. |
### Hoshe (QA): APPROVE
All seven QA checks pass: decision parity exact (357 records / 237 confirmed / 108
question / 12 rejected; `validate` ok; no duplicate IDs), ticket parity exact (1013
tickets / 481 deps / 16 history / 90 labels after `plan rebuild`; T-N bijection
confirmed), link integrity clean (correct `../decisions/` prefixes; no
`governance/governance/` corruption; PR refs + hex colours intact), command cutover
complete (no residual `tooling/db/*` invocations outside labelled rollback prose),
all four hooks guarded with `command -v pql`, migration scripts ruff-clean +
read-only on the source DB + idempotent.
### Verdict: CHANGES REQUESTED
Both Tyre comments accepted (no pushback). Fixes incoming on the branch.
Tyre (architecture review):
- .gitattributes: `.pql/changelog/*.sql` matched nothing (files are one level
deeper at .pql/changelog/<table>/<YYYY-MM>.sql), so the union-merge driver never
applied — `git check-attr merge` returned `unspecified`. Fixed to
`.pql/changelog/**/*.sql`; now resolves to `merge: union` for monthly + schema
files. Restores the changelog's conflict-free merge guarantee.
- Migration scripts: the re-runnable ones (seed_tickets.py, add_workshop_provenance.py)
now derive the repo root from `git rev-parse --show-toplevel` instead of a hardcoded
/main path, so re-running from a worktree/clone targets the right checkout. The three
one-shot transforms (restructure_decisions, repath_references, retag_ticket_refs)
get a comment noting they're already-applied and unsafe to re-run (git mv on moved
sources) — keeping the path honest rather than implying re-runnability.
Hoshe approved (all QA checks passed). ruff clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both Tyre comments resolved (commit f8d9b777b); Hoshe approved on the first pass.
.gitattributes*.sql → **/*.sql — git check-attr merge now reports merge: union on tickets, ticket_deps, and ticket_history changelog files.
The conflict-elimination guarantee that justifies the text changelog is wired up.
Migration scripts — seed_tickets.py + add_workshop_provenance.py derive REPO from git rev-parse --show-toplevel (worktree/clone-safe); the three
one-shot transforms carry an "already-applied, re-running unsupported" provenance note.
Verdict: APPROVED by both reviewers. Rollback path preserved (legacy tooling/db/*, SR_DB_PATH, settledreach.db intact until the Phase-6 follow-up); hooks guarded and
idempotent; governance cross-references resolve. Ready to merge.
## Re-review after fixes — APPROVED ✅
Both Tyre comments resolved (commit `f8d9b777b`); Hoshe approved on the first pass.
- **`.gitattributes`** `*.sql` → `**/*.sql` — `git check-attr merge` now reports
`merge: union` on `tickets`, `ticket_deps`, and `ticket_history` changelog files.
The conflict-elimination guarantee that justifies the text changelog is wired up.
- **Migration scripts** — `seed_tickets.py` + `add_workshop_provenance.py` derive
`REPO` from `git rev-parse --show-toplevel` (worktree/clone-safe); the three
one-shot transforms carry an "already-applied, re-running unsupported" provenance note.
**Verdict: APPROVED** by both reviewers. Rollback path preserved (legacy `tooling/db/*`,
`SR_DB_PATH`, `settledreach.db` intact until the Phase-6 follow-up); hooks guarded and
idempotent; governance cross-references resolve. Ready to merge.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Migrates the project's decisions + ticketing system off the bespoke SQLite tooling
(
tooling/db/*,settledreach.db) onto pql — the markdown-vault + planning toolthat was itself productized from this repo's planning structures. Phases 0-5 of
pql-migration.md. Big-bang cutover behind a verification gate; legacy tooling staysintact as the rollback path until a separate Phase-6 follow-up.
What changed
governance/{decisions,questions,rejected}/<domain>.md(pql DQR tree).357 records (237 D / 108 Q / 12 R), sync
broken: 0. Fixed two real id collisions(D-035 dup -> shadowcasting renumbered D-238; R-011 triple -> deduped).
.pql/changelog/(1013 tickets, 481 deps, 16 history, 90labels incl. milestone->
phase:4).T-N == legacy #Nbijection; fullpql plan rebuildparity verified. Replaces the binary-DB-plus-backup ritual.#N -> T-N(283 guarded rewrites; PR refs / hex / non-tickets skipped)..config/hooks/*(pre-commit export+validate;post-merge/checkout/rewrite replay), Makefile +
ticket-cli.md+ CLAUDE.md + skills(
whats-next/ticket/pr-process/bug-report) + settings all onpql.decision_refsfrontmatter on workshop outcomes.tooling/pql-migrate/;pql-requirements.mdis feedback tothe pql team (the "Critical" seeded-id blocker dissolved — pql kept our max-id counter).
Verification
pql decisions validateok; count parity 357; legacy check-dupes 0.Deferred to Phase 6 (post-merge, separate PR)
Delete
tooling/db/*, dropSR_DB_PATH, removedb-backup+ the committedsettledreach.db.backup. Kept now so rollback survives the first live days.🤖 Generated with Claude Code
Phase 1 of the pql migration. Moves the flat decisions/*.md layout into governance/{decisions,questions,rejected}/<domain>.md — the tree pql's `decisions sync` parses natively (record type from subdir, domain from filename stem). Proven against pql 1.6.2: sync reports 357 records (237 D / 108 Q / 12 R), 1057 refs, broken: 0; validate ok. - 6 D-domain files -> governance/decisions/ (git renames) - 5 questions-<domain>.md -> governance/questions/<domain>.md (prefix dropped) - rejected.md split by domain -> governance/rejected/{architecture(R-001..010), economics(R-011),perception(R-012)}.md - decisions/README.md + questions.md index folded into governance/README.md; pql's `decisions sync` now auto-maintains the record index appended below the hand-written domain guidance (no more manual ID-list table upkeep). - .pql/config.yaml: canonical vault config (tracked, not ignored). Link rewrites are token-preserving: only the relative `foo.md` path portion changes (e.g. `rejected.md#r-011` -> `../rejected/economics.md#r-011`); every `[D-NNN]` bracket text and `#anchor` stays byte-identical, so pql's reference extraction is unaffected. The one-shot transform is committed at tooling/pql-migrate/restructure_decisions.py for provenance. Codebase path references to decisions/ (CLAUDE.md, rules, skills, docs) are updated in a follow-up commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Phase 1 follow-up: update the active instruction layer (CLAUDE.md, project structure rule, DECISIONS.md redirect, agent personalities, skill docs) to reference governance/{decisions,questions,rejected}/<domain>.md instead of the retired flat decisions/*.md layout. Path references only — command-surface references (tooling/db/decision*, decisions-sync, Makefile targets, clerk) are repointed to the pql CLI in the Phase 4 consumer cutover. Historical archives (docs/sprints, docs/discussions, docs/workshops) keep their point-in-time decisions/ paths; the separate whatsinagame/ template distribution is untouched. Agent-memory is gitignored and out of scope. The agent/skill repath was applied by tooling/pql-migrate/repath_references.py (ordered, meaning-preserving replacements; bare-dir rule uses a negative lookbehind so it can't corrupt a freshly-created governance/decisions/ path), committed for provenance. CLAUDE.md, project-structure.md, and DECISIONS.md were hand-edited (structural tree/table changes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Adopts the T-NNN convention (T-N == old #N == pql ticket id) across the active operational layer: governance/ decision records, .claude/{rules,agents,skills}, CLAUDE.md, DECISIONS.md. 283 references rewritten. Guarded against false positives (17 correctly skipped, each logged): - PR references kept (PR #136/#138/... — PRs are a separate #-namespace) - non-ticket numbers kept (#4122; the "#1 process failure" idiom; "task #3") - only #N where N is an actual ticket id is rewritten; the 1-4 digit word-bounded match also excludes 6-digit hex colours in the visual decision records Git history is NOT rewritten (a commit's #N already equals T-N numerically), and historical archives (docs/sprints, docs/discussions, docs/workshops) keep their point-in-time #N. The /pr-process ticket-ID extraction logic moves to T-NNN in the Phase 4 consumer cutover. Verified: pql decisions validate ok; sync 357 records / 1057 refs / broken 0 (the prose edits don't affect decision parsing or the tickets.decision_ref linkage). Transform committed at tooling/pql-migrate/retag_ticket_refs.py. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Folds pql's planning logic into the version-controlled .config/hooks/* (pql's own .pql/hooks installer is dead under core.hooksPath=.config/hooks): - pre-commit: + `pql decisions validate` (decision-ID/format gate, supersedes the never-built check-decision-ids TODO) and `pql plan export --stage` (flush ticket mutations to the git-tracked changelog and stage them into the commit). Both guarded by `command -v pql`; export is a clean no-op when nothing changed. - post-merge: `pql plan import` + `pql decisions sync` (replay incoming changelog, re-sync markdown decisions). - post-checkout (branch only): `pql plan rebuild` + `decisions sync`. - post-rewrite (rebase/amend): `pql plan rebuild`. - install-hooks chmods the three new hooks. Makefile decision targets repointed to pql: decisions-sync -> `pql decisions sync`, decisions-active -> `pql decisions list --type confirmed`, new decisions-validate -> `pql decisions validate`. Dropped the SQLite-query conveniences (coverage/orphan/ orphan-tickets); per-decision coverage is `pql decisions show <id> --with-tickets`. db-backup/db-install and SR_DB_PATH are intentionally kept until Phase 6 so the legacy SQLite store stays intact as the migration rollback path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Review: pql-migration → main (type: code)
Multi-agent review — Tyre (architecture) + Hoshe (QA).
Tyre (Architecture): REQUEST_CHANGES
Cutover is architecturally correct — big-bang with preserved rollback, the text
changelog kills the binary-DB conflict class, governance cross-references are sound,
and the hooks are guarded and idempotent. One real bug + one low-severity note:
.gitattributes:1.pql/changelog/*.sqlmatches nothing — changelog files live at.pql/changelog/<table>/<YYYY-MM>.sql, one level deeper.git check-attr merge→unspecified. This defeats the union-merge guarantee that is the core value of the text changelog. Fix:.pql/changelog/**/*.sql merge=union.tooling/pql-migrate/*.pyREPO=.../main— re-runningseed_tickets.pyfrom a worktree writespql.dbto the wrong place (low severity:pql.dbis gitignored, the committed changelog is correct). Derive the root fromgit rev-parse --show-toplevel.Hoshe (QA): APPROVE
All seven QA checks pass: decision parity exact (357 records / 237 confirmed / 108
question / 12 rejected;
validateok; no duplicate IDs), ticket parity exact (1013tickets / 481 deps / 16 history / 90 labels after
plan rebuild; T-N bijectionconfirmed), link integrity clean (correct
../decisions/prefixes; nogovernance/governance/corruption; PR refs + hex colours intact), command cutovercomplete (no residual
tooling/db/*invocations outside labelled rollback prose),all four hooks guarded with
command -v pql, migration scripts ruff-clean +read-only on the source DB + idempotent.
Verdict: CHANGES REQUESTED
Both Tyre comments accepted (no pushback). Fixes incoming on the branch.
Re-review after fixes — APPROVED ✅
Both Tyre comments resolved (commit
f8d9b777b); Hoshe approved on the first pass..gitattributes*.sql→**/*.sql—git check-attr mergenow reportsmerge: unionontickets,ticket_deps, andticket_historychangelog files.The conflict-elimination guarantee that justifies the text changelog is wired up.
seed_tickets.py+add_workshop_provenance.pyderiveREPOfromgit rev-parse --show-toplevel(worktree/clone-safe); the threeone-shot transforms carry an "already-applied, re-running unsupported" provenance note.
Verdict: APPROVED by both reviewers. Rollback path preserved (legacy
tooling/db/*,SR_DB_PATH,settledreach.dbintact until the Phase-6 follow-up); hooks guarded andidempotent; governance cross-references resolve. Ready to merge.
Pull request closed