docs(workshops): add decision_refs provenance frontmatter (pql migration phase 5)
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>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,6 +6,7 @@ status: complete
|
||||
workshop: generation-cascade
|
||||
agent: qatux
|
||||
created: 2026-04-30
|
||||
decision_refs: [D-194]
|
||||
---
|
||||
|
||||
# Generation Cascade Workshop — Outcomes
|
||||
|
||||
@@ -7,6 +7,7 @@ workshop: generator-architecture
|
||||
agent: ""
|
||||
round: 0
|
||||
created: 2026-02-27
|
||||
decision_refs: [D-094]
|
||||
---
|
||||
|
||||
# Generator Architecture Workshop — Outcomes
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,6 +7,7 @@ workshop: wheres-the-fun
|
||||
agent: "qatux"
|
||||
round: 0
|
||||
created: 2026-03-05
|
||||
decision_refs: []
|
||||
---
|
||||
|
||||
# Workshop Outcomes: Where's the Fun?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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**
|
||||
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user