{
  "markdown": "# Product\n\n**A CLI and MCP server for the Product Framework — specify software as a verifiable What/How graph.**\n\nThe [Product Framework](docs/product-framework-open.md) is an open standard for\ndescribing a software product as one connected, machine-readable graph: the\n**What** (domain model + event model — entities, commands, events, read models,\nUI steps typed against Abstract Interaction Objects, *systems*, *triggers*,\n*Deciders*, *Projectors*), the **How** (contracts, the screen-composition /\nreification model, delivery features), and the typed links between them. The graph\ncan drive generation, gate verification, and explain itself — so \"describe this\nsystem\" is a query, not a stale document.\n\nThis repo is the reference tooling: a single Rust binary (`product`) plus an MCP\nserver that lets an agent author and verify the graph directly. No database, no\nservice — the graph lives as YAML/Turtle under `.product/`.\n\n```\n$ product init --demo                 # scaffold + seed the bookstore What model\n$ product domain new system sys-shop --system-kind application \\\n      --purpose \"consumer e-commerce\" --target-classes gui\n$ product domain validate --strict    # per-node shapes + graph-level completeness\n$ product decider derive Order        # derive an aggregate's executable signature\n$ product decider validate Order-decider\n$ product mcp --http                  # MCP server + a live Event-Modeling web view at /\n```\n\n---\n\n## Install\n\n```bash\n# from source\ncargo install --path product-cli\n```\n\nThe binary ships with the What→How→Build **Claude Code skills** baked in.\n`product init` writes them into `.claude/skills/` of the new repo (pass\n`--no-skills` to opt out); `product skills install` (re)installs them, and\n`product skills install --global` puts them in `~/.claude/skills/` for every\nproject. Start a fresh Claude Code session to pick them up, then `/product-session`.\n\n## Choosing the agent CLI\n\n`product session start` (and `product author domain`) host the What→How→Build\nsession in an agent CLI — **Claude Code** or **GitHub Copilot CLI**. The CLI is\nresolved in this order:\n\n1. the `--cli claude|copilot` flag, else\n2. the repo's `[author].cli` in `.product/config.toml`, else\n3. the global user default in `$XDG_CONFIG_HOME/product/config.toml`\n   (or `~/.config/product/config.toml`), else\n4. `claude`.\n\n```toml\n# .product/config.toml — make this repo default to Copilot CLI\n[author]\ncli = \"copilot\"\n```\n\nScaffold it on a new repo with `product init --cli copilot`, or set a personal\ndefault for every repo by putting the same `[author]` block in\n`~/.config/product/config.toml`. With a default configured, `product session\nstart` needs no `--cli` flag.\n\n## 60-second tour\n\n```bash\nproduct init --demo                   # a worked What model to explore\nproduct domain list                   # the captured nodes, by kind\nproduct domain show Order             # one node and its links\nproduct domain export                 # the graph as RDF/Turtle\nproduct domain validate               # §3.1/§3.2 per-node conformance shapes\nproduct domain validate --strict      # + §3.2.0/§3.2.5/§3.4/§4.5 completeness checks\nproduct decider derive Order          # §3.3 — derive decide/evolve signature\nproduct decider simulate Order-decider  # run its flow-derived scenarios\nproduct guide                         # where you are + the next step\n```\n\n## The model\n\n- **What** — `product domain …` captures the domain + event model; `product\n  decider …` (§3.3) and `product projector …` (§3.4) make behaviour and read\n  models executable; `product primitive …` (§3.5) names irreducible algorithms.\n- **How** — `product how`, `product feature`, `product build`, `product seam`,\n  `product preview` cover the How contract, delivery features, the screen seam, and\n  the §11/§12 design-system / content-store preview profiles.\n- Everything is validated against the framework's SHACL shapes + SPARQL rules;\n  the captured What serializes to Turtle (`product domain export`).\n\n## MCP + the web view\n\n`product mcp --http` starts the MCP server (framework tools: `product_domain_*`,\n`product_decider_*`, `product_projector_*`, …) and serves a live web view at `/`\nthat renders the active What graph across three connected views — **Systems**\n(the product → systems & journeys map, §3.0), **Domain** (one bounded context as\nan ER graph, §3.1), and **Flows** (a system's event-model as Event-Modeling\nswimlanes — triggers / commands / views over per-aggregate event streams, §3.2).\nA node detail panel, the What→How→Build phase stepper, dark/light theme and live\nSSE refresh round it out.\n\n## ddd — Decision-Driven Design governance\n\nThe workspace also ships `ddd` (crates `ddd-core`, `ddd-lsp`, `ddd-mcp`,\n`ddd-cli`), a separate tool over a separate store: a repo-local `.ddd/` graph\nof predicates, closure claims, decisions, analyzer/linter manifests, pattern\ninstances, seam declarations, and interception event rows\n([spec](docs/ddd-v1-spec.md), [umbrella PRD](docs/ddd-cli-prd.md), formats: [migrations](docs/ddd-format-migrations.md)).\n\n```bash\ncargo run -p ddd-cli -- init        # scaffold .ddd/\nddd validate                        # schema + ontology rules (CI gate)\nddd diff --sarif build.sarif        # declared vs. detected rules (CI gate)\nddd report escapes                  # diff + cadence + basis-loss report, each section stating its coverage\nddd why CA2007                      # rule -> decision -> principal -> claims (or: detected but unfiled)\nddd render                          # static self-contained HTML projection of the graph\nddd serve                           # the ddd_* MCP surface (stdio)\nddd warmup                          # pre-load the LSP hosts (Roslyn solution load)\nddd what                            # What-graph boundaries carrying no declaration\n```\n\n### Governing the What (the framework graph)\n\n`ddd what` treats the `.product/` What graph as a third governed surface\nalongside C# and Bicep. It needs no language server: `product-core` already\nowns the What as typed data, so the adapter reads kinds and containers\nstraight off `DomainGraph` and runs them through the same policy-table\nmechanism (`ddd-core/src/surface.rs`, shared with the LSP adapters).\n\nTwo kinds of row. **Boundary kinds** are surface whatever they connect to: a\nsystem (§3.2.5), a context mapping (§3.1), a journey crossing (§3.0.1), a\nquality demand (§3.6). **Published kinds** are surface only when a §3.2.0\nTranslation carries them — the View a Translation watches, the Command it\nissues, and the Events that View projects. Everything else is internal to its\nown system and never demands a declaration.\n\nThat published/internal split is the What's analogue of C# visibility, and it\nis load-bearing: the first table called every event and command a boundary,\nwhich the measurement in `DDD-what-02` killed (0 of 39 crossed anything). See\n`dec/ddd/what-published-qualifier`.\n\nA boundary counts as governed when a seam declaration's `contract_location`\nis `what:<element-id>`. `--strict` turns it into a CI gate; the default\nreports without failing, so the table can be calibrated against a real graph\nfirst.\n\n### MCP surface (M3/M4)\n\n`ddd serve` exposes the `ddd_*` tool namespace over stdio: LSP-backed\nlanguage intelligence for C# (`roslyn-language-server --stdio\n--autoLoadProjects`, the official prerelease .NET global tool) and Bicep\n(`bicep-ls` from `Azure.Bicep.LangServer`) — `find_symbol`, `references`,\n`hover`, `diagnostics` (joined to the manifests by rule id, the same join the\nSARIF path uses), `signature`, `rename` (computes; application funnels\nthrough the interceptor) — plus the governance tools `why`, `graph_query`,\n`declare_seam`, `declare_pattern`, `accept_risk`.\n\nThe three `declare`/`accept` tools take `amend: true` to revise an entry\nalready filed. The flag is explicit in both directions — a create never\nsilently overwrites, an amend never silently creates — and the split is by\nfield: judgement amends (`verdict_knowledge`, obligation answers, rationale),\nwhile identity and LSP-derived evidence (`contract_location`, `metadata`) are\ncarried forward untouched, so the interception rows stay machine-authored.\n\n`ddd_apply_edit` runs every edit through the per-language contract-surface\nclassifier (policy tables, PRD §9): non-surface edits apply; a surface edit\napplies only with a matching same-session declaration; otherwise it is\nrejected with a structured demand whose *facts* (symbol, kind, signature,\nvisibility, reference count) are pre-filled and whose judgment fields are\nblank (`dec/ddd/rejection-facts-prefilled`). Modes: `intercept: enforce |\nwarn | off`, per artifact class via `intercept_by_class` (config format 3);\n`adapter.csharp.internal_is_surface` flips the library-repo posture\n(`dec/ddd/internal-not-surface`). Every classified surface outcome lands as a\nrow under `.ddd/seams/events/` — the correspondence dataset. Hosts are\nspawned lazily, health-checked, and respawned on crash; while Roslyn loads\nthe solution, tools return an explicit `{\"status\": \"loading\"}` rather than\nhanging. CI runs against a fixture-grade mock host\n(`dec/ddd/fixtures-not-sdk`); set `DDD_LSP_E2E=1` with both tools on PATH to\nrun the gated real-host suites.\n\n`ddd diff` compares the manifests under `.ddd/manifest/` against two detected\nsources per language and reports `UNGOVERNED` (detected, no manifest entry),\n`STALE` (manifest entry, absent from config and emissions), and\n`UNCITED_SUPPRESSION` (a config or in-source suppression with no\nrisk-acceptance record):\n\n- **configured** — parsed from `.editorconfig` (`dotnet_diagnostic.<ID>.severity`\n  lines only; section globs are recorded, never evaluated — deliberately not an\n  editorconfig engine), `bicepconfig.json` (`analyzers.core.rules` levels), and\n  the root `Cargo.toml` (`[workspace.lints.clippy]`, for this repo's own gates).\n  Rules enabled by analyzer-package defaults have no config line and surface\n  via the emitted source only — `diff` says so when one source covers a rule.\n- **emitted** — SARIF 2.1 files from real builds, ingested by one shared\n  module. Produce them with (verified against current tool docs at M2):\n  - **C#**: `dotnet build -p:ErrorLog=diag.sarif%2Cversion=2.1` — the MSBuild\n    `ErrorLog` property; `version=2.1` is required (the default is SARIF 1.0),\n    and `%2C` escapes the comma on the CLI (or set `<ErrorLog>` in the project).\n  - **Bicep**: `bicep lint main.bicep --diagnostics-format sarif > bicep.sarif`\n    (also available as `az bicep lint`).\n\n  In-source suppressions differ per toolchain: the C# compiler still logs a\n  `#pragma`-suppressed diagnostic into SARIF (marked suppressed), which is how\n  `UNCITED_SUPPRESSION` sees it; Bicep's `#disable-next-line` removes the\n  diagnostic from the output entirely, so Bicep source suppressions are\n  invisible to detection — only `level: off` config suppressions are covered.\n\nPoint `ddd diff` at the files with `--sarif` or the `detect.sarif` list in\n`.ddd/config.yaml`. This repo governs itself: `.ddd/manifest/clippy.yaml` maps\n`clippy::unwrap_used` to its decision, and `ddd diff` verifies it against the\nworkspace lints table.\n\n## Build & test\n\n```bash\ncargo build\ncargo t                                          # full suite (alias: test --no-fail-fast)\ncargo clippy -- -D warnings -D clippy::unwrap_used\n```\n\nSee [CLAUDE.md](CLAUDE.md) for the architecture and contributor workflow, and\n[docs/product-framework-open.md](docs/product-framework-open.md) for the spec.\n\n## License\n\nSee [`LICENSE`](LICENSE).\n",
  "bytes": 11529,
  "sha": "eeff5ea58855874390444922ec373d70c830de15c1fd07c547afcd021f5bcf61",
  "repo_slug": "hafeok/product-cli",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_hafeok_product_cli_321f2b05/readme"
}