diff --git a/docs/workshops/art-direction-mood-board/workshop-outcomes.md b/docs/workshops/art-direction-mood-board/workshop-outcomes.md index d085f488a..e36d7b0f6 100644 --- a/docs/workshops/art-direction-mood-board/workshop-outcomes.md +++ b/docs/workshops/art-direction-mood-board/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: art-direction-mood-board agent: "" round: 0 created: 2026-02-12 +decision_refs: [D-015, D-019, D-024, D-031, D-033, D-035, D-041, D-042, D-043, D-044, D-045, D-046, D-047, D-048, D-049, D-050, D-051, D-066] --- # Art Direction & Mood Board Workshop — Final Outcomes diff --git a/docs/workshops/character-visuals/workshop-outcomes.md b/docs/workshops/character-visuals/workshop-outcomes.md index eec424880..c1c7c3da5 100644 --- a/docs/workshops/character-visuals/workshop-outcomes.md +++ b/docs/workshops/character-visuals/workshop-outcomes.md @@ -6,6 +6,7 @@ status: complete sprint: 28 ticket: 684 created: 2026-03-17 +decision_refs: [D-019, D-033, D-146, D-148, D-149, D-150, D-151, D-152, D-153, D-154, D-155, D-156, D-157] --- # Sprint 28 Character Visuals Workshop — Outcomes diff --git a/docs/workshops/commodity-catalog/workshop-outcomes.md b/docs/workshops/commodity-catalog/workshop-outcomes.md index bc942b11e..c79a2b3f7 100644 --- a/docs/workshops/commodity-catalog/workshop-outcomes.md +++ b/docs/workshops/commodity-catalog/workshop-outcomes.md @@ -1,3 +1,11 @@ +--- +title: "Workshop Outcomes: commodity-catalog" +type: workshop +workshop: commodity-catalog +status: archived +decision_refs: [D-131, D-173, D-175, D-181, D-183, D-184, D-185, D-186, D-187] +--- + # Workshop #801 Outcomes: Commodity Catalog **Ticket:** #801 — Define commodity catalog (TOML) diff --git a/docs/workshops/control-interaction/workshop-outcomes.md b/docs/workshops/control-interaction/workshop-outcomes.md index 4d8268c11..a4d9f3514 100644 --- a/docs/workshops/control-interaction/workshop-outcomes.md +++ b/docs/workshops/control-interaction/workshop-outcomes.md @@ -5,6 +5,7 @@ type: workshop status: archived workshop: "control-interaction" created: 2026-02-14 +decision_refs: [D-009, D-010, D-017, D-018, D-027, D-033, D-041, D-045, D-048, D-053, D-054, D-055, D-056, D-057, D-058, D-059, D-060, D-061, D-062, D-063, D-064, D-065, D-066] --- # Workshop Outcomes: Control & Interaction Scheme diff --git a/docs/workshops/generation-cascade/workshop-outcomes.md b/docs/workshops/generation-cascade/workshop-outcomes.md index f66d599b8..56e1749c8 100644 --- a/docs/workshops/generation-cascade/workshop-outcomes.md +++ b/docs/workshops/generation-cascade/workshop-outcomes.md @@ -6,6 +6,7 @@ status: complete workshop: generation-cascade agent: qatux created: 2026-04-30 +decision_refs: [D-194] --- # Generation Cascade Workshop — Outcomes diff --git a/docs/workshops/generator-architecture/workshop-outcomes.md b/docs/workshops/generator-architecture/workshop-outcomes.md index 301b148a8..2e86d534d 100644 --- a/docs/workshops/generator-architecture/workshop-outcomes.md +++ b/docs/workshops/generator-architecture/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: generator-architecture agent: "" round: 0 created: 2026-02-27 +decision_refs: [D-094] --- # Generator Architecture Workshop — Outcomes diff --git a/docs/workshops/gj-6711-furthest-system/workshop-outcomes.md b/docs/workshops/gj-6711-furthest-system/workshop-outcomes.md index 3bef24f8f..e3e96262b 100644 --- a/docs/workshops/gj-6711-furthest-system/workshop-outcomes.md +++ b/docs/workshops/gj-6711-furthest-system/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: gj-6711-furthest-system agent: "" round: 0 created: 2026-03-16 +decision_refs: [] --- # Workshop Outcomes: GJ 6711 / Abzu — Furthest System diff --git a/docs/workshops/knowledge-flow-npc-boundaries/workshop-outcomes.md b/docs/workshops/knowledge-flow-npc-boundaries/workshop-outcomes.md index ae7d5bd0a..00e4d6af0 100644 --- a/docs/workshops/knowledge-flow-npc-boundaries/workshop-outcomes.md +++ b/docs/workshops/knowledge-flow-npc-boundaries/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: knowledge-flow-npc-boundaries agent: "qatux" round: 2 created: 2026-02-24 +decision_refs: [D-010, D-026, D-033, D-034, D-041, D-078, D-079, D-080, D-081, D-082, D-083] --- # Workshop Outcomes — Knowledge Flow & NPC Information Boundaries diff --git a/docs/workshops/knowledge-graph-information-boundaries/workshop-outcomes.md b/docs/workshops/knowledge-graph-information-boundaries/workshop-outcomes.md index 94aedec26..af1039ab8 100644 --- a/docs/workshops/knowledge-graph-information-boundaries/workshop-outcomes.md +++ b/docs/workshops/knowledge-graph-information-boundaries/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: knowledge-graph-information-boundaries agent: "" round: 0 created: 2026-02-11 +decision_refs: [D-010, D-011, D-012, D-017, D-028, D-033, D-041, D-080, D-083] --- # Workshop Outcomes: Knowledge Graph & Information Boundaries diff --git a/docs/workshops/llm-voice-pipeline/workshop-outcomes.md b/docs/workshops/llm-voice-pipeline/workshop-outcomes.md index 1d614dfff..39cd8434c 100644 --- a/docs/workshops/llm-voice-pipeline/workshop-outcomes.md +++ b/docs/workshops/llm-voice-pipeline/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: llm-voice-pipeline agent: "" round: 0 created: 2026-03-07 +decision_refs: [D-007, D-010, D-020, D-028, D-029, D-092, D-121, D-122, D-123, D-124, D-128, D-138] --- # LLM Voice Pipeline Workshop — Outcomes diff --git a/docs/workshops/planet-down-cascade/workshop-outcomes.md b/docs/workshops/planet-down-cascade/workshop-outcomes.md index a2ed3d606..20a66182e 100644 --- a/docs/workshops/planet-down-cascade/workshop-outcomes.md +++ b/docs/workshops/planet-down-cascade/workshop-outcomes.md @@ -5,6 +5,7 @@ workshop: planet-down-cascade status: complete created: 2026-05-01 rounds: 3 +decision_refs: [D-194, D-195, D-196, D-197, D-198, D-199, D-200, D-201, D-202, D-203, D-204, D-205, D-206, D-207, D-208, D-209, D-210, D-211, D-212, D-213, D-214, D-215, D-216, D-217, D-218] --- # Planet-Down Cascade — Workshop Outcomes diff --git a/docs/workshops/system-economic-specialization/workshop-outcomes.md b/docs/workshops/system-economic-specialization/workshop-outcomes.md index c00ec26e8..f8ed88ddd 100644 --- a/docs/workshops/system-economic-specialization/workshop-outcomes.md +++ b/docs/workshops/system-economic-specialization/workshop-outcomes.md @@ -1,3 +1,11 @@ +--- +title: "Workshop Outcomes: system-economic-specialization" +type: workshop +workshop: system-economic-specialization +status: archived +decision_refs: [D-010, D-172, D-174, D-177, D-184, D-197, D-199, D-214, D-220, D-222, D-232, D-233, D-237, D-238] +--- + # Workshop Outcomes — System Economic-Specialization *Workshop: `system-economic-specialization` | Date: 2026-05-31* *Participants: Miri, Burnelli-Sheldon, Paula | Documenter: Qatux* diff --git a/docs/workshops/test-architecture/workshop-outcomes.md b/docs/workshops/test-architecture/workshop-outcomes.md index a1a51e666..2e8bb8685 100644 --- a/docs/workshops/test-architecture/workshop-outcomes.md +++ b/docs/workshops/test-architecture/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: test-architecture agent: "" round: 0 created: 2026-02-17 +decision_refs: [D-015, D-017, D-028, D-031, D-033, D-035, D-041, D-055, D-057, D-059, D-060, D-062, D-065] --- # QA Strategy & Test Architecture Workshop — Outcomes diff --git a/docs/workshops/v01-gap-analysis/workshop-outcomes.md b/docs/workshops/v01-gap-analysis/workshop-outcomes.md index 7da8f43bd..584a0fa41 100644 --- a/docs/workshops/v01-gap-analysis/workshop-outcomes.md +++ b/docs/workshops/v01-gap-analysis/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: v01-gap-analysis agent: qatux round: 0 created: 2026-02-25 +decision_refs: [D-010, D-023, D-027, D-029, D-031, D-038] --- # Workshop Outcomes: v0.1 Gap Analysis diff --git a/docs/workshops/wheres-the-fun/workshop-outcomes.md b/docs/workshops/wheres-the-fun/workshop-outcomes.md index 479c70645..24a78eefc 100644 --- a/docs/workshops/wheres-the-fun/workshop-outcomes.md +++ b/docs/workshops/wheres-the-fun/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: wheres-the-fun agent: "qatux" round: 0 created: 2026-03-05 +decision_refs: [] --- # Workshop Outcomes: Where's the Fun? diff --git a/docs/workshops/wiki-review/workshop-outcomes.md b/docs/workshops/wiki-review/workshop-outcomes.md index 7a63340fe..676ceec51 100644 --- a/docs/workshops/wiki-review/workshop-outcomes.md +++ b/docs/workshops/wiki-review/workshop-outcomes.md @@ -7,6 +7,7 @@ workshop: wiki-review agent: "" round: 0 created: 2026-02-25 +decision_refs: [D-088, D-090, D-092] --- # Workshop Outcomes: Wiki Review & Content Standards diff --git a/docs/workshops/world-generation/workshop-outcomes.md b/docs/workshops/world-generation/workshop-outcomes.md index a2b7dfbb2..b1c19543f 100644 --- a/docs/workshops/world-generation/workshop-outcomes.md +++ b/docs/workshops/world-generation/workshop-outcomes.md @@ -5,6 +5,7 @@ date: 2026-03-24 status: complete participants: Gestalt, Miri, Nigel, Ozzie, Tyre, Qatux (documenter) rounds: 3 (SW1 only — SW2-SW4 cancelled) +decision_refs: [D-101, D-104, D-105, D-107] --- # World Generation Architecture Workshop — Outcomes diff --git a/pql-requirements.md b/pql-requirements.md index ec77ffe29..0dc812515 100644 --- a/pql-requirements.md +++ b/pql-requirements.md @@ -109,6 +109,14 @@ requiring link syntax in source. **Workaround.** Adopt a link convention in *authored* files only; accept that generated files are search-only. +**Related gap — frontmatter list-membership in the DSL.** Our Phase-5 provenance puts the decisions +each workshop touches in a `decision_refs: [D-010, …]` frontmatter list. pql indexes the list and +`SELECT fm.decision_refs` round-trips it, but we found no DSL operator that filters by membership: +`fm.decision_refs ~ 'D-010'` and `… contains …` are lex/parse errors, and `'D-010' in fm.decision_refs` +parses but matches nothing. So "which workshops touch D-010?" needs a `SELECT` + client-side filter or +a `pql search`. A documented list-membership operator (or making `in` work against frontmatter arrays) +would close this. + --- ## 6. WIP-limit enforcement (advisory) on `ticket status … in_progress` — **MEDIUM** diff --git a/tooling/pql-migrate/add_workshop_provenance.py b/tooling/pql-migrate/add_workshop_provenance.py new file mode 100644 index 000000000..08ace0afa --- /dev/null +++ b/tooling/pql-migrate/add_workshop_provenance.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +"""Add decision_refs provenance frontmatter to workshop outcomes (pql migration, Phase 5). + +Workshop -> decision provenance was prose-only. This injects a `decision_refs:` YAML +frontmatter list (the confirmed D-records each workshop-outcomes.md touches) so pql can +answer "which workshop produced D-NNN" via + pql query "SELECT name, fm.workshop WHERE fm.decision_refs CONTAINS 'D-238'" + +decision_refs = distinct valid confirmed-D ids mentioned in the file body (filtered +against the governance decision set, so typos/multi-refs/stale ids are dropped). Files +without frontmatter get a minimal block. Idempotent: re-running rewrites the same line. + +Default is a dry run. Pass --apply to write. +""" +import glob +import os +import re +import sqlite3 +import sys + +APPLY = "--apply" in sys.argv +REPO = "/var/mnt/data/projects/settled-reach/main" +DB = f"{REPO}/.pql/pql.db" + +D_IDS = set(r[0] for r in sqlite3.connect(DB).execute( + "SELECT id FROM decisions WHERE type='confirmed'")) + +D_REF = re.compile(r"\bD-\d{3}\b") +FILES = sorted(glob.glob(f"{REPO}/docs/workshops/*/workshop-outcomes.md")) + + +def split_frontmatter(text): + """Return (fm_lines, body) where fm_lines excludes the --- fences; fm is None if absent.""" + if text.startswith("---\n"): + end = text.find("\n---\n", 4) + if end != -1: + return text[4:end].splitlines(), text[end + 5:] + return None, text + + +def refs_in(body): + return sorted({m for m in D_REF.findall(body) if m in D_IDS}, key=lambda d: int(d[2:])) + + +def main(): + print(f"=== add_workshop_provenance.py ({'APPLY' if APPLY else 'DRY-RUN'}) ===\n") + for f in FILES: + text = open(f, encoding="utf-8").read() + fm, body = split_frontmatter(text) + refs = refs_in(body if fm is not None else text) + rel = f.split("/main/", 1)[-1] + wname = os.path.basename(os.path.dirname(f)) + refs_yaml = "[" + ", ".join(refs) + "]" + + if fm is not None: + fm = [ln for ln in fm if not ln.startswith("decision_refs:")] + fm.append(f"decision_refs: {refs_yaml}") + new = "---\n" + "\n".join(fm) + "\n---\n" + body + action = f"inject decision_refs ({len(refs)})" + else: + new = (f"---\ntitle: \"Workshop Outcomes: {wname}\"\ntype: workshop\n" + f"workshop: {wname}\nstatus: archived\ndecision_refs: {refs_yaml}\n---\n\n" + text) + action = f"ADD frontmatter + decision_refs ({len(refs)})" + + print(f"{rel}: {action}") + if refs: + print(f" {refs_yaml}") + if APPLY: + open(f, "w", encoding="utf-8").write(new) + print("\nDone." + ("" if APPLY else " (dry run — pass --apply)")) + + +if __name__ == "__main__": + main()