From 2f024c764bf86601cd584c3ac0fd27ee1b739e1d Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Mon, 27 Apr 2026 14:33:53 +0800 Subject: [PATCH 1/8] Implement decision graph tool Refs: ADR-001, ADR-002 --- .config/lingo.dic | 1 + .config/spellcheck.toml | 1 - .dg/org.kdl | 3 + .editorconfig | 13 + .gemini/hooks/check-code.sh | 6 + .gemini/hooks/check-fixme.sh | 4 + .gemini/settings.json | 22 ++ .gemini/skills/adr/SKILL.md | 56 ++++ .gemini/skills/diagram/SKILL.md | 146 +++++++++ .gemini/skills/image/SKILL.md | 66 ++++ .gemini/skills/incident/SKILL.md | 111 +++++++ .gemini/skills/mermaid-flowchart/SKILL.md | 244 +++++++++++++++ .gemini/skills/mermaid-sequence/SKILL.md | 294 ++++++++++++++++++ .gemini/skills/opportunity/SKILL.md | 71 +++++ .gemini/skills/policy/SKILL.md | 68 ++++ .gemini/skills/spec/SKILL.md | 90 ++++++ .github/workflows/check.yml | 44 +++ .gitignore | 2 + .index.json | 20 ++ .mise.toml | 33 +- .templates/adr.md | 85 +++++ .templates/customer.md | 68 ++++ .templates/decision.md | 71 +++++ .templates/hiring.md | 74 +++++ .templates/incident.md | 81 +++++ .templates/legal.md | 45 +++ .templates/meeting.md | 69 ++++ .templates/opportunity.md | 89 ++++++ .templates/policy.md | 78 +++++ .templates/process.md | 94 ++++++ .templates/runbook.md | 79 +++++ .templates/strategy.md | 81 +++++ AGENTS.md | 150 +++++++++ CLAUDE.md | 150 +++++++++ README.md | 5 +- dg.toml | 51 +++ .../architecture/adr-001-decisions.md | 59 +++- ...dr-002-initial-open-source-repositories.md | 20 +- dprint.json | 22 ++ 39 files changed, 2632 insertions(+), 34 deletions(-) create mode 100644 .dg/org.kdl create mode 100755 .gemini/hooks/check-code.sh create mode 100755 .gemini/hooks/check-fixme.sh create mode 100644 .gemini/settings.json create mode 100644 .gemini/skills/adr/SKILL.md create mode 100644 .gemini/skills/diagram/SKILL.md create mode 100644 .gemini/skills/image/SKILL.md create mode 100644 .gemini/skills/incident/SKILL.md create mode 100644 .gemini/skills/mermaid-flowchart/SKILL.md create mode 100644 .gemini/skills/mermaid-sequence/SKILL.md create mode 100644 .gemini/skills/opportunity/SKILL.md create mode 100644 .gemini/skills/policy/SKILL.md create mode 100644 .gemini/skills/spec/SKILL.md create mode 100644 .github/workflows/check.yml create mode 100644 .index.json create mode 100644 .templates/adr.md create mode 100644 .templates/customer.md create mode 100644 .templates/decision.md create mode 100644 .templates/hiring.md create mode 100644 .templates/incident.md create mode 100644 .templates/legal.md create mode 100644 .templates/meeting.md create mode 100644 .templates/opportunity.md create mode 100644 .templates/policy.md create mode 100644 .templates/process.md create mode 100644 .templates/runbook.md create mode 100644 .templates/strategy.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 dg.toml rename ADR/R1/0001-decisions.md => docs/architecture/adr-001-decisions.md (77%) rename ADR/R1/0002-open-source.md => docs/architecture/adr-002-initial-open-source-repositories.md (98%) create mode 100644 dprint.json diff --git a/.config/lingo.dic b/.config/lingo.dic index 3d99668..082de7a 100644 --- a/.config/lingo.dic +++ b/.config/lingo.dic @@ -6,6 +6,7 @@ ADR ADRs Agilab CD +CLI CRICOS Curtin EECMS diff --git a/.config/spellcheck.toml b/.config/spellcheck.toml index 05b3930..bd2ddc7 100644 --- a/.config/spellcheck.toml +++ b/.config/spellcheck.toml @@ -35,7 +35,6 @@ skip_os_lookups = true # for topic specific lingo. use_builtin = true - [Hunspell.quirks] # Transforms words that are provided by the tokenizer # into word fragments based on the capture groups which are to diff --git a/.dg/org.kdl b/.dg/org.kdl new file mode 100644 index 0000000..7c69714 --- /dev/null +++ b/.dg/org.kdl @@ -0,0 +1,3 @@ +org "edge-toolkit" { + name "edge-toolkit" +} diff --git a/.editorconfig b/.editorconfig index c602028..ef6c51e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,19 @@ indent_style = space max_line_length = 120 trim_trailing_whitespace = true +[SKILL.md] +max_line_length = 200 + +[AGENTS.md] +max_line_length = 300 + +[CLAUDE.md] +max_line_length = 300 + # Markdown files can have flexible indentation for lists [*.md] indent_size = unset + +[.cache.json] +end_of_line = unset +insert_final_newline = unset diff --git a/.gemini/hooks/check-code.sh b/.gemini/hooks/check-code.sh new file mode 100755 index 0000000..d1b3e46 --- /dev/null +++ b/.gemini/hooks/check-code.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +# Check if edited files match decision doc code_paths. +# Delegates to dg hooks check-code for the actual logic. +if [ -n "$1" ]; then + exec dg hooks check-code "$1" +fi diff --git a/.gemini/hooks/check-fixme.sh b/.gemini/hooks/check-fixme.sh new file mode 100755 index 0000000..8226f04 --- /dev/null +++ b/.gemini/hooks/check-fixme.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +# Minimal wrapper - delegates to dg hooks check-fixme +# This allows upgrading dg to get new functionality +exec dg hooks check-fixme "$@" diff --git a/.gemini/settings.json b/.gemini/settings.json new file mode 100644 index 0000000..0844469 --- /dev/null +++ b/.gemini/settings.json @@ -0,0 +1,22 @@ +{ + "context": { + "fileName": ["AGENTS.md", "GEMINI.md"] + }, + "hooks": { + "AfterTool": [ + { + "matcher": "^(Edit|WriteFile)$", + "hooks": [ + { + "type": "command", + "command": ".gemini/hooks/check-fixme.sh" + }, + { + "type": "command", + "command": ".gemini/hooks/check-code.sh" + } + ] + } + ] + } +} diff --git a/.gemini/skills/adr/SKILL.md b/.gemini/skills/adr/SKILL.md new file mode 100644 index 0000000..9c99f10 --- /dev/null +++ b/.gemini/skills/adr/SKILL.md @@ -0,0 +1,56 @@ +--- +name: adr +description: Create architecture decision records using MADR 4.0 format +--- + +# Create Architecture Decision Record + +Capture a technical architecture decision using MADR 4.0 format. + +## When to Use + +- Technical architecture choices (database, framework, protocol) +- Infrastructure decisions (hosting, CI/CD, deployment) +- Code organization choices (monorepo vs multi-repo, module structure) +- API design decisions + +## Workflow + +1. **Check existing context**: + ```bash + dg list + dg validate + ``` + +2. **Link to OPP when applicable**: If this ADR implements a business opportunity, reference it. + +3. **Create the ADR**: + ```bash + dg new adr "Use Ruby on Rails with PostgreSQL" + ``` + +4. **Fill in the document**: + - **Context and Problem Statement**: What is the issue? + - **Decision Drivers**: What factors matter? + - **Considered Options**: At least 2-3 alternatives + - **Decision Outcome**: Which option and why + - **Consequences**: Good, bad, and neutral + +## Status Lifecycle + +- `draft` — Incomplete, not ready for review +- `proposed` — Under discussion, not yet decided +- `accepted` — Decision is final and active +- `deprecated` — No longer relevant +- `superseded` — Replaced by a newer ADR (link to it) +- `rejected` — Decision was considered but rejected (link to alternatives) + +## Tips + +- Good title: "Use Ruby on Rails with PostgreSQL" +- Bad title: "Tech stack decision" +- Always document rejected alternatives — they prevent revisiting the same discussion +- Link to OPPs this decision realizes using `implements:` field +- Link to POLs that constrain this decision using `implements:` or `conflicts_with:` fields +- Use `depends_on:` for decisions that block or are blocked by other docs +- Use `` for information gaps that need follow-up diff --git a/.gemini/skills/diagram/SKILL.md b/.gemini/skills/diagram/SKILL.md new file mode 100644 index 0000000..c937248 --- /dev/null +++ b/.gemini/skills/diagram/SKILL.md @@ -0,0 +1,146 @@ +--- +name: diagram +description: Create effective D2/Mermaid diagrams optimized for terminal display +--- + +# Create Diagram + +Create effective D2 or Mermaid diagrams optimized for terminal display. + +## When to Use + +- Architecture or infrastructure diagrams +- System interaction flows (request paths, failure cascades) +- Process flowcharts or state machines +- Incident failure diagrams showing what went wrong + +## Workflow + +1. **Identify components**: Ask what nodes (services, databases, users) and edges (connections, data flows) to show +2. **Draft the D2/Mermaid code**: Write a first version following the terminal best practices below +3. **Review for readability**: Check label lengths, node count, layout direction +4. **Place in document**: Add as a fenced code block in the appropriate section + +## Terminal Best Practices + +Diagrams render as ASCII art in the terminal. Follow these rules for clean output. + +### Keep it small + +Aim for **5-7 nodes** max. Terminals are typically 80-120 columns wide. More nodes = unreadable overlaps. + +If you need more, use **containers** to group related nodes: + +```d2 +vpc: VPC { + api: API + db: Database {shape: cylinder} + api -> db +} +client: Client +client -> vpc.api +``` + +### Use short labels + +Edge labels over ~15 characters get moved to a legend at the bottom, disconnecting them from context. + +- Bad: `api -> db: "sends authenticated read requests for user data"` +- Good: `api -> db: reads` + +Node labels should also be concise. Use the key as short ID and label for display: + +```d2 +pg: PostgreSQL {shape: cylinder} +``` + +### Set direction + +Default is top-to-bottom. For terminal, `direction: right` often works better as it uses horizontal space: + +```d2 +direction: right +a: Service A +b: Service B +a -> b: calls +``` + +### Use shapes for meaning + +Supported shapes that render distinctly: + +- `shape: cylinder` — databases, connection pools, queues +- `shape: diamond` — decision points +- `shape: hexagon` — APIs or key services +- `shape: circle` — users, external actors +- Default rectangle — everything else + +### Cycles are warned + +A cycle like `A -> B -> C -> A` triggers a D002 warning. This is informational — cycles in incident/failure diagrams are often intentional. To avoid warnings on return paths, restructure as: + +```d2 +# Instead of A -> B and B -> A, use: +a <-> b: request/response +``` + +### Mermaid vs D2 + +Both work. D2 is simpler for architecture diagrams. Mermaid is better for state machines and sequence diagrams. + +```mermaid +stateDiagram-v2 + proposed --> accepted + proposed --> rejected + accepted --> deprecated + accepted --> superseded +``` + +## Common Patterns + +### Incident failure diagram + +```d2 +users: Users {shape: circle} +api: API +db: Database {shape: cylinder} + +users -> api: requests +api -> db: queries +api -> users: 503 errors +``` + +### Architecture overview + +```d2 +direction: right +client: Browser +api: API {shape: hexagon} +db: PostgreSQL {shape: cylinder} +cache: Redis {shape: cylinder} + +client -> api: HTTPS +api -> db: reads/writes +api -> cache: cached reads +``` + +### Decision flow + +```d2 +direction: right +start: Request +auth: Authenticated? {shape: diamond} +allow: Allow +deny: Deny + +start -> auth +auth -> allow: yes +auth -> deny: no +``` + +## Tips + +- Always test rendering width: `dg show DOC-ID` shows actual terminal output +- If labels overflow to legend, shorten them — inline labels are always more readable +- Use comments (`# ...` in D2) to document intent without affecting rendering +- Prefer D2 for static architecture, Mermaid `stateDiagram-v2` for lifecycles diff --git a/.gemini/skills/image/SKILL.md b/.gemini/skills/image/SKILL.md new file mode 100644 index 0000000..1c823d3 --- /dev/null +++ b/.gemini/skills/image/SKILL.md @@ -0,0 +1,66 @@ +--- +name: image +description: Add an image to a decision document — rename, move to docs/assets/, insert reference +--- + +# Add Image to Document + +Add an image to a decision document. Handles renaming, moving to docs/assets/, and inserting the markdown reference. + +## When to Use + +- User pastes or provides an image to include in a document +- User asks to add a screenshot, diagram, or photo to a doc +- User provides an image file path that needs to be moved to the correct location + +## Workflow + +1. **Identify the image source**: The user may paste an image (saved to a temp path), provide a file path, or provide a URL. + +2. **Determine the target document**: Ask which document (e.g. ADR-001, OPP-002) the image belongs to, if not obvious from context. + +3. **Name the image file**: Use a descriptive, kebab-case name based on content: + - `architecture-overview.png` + - `incident-timeline.png` + - `deployment-flow.svg` + - Format: `{doc-id-lowercase}-{description}.{ext}` e.g. `adr-001-architecture-overview.png` + +4. **Ensure docs/assets/ exists**: + ```bash + mkdir -p docs/assets + ``` + +5. **Move/copy the image**: + ```bash + cp /path/to/source/image.png docs/assets/adr-001-architecture-overview.png + ``` + +6. **Insert markdown reference** in the target document using `dg set`: + ```bash + dg set ADR-001 --section "Context and Problem Statement" --append '![Architecture overview](../assets/adr-001-architecture-overview.png)' + ``` + Or for documents that reference from project root: + ```markdown + ![Architecture overview](docs/assets/adr-001-architecture-overview.png) + ``` + +7. **Validate**: + ```bash + dg validate + ``` + +## Image Path Rules + +- All local images MUST be stored in `docs/assets/` +- Reference from within docs/ subdirs: `../assets/filename.png` +- Reference from project root: `docs/assets/filename.png` +- External URLs (https://...) are allowed anywhere +- `dg validate` will flag images stored outside docs/assets/ (error C002) + +## Tips + +- Prefer SVG for diagrams (scalable, small file size) +- Prefer PNG for screenshots (lossless, good for text) +- Keep file sizes reasonable — compress large screenshots +- Use descriptive alt text for accessibility +- Prefix image filenames with the doc ID to avoid naming collisions diff --git a/.gemini/skills/incident/SKILL.md b/.gemini/skills/incident/SKILL.md new file mode 100644 index 0000000..0624359 --- /dev/null +++ b/.gemini/skills/incident/SKILL.md @@ -0,0 +1,111 @@ +--- +name: incident +description: Create blameless incident reports and post-mortems +--- + +# Create Incident Report + +Capture a post-mortem / incident report using blameless format. + +## When to Use + +- Production outages +- Security incidents +- Data loss events +- Service degradation +- Near-misses worth documenting + +## Valid Statuses + +- `open` — incident detected, being investigated (covers the "investigating" phase) +- `mitigated` — impact reduced but not fully resolved +- `resolved` — incident fully resolved + +Do NOT use "investigating" — use `open` instead. + +## Duration Field + +Format: human-readable, e.g. "2h 30m", "45m", "3d 4h". Free-form text. + +## Action Items Table + +- Due Date: YYYY-MM-DD format only +- Leave empty if date unknown — do NOT write "TBD" +- Actor: `@handle` or empty for system events + +## Workflow + +### Step 1: Confirm and create + +When a user reports an incident: + +1. Ask: "This sounds important. Shall I create an incident report?" +2. After confirmation, create immediately: + +```bash +dg new inc "Checkout page down for 2 hours" +``` + +Incidents should be documented quickly. Gather basic facts (timeline, impact) but don't ask extensive discovery questions. + +Good titles: "Checkout page down for 2 hours", "Customer data leaked" +Bad title: "Things broke" + +### Step 2: Fill in the timeline + +As events unfold or are reported: + +- When did it start? +- When was it detected? +- When was it mitigated? +- When was it resolved? + +### Step 3: After resolution, complete + +- **Impact**: Users affected, duration, revenue impact +- **Root Cause**: Use 5 Whys technique + ``` + 1. Why did the service go down? → Database connection pool exhausted + 2. Why was the pool exhausted? → Query N+1 problem under load + 3. Why wasn't this caught? → No connection pool monitoring + 4. Why no monitoring? → Monitoring setup not in deployment checklist + 5. Why not in checklist? → No formal deployment review process + ``` +- **What went well**: Detection, response, communication +- **What went poorly**: Gaps in monitoring, slow response, missing runbooks +- **Action items**: With owners and due dates + +### Step 4: Link to related records + +```bash +# Link to ADRs that need updating based on lessons learned +# Link to OPPs if this reveals a business opportunity (e.g., better monitoring product) +# Link to POLs if this reveals need for new policies +``` + +### Step 5: Create follow-up records + +Incidents often reveal needs for: + +- New ADRs (technical changes to prevent recurrence) +- New POLs (process/policy changes) +- Updated existing records + +## Example + +User: "The checkout page was down for 2 hours yesterday" + +1. Create: `dg new inc "Checkout page down for 2 hours"` +2. Fill timeline, impact, root cause +3. Add action items with owners +4. Link to ADRs that need updating +5. Create new ADR if architectural changes needed + +## Tips + +- **Blameless**: Focus on systems and processes, not individuals +- Title INC by what happened and when +- Status: `open` -> `mitigated` -> `resolved` +- Action items should be specific and assigned +- Link to ADRs that need updating using `triggers:` field +- Use `related:` for loosely associated docs diff --git a/.gemini/skills/mermaid-flowchart/SKILL.md b/.gemini/skills/mermaid-flowchart/SKILL.md new file mode 100644 index 0000000..0862ac8 --- /dev/null +++ b/.gemini/skills/mermaid-flowchart/SKILL.md @@ -0,0 +1,244 @@ +--- +name: mermaid-flowchart +description: Complete Mermaid flowchart reference — shapes, edges, subgraphs, styling +--- + +# Mermaid Flowchart + +Complete reference for building Mermaid flowchart diagrams in DecisionGraph documents. + +## When to Use + +- Process flows, decision trees, system interactions +- Document relationship diagrams (how OPPs, ADRs, SPECs connect) +- Onboarding flows, deployment pipelines, data flows +- Any directed graph that fits in a `mermaid` code block + +## Direction + +``` +flowchart TD %% Top-down (default) +flowchart LR %% Left-right (better for wide diagrams) +flowchart BT %% Bottom-top +flowchart RL %% Right-left +``` + +## Node Shapes + +### Basic (all Mermaid versions) + +``` +A["Rectangle"] +B("Rounded") +C(["Stadium / pill"]) +D[["Subroutine"]] +E[(Cylinder / database)] +F((Circle)) +G>Asymmetric / flag] +H{Diamond / decision} +I{{Hexagon}} +J[/Parallelogram/] +K[\Parallelogram alt\] +L[/Trapezoid\] +M[\Trapezoid alt/] +N(((Double circle))) +``` + +### Semantic shapes (Mermaid v11.3+) + +Use `@{ shape: name, label: "text" }` for richer shapes: + +``` +%% Stacked shapes — visually show "many of this" +A@{ shape: docs, label: "Multiple documents" } +B@{ shape: processes, label: "Multiple processes" } + +%% Special shapes +C@{ shape: cloud, label: "Cloud service" } +D@{ shape: bolt, label: "Event / trigger" } +E@{ shape: flag, label: "Milestone" } +F@{ shape: brace, label: "Annotation" } +G@{ shape: text, label: "Floating text" } + +%% All semantic names: +%% rect, rounded, stadium, pill, circle, diam, hex, lean-r, lean-l, +%% trap-b, trap-t, dbl-circ, fr-rect, cyl, docs, doc, processes, +%% notch-rect, tag-rect, brace, brace-r, cloud, bolt, flag, +%% hourglass, tri, win-pane, text, lin-rect, lin-cyl, curv-trap, +%% div-rect, odd, cross, comment +``` + +### Shape selection guide + +| Shape | Use for | Syntax | +| ----------- | -------------------------------------- | -------------------------------------- | +| `docs` | Collection of documents (OPPs, POLs) | `@{ shape: docs }` | +| `processes` | Multiple processes or decisions (ADRs) | `@{ shape: processes }` | +| `cyl` | Databases, queues, storage | `[(text)]` or `@{ shape: cyl }` | +| `diam` | Decision points, conditionals | `{text}` or `@{ shape: diam }` | +| `circle` | Actors, users, external systems | `((text))` or `@{ shape: circle }` | +| `dbl-circ` | Organizations, top-level entities | `(((text)))` or `@{ shape: dbl-circ }` | +| `cloud` | External services, SaaS | `@{ shape: cloud }` | +| `flag` | Milestones, goals | `@{ shape: flag }` | +| `bolt` | Events, triggers, incidents | `@{ shape: bolt }` | +| `stadium` | Key processes, starting points | `([text])` or `@{ shape: stadium }` | + +## Links / Edges + +### Arrow types + +``` +A --> B %% Solid arrow +A --- B %% Solid line (no arrow) +A -.-> B %% Dotted arrow +A -.- B %% Dotted line +A ==> B %% Thick arrow +A === B %% Thick line +A ~~~ B %% Invisible link (layout only) +A <--> B %% Bidirectional +A --o B %% Circle end +A --x B %% Cross end +``` + +### Text on edges + +``` +A -->|"label text"| B %% Pipe syntax (preferred) +A -- "label text" --> B %% Inline syntax +A -. "dotted label" .-> B %% Dotted with text +A == "thick label" ==> B %% Thick with text +``` + +### Link length + +Add extra dashes/dots/equals to increase length: + +``` +A --> B %% Normal +A ----> B %% Longer +A ------> B %% Even longer +A -.....-> B %% Long dotted +A ====> B %% Long thick +``` + +## Subgraphs + +```mermaid +flowchart TD + subgraph Backend["Backend Services"] + direction LR + api[API] + db[(Database)] + api --> db + end + + subgraph Frontend + web[Web App] + end + + web --> api +``` + +Subgraphs can have their own direction and can be nested. + +## Styling + +### Class definitions + +``` +classDef primary fill:#4f46e5,stroke:#3730a3,color:#fff; +classDef danger fill:#dc2626,stroke:#991b1b,color:#fff; +classDef muted fill:#f3f4f6,stroke:#d1d5db,color:#374151; + +A:::primary --> B:::danger +C:::muted +``` + +### Direct node styling + +``` +style A fill:#f9f,stroke:#333,stroke-width:2px +``` + +### Link styling (by index) + +``` +linkStyle 0 stroke:#ff3,stroke-width:4px +linkStyle 1,2 stroke:#0f0 +``` + +## Interactions + +``` +click A "https://example.com" "Opens docs" _blank +click B callback "Tooltip text" +``` + +## Text & Special Characters + +- Use double quotes for special chars: `A["Node with (parens)"]` +- Line breaks: `
` inside quoted labels +- HTML entities: `#amp;` `#lt;` `#gt;` `#quot;` +- Unicode works in quoted strings: `A["Café"]` +- Comments: `%% This is a comment` +- Markdown in labels: `A["**bold** and *italic*"]` + +## Best Practices for DecisionGraph + +1. **5-8 nodes max** — more gets unreadable, use subgraphs to group +2. **Short edge labels** — max ~15 chars, use `
` for 2-line labels +3. **LR for wide flows**, **TD for hierarchies** +4. **Use semantic shapes** to convey meaning at a glance (docs for document collections, bolt for events) +5. **Dashed edges for feedback loops** — solid for primary flow, `-.->` for secondary/feedback +6. **Double-circle for actors** — organizations, users, external systems + +## Common Patterns + +### Decision flow + +```mermaid +flowchart TD + start(["Start"]) + check{{"Meets criteria?"}} + approve["Approve"] + reject["Reject"] + review(["Review needed"]) + + start --> check + check -->|yes| approve + check -->|no| reject + check -->|unclear| review + review -.-> check +``` + +### System architecture + +```mermaid +flowchart LR + user((User)) + cdn@{ shape: cloud, label: "CDN" } + api["API Gateway"] + db[(PostgreSQL)] + cache[(Redis)] + + user --> cdn --> api + api --> db + api --> cache +``` + +### Document relationship graph + +```mermaid +flowchart TD + opp@{ shape: docs, label: "Opportunities" } + pol@{ shape: docs, label: "Policies" } + adr@{ shape: processes, label: "Decisions" } + spec@{ shape: docs, label: "Specifications" } + inc@{ shape: bolt, label: "Incidents" } + + opp --> adr + opp --> spec + spec -.-> inc + inc -.-> pol + inc -.-> adr +``` diff --git a/.gemini/skills/mermaid-sequence/SKILL.md b/.gemini/skills/mermaid-sequence/SKILL.md new file mode 100644 index 0000000..5c0cec1 --- /dev/null +++ b/.gemini/skills/mermaid-sequence/SKILL.md @@ -0,0 +1,294 @@ +--- +name: mermaid-sequence +description: Complete Mermaid sequence diagram reference — participants, arrows, activations, control flow +--- + +# Mermaid Sequence Diagram + +Complete reference for building Mermaid sequence diagrams in DecisionGraph documents. + +## When to Use + +- API call flows between services +- User interaction sequences (login, checkout, onboarding) +- Incident timelines showing failure cascades +- Integration flows with external systems +- Any time-ordered interaction between participants + +## Participants + +### Types + +``` +participant API %% Rectangle box +actor User %% Stick figure +participant DB as Database %% Alias +actor Admin as "Admin User" %% Actor with alias +``` + +### Stereotypes (typed participants) + +``` +participant DB, {"type": "database"} +participant Q, {"type": "queue"} +participant Cache, {"type": "collections"} +participant Auth, {"type": "boundary"} +participant Logic, {"type": "control"} +participant User, {"type": "entity"} +``` + +### Grouping in boxes + +``` +box "Backend" rgb(230, 240, 255) + participant API + participant DB +end + +box "External" + participant Stripe + participant SendGrid +end +``` + +## Messages / Arrows + +### Arrow types + +``` +A -> B: Solid line, no arrow +A --> B: Dotted line, no arrow +A ->> B: Solid with arrowhead (most common) +A -->> B: Dotted with arrowhead (response/async return) +A -x B: Solid with cross (failure/rejection) +A --x B: Dotted with cross +A -) B: Solid open arrow (async fire-and-forget) +A --) B: Dotted open arrow +A <<->> B: Bidirectional solid (v11+) +A <<-->> B: Bidirectional dotted (v11+) +``` + +### Choosing the right arrow + +| Arrow | Use for | +| ------- | ------------------------------- | +| `->>` | Synchronous request | +| `-->>` | Response / return value | +| `-)` | Async message (fire-and-forget) | +| `-x` | Failed request / rejection | +| `<<->>` | Bidirectional / handshake | + +## Activations + +Show when a participant is actively processing: + +```mermaid +sequenceDiagram + User ->>+ API: POST /login + API ->>+ DB: SELECT user + DB -->>- API: user row + API -->>- User: 200 JWT token +``` + +- `+` after arrow activates the target +- `-` after arrow deactivates the target +- Can stack multiple activations + +Explicit form: + +``` +activate API +deactivate API +``` + +## Notes + +``` +Note right of API: Validates JWT +Note left of User: Enters credentials +Note over API: Processing... +Note over API, DB: Shared context +``` + +Use `
` for line breaks in notes. + +## Control Flow + +### Loop + +``` +loop Every 30 seconds + Monitor ->> API: Health check + API -->> Monitor: 200 OK +end +``` + +### Alt / Else (conditionals) + +``` +alt Success + API -->> User: 200 OK +else Unauthorized + API -->> User: 401 +else Server Error + API -->> User: 500 +end +``` + +### Opt (optional) + +``` +opt User has 2FA enabled + API ->> User: Enter OTP + User ->> API: OTP code +end +``` + +### Par (parallel) + +``` +par Notify user + API -) Email: Send confirmation +and Update analytics + API -) Analytics: Track event +and Invalidate cache + API -) Cache: Delete key +end +``` + +### Critical + +``` +critical Payment processing + API ->> Stripe: Charge card + Stripe -->> API: Success +option Card declined + Stripe -->> API: Declined + API -->> User: Payment failed +option Timeout + API -->> User: Try again later +end +``` + +### Break + +``` +break Auth token expired + API -->> User: 401 Unauthorized +end +``` + +## Background Highlighting + +Highlight regions with color: + +``` +rect rgba(0, 128, 255, 0.1) + User ->> API: Request + API -->> User: Response +end +``` + +## Create & Destroy Participants + +``` +User ->> API: POST /webhook +create participant Worker +API ->> Worker: Process job +Worker -->> API: Done +destroy Worker +API ->> Worker: Cleanup +``` + +## Sequence Numbers + +``` +autonumber +User ->> API: Step 1 +API ->> DB: Step 2 +DB -->> API: Step 3 +``` + +## Actor Menus (clickable links) + +``` +link API: Swagger Docs @ https://api.example.com/docs +link API: Source Code @ https://github.com/org/api +links DB: {"Schema": "/docs/schema", "Migrations": "/docs/migrations"} +``` + +## Comments + +``` +%% This is a comment +``` + +## Best Practices for DecisionGraph + +1. **4-6 participants max** — more gets unreadable, group with boxes +2. **Name participants by role**, not technology: "Payment Service" not "Stripe API" +3. **Show the happy path first**, then alt/else for error cases +4. **Use activations** to show processing time and call depth +5. **Dotted arrows for responses** — solid for requests, dotted for returns +6. **Notes for context** — explain non-obvious steps without cluttering arrows +7. **Use `autonumber`** for incident timelines so steps can be referenced + +## Common Patterns + +### API request flow + +```mermaid +sequenceDiagram + actor User + participant API + participant DB, {"type": "database"} + participant Cache, {"type": "collections"} + + User ->>+ API: GET /profile + API ->> Cache: Lookup + alt Cache hit + Cache -->> API: Cached data + else Cache miss + API ->>+ DB: SELECT + DB -->>- API: Row + API ->> Cache: Store + end + API -->>- User: 200 Profile JSON +``` + +### Incident timeline + +```mermaid +sequenceDiagram + autonumber + participant LB as Load Balancer + participant API + participant DB, {"type": "database"} + + LB ->> API: Route request + API ->>+ DB: Query + Note over DB: Connection pool exhausted + DB --x API: Timeout (30s) + API -->> LB: 503 + loop Retry storm + LB ->> API: Retry + API -x DB: Connection refused + API -->> LB: 503 + end +``` + +### Async event flow + +```mermaid +sequenceDiagram + participant API + participant Q, {"type": "queue"} + participant Worker + participant Email + + API -)+ Q: Enqueue job + Q ->>+ Worker: Dequeue + Worker ->> Worker: Process + Worker -)- Email: Send notification + Worker -->>- Q: Ack +``` diff --git a/.gemini/skills/opportunity/SKILL.md b/.gemini/skills/opportunity/SKILL.md new file mode 100644 index 0000000..b7b9d41 --- /dev/null +++ b/.gemini/skills/opportunity/SKILL.md @@ -0,0 +1,71 @@ +--- +name: opportunity +description: Create business opportunity documents with thorough questioning +--- + +# Create Opportunity Document + +Capture a business opportunity using the Opportunity Solution Tree framework. + +## When to Use + +- New feature requests +- Market opportunities identified +- Product ideas +- User pain points discovered +- Business expansion plans + +## Workflow + +### Step 1: List clarifying questions in your response + +Before creating the document, write out questions about: + +- **Outcome**: What business outcome are we trying to achieve? What metric improves? +- **Problem**: What specific problem or pain point does this address? How do we know it's real? +- **Audience**: Who benefits and how? Is this a learning project or real business opportunity? +- **Assumptions**: What makes us think we can do this better than existing solutions? + +### Step 2: Gather answers or proceed + +**In interactive sessions**: Ask questions and get answers to critical questions before creating the document. + +**In batch mode**: Proceed with your best understanding and mark unknowns with FIXMEs. + +```bash +dg new opp "Selling lama milk online" +``` + +Good title: "Selling lama milk online" +Bad title: "Build e-commerce app" + +### Step 3: Fill in the document + +Edit the created document to add: + +- **Outcome**: The metric and target (use FIXME if unknown) +- **Opportunity**: Problem statement and evidence +- **Solutions**: Multiple approaches (don't commit to one) +- **RICE Score**: If enough info; otherwise add FIXME +- **Strategic Alignment**: Which competitive moats this builds + +### Step 4: Mark unknowns with FIXMEs + +```markdown +## Evidence + + + +## RICE Score + + +``` + +## Tips + +- Title OPPs by the problem/opportunity, not the solution +- Status: `proposed` -> `validated` -> `in-progress` -> `done` +- FIXMEs are OK — they track what questions need answers later +- Link ADRs that realize this opportunity using `implemented_by:` in OPP or `implements:` in ADR +- Use `depends_on:` when this opportunity is blocked by another +- Use `conflicts_with:` when this opportunity creates tension with a policy diff --git a/.gemini/skills/policy/SKILL.md b/.gemini/skills/policy/SKILL.md new file mode 100644 index 0000000..c216bcd --- /dev/null +++ b/.gemini/skills/policy/SKILL.md @@ -0,0 +1,68 @@ +--- +name: policy +description: Create organizational policy documents for compliance and governance +--- + +# Create Policy Document + +Capture an organizational or business policy — regulatory constraints, compliance requirements, operational rules. + +## When to Use + +- Regulatory/legal requirements (GDPR, PCI-DSS, SOX) +- Compliance constraints +- Business rules or operational policies +- Security policies +- Governance decisions + +## Workflow + +### Step 1: List clarifying questions in your response + +Before creating the document, write out questions about: + +- **Driver**: What regulation, law, or business need requires this policy? +- **Scope**: Which teams/systems are affected? Are there exceptions? +- **Enforcement**: What's the enforcement mechanism? What happens on non-compliance? +- **Authority**: Do we have authority to set this policy? Is there an existing one this replaces? + +### Step 2: Gather answers or proceed + +**In interactive sessions**: Ask questions and get answers to critical questions before creating the document. + +**In batch mode**: Proceed with your best understanding and mark unknowns with FIXMEs. + +```bash +dg new pol "Cold chain logistics for lama milk delivery" +``` + +Good title: "Cold chain logistics for lama milk delivery" +Bad title: "Shipping stuff" + +### Step 3: Fill in the document + +Edit the created document to add: + +- **Purpose**: Why this policy exists, what regulation/need drives it +- **Scope**: Who and what it applies to +- **Background**: Context, regulatory references, prior state +- **Policy Statement**: The actual rules/constraints (clear, actionable) +- **Implementation**: How to comply, what changes are needed +- **Compliance**: How compliance is measured and enforced + +### Step 4: Link and mark unknowns + +- Link to related OPP/ADR documents using frontmatter relation fields +- Add FIXMEs for gaps: + ```markdown + + + ``` + +## Tips + +- Title POLs by what they govern, not why they exist +- Status: `draft` -> `active` -> `superseded` +- Always reference the specific regulation/law driving the policy +- Link ADRs that implement this policy using `implemented_by:` +- Use `conflicts_with:` when a decision contradicts this policy diff --git a/.gemini/skills/spec/SKILL.md b/.gemini/skills/spec/SKILL.md new file mode 100644 index 0000000..eb0b631 --- /dev/null +++ b/.gemini/skills/spec/SKILL.md @@ -0,0 +1,90 @@ +--- +name: spec +description: Create behavioral specifications with Gherkin scenarios +--- + +# Create Behavioral Specification + +Capture a user story with Gherkin scenarios as a first-class decision graph document. + +## When to Use + +- Defining user-facing behavior before implementation +- Translating opportunities into testable acceptance criteria +- Documenting edge cases and business rules +- Aligning stakeholders on expected behavior + +## Workflow + +### Step 1: Clarify the behavior + +Before creating a spec, ask: + +1. **Who** is the user/persona? What role do they have? +2. **What** do they want to accomplish? +3. **Why** — what value does it deliver? +4. **Edge cases** — what happens when things go wrong? +5. **Constraints** — rate limits, permissions, data formats? + +### Step 2: Create the spec + +```bash +dg new spec "Lama milk checkout flow" +``` + +Good title: "Lama milk checkout flow" +Bad title: "Checkout feature" + +### Step 3: Write the Story section + +Use the standard user story format: + +> As a [role], I want [capability] so that [benefit]. + +### Step 4: Write Gherkin scenarios + +Put scenarios in fenced code blocks: + +````markdown +```gherkin +Feature: Lama milk checkout flow + + Scenario: Successful purchase with cold shipping + Given a customer with lama milk in their cart + When the customer completes checkout + Then the order is placed with cold chain shipping + And a confirmation email is sent + + Scenario: Out of stock during checkout + Given a customer with lama milk in their cart + When the product goes out of stock before payment + Then the checkout is halted + And the customer sees an out-of-stock message +``` +```` + +### Step 5: Link to related records + +```bash +# Spec implements an opportunity +dg new spec "Lama milk checkout flow" implements OPP-001 + +# Spec depends on a policy +dg new spec "Lama milk checkout flow" depends_on POL-001 +``` + +## Status Lifecycle + +- `draft` — initial capture, scenarios being written +- `review` — ready for stakeholder review +- `approved` — signed off, ready for implementation +- `implemented` — behavior verified in code +- `deprecated` — no longer relevant + +## Tips + +- Link specs to OPPs with `implements:` to show which opportunity a spec realizes +- Link specs to POLs with `depends_on:` when behavior must comply with a policy +- Each scenario should test one behavior — keep them focused +- Use Background blocks for shared Given steps +- Add Acceptance Criteria section for non-Gherkin conditions (performance, accessibility) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..bf9ec1a --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,44 @@ +--- +name: check + +"on": + pull_request: + workflow_dispatch: + +permissions: + id-token: write + contents: write + +# this allows a subsequently queued workflow run to interrupt previous runs in pull requests only +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} + +jobs: + check: + runs-on: ubuntu-latest + timeout-minutes: 25 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install mise + uses: taiki-e/install-action@v2 + with: + tool: mise + + - name: Install mise tools + run: | + mise settings add idiomatic_version_file_enable_tools "[]" + mise settings experimental=true + mise settings set cargo.binstall true + mise use -g cargo-binstall + mise install + env: + GITHUB_TOKEN: ${{ github.token }} + + - name: Run checkers + run: | + mise run check diff --git a/.gitignore b/.gitignore index e43b0f9..c6fedbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .DS_Store +.dg/ +.dg.lock diff --git a/.index.json b/.index.json new file mode 100644 index 0000000..52e6c45 --- /dev/null +++ b/.index.json @@ -0,0 +1,20 @@ +{ + "generated": "2026-04-24T15:28:52.230955+08:00", + "records": [ + { + "id": "ADR-001", + "title": "Require architectural decision records", + "type": "ADR", + "status": "proposed", + "tags": [ + "architecture" + ], + "links": [], + "path": "docs/architecture/ADR-001-decisions.md" + } + ], + "stats": { + "total": 1, + "edges": 0 + } +} diff --git a/.mise.toml b/.mise.toml index 46c2451..41085c1 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,20 +1,39 @@ [tools] "cargo:cargo-spellcheck" = "latest" "cargo:topgrade" = "latest" +dprint = "latest" editorconfig-checker = "latest" +"github:decisiongraph/dg" = "latest" harper-cli = "latest" -ollama = "latest" rust = "latest" typos = "latest" -[tasks.typos] -run = "typos" +[tasks] +ec = "ec" +editorconfig-check = "ec" +typos = "typos" + +[tasks.check] +depends = ["ec", "cargo-spellcheck", "dg-check", "dprint-check", "harper", "typos"] [tasks.cargo-spellcheck] -run = "cargo spellcheck check" +run = "cargo spellcheck check README.md docs/" + +[tasks.dprint-check] +run = "dprint check" + +[tasks.dprint-check.env] +DPRINT_CACHE_DIR = "/tmp/dprint-cache" + +[tasks.dprint-fmt] +run = "dprint fmt" [tasks.harper] -run = "harper-cli lint --user-dict-path .config/lingo.dic --dialect au --ignore OrthographicConsistency,UnclosedQuotes,UseTitleCase *.md ADR/R1/*.md" +run = """ +harper-cli lint --user-dict-path .config/lingo.dic --dialect au \ + --ignore OrthographicConsistency,UnclosedQuotes,UseTitleCase \ + README.md docs/architecture/*.md +""" -[tasks.check] -depends = ["typos", "cargo-spellcheck", "harper"] +[tasks.dg-check] +run = "dg validate --pattern 'docs/architecture/*.md'" diff --git a/.templates/adr.md b/.templates/adr.md new file mode 100644 index 0000000..3e1a309 --- /dev/null +++ b/.templates/adr.md @@ -0,0 +1,85 @@ +--- +id: ADR-{{NUMBER}} +status: proposed +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [architecture] +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + +## Context + + + +## Decision + + + +## Consequences + +### Positive + + + +- + +### Negative + + + +- + +### Neutral + + + +- + +## Alternatives Considered + +### Alternative 1: {{NAME}} + +**Description:** + +**Pros:** +- + +**Cons:** +- + +**Why not chosen:** + +### Alternative 2: {{NAME}} + +**Description:** + +**Pros:** +- + +**Cons:** +- + +**Why not chosen:** + +## References + + + +- + +## Notes + + + +- diff --git a/.templates/customer.md b/.templates/customer.md new file mode 100644 index 0000000..86f79c1 --- /dev/null +++ b/.templates/customer.md @@ -0,0 +1,68 @@ +--- +id: CUS-{{NUMBER}} +status: active +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + + + +## Overview + + +## Architecture Impact + +### Required Customizations + + +| Customization | Architectural Impact | ADR Reference | +|--------------|---------------------|---------------| +| | | | + +### Technical Constraints + + +- + +### Compliance Requirements + + +- + +## Integration Requirements + +### APIs & Data Flows + + +- + +### Performance Requirements + + +- + +## Decisions Made + + + +| Decision | Status | Link | +|----------|--------|------| +| | | | diff --git a/.templates/decision.md b/.templates/decision.md new file mode 100644 index 0000000..9ac3fbf --- /dev/null +++ b/.templates/decision.md @@ -0,0 +1,71 @@ +--- +id: DEC-{{NUMBER}} +status: proposed +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + +## Setting + + +## People + +- **Responsible**: +- **Approvers**: +- **Consulted**: +- **Informed**: + +## Alternatives + + +### Option A: {{NAME}} +**Pros:** +- + +**Cons:** +- + +### Option B: {{NAME}} +**Pros:** +- + +**Cons:** +- + +### Option C: {{NAME}} +**Pros:** +- + +**Cons:** +- + +## Decision + + +Chosen: **Option X** + +Rationale: + +## Consequences + +### Positive +- + +### Negative +- + +### Follow-up Actions +- [ ] diff --git a/.templates/hiring.md b/.templates/hiring.md new file mode 100644 index 0000000..338d338 --- /dev/null +++ b/.templates/hiring.md @@ -0,0 +1,74 @@ +--- +id: HIR-{{NUMBER}} +status: draft +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +hiring_meta: + department: null + level: null + location: null + reports_to: null +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + + + +## Mission + + +## Outcomes + + +1. **Outcome**: + **Measure**: + +2. **Outcome**: + **Measure**: + +3. **Outcome**: + **Measure**: + +## Required Competencies + +| Competency | Description | +|------------|-------------| +| | | + +## Technical Requirements + +### Must Have +- + +### Nice to Have +- + +## Interview Focus Areas + +| Stage | Focus | +|-------|-------| +| Screen | Culture fit, basics | +| Technical | Technical competencies | +| Hiring Manager | Outcomes, motivation | +| Team | Collaboration | + +## Evaluation Criteria + +| Criteria | What "Good" Looks Like | +|----------|------------------------| +| | | diff --git a/.templates/incident.md b/.templates/incident.md new file mode 100644 index 0000000..af7f483 --- /dev/null +++ b/.templates/incident.md @@ -0,0 +1,81 @@ +--- +id: INC-{{NUMBER}} +status: open +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +incident_meta: + severity: sev1|sev2|sev3|sev4 + started: null + detected: null + resolved: null + duration_minutes: null +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + + + +## Summary + + +## Timeline + +| Time | Event | +|------|-------| +| | Incident started | +| | Incident detected | +| | Response began | +| | Mitigated | +| | Resolved | + +## Impact + +- **Users affected**: +- **Duration**: +- **Revenue impact**: +- **Data loss**: + +## Root Cause + + + +## Contributing Factors + +- + +## What Went Well + +- + +## What Went Poorly + +- + +## Action Items + +| Action | Owner | Due Date | Status | +|--------|-------|----------|--------| +| | | | | + +## Lessons Learned + +- + +## Detection + + + +## Prevention + + diff --git a/.templates/legal.md b/.templates/legal.md new file mode 100644 index 0000000..3dd925d --- /dev/null +++ b/.templates/legal.md @@ -0,0 +1,45 @@ +--- +id: LEG-{{NUMBER}} +status: draft +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +legal_meta: + legal_type: privacy # privacy | tos | agreement | charter | other + version: "1.0" + effective_date: null + parties: [] + jurisdiction: [] +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + +## Document Info + +| Version | Effective | Status | +|---------|-----------|--------| +| 1.0 | TBD | Draft | + +## Purpose + + +## Scope + + +## Content + + +## Related Records + + +- diff --git a/.templates/meeting.md b/.templates/meeting.md new file mode 100644 index 0000000..d1f68b8 --- /dev/null +++ b/.templates/meeting.md @@ -0,0 +1,69 @@ +--- +id: MTG-{{NUMBER}} +status: draft +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +meeting_meta: + date: {{DATE}} + attendees: [] + duration_minutes: null +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + +## Attendees + +- + +## Agenda + +1. +2. +3. + +## Discussion + +### Topic 1 + +**Summary:** + +**Key points:** +- + +### Topic 2 + +**Summary:** + +**Key points:** +- + +## Decisions Made + +| Decision | Owner | +|----------|-------| +| | | + +## Action Items + +| Action | Owner | Due | +|--------|-------|-----| +| | | | + +## Next Steps + +- + +## Follow-up Meeting + + diff --git a/.templates/opportunity.md b/.templates/opportunity.md new file mode 100644 index 0000000..223da31 --- /dev/null +++ b/.templates/opportunity.md @@ -0,0 +1,89 @@ +--- +id: OPP-{{NUMBER}} +status: proposed +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +opportunity_meta: + outcome_metric: null + target_value: null + confidence: low + effort: medium +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + + + +## Outcome + + +**Target Metric**: +**Current Value**: +**Target Value**: +**Timeline**: + +## Opportunity + + +### Problem Statement + +### Evidence + + +- **User Research**: +- **Data**: +- **Customer Feedback**: + +### Affected Segments + + +## Solutions + + +### Solution A: {{NAME}} + +**Description**: + +**Validation Status**: untested | assumption | validated + +**Expected Impact**: + +### Solution B: {{NAME}} + +**Description**: + +**Validation Status**: untested | assumption | validated + +**Expected Impact**: + +## Experiments + + +| Experiment | Hypothesis | Result | Learning | +|------------|-----------|--------|----------| +| | | | | + +## Decision + + +**Chosen Solution**: + +**Rationale**: + +## Success Metrics + + +| Metric | Baseline | Target | Actual | +|--------|----------|--------|--------| +| | | | | diff --git a/.templates/policy.md b/.templates/policy.md new file mode 100644 index 0000000..0dae608 --- /dev/null +++ b/.templates/policy.md @@ -0,0 +1,78 @@ +--- +id: POL-{{NUMBER}} +status: proposed +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +effective_date: {{DATE}} +review_date: null +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + +## Purpose + + +## Scope + + +- **Applies to**: +- **Does not apply to**: + +## Background + + +## Policy Statement + + +### Requirements + +1. +2. +3. + +### Prohibited Actions + +1. +2. + +### Exceptions + + +## Implementation + +### Responsibilities + +| Role | Responsibility | +|------|---------------| +| | | + +### Procedures + + +1. +2. +3. + +## Compliance + +### Monitoring + + +### Consequences + + +## References + + +- diff --git a/.templates/process.md b/.templates/process.md new file mode 100644 index 0000000..f8b253f --- /dev/null +++ b/.templates/process.md @@ -0,0 +1,94 @@ +--- +id: PRC-{{NUMBER}} +status: proposed +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +process_meta: + frequency: as-needed + duration: null + last_review: null +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + + + +## Purpose + + +## DACI + +- **Driver**: +- **Approver**: +- **Contributors**: +- **Informed**: + +## Trigger + + +## Inputs + + +- + +## Process Steps + +### Step 1: {{NAME}} +**Owner**: +**Duration**: + +**Actions**: +1. +2. + +**Output**: + +### Step 2: {{NAME}} +**Owner**: +**Duration**: + +**Actions**: +1. +2. + +**Output**: + +## Outputs + + +- + +## Quality Checks + + +- [ ] + +## Exceptions + + +| Scenario | Action | Escalation | +|----------|--------|------------| +| | | | + +## Tools & Systems + + +- + +## Metrics + + +| Metric | Target | Current | +|--------|--------|---------| +| | | | diff --git a/.templates/runbook.md b/.templates/runbook.md new file mode 100644 index 0000000..40fb207 --- /dev/null +++ b/.templates/runbook.md @@ -0,0 +1,79 @@ +--- +id: RUN-{{NUMBER}} +status: accepted +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +runbook_meta: + last_verified: null + estimated_duration: null +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + + + +## Purpose + + +## Prerequisites + +- [ ] + +## Steps + +### 1. {{STEP_NAME}} + +```bash +# Commands or actions +``` + +**Expected outcome:** + +### 2. {{STEP_NAME}} + +```bash +# Commands or actions +``` + +**Expected outcome:** + +### 3. {{STEP_NAME}} + +```bash +# Commands or actions +``` + +**Expected outcome:** + +## Verification + + + +- [ ] + +## Rollback + + + +## Troubleshooting + +| Problem | Solution | +|---------|----------| +| | | + +## Related + + + +- diff --git a/.templates/strategy.md b/.templates/strategy.md new file mode 100644 index 0000000..1467b30 --- /dev/null +++ b/.templates/strategy.md @@ -0,0 +1,81 @@ +--- +id: STR-{{NUMBER}} +status: proposed +created: {{DATE}} +updated: {{DATE}} +authors: [] +tags: [] +links: + supersedes: [] + superseded_by: [] + depends_on: [] + enables: [] + relates_to: [] + conflicts_with: [] + refines: [] + implements: [] +--- + +# {{TITLE}} + + + +## Introduction + + +## Goals + + +1. +2. +3. + +## Tenets + + +1. +2. +3. + +## State of the Business + + +### Current Metrics + +### Market Context + +### Competitive Position + +## Strategic Priorities + + +### Priority 1: + +### Priority 2: + +### Priority 3: + +## Resource Requirements + + +- **People**: +- **Budget**: +- **Timeline**: +- **Dependencies**: + +## Risks and Mitigations + +| Risk | Likelihood | Impact | Mitigation | +|------|------------|--------|------------| +| | | | | + +## FAQ + + +**Q: ?** +A: + +## Success Criteria + + +- [ ] diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..a59996b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,150 @@ +# Decision Graph + +This project uses `dg` to maintain a knowledge graph of decisions, architecture, policies, and operational knowledge. + +## Before You Act + +**CRITICAL**: For vague requests, you MUST ask clarifying questions and WAIT for answers BEFORE creating documents. + +**For incidents**: When a user reports a production issue, outage, or incident, first ask: "Shall I create an incident report?" Then gather brief timeline/impact facts and create the INC document. Don't ask extensive questions — incidents need quick documentation. + +### Questioning Philosophy + +Your goal is to gather enough information to create **complete documents with no TBD/FIXME markers**. + +**ALWAYS use the `AskUserQuestion` tool** (Claude Code) or `ask_user` tool (Gemini/OpenCode) — never dump questions as plain text. This gives the user a proper interactive experience instead of a wall of text. + +- Ask **3-5 questions per batch** — not all at once +- Wait for answers before asking the next batch +- Run **2-3 rounds** of questions to reach full clarity +- Never guess or assume — always ask +- Keep asking until: + - User says "I don't know" or similar + - User explicitly asks you to proceed without the info +- Only use TBD/FIXME when the user cannot or won't answer a question + +### Workflow + +1. Run `dg list` to check existing context +2. Use `AskUserQuestion`/`ask_user` with 3-5 questions — **wait** for answers +3. If answers reveal new unknowns, ask a follow-up batch +4. Plan which documents to create and how to cross-link them +5. **Only when fully informed**: Create documents with `dg new` + +### What to Ask About + +For any request, ensure you understand: + +- **Problem**: What problem are we solving? Why now? +- **Audience**: Who is affected? Who decides? +- **Constraints**: Budget, timeline, technical limitations? +- **Success criteria**: How do we know it worked? +- **Alternatives**: What options exist? What was rejected? +- **Dependencies**: What does this block or depend on? + +Run `dg guide` for detailed workflow guidance. + +## Creating & Updating Records + +```bash +# Create — pass --field=value to set fields at creation (avoids separate dg set calls) +dg new opp "Problem-focused title" # Business opportunity +dg new adr "Decision title" --status=accepted # Set fields inline +dg new pol "Policy name" # Policy/constraint +dg new inc "Incident summary" # Incident report +dg new spec "Spec title" # Behavioral specification + +# Read +dg list [--type adr] [--status active] # List documents +dg list --json --no-untyped # JSON output, typed docs only +dg list --group-by type # Group by type, sorted by date +dg show OPP-001 # Display document +dg show OPP-001 --json # JSON output +dg refs OPP-001 # Outgoing references +dg refs OPP-001 --backlinks # Incoming references + +# Update — combine multiple assignments in one call +dg set OPP-001 status=completed date=2025-01-01 # Set multiple fields at once +dg set OPP-001 tags+=backend # Append to array field +dg set OPP-001 --remove tags # Remove field +dg set OPP-001 --section Decision --content "New text" # Replace section +dg set OPP-001 --section Decision --append "Extra note" # Append to section + +# Validate & lint +dg validate # Schema validation +dg lint # Validate + graph health checks +dg suggest # Advisory improvement suggestions + +# Team management (org.kdl) +dg team add-team vendors --kind=external # External team (contractors, vendors) +dg team add-user ext-dev --kind=external --teams=vendors +dg team add-user jane --name="Jane" --teams=engineering # Internal (default) +dg team depart-user former-dev # Mark user as departed +dg team list # Show orgs, teams, users + +# Maintenance +dg fmt # Auto-format documents +dg renumber # Reorder document IDs chronologically +``` + +Always use `dg new` and `dg set` — never create or edit markdown files manually. + +## Field Assignment Rules + +- `key=value` — set/replace a field. Use for all scalar fields and single-ref relations +- `key+=value` — append to array. Use ONLY for array fields + +| Scalar (use `=`) | Array (use `+=`) | +| -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | +| status, title, date, author, supersedes, superseded_by, enabled_by, triggered_by | tags, implements, depends_on, related, conflicts_with, responders, code_paths | + +Wrong: `dg set ADR-001 superseded_by+=ADR-010` (creates array `[ADR-010]`) +Right: `dg set ADR-001 superseded_by=ADR-010` (sets scalar) + +## Editing Complex Content + +For simple updates: `dg set DOC --section "Title" --content "text"` + +For multi-line content, tables, or content with special characters (dashes, pipes, backticks): + +1. Get file path: `dg show DOC-ID --json` → check `"path"` field +2. Edit the markdown file directly with your file editing tools +3. Run `dg validate` to verify the result + +This avoids all shell escaping issues. + +## Table Editing + +- Append row: `dg set DOC --section Timeline --add-row "10:30,Restored,@ops"` +- Insert/update rows: edit the markdown file directly, then `dg validate` +- **Date columns**: use `YYYY-MM-DD` format. Leave cell empty if date unknown — do NOT write "TBD" +- **Actor columns**: use `@handle` for known actors. Leave cell empty for system/automated events + +## Cloning a Document + +To create a new doc based on an existing one: + +1. `dg show SOURCE-ID --json` — read fields and structure +2. `dg new TYPE "New Title" --field1=value1 --field2=value2` — create with same fields +3. Copy relevant sections from source file into new file +4. `dg validate` + +## Quality Standards + +- **No TBD/FIXME**: If you don't know something, ask — don't mark it TBD +- **Problem-focused titles**: Describe the problem, not the solution +- **Cross-link documents**: Use frontmatter refs — pick the most specific relation: + - **Single-ref relations** (use `=`): `supersedes`, `superseded_by`, `enables`, `enabled_by`, `triggers`, `triggered_by` + - **Multi-ref relations** (use `+=`): `implements`, `depends_on`, `related`, `conflicts_with` +- **Add your name to authors list** + +## Fixing Incomplete Documents + +If you've created a document with TBD/FIXME markers, don't leave it incomplete: + +1. **Identify gaps**: Review the document for any TBD, FIXME, TODO, or `[TBD]` markers +2. **Ask follow-up questions**: Get the missing information from the user +3. **Update the document**: Replace markers with concrete details once you have answers +4. **Verify completeness**: Re-read the document to ensure no gaps remain + +**When TBD/FIXME is acceptable**: Only leave placeholders if the user explicitly says they don't know or asks you to proceed without the information. In all other cases, keep asking. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..58705db --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,150 @@ +# Decision Graph + +This project uses `dg` to maintain a knowledge graph of decisions, architecture, policies, and operational knowledge. + +## Before You Act + +**CRITICAL**: For vague requests, you MUST ask clarifying questions and WAIT for answers BEFORE creating documents. + +**For incidents**: When a user reports a production issue, outage, or incident, first ask: "Shall I create an incident report?" Then gather brief timeline/impact facts and create the INC document. Don't ask extensive questions — incidents need quick documentation. + +### Questioning Philosophy + +Your goal is to gather enough information to create **complete documents with no TBD/FIXME markers**. + +**ALWAYS use the `AskUserQuestion` tool** — never dump questions as plain text. This gives the user a proper interactive experience instead of a wall of text. + +- Ask **3-5 questions per batch** using `AskUserQuestion` — not all at once +- Wait for answers before asking the next batch +- Run **2-3 rounds** of questions to reach full clarity +- Never guess or assume — always ask +- Keep asking until: + - User says "I don't know" or similar + - User explicitly asks you to proceed without the info +- Only use TBD/FIXME when the user cannot or won't answer a question + +### Workflow + +1. Run `dg list` to check existing context +2. Use `AskUserQuestion` with 3-5 questions — **wait** for answers +3. If answers reveal new unknowns, ask a follow-up batch with `AskUserQuestion` +4. Use `EnterPlanMode` to plan which documents to create and how to cross-link them +5. **Only when fully informed**: Create documents with `dg new` + +### What to Ask About + +For any request, ensure you understand: + +- **Problem**: What problem are we solving? Why now? +- **Audience**: Who is affected? Who decides? +- **Constraints**: Budget, timeline, technical limitations? +- **Success criteria**: How do we know it worked? +- **Alternatives**: What options exist? What was rejected? +- **Dependencies**: What does this block or depend on? + +Run `dg guide` for detailed workflow guidance. + +## Creating & Updating Records + +```bash +# Create — pass --field=value to set fields at creation (avoids separate dg set calls) +dg new opp "Problem-focused title" # Business opportunity +dg new adr "Decision title" --status=accepted # Set fields inline +dg new pol "Policy name" # Policy/constraint +dg new inc "Incident summary" # Incident report +dg new spec "Spec title" # Behavioral specification + +# Read +dg list [--type adr] [--status active] # List documents +dg list --json --no-untyped # JSON output, typed docs only +dg list --group-by type # Group by type, sorted by date +dg show OPP-001 # Display document +dg show OPP-001 --json # JSON output +dg refs OPP-001 # Outgoing references +dg refs OPP-001 --backlinks # Incoming references + +# Update — combine multiple assignments in one call +dg set OPP-001 status=completed date=2025-01-01 # Set multiple fields at once +dg set OPP-001 tags+=backend # Append to array field +dg set OPP-001 --remove tags # Remove field +dg set OPP-001 --section Decision --content "New text" # Replace section +dg set OPP-001 --section Decision --append "Extra note" # Append to section + +# Validate & lint +dg validate # Schema validation +dg lint # Validate + graph health checks +dg suggest # Advisory improvement suggestions + +# Team management (org.kdl) +dg team add-team vendors --kind=external # External team (contractors, vendors) +dg team add-user ext-dev --kind=external --teams=vendors +dg team add-user jane --name="Jane" --teams=engineering # Internal (default) +dg team depart-user former-dev # Mark user as departed +dg team list # Show orgs, teams, users + +# Maintenance +dg fmt # Auto-format documents +dg renumber # Reorder document IDs chronologically +``` + +Always use `dg new` and `dg set` — never create or edit markdown files manually. + +## Field Assignment Rules + +- `key=value` — set/replace a field. Use for all scalar fields and single-ref relations +- `key+=value` — append to array. Use ONLY for array fields + +| Scalar (use `=`) | Array (use `+=`) | +| -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | +| status, title, date, author, supersedes, superseded_by, enabled_by, triggered_by | tags, implements, depends_on, related, conflicts_with, responders, code_paths | + +Wrong: `dg set ADR-001 superseded_by+=ADR-010` (creates array `[ADR-010]`) +Right: `dg set ADR-001 superseded_by=ADR-010` (sets scalar) + +## Editing Complex Content + +For simple updates: `dg set DOC --section "Title" --content "text"` + +For multi-line content, tables, or content with special characters (dashes, pipes, backticks): + +1. Get file path: `dg show DOC-ID --json` → check `"path"` field +2. Edit the markdown file directly with your file editing tools +3. Run `dg validate` to verify the result + +This avoids all shell escaping issues. + +## Table Editing + +- Append row: `dg set DOC --section Timeline --add-row "10:30,Restored,@ops"` +- Insert/update rows: edit the markdown file directly, then `dg validate` +- **Date columns**: use `YYYY-MM-DD` format. Leave cell empty if date unknown — do NOT write "TBD" +- **Actor columns**: use `@handle` for known actors. Leave cell empty for system/automated events + +## Cloning a Document + +To create a new doc based on an existing one: + +1. `dg show SOURCE-ID --json` — read fields and structure +2. `dg new TYPE "New Title" --field1=value1 --field2=value2` — create with same fields +3. Copy relevant sections from source file into new file +4. `dg validate` + +## Quality Standards + +- **No TBD/FIXME**: If you don't know something, ask — don't mark it TBD +- **Problem-focused titles**: Describe the problem, not the solution +- **Cross-link documents**: Use frontmatter refs — pick the most specific relation: + - **Single-ref relations** (use `=`): `supersedes`, `superseded_by`, `enables`, `enabled_by`, `triggers`, `triggered_by` + - **Multi-ref relations** (use `+=`): `implements`, `depends_on`, `related`, `conflicts_with` +- **Add `claude` to authors list** + +## Fixing Incomplete Documents + +If you've created a document with TBD/FIXME markers, don't leave it incomplete: + +1. **Identify gaps**: Review the document for any TBD, FIXME, TODO, or `[TBD]` markers +2. **Ask follow-up questions**: Get the missing information from the user +3. **Update the document**: Replace markers with concrete details once you have answers +4. **Verify completeness**: Re-read the document to ensure no gaps remain + +**When TBD/FIXME is acceptable**: Only leave placeholders if the user explicitly says they don't know or asks you to proceed without the information. In all other cases, keep asking. diff --git a/README.md b/README.md index 6b178ff..14f583a 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,10 @@ This repository uses [`mise`](https://mise.jdx.dev/) for tool management and task definition. -After installing `mise`, run `mise run check` to check the repository contents. +After installing `mise`, run `mise run check` to check the repository contents.Decision Graph -It currently exits with an error due to a bug in `harper-cli`. +This repository uses [decision graph](https://decisiongraph.dev/) CLI to assist manage +the documents here. ## Spelling and grammar diff --git a/dg.toml b/dg.toml new file mode 100644 index 0000000..ee2665a --- /dev/null +++ b/dg.toml @@ -0,0 +1,51 @@ +record_types = [] + +[site] +title = "Decision Graph" +description = "Company decisions and knowledge graph" +primary_color = "#0f3460" +accent_color = "#e94560" +quick_preview = true +github_avatars = true + +[authors] + +[users.pierre-tenedero] +name = "Pierre Tenedero" +github = "pierre-tenedero" + +[users.claude] +name = "Claude" +email = "claude@anthropic.com" +teams = ["llms"] +roles = [ + "llm", + "assistant", +] + +[users.michaeljfazio] +name = "Michael J. Fazio" +github = "michaeljfazio" + +[users.jamesbychance] +name = "James Eggleston" +github = "jamesbychance" + +[users.jayvdb] +name = "John Vandenberg" +github = "jayvdb" +email = "jayvdb@gmail.com" + +[users.Zoybean] +name = "Zoey Hewll" +github = "Zoybean" + +[teams.llms] +name = "AI Assistants" +description = "LLM-powered assistants" + +[teams.core] +name = "edge-toolkit Core Team" +description = "Core team members" + +[validation] diff --git a/ADR/R1/0001-decisions.md b/docs/architecture/adr-001-decisions.md similarity index 77% rename from ADR/R1/0001-decisions.md rename to docs/architecture/adr-001-decisions.md index 7322789..6da9af5 100644 --- a/ADR/R1/0001-decisions.md +++ b/docs/architecture/adr-001-decisions.md @@ -1,11 +1,18 @@ -# ADR-0001: Require architectural decision records for all development +--- +id: ADR-001 +status: proposed +date: 2026-03-18 +updated: 2026-04-24 +author: jayvdb +tags: [architecture] +--- -## Status - -Proposed +# Require architectural decision records ## Context + + The Curtin project requires a systematic approach to documenting architectural and significant technical decisions. Without a formal decision-making framework, knowledge about why certain architectural choices were made is lost over time, making it difficult for current and future team members to understand the rationale behind the system's design. @@ -18,6 +25,8 @@ reducing legal and licensing risks. ## Decision + + We will require that all significant architectural decisions, system design choices, and technical direction changes be documented using Architectural Decision Records (ADRs). @@ -27,6 +36,8 @@ An ADR is a short text document that captures a single architectural decision in ### Positive + + - **Knowledge Preservation**: Decision rationale is preserved for future reference and context - **Communication**: Ensures all stakeholders understand the reasoning behind major decisions - **Consistency**: Establishes a uniform approach to decision-making across the project @@ -39,11 +50,41 @@ An ADR is a short text document that captures a single architectural decision in ### Negative + + - **Overhead**: Requires commitment to documenting decisions in addition to implementation - **Time Investment**: Initial setup and learning curve for the ADR format and process - **Maintenance**: Deprecated decisions must be marked as superseded to prevent confusion -## Implementation Notes +### Neutral + + + +## Alternatives Considered + + + +## References + + + +## Notes + + + +### Implementation Notes - Each ADR will be numbered sequentially starting from 0001, with a short name given to each. - ADRs should follow the standard template with Status, Context, Decision, Author, and Date. @@ -55,11 +96,3 @@ An ADR is a short text document that captures a single architectural decision in - Decisions involving private or sensitive information should not be included in public ADRs. - Public ADRs should define public interfaces and contracts that enable private components to be constructed in separate private repositories. - -## Author - -John Vandenberg - -## Date - -18 March 2026 diff --git a/ADR/R1/0002-open-source.md b/docs/architecture/adr-002-initial-open-source-repositories.md similarity index 98% rename from ADR/R1/0002-open-source.md rename to docs/architecture/adr-002-initial-open-source-repositories.md index bcaee2e..64a590f 100644 --- a/ADR/R1/0002-open-source.md +++ b/docs/architecture/adr-002-initial-open-source-repositories.md @@ -1,8 +1,14 @@ -# ADR-0002: Initial Open Source Repositories +--- +author: "jayvdb" +code_paths: [] +date: 2026-03-18 +status: proposed +tags: [] +--- -## Status +# Initial Open Source Repositories -Proposed + ## Context @@ -190,11 +196,3 @@ The open source repository is at . fred & Agilab are both written in Python language, whereas this project requires compiled languages be used for the core components. - -## Author - -John Vandenberg - -## Date - -18 March 2026 diff --git a/dprint.json b/dprint.json new file mode 100644 index 0000000..42be3dc --- /dev/null +++ b/dprint.json @@ -0,0 +1,22 @@ +{ + "json": { + }, + "markdown": { + }, + "toml": { + }, + "markup": { + }, + "yaml": { + }, + "excludes": [ + ".templates/**" + ], + "plugins": [ + "https://plugins.dprint.dev/json-0.21.3.wasm", + "https://plugins.dprint.dev/markdown-0.21.1.wasm", + "https://plugins.dprint.dev/toml-0.7.0.wasm", + "https://plugins.dprint.dev/g-plane/markup_fmt-v0.27.0.wasm", + "https://plugins.dprint.dev/g-plane/pretty_yaml-v0.6.0.wasm" + ] +} From 607423e651f1364b4fec4c9a64c739ce004b4fcb Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Mon, 27 Apr 2026 14:52:46 +0800 Subject: [PATCH 2/8] disable cargo-binstall --- .github/workflows/check.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index bf9ec1a..69cbdf8 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -33,8 +33,6 @@ jobs: run: | mise settings add idiomatic_version_file_enable_tools "[]" mise settings experimental=true - mise settings set cargo.binstall true - mise use -g cargo-binstall mise install env: GITHUB_TOKEN: ${{ github.token }} From 9035027d775f42a36231beb021b242f93198fcc1 Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Mon, 27 Apr 2026 14:59:28 +0800 Subject: [PATCH 3/8] Install clang --- .mise.toml | 1 + .templates/adr.md | 85 ----------------------------------- .templates/customer.md | 68 ---------------------------- .templates/decision.md | 71 ----------------------------- .templates/hiring.md | 74 ------------------------------ .templates/incident.md | 81 --------------------------------- .templates/legal.md | 45 ------------------- .templates/meeting.md | 69 ---------------------------- .templates/opportunity.md | 89 ------------------------------------ .templates/policy.md | 78 -------------------------------- .templates/process.md | 94 --------------------------------------- .templates/runbook.md | 79 -------------------------------- .templates/strategy.md | 81 --------------------------------- 13 files changed, 1 insertion(+), 914 deletions(-) delete mode 100644 .templates/adr.md delete mode 100644 .templates/customer.md delete mode 100644 .templates/decision.md delete mode 100644 .templates/hiring.md delete mode 100644 .templates/incident.md delete mode 100644 .templates/legal.md delete mode 100644 .templates/meeting.md delete mode 100644 .templates/opportunity.md delete mode 100644 .templates/policy.md delete mode 100644 .templates/process.md delete mode 100644 .templates/runbook.md delete mode 100644 .templates/strategy.md diff --git a/.mise.toml b/.mise.toml index 41085c1..83057f7 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,6 +1,7 @@ [tools] "cargo:cargo-spellcheck" = "latest" "cargo:topgrade" = "latest" +clang = "latest" dprint = "latest" editorconfig-checker = "latest" "github:decisiongraph/dg" = "latest" diff --git a/.templates/adr.md b/.templates/adr.md deleted file mode 100644 index 3e1a309..0000000 --- a/.templates/adr.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -id: ADR-{{NUMBER}} -status: proposed -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [architecture] -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - -## Context - - - -## Decision - - - -## Consequences - -### Positive - - - -- - -### Negative - - - -- - -### Neutral - - - -- - -## Alternatives Considered - -### Alternative 1: {{NAME}} - -**Description:** - -**Pros:** -- - -**Cons:** -- - -**Why not chosen:** - -### Alternative 2: {{NAME}} - -**Description:** - -**Pros:** -- - -**Cons:** -- - -**Why not chosen:** - -## References - - - -- - -## Notes - - - -- diff --git a/.templates/customer.md b/.templates/customer.md deleted file mode 100644 index 86f79c1..0000000 --- a/.templates/customer.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -id: CUS-{{NUMBER}} -status: active -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - - - -## Overview - - -## Architecture Impact - -### Required Customizations - - -| Customization | Architectural Impact | ADR Reference | -|--------------|---------------------|---------------| -| | | | - -### Technical Constraints - - -- - -### Compliance Requirements - - -- - -## Integration Requirements - -### APIs & Data Flows - - -- - -### Performance Requirements - - -- - -## Decisions Made - - - -| Decision | Status | Link | -|----------|--------|------| -| | | | diff --git a/.templates/decision.md b/.templates/decision.md deleted file mode 100644 index 9ac3fbf..0000000 --- a/.templates/decision.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: DEC-{{NUMBER}} -status: proposed -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - -## Setting - - -## People - -- **Responsible**: -- **Approvers**: -- **Consulted**: -- **Informed**: - -## Alternatives - - -### Option A: {{NAME}} -**Pros:** -- - -**Cons:** -- - -### Option B: {{NAME}} -**Pros:** -- - -**Cons:** -- - -### Option C: {{NAME}} -**Pros:** -- - -**Cons:** -- - -## Decision - - -Chosen: **Option X** - -Rationale: - -## Consequences - -### Positive -- - -### Negative -- - -### Follow-up Actions -- [ ] diff --git a/.templates/hiring.md b/.templates/hiring.md deleted file mode 100644 index 338d338..0000000 --- a/.templates/hiring.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -id: HIR-{{NUMBER}} -status: draft -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -hiring_meta: - department: null - level: null - location: null - reports_to: null -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - - - -## Mission - - -## Outcomes - - -1. **Outcome**: - **Measure**: - -2. **Outcome**: - **Measure**: - -3. **Outcome**: - **Measure**: - -## Required Competencies - -| Competency | Description | -|------------|-------------| -| | | - -## Technical Requirements - -### Must Have -- - -### Nice to Have -- - -## Interview Focus Areas - -| Stage | Focus | -|-------|-------| -| Screen | Culture fit, basics | -| Technical | Technical competencies | -| Hiring Manager | Outcomes, motivation | -| Team | Collaboration | - -## Evaluation Criteria - -| Criteria | What "Good" Looks Like | -|----------|------------------------| -| | | diff --git a/.templates/incident.md b/.templates/incident.md deleted file mode 100644 index af7f483..0000000 --- a/.templates/incident.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -id: INC-{{NUMBER}} -status: open -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -incident_meta: - severity: sev1|sev2|sev3|sev4 - started: null - detected: null - resolved: null - duration_minutes: null -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - - - -## Summary - - -## Timeline - -| Time | Event | -|------|-------| -| | Incident started | -| | Incident detected | -| | Response began | -| | Mitigated | -| | Resolved | - -## Impact - -- **Users affected**: -- **Duration**: -- **Revenue impact**: -- **Data loss**: - -## Root Cause - - - -## Contributing Factors - -- - -## What Went Well - -- - -## What Went Poorly - -- - -## Action Items - -| Action | Owner | Due Date | Status | -|--------|-------|----------|--------| -| | | | | - -## Lessons Learned - -- - -## Detection - - - -## Prevention - - diff --git a/.templates/legal.md b/.templates/legal.md deleted file mode 100644 index 3dd925d..0000000 --- a/.templates/legal.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -id: LEG-{{NUMBER}} -status: draft -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -legal_meta: - legal_type: privacy # privacy | tos | agreement | charter | other - version: "1.0" - effective_date: null - parties: [] - jurisdiction: [] -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - -## Document Info - -| Version | Effective | Status | -|---------|-----------|--------| -| 1.0 | TBD | Draft | - -## Purpose - - -## Scope - - -## Content - - -## Related Records - - -- diff --git a/.templates/meeting.md b/.templates/meeting.md deleted file mode 100644 index d1f68b8..0000000 --- a/.templates/meeting.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -id: MTG-{{NUMBER}} -status: draft -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -meeting_meta: - date: {{DATE}} - attendees: [] - duration_minutes: null -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - -## Attendees - -- - -## Agenda - -1. -2. -3. - -## Discussion - -### Topic 1 - -**Summary:** - -**Key points:** -- - -### Topic 2 - -**Summary:** - -**Key points:** -- - -## Decisions Made - -| Decision | Owner | -|----------|-------| -| | | - -## Action Items - -| Action | Owner | Due | -|--------|-------|-----| -| | | | - -## Next Steps - -- - -## Follow-up Meeting - - diff --git a/.templates/opportunity.md b/.templates/opportunity.md deleted file mode 100644 index 223da31..0000000 --- a/.templates/opportunity.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: OPP-{{NUMBER}} -status: proposed -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -opportunity_meta: - outcome_metric: null - target_value: null - confidence: low - effort: medium -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - - - -## Outcome - - -**Target Metric**: -**Current Value**: -**Target Value**: -**Timeline**: - -## Opportunity - - -### Problem Statement - -### Evidence - - -- **User Research**: -- **Data**: -- **Customer Feedback**: - -### Affected Segments - - -## Solutions - - -### Solution A: {{NAME}} - -**Description**: - -**Validation Status**: untested | assumption | validated - -**Expected Impact**: - -### Solution B: {{NAME}} - -**Description**: - -**Validation Status**: untested | assumption | validated - -**Expected Impact**: - -## Experiments - - -| Experiment | Hypothesis | Result | Learning | -|------------|-----------|--------|----------| -| | | | | - -## Decision - - -**Chosen Solution**: - -**Rationale**: - -## Success Metrics - - -| Metric | Baseline | Target | Actual | -|--------|----------|--------|--------| -| | | | | diff --git a/.templates/policy.md b/.templates/policy.md deleted file mode 100644 index 0dae608..0000000 --- a/.templates/policy.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -id: POL-{{NUMBER}} -status: proposed -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -effective_date: {{DATE}} -review_date: null -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - -## Purpose - - -## Scope - - -- **Applies to**: -- **Does not apply to**: - -## Background - - -## Policy Statement - - -### Requirements - -1. -2. -3. - -### Prohibited Actions - -1. -2. - -### Exceptions - - -## Implementation - -### Responsibilities - -| Role | Responsibility | -|------|---------------| -| | | - -### Procedures - - -1. -2. -3. - -## Compliance - -### Monitoring - - -### Consequences - - -## References - - -- diff --git a/.templates/process.md b/.templates/process.md deleted file mode 100644 index f8b253f..0000000 --- a/.templates/process.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: PRC-{{NUMBER}} -status: proposed -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -process_meta: - frequency: as-needed - duration: null - last_review: null -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - - - -## Purpose - - -## DACI - -- **Driver**: -- **Approver**: -- **Contributors**: -- **Informed**: - -## Trigger - - -## Inputs - - -- - -## Process Steps - -### Step 1: {{NAME}} -**Owner**: -**Duration**: - -**Actions**: -1. -2. - -**Output**: - -### Step 2: {{NAME}} -**Owner**: -**Duration**: - -**Actions**: -1. -2. - -**Output**: - -## Outputs - - -- - -## Quality Checks - - -- [ ] - -## Exceptions - - -| Scenario | Action | Escalation | -|----------|--------|------------| -| | | | - -## Tools & Systems - - -- - -## Metrics - - -| Metric | Target | Current | -|--------|--------|---------| -| | | | diff --git a/.templates/runbook.md b/.templates/runbook.md deleted file mode 100644 index 40fb207..0000000 --- a/.templates/runbook.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -id: RUN-{{NUMBER}} -status: accepted -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -runbook_meta: - last_verified: null - estimated_duration: null -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - - - -## Purpose - - -## Prerequisites - -- [ ] - -## Steps - -### 1. {{STEP_NAME}} - -```bash -# Commands or actions -``` - -**Expected outcome:** - -### 2. {{STEP_NAME}} - -```bash -# Commands or actions -``` - -**Expected outcome:** - -### 3. {{STEP_NAME}} - -```bash -# Commands or actions -``` - -**Expected outcome:** - -## Verification - - - -- [ ] - -## Rollback - - - -## Troubleshooting - -| Problem | Solution | -|---------|----------| -| | | - -## Related - - - -- diff --git a/.templates/strategy.md b/.templates/strategy.md deleted file mode 100644 index 1467b30..0000000 --- a/.templates/strategy.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -id: STR-{{NUMBER}} -status: proposed -created: {{DATE}} -updated: {{DATE}} -authors: [] -tags: [] -links: - supersedes: [] - superseded_by: [] - depends_on: [] - enables: [] - relates_to: [] - conflicts_with: [] - refines: [] - implements: [] ---- - -# {{TITLE}} - - - -## Introduction - - -## Goals - - -1. -2. -3. - -## Tenets - - -1. -2. -3. - -## State of the Business - - -### Current Metrics - -### Market Context - -### Competitive Position - -## Strategic Priorities - - -### Priority 1: - -### Priority 2: - -### Priority 3: - -## Resource Requirements - - -- **People**: -- **Budget**: -- **Timeline**: -- **Dependencies**: - -## Risks and Mitigations - -| Risk | Likelihood | Impact | Mitigation | -|------|------------|--------|------------| -| | | | | - -## FAQ - - -**Q: ?** -A: - -## Success Criteria - - -- [ ] From 67d15868bc1fbb1a0b57f5270cc798e5ffd3ab81 Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Mon, 27 Apr 2026 15:04:45 +0800 Subject: [PATCH 4/8] Add zig --- .mise.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.mise.toml b/.mise.toml index 83057f7..1d03da5 100644 --- a/.mise.toml +++ b/.mise.toml @@ -8,6 +8,7 @@ editorconfig-checker = "latest" harper-cli = "latest" rust = "latest" typos = "latest" +zig = "latest" [tasks] ec = "ec" From 3b2672455f68e4f3a9270ae0b8d4e0a1aeec2d26 Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Mon, 27 Apr 2026 15:09:22 +0800 Subject: [PATCH 5/8] Use github action to install llvm --- .github/workflows/check.yml | 5 +++++ .mise.toml | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 69cbdf8..e944963 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -29,6 +29,11 @@ jobs: with: tool: mise + - name: Install LLVM and Clang needed for building cargo-spellcheck + uses: KyleMayes/install-llvm-action@v2 + with: + version: "10.0" + - name: Install mise tools run: | mise settings add idiomatic_version_file_enable_tools "[]" diff --git a/.mise.toml b/.mise.toml index 1d03da5..41085c1 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,14 +1,12 @@ [tools] "cargo:cargo-spellcheck" = "latest" "cargo:topgrade" = "latest" -clang = "latest" dprint = "latest" editorconfig-checker = "latest" "github:decisiongraph/dg" = "latest" harper-cli = "latest" rust = "latest" typos = "latest" -zig = "latest" [tasks] ec = "ec" From ed010fdbbe7417737ee2a7e94047a52981019c7e Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Mon, 27 Apr 2026 15:15:17 +0800 Subject: [PATCH 6/8] install libtinfo5 --- .github/workflows/check.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index e944963..e62ff12 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -29,6 +29,11 @@ jobs: with: tool: mise + - name: Install llvm dep libtinfo5 + run: | + sudo apt-get update + sudo apt-get install -y libtinfo5 + - name: Install LLVM and Clang needed for building cargo-spellcheck uses: KyleMayes/install-llvm-action@v2 with: From 969f289e70bd090dfbaff3a471e8b1651a7a84e6 Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Mon, 27 Apr 2026 15:18:56 +0800 Subject: [PATCH 7/8] choose llvm 22 --- .github/workflows/check.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index e62ff12..9316f9d 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -29,15 +29,10 @@ jobs: with: tool: mise - - name: Install llvm dep libtinfo5 - run: | - sudo apt-get update - sudo apt-get install -y libtinfo5 - - name: Install LLVM and Clang needed for building cargo-spellcheck uses: KyleMayes/install-llvm-action@v2 with: - version: "10.0" + version: "22" - name: Install mise tools run: | From 85330700071a6a5e81c3f533ee0dedfcd99ed2d7 Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Mon, 27 Apr 2026 15:21:31 +0800 Subject: [PATCH 8/8] Install llvm using apt --- .github/workflows/check.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 9316f9d..8551a89 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -29,10 +29,10 @@ jobs: with: tool: mise - - name: Install LLVM and Clang needed for building cargo-spellcheck - uses: KyleMayes/install-llvm-action@v2 - with: - version: "22" + - name: Install LibClang needed for cargo-spellcheck + run: | + sudo apt-get update + sudo apt-get install -y libclang-dev - name: Install mise tools run: |