Skip to content

Commit f1fc586

Browse files
authored
Fix dg U011, add notes doc type (#4)
1 parent f4c7577 commit f1fc586

9 files changed

Lines changed: 354 additions & 56 deletions

File tree

.dg/org.kdl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
11
org "edge-toolkit" {
22
name "edge-toolkit"
33
}
4+
5+
user "jayvdb" {
6+
name "John Vandenberg"
7+
title "Research Associate"
8+
email "jayvdb@gmail.com"
9+
org "edge-toolkit"
10+
}
11+
12+
user "pierre-tenedero" {
13+
name "Pierre Tenedero"
14+
title "Research Associate"
15+
email "pierre.tenedero@gmail.com"
16+
org "edge-toolkit"
17+
}
18+
19+
user "jamesbychance" {
20+
name "James Eggleston"
21+
title "Research Fellow"
22+
org "edge-toolkit"
23+
}

.dg/schema.kdl

Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
// DecisionGraph schema
2+
// Edit freely. Validate with `dg validate`.
3+
4+
// ─── Reference resolution rules ──────────────────────────────────────────────
5+
6+
ref-format {
7+
string-id pattern="^(ADR|INC|POL|OPP|SPEC|PROC)-\\d+$"
8+
relative-path pattern="\\.md$"
9+
}
10+
11+
// ─── Relations ───────────────────────────────────────────────────────────────
12+
13+
relation "supersedes" inverse="superseded_by" cardinality="one" description="Replaces a previous document"
14+
relation "enables" inverse="enabled_by" cardinality="many" description="Prerequisite — target can exist but can't succeed without source"
15+
relation "triggers" inverse="triggered_by" cardinality="many" description="Direct cause — target was created specifically because of source"
16+
relation "depends_on" inverse="dependency_of" cardinality="many" description="Cannot proceed until target is resolved"
17+
relation "implements" inverse="implemented_by" cardinality="many" description="Technical realization of a policy or opportunity"
18+
relation "conflicts_with" cardinality="many" description="Contradicts or creates tension with target"
19+
relation "related" cardinality="many" description="Loosely associated — use a more specific relation when possible"
20+
21+
// ─── ADR: Architecture Decision Record ───────────────────────────────────────
22+
23+
type "adr" description="Architecture Decision Record" folder="docs/architecture" {
24+
alias "architecture" "tech"
25+
field "status" type="enum" required=#true default="proposed" description="Lifecycle state" {
26+
values "proposed" "accepted" "rejected" "deprecated" "superseded"
27+
transition "proposed" "accepted" "rejected"
28+
transition "accepted" "deprecated" "superseded"
29+
}
30+
field "author" type="user" required=#true description="Decision author"
31+
field "date" type="string" required=#true pattern="^\\d{4}-\\d{2}-\\d{2}$" default="$TODAY"
32+
field "tags" type="string[]"
33+
field "code_paths" type="string[]" description="Glob patterns of source code paths related to this decision"
34+
35+
section "Context" required=#true description="Problem statement and constraints" {
36+
content min-paragraphs=1
37+
}
38+
section "Decision" required=#true description="The decision and rationale" {
39+
content min-paragraphs=1
40+
}
41+
section "Consequences" required=#true {
42+
section "Positive" required=#true
43+
section "Negative"
44+
}
45+
}
46+
47+
// ─── POL: Policy Document ────────────────────────────────────────────────────
48+
49+
type "pol" description="Policy Document" folder="docs/policies" {
50+
alias "policy"
51+
field "status" type="enum" required=#true default="proposed" description="Lifecycle state" {
52+
values "proposed" "active" "deprecated" "superseded"
53+
transition "proposed" "active"
54+
transition "active" "deprecated" "superseded"
55+
}
56+
field "author" type="user" required=#true description="Policy author"
57+
field "owner" type="user" description="Current policy owner"
58+
field "date" type="string" required=#true pattern="^\\d{4}-\\d{2}-\\d{2}$" default="$TODAY"
59+
field "review_date" type="string" pattern="^\\d{4}-\\d{2}-\\d{2}$" description="Next review date"
60+
field "tags" type="string[]"
61+
field "code_paths" type="string[]" description="Glob patterns of source code paths related to this policy"
62+
63+
section "Purpose" required=#true description="Why this policy exists" {
64+
content min-paragraphs=1
65+
}
66+
section "Policy" required=#true description="The policy statement" {
67+
content min-paragraphs=1
68+
}
69+
section "Scope" required=#true description="Who and what this policy applies to"
70+
section "Compliance" description="How compliance is measured"
71+
section "Roles" description="Roles and responsibilities"
72+
section "Enforcement" description="Consequences of non-compliance"
73+
section "Review History" {
74+
table {
75+
column "Date" type="string" required=#true
76+
column "Reviewer" type="user" required=#true
77+
column "Changes" type="string" required=#true
78+
}
79+
}
80+
}
81+
82+
// ─── OPP: Opportunity ────────────────────────────────────────────────────────
83+
84+
type "opp" description="Opportunity" folder="docs/opportunities" {
85+
alias "opportunity"
86+
field "status" type="enum" required=#true default="identified" description="Discovery phase" {
87+
values "identified" "validating" "pursuing" "completed" "deprecated" "declined"
88+
transition "identified" "validating" "declined"
89+
transition "validating" "pursuing" "declined"
90+
transition "pursuing" "completed" "declined"
91+
transition "completed" "deprecated"
92+
}
93+
field "author" type="user" required=#true description="Opportunity author"
94+
field "owner" type="user" description="Current opportunity owner"
95+
field "priority" type="enum" description="Priority level" {
96+
values "critical" "high" "medium" "low"
97+
}
98+
field "effort" type="enum" description="Estimated effort" {
99+
values "small" "medium" "large"
100+
}
101+
field "impact" type="enum" description="Expected impact" {
102+
values "critical" "high" "medium" "low"
103+
}
104+
field "date" type="string" required=#true pattern="^\\d{4}-\\d{2}-\\d{2}$" default="$TODAY"
105+
field "tags" type="string[]"
106+
107+
section "Description" required=#true description="What is the opportunity and why it matters" {
108+
content min-paragraphs=1
109+
}
110+
section "Impact" description="Expected business impact with evidence (revenue, retention, competitive advantage)"
111+
section "Success Metrics" description="Measurable KPIs to evaluate if this delivered value" {
112+
list min-items=1
113+
}
114+
section "Non-Goals" description="What is explicitly out of scope to prevent scope creep" {
115+
list min-items=1
116+
}
117+
section "Alternatives Considered" description="Other approaches evaluated and why they were not chosen" {
118+
table {
119+
column "❓" type="string" required=#true
120+
column "Option" type="string" required=#true
121+
column "Rationale" type="string" required=#true
122+
}
123+
}
124+
section "Risks" description="Known risks and mitigations that could prevent success"
125+
section "Requirements" description="Technical and business requirements for pursuing this opportunity"
126+
127+
rule "active requires Requirements table" {
128+
when "status" equals-any="pursuing,completed"
129+
then-section-table "Requirements" {
130+
table {
131+
column "Status" type="enum" required=#true {
132+
values "completed" "in-progress" "pending"
133+
}
134+
column "Requirement" type="string" required=#true
135+
column "Owner" type="user" required=#true
136+
}
137+
}
138+
}
139+
}
140+
141+
// ─── INC: Incident Report ────────────────────────────────────────────────────
142+
143+
type "inc" description="Incident Report" folder="docs/incidents" {
144+
alias "incident"
145+
field "status" type="enum" required=#true default="open" description="Incident state" {
146+
values "open" "mitigated" "resolved"
147+
transition "open" "mitigated" "resolved"
148+
transition "mitigated" "resolved"
149+
}
150+
field "severity" type="enum" required=#true description="Severity level" {
151+
values "sev1" "sev2" "sev3" "sev4"
152+
}
153+
field "commander" type="user" description="Incident commander"
154+
field "responders" type="user[]" description="Incident responders"
155+
field "date" type="string" required=#true pattern="^\\d{4}-\\d{2}-\\d{2}$" default="$TODAY"
156+
field "duration" type="string" description="Total incident duration (e.g. 2h 30m, 45m, 3d)"
157+
field "tags" type="string[]"
158+
159+
section "Summary" required=#true description="What happened" {
160+
content min-paragraphs=1
161+
}
162+
section "Timeline" required=#true description="Chronological events" {
163+
table {
164+
column "Time" type="string" required=#true
165+
column "Event" type="string" required=#true
166+
column "Actor" type="user"
167+
}
168+
}
169+
section "Root Cause" required=#true description="Root cause analysis"
170+
section "Five Whys" description="5-Whys root cause drill-down" {
171+
list min-items=1 ordered=#true
172+
}
173+
section "Action Items" {
174+
table {
175+
column "Status" type="enum" required=#true {
176+
values "completed" "in-progress" "pending"
177+
}
178+
column "Action" type="string" required=#true
179+
column "Owner" type="user" required=#true
180+
column "Due Date" type="date"
181+
}
182+
}
183+
}
184+
185+
// ─── README: Project overview ────────────────────────────────────────────────
186+
187+
type "readme" folder="." max_count=1 singleton=#true description="Project README" {
188+
match "README.md"
189+
190+
section "Architecture" required=#true description="High-level system diagram (C4, block, etc.)" {
191+
diagram required=#true
192+
}
193+
section "Risks" required=#true min-subsections=1 callout=#true description="Top business risks: data breach, GDPR, data loss, pricing errors, theft, reputation damage, etc." {
194+
}
195+
section "License" required=#true description="License name or proprietary notice" {
196+
content min-paragraphs=1
197+
}
198+
}
199+
200+
// ─── Service README: Per-service overview ────────────────────────────────────
201+
202+
type "service-readme" folder="services" singleton=#true description="Service README in monorepo" {
203+
match "README.md"
204+
205+
section "Architecture" required=#true description="Service-level architecture diagram" {
206+
diagram required=#true
207+
}
208+
section "Local Development" required=#true description="Setup, build, test, run instructions" {
209+
section "Setup" required=#true description="Environment setup" {
210+
content min-paragraphs=1
211+
}
212+
section "Build" description="Build instructions" {
213+
content min-paragraphs=1
214+
}
215+
section "Test" required=#true description="How to run tests" {
216+
content min-paragraphs=1
217+
}
218+
section "Run" required=#true description="How to run locally" {
219+
content min-paragraphs=1
220+
}
221+
}
222+
}
223+
224+
type "app-readme" folder="apps" singleton=#true description="App README in monorepo" {
225+
match "README.md"
226+
227+
section "Local Development" required=#true description="Setup, build, test, run instructions" {
228+
section "Setup" required=#true description="Environment setup" {
229+
content min-paragraphs=1
230+
}
231+
section "Test" required=#true description="How to run tests" {
232+
content min-paragraphs=1
233+
}
234+
section "Run" required=#true description="How to run locally" {
235+
content min-paragraphs=1
236+
}
237+
}
238+
}
239+
240+
// ─── SPEC: Behavioral Specification / User Story ────────────────────────────
241+
242+
type "spec" description="Behavioral Specification / User Story" folder="docs/specs" nav_label="specifications" {
243+
alias "feature"
244+
field "status" type="enum" required=#true default="draft" description="Spec lifecycle" {
245+
values "draft" "proposed" "approved" "implemented" "deprecated"
246+
transition "draft" "proposed"
247+
transition "proposed" "approved"
248+
transition "approved" "implemented" "deprecated"
249+
transition "implemented" "deprecated"
250+
}
251+
field "priority" type="enum" description="MoSCoW priority" {
252+
values "must" "should" "could"
253+
}
254+
field "author" type="user" required=#true description="Spec author"
255+
field "date" type="string" required=#true pattern="^\\d{4}-\\d{2}-\\d{2}$" default="$TODAY"
256+
field "tags" type="string[]"
257+
258+
section "Story" required=#true description="User story (As a / I want / So that)" {
259+
content min-paragraphs=1
260+
}
261+
section "Scenarios" required=#true description="Gherkin scenarios in code blocks"
262+
section "Acceptance Criteria" description="Non-Gherkin acceptance conditions" {
263+
list min-items=1
264+
}
265+
}
266+
267+
// ─── PROC: Process Document ─────────────────────────────────────────────────
268+
269+
type "proc" description="Process Document" folder="docs/processes" {
270+
alias "process"
271+
field "status" type="enum" required=#true default="draft" description="Process lifecycle" {
272+
values "draft" "proposed" "active" "deprecated" "superseded"
273+
transition "draft" "proposed"
274+
transition "proposed" "active"
275+
transition "active" "deprecated" "superseded"
276+
}
277+
field "author" type="user" required=#true description="Process author"
278+
field "owner" type="user" description="Accountable process owner"
279+
field "date" type="string" required=#true pattern="^\\d{4}-\\d{2}-\\d{2}$" default="$TODAY"
280+
field "review_date" type="string" pattern="^\\d{4}-\\d{2}-\\d{2}$" description="Next review date"
281+
field "tags" type="string[]"
282+
283+
section "Overview" required=#true description="Purpose and scope of the process" {
284+
content min-paragraphs=1
285+
}
286+
section "Inputs and Prerequisites" required=#true description="Triggers and required state to begin" {
287+
list min-items=1
288+
}
289+
section "Outputs" required=#true description="Expected artifacts and end state" {
290+
list min-items=1
291+
}
292+
section "Roles and Responsibilities" description="RACI matrix for the process" {
293+
table {
294+
column "Role" type="string" required=#true
295+
column "Responsibility" type="string" required=#true
296+
column "Owner" type="user"
297+
}
298+
}
299+
section "Process Flow" required=#true description="High-level visual flow" {
300+
diagram required=#true
301+
}
302+
section "Steps" required=#true description="Detailed step-by-step procedure" {
303+
list min-items=1 ordered=#true
304+
}
305+
section "Exceptions and Escalation" description="Handling edge cases and failure modes"
306+
section "Metrics" description="Key performance indicators and SLAs"
307+
section "Revision History" {
308+
table {
309+
column "Date" type="string" required=#true
310+
column "Author" type="user" required=#true
311+
column "Changes" type="string" required=#true
312+
}
313+
}
314+
}
315+
316+
type "note" description="Note" folder="docs/notes" {
317+
alias "note"
318+
319+
field "author" type="user" required=#true description="Spec author"
320+
field "date" type="string" required=#true pattern="^\\d{4}-\\d{2}-\\d{2}$" default="$TODAY"
321+
field "tags" type="string[]"
322+
}

.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ indent_style = space
88
max_line_length = 120
99
trim_trailing_whitespace = true
1010

11+
[schema.kdl]
12+
max_line_length = 250
13+
1114
[SKILL.md]
1215
max_line_length = 200
1316

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.DS_Store
22
.dg/
33
.dg.lock
4+
cache/

.mise.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ harper-cli lint --user-dict-path .config/lingo.dic --dialect au \
3636
"""
3737

3838
[tasks.dg-check]
39-
run = "dg validate --pattern 'docs/architecture/*.md'"
39+
# Ignore some S rules that apply to README.md
40+
# U011 ignored as dg appears unable to resolve user identifiers
41+
run = "dg validate --skip S032,S010"

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ This repository uses [`mise`](https://mise.jdx.dev/) for tool management and tas
66

77
After installing `mise`, run `mise run check` to check the repository contents.Decision Graph
88

9+
## Architecture
10+
911
This repository uses [decision graph](https://decisiongraph.dev/) CLI to assist manage
1012
the documents here.
1113

14+
The Architecture docs are located under [docs/architecture](docs/architecture).
15+
1216
## Spelling and grammar
1317

1418
The following Rust utilities used for spelling and grammar.

0 commit comments

Comments
 (0)