ITADN
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

DecisionGraph

面向软件团队的决策管理工具。将业务机会、策略、架构决策、事件和行为规范作为带有 YAML frontmatter 的结构化 Markdown 文档进行跟踪,并针对 KDL schema 进行验证。

文档构成一个包含前向引用和反向链接的依赖图,使团队能够了解决策的制定原因、影响范围以及何时失效。

安装

# Install to ~/.cargo/bin (release build)
cargo install --path crates/dg-cli
cargo install --path crates/dg-mcp   # optional: MCP server for AI agents

# Or build release binaries in target/release/
cargo build --release

Nix / devenv

该仓库是一个 Nix flake,暴露了一个 dg 包(包含 dgdg-mcp 二进制文件):

nix run github:decisiongraph/dg -- --version   # run without installing
nix profile install github:decisiongraph/dg    # install to profile

要在 devenv 项目中使用,请将输入添加到 devenv.yaml

inputs:
  dg:
    url: github:decisiongraph/dg
    inputs:
      nixpkgs:
        follows: nixpkgs

以及该包到 devenv.nix

{ pkgs, inputs, ... }: {
  packages = [ inputs.dg.packages.${pkgs.stdenv.system}.default ];
}

Plain flakes 也可以使用 overlays.default,它会添加 pkgs.dg

nix build 包含完整的嵌入式 SvelteKit SPA:ui/bun.nix (由 bun2nix 生成)固定了所有 npm 依赖项,因此沙箱化构建永远不会访问网络。在更改 ui/package.json 依赖项后,使用以下命令重新生成:

bun install --cwd ui                        # updates ui/bun.lock
nix run .#bun2nix -- -l ui/bun.lock -o ui/bun.nix

如果 Cargo.lockui/bun.lockui/bun.nix 不同步,CI 将失败。

快速入门

dg init                              # Scaffold project + git hooks + AI agent config
dg new opportunity "Sell llama milk online"                  # OPP-001
dg new adr "Use Rails with PostgreSQL" enables OPP-001       # ADR-001
dg new spec "Llama milk checkout flow" implements OPP-001    # SPEC-001
dg new policy "GDPR: Serving European customers" enables OPP-001  # POL-001
dg validate                          # Check all docs against schema
dg list                              # List all documents
dg refs ADR-001                      # Show what ADR-001 references
dg refs ADR-001 --backlinks          # Show what references ADR-001

类型别名:opportunity→opp, architecture/tech→adr, policy→pol, incident→inc, feature→spec.

文档类型

类型别名前缀文件夹用途
oppopportunityOPP-001docs/opportunities/商业机会、功能、需求
adrarchitecture, techADR-001docs/architecture/架构/技术决策 (MADR 4.0)
polpolicyPOL-001docs/policies/策略、约束、合规规则
incincidentINC-001docs/incidents/事故、事后分析、根本原因分析
specfeatureSPEC-001docs/specs/包含 Gherkin 场景的行为规范

命令

# Create
dg new <type> "Title" [--field=value] [relation REF-001]
dg new adr "Use PostgreSQL" --author=@jane enables OPP-001   # field + relation

# Read
dg list [--type adr] [--status active] [--group-by type]
dg show OPP-001                      # Rendered output
dg show OPP-001 --json               # Full JSON (frontmatter + sections)
dg show OPP-001 --raw                # Raw markdown source
dg refs OPP-001                      # Outgoing references
dg refs OPP-001 --backlinks          # Incoming references
dg search "query"                    # Full-text search across all docs
dg search "query" --section "Root Cause" --type inc

# Update
dg set OPP-001 status=completed date=2026-01-15   # Multiple fields at once
dg set OPP-001 tags+=backend                      # Append to array field
dg set OPP-001 --section Decision --content "New text"
dg set OPP-001 --section Decision --content-file notes.md  # Read from file
dg set OPP-001 --section Timeline --add-row "10:30,Restored,@ops"
dg set OPP-001 --remove tags                      # Remove a field

