ddduck 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/docs/architecture.md +77 -0
  4. package/docs/cli.md +239 -0
  5. package/docs/getting-started.md +98 -0
  6. package/docs/model-reference.md +92 -0
  7. package/docs/model.md +75 -0
  8. package/package.json +76 -0
  9. package/policies/concept-owner-domain.yaml +8 -0
  10. package/policies/documentation-model-reference-resolution.yaml +8 -0
  11. package/policies/no-dangling-model-reference.yaml +8 -0
  12. package/policies/policy-spec.schema.json +23 -0
  13. package/schemas/context-pack.schema.json +83 -0
  14. package/schemas/fr-to-code-audit.schema.json +85 -0
  15. package/schemas/product/concept.schema.json +17 -0
  16. package/schemas/product/domain-interface.schema.json +18 -0
  17. package/schemas/product/domain.schema.json +24 -0
  18. package/schemas/product/evidence-anchor.schema.json +30 -0
  19. package/schemas/product/guarantee.schema.json +35 -0
  20. package/schemas/product/model.schema.json +20 -0
  21. package/schemas/product/relationship.schema.json +21 -0
  22. package/schemas/product/use-case.schema.json +27 -0
  23. package/scripts/audit-fr-to-code.mjs +162 -0
  24. package/scripts/check-generated-docs.mjs +58 -0
  25. package/scripts/check-generated-graph-svg.mjs +60 -0
  26. package/scripts/check-generated-graph.mjs +66 -0
  27. package/scripts/check-model.mjs +488 -0
  28. package/scripts/ddduck.mjs +542 -0
  29. package/scripts/generate-agent-readiness-report.mjs +23 -0
  30. package/scripts/generate-docs.mjs +205 -0
  31. package/scripts/generate-graph-svg.mjs +359 -0
  32. package/scripts/generate-graph.mjs +268 -0
  33. package/scripts/lib/agent-readiness-evals.mjs +433 -0
  34. package/scripts/lib/agent-readiness-report.mjs +79 -0
  35. package/scripts/lib/cli-contract.mjs +162 -0
  36. package/scripts/lib/context-pack.mjs +107 -0
  37. package/scripts/lib/ddduck-config.mjs +57 -0
  38. package/scripts/lib/fr-to-code-audit.mjs +144 -0
  39. package/scripts/lib/product-layout.mjs +93 -0
  40. package/scripts/lib/product-operation.mjs +431 -0
  41. package/scripts/lib/product-paths.mjs +43 -0
  42. package/scripts/lib/product-query.mjs +284 -0
  43. package/scripts/lib/product-root-resolver.mjs +167 -0
  44. package/scripts/lib/scan-ignore.mjs +8 -0
  45. package/scripts/lib/skill-installer.mjs +410 -0
  46. package/scripts/query-model.mjs +64 -0
  47. package/scripts/run-agent-readiness-evals.mjs +57 -0
  48. package/skills/update-ddduck-specs/SKILL.md +98 -0