# Validate & lint
dg validate                          # Schema validation (errors + warnings)
dg validate --skip C002              # Suppress specific diagnostic codes
dg lint                              # Validate + graph health (orphans, cycles, dangling refs)
dg suggest                           # Advisory improvement suggestions

# Inspect schema
dg schema                            # List all types and relations
dg schema adr                        # Fields, sections, rules for a type
dg schema --json                     # Machine-readable output

# History & diff
dg diff ADR-001                      # Field/section changes vs HEAD
dg diff ADR-001 --commit abc1234     # Compare against specific commit
dg history ADR-001                   # Status transitions from git history

# Export & diagrams
dg export --features -o ./features                # Extract .feature files
dg export --features --check -o ./features        # Validate + extract
dg export --features --diagram mermaid -o ./out   # Generate Mermaid diagrams
dg site -o ./site                                 # Static HTML documentation site

# Maintenance
dg fmt                               # Auto-format documents to schema order
dg renumber                          # Reorder document IDs chronologically
dg coverage                          # Coverage metrics by type/status
dg team list                         # Show orgs, teams, users

字段赋值规则

dg setdg new 使用 = 设置标量字段,使用 += 向数组追加元素:

运算符用途示例
key=value标量字段和单引用关系status=accepted, supersedes=ADR-001
key+=value数组字段和多引用关系tags+=backend, implements+=OPP-001

单引用关系=):supersedes, superseded_by, enables, enabled_by, triggers, triggered_by

多引用关系+=):implements, depends_on, related, conflicts_with

dg set 在对标量字段使用 += 时会发出警告。

关系

文档通过 frontmatter 关系相互链接:

implements:
  - OPP-001
supersedes: ADR-002
关系逆关系基数描述
supersedessuperseded_byone替换之前的文档
enablesenabled_bymany前置条件 — 源必须存在,目标才能成功
triggerstriggered_bymany直接原因 — 目标因源而创建
depends_ondependency_ofmany在目标解决之前无法继续
implementsimplemented_bymany策略或机会的技术实现
conflicts_withmany与目标相矛盾或产生张力
relatedmany松散关联(尽可能使用更具体的关系)

dg lint 检查悬空引用、循环和孤立文档。

配置文件

dg init 创建一个 .dg/ 目录,其中包含两个 KDL 配置文件。

.dg/schema.kdl — 文档模式

定义文档类型、字段、章节和验证规则。默认使用内置模式。运行 dg init --eject 将内置模式复制到 .dg/schema.kdl 以进行自定义。

// Define a custom document type
type "rfc" description="Request for Comments" folder="docs/rfcs" {
    alias "proposal"
    field "status" type="enum" required=#true default="draft" {
        values "draft" "review" "accepted" "rejected"
        transition "draft" "review"
        transition "review" "accepted" "rejected"
    }
    field "author" type="user" required=#true
    field "date" type="string" required=#true pattern="^\\d{4}-\\d{2}-\\d{2}$"
    field "tags" type="string[]"

    section "Motivation" required=#true { content min-paragraphs=1 }
    section "Design" required=#true { content min-paragraphs=1 }
    section "Drawbacks"
    section "Alternatives"
}

// Define custom relations
relation "replaces" inverse="replaced_by" cardinality="one"

// Configure valid ID formats (used by dg validate for ref checking)
ref-format {
    string-id pattern="^(ADR|INC|POL|OPP|SPEC|RFC)-\\d+$"
    relative-path pattern="\\.md$"
}

字段类型:stringstring[]enumuseruser[]date

章节约束:content min-paragraphs=Nlist min-items=Ndiagram required=#truetable { column ... }

条件规则根据字段值强制实施额外要求:

rule "active OPPs require a Requirements table" {
    when "status" equals-any="pursuing,completed"
    then-section-table "Requirements" {
        table {
            column "Status" type="enum" required=#true { values "completed" "in-progress" "pending" }
            column "Requirement" type="string" required=#true
            column "Owner" type="user" required=#true
        }
    }
}

使用 dg schema [TYPE] 在不打开文件的情况下检查活动模式。

.dg/org.kdl — 团队和用户注册表