package/docs/model.md ADDED
@@ -0,0 +1,75 @@
1
+ # Product model
2
+
3
+ ddduck models a product from canonical YAML. A product root contains one `product.yaml`,
4
+ its model nodes, decision records, and derived views. The root can live wherever the repository
5
+ chooses; `docs/ddd/` works well when the model is part of the repository's documentation, while
6
+ `ddd/` remains a compact default for a dedicated product root.
7
+
8
+ ```text
9
+ docs/ddd/
10
+ product.yaml
11
+ model/
12
+ domains/
13
+ concepts/
14
+ relationships/
15
+ use-cases/
16
+ interfaces/
17
+ guarantees/
18
+ decisions/
19
+ generated/
20
+ docs/model-overview.md
21
+ graph/model-graph.json
22
+ graph/model-graph.ndjson
23
+ ```
24
+
25
+ `product.yaml` and `model/**/*.yaml` are canonical. `generated/` is derived output and
26
+ must be regenerated through `ddduck generate` rather than edited directly.
27
+ `.ddduck/config.json` may point commands at the selected root, but `.ddduck/` is tool metadata,
28
+ not product source.
29
+
30
+ ## Nodes
31
+
32
+ Every canonical node declares a `schemaVersion`, `kind`, and `id`. The product root is the
33
+ one `Model` node; it does **not** declare `model`. Its `domains`, `useCases`,
34
+ `relationships`, and `decisions` list the owned top-level records. Every child node declares
35
+ `model` with that Model ID; domain-owned children also declare `ownerDomain`.
36
+
37
+ | Kind | Purpose |
38
+ | ----------------- | --------------------------------------------------------------------- |
39
+ | `Domain` | Owns concepts, interfaces, and guarantees. |
40
+ | `Concept` | Names a domain-owned product idea. |
41
+ | `Relationship` | Records an explicit connection between canonical nodes. |
42
+ | `UseCase` | States a goal, its guarantee preconditions, outcomes, and interfaces. |
43
+ | `DomainInterface` | Declares a command or query boundary and its guarantees. |
44
+ | `Guarantee` | States an invariant or acceptance criterion with lifecycle state. |
45
+
46
+ Guarantee IDs are stable. An active Guarantee can be moved, split into existing active
47
+ successors, or retired only when an ADR authorizes that lifecycle transition. Use cases and
48
+ interfaces cannot retain references to non-effective Guarantees.
49
+
50
+ ```mermaid
51
+ flowchart LR
52
+ Active -->|move; preserve ID and prior owner| Active
53
+ Active -->|split; active successors and ADR-NNN| Split
54
+ Active -->|retire; ADR-NNN| Retired
55
+ Reference[Active UseCase and DomainInterface references] -. block .-> Split
56
+ Reference -. block .-> Retired
57
+ ```
58
+
59
+ ## Decisions and evidence
60
+
61
+ Decision records live in `decisions/` and use the `ADR-NNN-*.md` filename convention.
62
+ Nodes may cite decisions. Interfaces may also declare evidence anchors with a product-relative
63
+ path, anchor name, and role (`source`, `decision`, or `verification`). The checker rejects an
64
+ anchor that escapes the selected product root or does not resolve to a regular file.
65
+
66
+ ## Derived views and validation
67
+
68
+ `ddduck generate --root <product-root>` creates the model overview and graph views. `ddduck
69
+ check --root <product-root>` validates schemas, node ownership, references, decisions,
70
+ Guarantee lifecycle, evidence anchors, global policies, and documentation references. With
71
+ `--base <previous-product-root>`, it also verifies that historical Guarantee IDs were not
72
+ silently removed.
73
+
74
+ Use [the model reference](model-reference.md) for fields and minimal YAML, and
75
+ [the CLI reference](cli.md) for exact commands and JSON query contracts.
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "ddduck",
3
+ "version": "0.1.0",
4
+ "description": "An opinionated DDD framework for authoring, validating, and visualizing machine-readable product-spec models.",
5
+ "keywords": [
6
+ "ddd",
7
+ "domain-driven-design",
8
+ "product-spec",
9
+ "model",
10
+ "traceability",
11
+ "yaml",
12
+ "json-schema",
13
+ "cli"
14
+ ],
15
+ "license": "MIT",
16
+ "author": "diegomarino <760919+diegomarino@users.noreply.github.com> (https://github.com/diegomarino)",
17
+ "homepage": "https://github.com/diegomarino/ddduck#readme",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/diegomarino/ddduck.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/diegomarino/ddduck/issues"
24
+ },
25
+ "engines": {
26
+ "node": ">=20"
27
+ },
28
+ "type": "module",
29
+ "files": [
30
+ "scripts/",
31
+ "schemas/",
32
+ "policies/",
33
+ "skills/",
34
+ "docs/architecture.md",
35
+ "docs/getting-started.md",
36
+ "docs/model.md",
37
+ "docs/model-reference.md",
38
+ "docs/cli.md"
39
+ ],
40
+ "bin": {
41
+ "ddduck": "scripts/ddduck.mjs"
42
+ },
43
+ "scripts": {
44
+ "check": "npm run check:model && npm run check:docs && npm run check:graph && npm run check:graph:svg && npm run lint && npm run lint:md && npm run format:check && npm test",
45
+ "check:docs": "node scripts/check-generated-docs.mjs",
46
+ "check:graph": "node scripts/check-generated-graph.mjs",
47
+ "check:graph:svg": "node scripts/check-generated-graph-svg.mjs",
48
+ "check:model": "node scripts/check-model.mjs --root docs/ddd --docs-root docs/ddd --docs-root .",
49
+ "format:check": "prettier --check .",
50
+ "generate:docs": "node scripts/generate-docs.mjs",
51
+ "generate:graph": "node scripts/generate-graph.mjs",
52
+ "generate:graph:svg": "node scripts/generate-graph-svg.mjs",
53
+ "lint": "eslint .",
54
+ "lint:md": "markdownlint-cli2 \"*.md\" \"docs/**/*.md\" \"examples/**/*.md\"",
55
+ "test": "node --test test/*.test.mjs",
56
+ "test:coverage": "node --test --experimental-test-coverage test/*.test.mjs",
57
+ "pack:dry-run": "npm pack --dry-run --cache .npm-cache",
58
+ "release:check": "npm run check && npm run pack:dry-run",
59
+ "prepublishOnly": "npm run release:check"
60
+ },
61
+ "dependencies": {
62
+ "@hpcc-js/wasm": "^2.35.0",
63
+ "ajv": "^8.20.0",
64
+ "remark-parse": "^11.0.0",
65
+ "unified": "^11.0.5",
66
+ "yaml": "^2.8.0"
67
+ },
68
+ "devDependencies": {
69
+ "eslint": "^10.8.0",
70
+ "markdownlint-cli2": "^0.23.2",
71
+ "prettier": "^3.9.6"
72
+ },
73
+ "overrides": {
74
+ "fast-uri": "^3.1.5"
75
+ }
76
+ }
@@ -0,0 +1,8 @@
1
+ schemaVersion: "1"
2
+ kind: PolicySpec
3
+ id: policy:concept-owner-domain
4
+ name: Concept Owner Domain
5
+ condition: Each domain-owned product fact resolves to exactly one owner domain.
6
+ implementation:
7
+ checker: check-model
8
+ check: concept-owner-domain
@@ -0,0 +1,8 @@
1
+ schemaVersion: "1"
2
+ kind: PolicySpec
3
+ id: policy:documentation-model-reference-resolution
4
+ name: Documentation Model Reference Resolution
5
+ condition: Structural documentation references resolve in the canonical model.
6
+ implementation:
7
+ checker: check-model
8
+ check: documentation-model-reference-resolution
@@ -0,0 +1,8 @@
1
+ schemaVersion: "1"
2
+ kind: PolicySpec
3
+ id: policy:no-dangling-model-reference
4
+ name: No Dangling Model Reference
5
+ condition: Every declared product reference resolves.
6
+ implementation:
7
+ checker: check-model
8
+ check: no-dangling-model-reference
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/policies/policy-spec.schema.json",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["schemaVersion", "kind", "id", "name", "condition", "implementation"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "1" },
9
+ "kind": { "const": "PolicySpec" },
10
+ "id": { "type": "string", "pattern": "^policy:[a-z0-9][a-z0-9-]*$" },
11
+ "name": { "type": "string", "minLength": 1 },
12
+ "condition": { "type": "string", "minLength": 1 },
13
+ "implementation": {
14
+ "type": "object",
15
+ "additionalProperties": false,
16
+ "required": ["checker", "check"],
17
+ "properties": {
18
+ "checker": { "const": "check-model" },
19
+ "check": { "type": "string", "minLength": 1 }
20
+ }
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,83 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/context-pack.schema.json",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["schemaVersion", "query", "rootModelId", "snapshot", "result", "diagnostics"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "1" },
9
+ "query": { "$ref": "#/$defs/query" },
10
+ "rootModelId": { "type": "string", "minLength": 1 },
11
+ "snapshot": { "$ref": "#/$defs/snapshot" },
12
+ "result": { "$ref": "#/$defs/result" },
13
+ "diagnostics": { "type": "array" }
14
+ },
15
+ "$defs": {
16
+ "query": {
17
+ "type": "object",
18
+ "additionalProperties": false,
19
+ "required": ["operation", "ids", "history"],
20
+ "properties": {
21
+ "operation": { "const": "context" },
22
+ "ids": {
23
+ "type": "array",
24
+ "minItems": 1,
25
+ "uniqueItems": true,
26
+ "items": { "type": "string", "minLength": 1 }
27
+ },
28
+ "history": { "const": false }
29
+ }
30
+ },
31
+ "snapshot": {
32
+ "type": "object",
33
+ "additionalProperties": false,
34
+ "required": ["algorithm", "sourceDigest"],
35
+ "properties": {
36
+ "algorithm": { "const": "sha256" },
37
+ "sourceDigest": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
38
+ }
39
+ },
40
+ "result": {
41
+ "type": "object",
42
+ "additionalProperties": false,
43
+ "required": ["selected", "edges", "neighbors"],
44
+ "properties": {
45
+ "selected": { "type": "array", "items": { "$ref": "#/$defs/selectedNode" } },
46
+ "edges": { "type": "array", "items": { "$ref": "#/$defs/edge" } },
47
+ "neighbors": { "type": "array", "items": { "$ref": "#/$defs/neighbor" } }
48
+ }
49
+ },
50
+ "selectedNode": {
51
+ "type": "object",
52
+ "required": ["id", "kind", "sourcePath"],
53
+ "properties": {
54
+ "id": { "type": "string", "minLength": 1 },
55
+ "kind": { "type": "string", "minLength": 1 },
56
+ "sourcePath": { "type": "string", "minLength": 1 }
57
+ },
58
+ "additionalProperties": true
59
+ },
60
+ "edge": {
61
+ "type": "object",
62
+ "required": ["id", "from", "to", "kind"],
63
+ "properties": {
64
+ "id": { "type": "string", "minLength": 1 },
65
+ "from": { "type": "string", "minLength": 1 },
66
+ "to": { "type": "string", "minLength": 1 },
67
+ "kind": { "type": "string", "minLength": 1 }
68
+ },
69
+ "additionalProperties": true
70
+ },
71
+ "neighbor": {
72
+ "type": "object",
73
+ "additionalProperties": false,
74
+ "required": ["id", "kind", "name", "sourcePath"],
75
+ "properties": {
76
+ "id": { "type": "string", "minLength": 1 },
77
+ "kind": { "type": "string", "minLength": 1 },
78
+ "name": { "type": ["string", "null"] },
79
+ "sourcePath": { "type": "string", "minLength": 1 }
80
+ }
81
+ }
82
+ }
83
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/fr-to-code-audit.schema.json",
4
+ "description": "This standard JSON Schema validates record structure. verifyFrToCodeAudit is the normative semantic validator for within-record constraints, including unique source IDs and anchor endLine >= startLine.",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "kind",
10
+ "id",
11
+ "sources",
12
+ "requirement",
13
+ "coverage",
14
+ "verdict",
15
+ "productionAnchors",
16
+ "testAnchors",
17
+ "reviewerDisposition"
18
+ ],
19
+ "properties": {
20
+ "schemaVersion": { "const": "1" },
21
+ "kind": { "const": "FrToCodeAudit" },
22
+ "id": { "$ref": "#/$defs/nonEmptyString" },
23
+ "sources": {
24
+ "type": "array",
25
+ "minItems": 1,
26
+ "items": { "$ref": "#/$defs/source" }
27
+ },
28
+ "requirement": { "$ref": "#/$defs/requirement" },
29
+ "coverage": { "$ref": "#/$defs/coverage" },
30
+ "verdict": { "enum": ["realized-and-tested", "realized-untested", "unrealized"] },
31
+ "productionAnchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
32
+ "testAnchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
33
+ "reviewerDisposition": { "enum": ["accepted", "rejected"] }
34
+ },
35
+ "$defs": {
36
+ "nonEmptyString": { "type": "string", "minLength": 1 },
37
+ "source": {
38
+ "type": "object",
39
+ "additionalProperties": false,
40
+ "required": ["id", "repository", "revision"],
41
+ "properties": {
42
+ "id": { "$ref": "#/$defs/nonEmptyString" },
43
+ "repository": { "$ref": "#/$defs/nonEmptyString" },
44
+ "revision": { "type": "string", "pattern": "^[0-9a-f]{40}$" }
45
+ }
46
+ },
47
+ "requirement": {
48
+ "type": "object",
49
+ "additionalProperties": false,
50
+ "required": ["sourceId", "sourcePath", "id", "qualifier"],
51
+ "properties": {
52
+ "sourceId": { "$ref": "#/$defs/nonEmptyString" },
53
+ "sourcePath": { "$ref": "#/$defs/nonEmptyString" },
54
+ "id": { "$ref": "#/$defs/nonEmptyString" },
55
+ "qualifier": { "$ref": "#/$defs/nonEmptyString" },
56
+ "tracedGuarantee": { "$ref": "#/$defs/nonEmptyString" }
57
+ }
58
+ },
59
+ "coverage": {
60
+ "type": "object",
61
+ "additionalProperties": false,
62
+ "required": ["includes", "excludes"],
63
+ "properties": {
64
+ "includes": { "$ref": "#/$defs/nonEmptyStrings" },
65
+ "excludes": { "$ref": "#/$defs/nonEmptyStrings" }
66
+ }
67
+ },
68
+ "nonEmptyStrings": {
69
+ "type": "array",
70
+ "minItems": 1,
71
+ "items": { "$ref": "#/$defs/nonEmptyString" }
72
+ },
73
+ "anchor": {
74
+ "type": "object",
75
+ "additionalProperties": false,
76
+ "required": ["sourceId", "path", "startLine", "endLine"],
77
+ "properties": {
78
+ "sourceId": { "$ref": "#/$defs/nonEmptyString" },
79
+ "path": { "$ref": "#/$defs/nonEmptyString" },
80
+ "startLine": { "type": "integer", "minimum": 1 },
81
+ "endLine": { "type": "integer", "minimum": 1 }
82
+ }
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/product/concept.schema.json",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["schemaVersion", "kind", "id", "model", "ownerDomain", "name", "purpose"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "1" },
9
+ "kind": { "const": "Concept" },
10
+ "id": { "type": "string", "pattern": "^concept:[a-z0-9][a-z0-9-]*$" },
11
+ "model": { "type": "string", "pattern": "^model:" },
12
+ "ownerDomain": { "type": "string", "pattern": "^domain:" },
13
+ "name": { "type": "string", "minLength": 1 },
14
+ "purpose": { "type": "string", "minLength": 1 },
15
+ "decisions": { "type": "array", "items": { "type": "string", "pattern": "^ADR-[0-9]{3}$" }, "uniqueItems": true }
16
+ }
17
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/product/domain-interface.schema.json",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["schemaVersion", "kind", "id", "model", "ownerDomain", "name", "operationKind"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "1" },
9
+ "kind": { "const": "DomainInterface" },
10
+ "id": { "type": "string", "pattern": "^interface:[a-z0-9][a-z0-9-]*$" },
11
+ "model": { "type": "string", "pattern": "^model:" },
12
+ "ownerDomain": { "type": "string", "pattern": "^domain:" },
13
+ "name": { "type": "string", "minLength": 1 },
14
+ "operationKind": { "enum": ["query", "command"] },
15
+ "guarantees": { "$ref": "evidence-anchor.schema.json#/$defs/guaranteeReferenceArray" },
16
+ "evidence": { "$ref": "evidence-anchor.schema.json#/$defs/evidenceAnchors" }
17
+ }
18
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/product/domain.schema.json",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["schemaVersion", "kind", "id", "model", "name", "purpose"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "1" },
9
+ "kind": { "const": "Domain" },
10
+ "id": { "type": "string", "pattern": "^domain:[a-z0-9][a-z0-9-]*$" },
11
+ "model": { "type": "string", "pattern": "^model:" },
12
+ "name": { "type": "string", "minLength": 1 },
13
+ "purpose": { "type": "string", "minLength": 1 },
14
+ "concepts": { "type": "array", "items": { "type": "string", "pattern": "^concept:" }, "uniqueItems": true },
15
+ "excludedConcepts": { "type": "array", "items": { "type": "string", "pattern": "^concept:" }, "uniqueItems": true },
16
+ "interfaces": { "type": "array", "items": { "type": "string", "pattern": "^interface:" }, "uniqueItems": true },
17
+ "guarantees": {
18
+ "type": "array",
19
+ "items": { "type": "string", "pattern": "^(?:[A-Z][A-Z0-9-]+-(?:INV|AC)-[0-9]+)$" },
20
+ "uniqueItems": true
21
+ },
22
+ "decisions": { "type": "array", "items": { "type": "string", "pattern": "^ADR-[0-9]{3}$" }, "uniqueItems": true }
23
+ }
24
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/product/evidence-anchor.schema.json",
4
+ "$defs": {
5
+ "guaranteeReferenceArray": {
6
+ "type": "array",
7
+ "items": { "type": "string", "pattern": "^[A-Z][A-Z0-9-]+-(?:INV|AC)-[0-9]+$" },
8
+ "uniqueItems": true
9
+ },
10
+ "guaranteeReferences": {
11
+ "type": "object",
12
+ "additionalProperties": false,
13
+ "required": ["requires"],
14
+ "properties": { "requires": { "$ref": "#/$defs/guaranteeReferenceArray" } }
15
+ },
16
+ "evidenceAnchors": {
17
+ "type": "array",
18
+ "items": {
19
+ "type": "object",
20
+ "additionalProperties": false,
21
+ "required": ["path", "anchor", "role"],
22
+ "properties": {
23
+ "path": { "type": "string", "minLength": 1 },
24
+ "anchor": { "type": "string", "minLength": 1 },
25
+ "role": { "enum": ["source", "decision", "verification"] }
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/product/guarantee.schema.json",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["schemaVersion", "kind", "id", "model", "ownerDomain", "classification", "statement", "status"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "1" },
9
+ "kind": { "const": "Guarantee" },
10
+ "id": { "type": "string", "pattern": "^[A-Z][A-Z0-9-]+-(?:INV|AC)-[0-9]+$" },
11
+ "model": { "type": "string", "pattern": "^model:" },
12
+ "ownerDomain": { "type": "string", "pattern": "^domain:" },
13
+ "classification": { "enum": ["invariant", "acceptance-criterion"] },
14
+ "statement": { "type": "string", "minLength": 1 },
15
+ "status": { "enum": ["active", "split", "retired"] },
16
+ "lifecycleDecision": { "type": "string", "pattern": "^ADR-[0-9]{3}$" },
17
+ "successors": { "$ref": "evidence-anchor.schema.json#/$defs/guaranteeReferenceArray" },
18
+ "ownershipHistory": {
19
+ "type": "array",
20
+ "items": { "type": "string", "pattern": "^domain:" },
21
+ "uniqueItems": true
22
+ },
23
+ "evidence": { "$ref": "evidence-anchor.schema.json#/$defs/evidenceAnchors" }
24
+ },
25
+ "allOf": [
26
+ {
27
+ "if": { "properties": { "status": { "const": "active" } } },
28
+ "then": { "not": { "required": ["lifecycleDecision"] } }
29
+ },
30
+ {
31
+ "if": { "properties": { "status": { "enum": ["split", "retired"] } } },
32
+ "then": { "required": ["lifecycleDecision"] }
33
+ }
34
+ ]
35
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/product/model.schema.json",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["schemaVersion", "kind", "id", "name", "purpose", "domains"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "1" },
9
+ "kind": { "const": "Model" },
10
+ "id": { "type": "string", "pattern": "^model:[a-z0-9][a-z0-9-]*$" },
11
+ "name": { "type": "string", "minLength": 1 },
12
+ "nameStatus": { "type": "string", "minLength": 1 },
13
+ "purpose": { "type": "string", "minLength": 1 },
14
+ "domains": { "type": "array", "items": { "type": "string", "pattern": "^domain:" }, "uniqueItems": true },
15
+ "useCases": { "type": "array", "items": { "type": "string", "pattern": "^use-case:" }, "uniqueItems": true },
16
+ "relationships": { "type": "array", "items": { "type": "string", "pattern": "^rel:" }, "uniqueItems": true },
17
+ "decisions": { "type": "array", "items": { "type": "string", "pattern": "^ADR-[0-9]{3}$" }, "uniqueItems": true },
18
+ "notes": { "type": "array", "items": { "type": "string" } }
19
+ }
20
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/product/relationship.schema.json",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["schemaVersion", "kind", "id", "model", "from", "to", "relationshipType", "mode", "ownedBy"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "1" },
9
+ "kind": { "const": "Relationship" },
10
+ "id": { "type": "string", "pattern": "^rel:[a-z0-9][a-z0-9-]*$" },
11
+ "model": { "type": "string", "pattern": "^model:" },
12
+ "from": { "type": "string", "minLength": 1 },
13
+ "to": { "type": "string", "minLength": 1 },
14
+ "relationshipType": { "type": "string", "minLength": 1 },
15
+ "mode": { "type": "string", "minLength": 1 },
16
+ "ownedBy": { "type": "string", "pattern": "^domain:" },
17
+ "description": { "type": "string" },
18
+ "constraints": { "type": "array", "items": { "type": "string" } },
19
+ "decisions": { "type": "array", "items": { "type": "string", "pattern": "^ADR-[0-9]{3}$" }, "uniqueItems": true }
20
+ }
21
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ddduck.local/schemas/product/use-case.schema.json",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["schemaVersion", "kind", "id", "model", "name", "goal", "preconditions", "success"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "1" },
9
+ "kind": { "const": "UseCase" },
10
+ "id": { "type": "string", "pattern": "^use-case:[a-z0-9][a-z0-9-]*$" },
11
+ "model": { "type": "string", "pattern": "^model:" },
12
+ "name": { "type": "string", "minLength": 1 },
13
+ "goal": { "type": "string", "minLength": 1 },
14
+ "preconditions": { "$ref": "evidence-anchor.schema.json#/$defs/guaranteeReferences" },
15
+ "success": {
16
+ "type": "object",
17
+ "additionalProperties": false,
18
+ "required": ["preserves", "establishes"],
19
+ "properties": {
20
+ "preserves": { "$ref": "evidence-anchor.schema.json#/$defs/guaranteeReferenceArray" },
21
+ "establishes": { "$ref": "evidence-anchor.schema.json#/$defs/guaranteeReferenceArray" }
22
+ }
23
+ },
24
+ "interfaces": { "type": "array", "items": { "type": "string", "pattern": "^interface:" }, "uniqueItems": true },
25
+ "evidence": { "$ref": "evidence-anchor.schema.json#/$defs/evidenceAnchors" }
26
+ }
27
+ }