定义在 authorownerresponders 及其他用户类型字段中引用的人员、团队和法律实体。用户句柄在文档和表格单元格中显示为 @handle

org "acme-corp" {
    name "Acme Corporation"
}

org "acme-eu" {
    name "Acme EU GmbH"
    parent "acme-corp"
}

team "engineering" {
    name "Engineering"
    org "acme-corp"
    lead "jane"
}

team "platform" {
    name "Platform Team"
    org "acme-eu"
    parent "engineering"     // sub-team
    lead "onni"
}

team "vendors" {
    name "External Contractors"
    kind "external"
    org "acme-corp"
}

user "jane" {
    name "Jane Smith"
    title "VP Engineering"
    email "jane@acme.com"
    teams "engineering"
    org "acme-corp"
}

user "ext-dev" {
    name "External Dev"
    kind "external"          // marks as external contributor
    teams "vendors"
    org "acme-corp"
}

user "former-alice" {
    name "Alice Former"
    status "departed"        // excluded from active user validation
}

通过 dg team 命令进行管理:

dg team list                                         # Show all orgs, teams, users
dg team add-user jane --name="Jane Smith" --teams=engineering
dg team add-team vendors --kind=external
dg team depart-user former-alice                     # Mark as departed

在文档中使用其用户名(不带 @)来引用用户:

author: jane
owner: team/platform
responders:
  - jane
  - ext-dev

dg validate 检查所有用户引用是否能在 org.kdl 中解析。

Gherkin 支持

SPEC 文档在围栏代码块中包含 Gherkin 场景:

```gherkin
Feature: Checkout

  Scenario: Successful purchase
    Given the cart has items
    When the user submits payment
    Then an order confirmation is sent
```

dg validate 检查 Gherkin 语法(G001)和语义(G002:缺少 Then 步骤、名称重复、空场景)。

dg export --features 将场景提取为独立的 .feature 文件。添加 --diagram mermaid--diagram d2 以生成流程图。

AI 代理集成

dg init 自动检测已安装的 AI CLI,并设置工作流指令和技能:

dg init                    # Auto-detect claude/gemini/opencode in PATH
dg init --with-claude      # Force Claude Code setup (CLAUDE.md + .claude/skills/)
dg init --with-gemini      # Force Gemini CLI setup (AGENTS.md + .gemini/skills/)
dg init --with-opencode    # Force OpenCode setup   (AGENTS.md + .opencode/skills/)
dg init --eject            # Export all templates to .dg/templates/ for customization

已安装的技能涵盖:机会、ADR、策略、事件、规范、图表、团队、图像、Mermaid 流程图、Mermaid 时序图。

MCP 服务器(dg-mcp)通过 stdio 暴露 JSON-RPC 工具,用于无需 CLI 的直接代理集成:dg-validatedg-getdg-listdg-inspectdg-describedg-setdg-newdg-refsdg-graphdg-deprecate

项目结构

dg init 之后:

.dg/
  org.kdl          # Team/user registry
  schema.kdl       # Custom schema (only if ejected with dg init --eject)
docs/
  architecture/    # ADR-001.md, ADR-002.md, ...
  opportunities/   # OPP-001.md, ...
  policies/        # POL-001.md, ...
  incidents/       # INC-001.md, ...
  specs/           # SPEC-001.md, ...
  assets/          # Images referenced in docs (validated by dg validate)
CLAUDE.md          # AI agent instructions (auto-generated)

工作区 crate

Crate描述
crates/dg-cliCLI 二进制文件(dg
crates/md-db核心库:解析、验证、图、搜索、差异、导出、站点生成
crates/dg-schemas内置 KDL schema、org 模板、AI agent 模板
crates/gherkinGherkin 解析、语义验证、图表生成
crates/dg-mcp面向 AI agent 的 MCP 服务器(基于 stdio 的 JSON-RPC)
crates/markdown-tui终端 Markdown 渲染器(GFM → ANSI / ratatui 组件)
cc-eval/Claude Code 评估运行器(独立,不在工作区内)

许可证

AGPL-3.0-or-later