@tacuchi/agent-workflow-cli 20.25.0 → 21.0.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 (124) hide show
  1. package/README.md +1 -1
  2. package/dist/adapters/node-file-system.js +3 -0
  3. package/dist/adapters/node-file-system.js.map +1 -1
  4. package/dist/application/design/design-gate-service.js +246 -0
  5. package/dist/application/design/design-gate-service.js.map +1 -0
  6. package/dist/application/design/design-graph-service.js +85 -0
  7. package/dist/application/design/design-graph-service.js.map +1 -0
  8. package/dist/application/design/design-index-service.js +132 -0
  9. package/dist/application/design/design-index-service.js.map +1 -0
  10. package/dist/application/design/design-publish-service.js +488 -0
  11. package/dist/application/design/design-publish-service.js.map +1 -0
  12. package/dist/application/design/design-resolver-service.js +165 -0
  13. package/dist/application/design/design-resolver-service.js.map +1 -0
  14. package/dist/application/resume-service.js +23 -4
  15. package/dist/application/resume-service.js.map +1 -1
  16. package/dist/application/self/install-skill.js +25 -8
  17. package/dist/application/self/install-skill.js.map +1 -1
  18. package/dist/application/semantic-operation/protocol.js +18 -12
  19. package/dist/application/semantic-operation/protocol.js.map +1 -1
  20. package/dist/application/semantic-operation/publish.js +56 -9
  21. package/dist/application/semantic-operation/publish.js.map +1 -1
  22. package/dist/application/skills-resolver-service.js +19 -4
  23. package/dist/application/skills-resolver-service.js.map +1 -1
  24. package/dist/application/status-service.js +1 -0
  25. package/dist/application/status-service.js.map +1 -1
  26. package/dist/application/workline-index-service.js +6 -0
  27. package/dist/application/workline-index-service.js.map +1 -1
  28. package/dist/application/workspace-init-service.js +9 -1
  29. package/dist/application/workspace-init-service.js.map +1 -1
  30. package/dist/cli/commands/designs.js +110 -0
  31. package/dist/cli/commands/designs.js.map +1 -0
  32. package/dist/cli/commands/index.js +2 -0
  33. package/dist/cli/commands/index.js.map +1 -1
  34. package/dist/cli/commands/resume.js +8 -0
  35. package/dist/cli/commands/resume.js.map +1 -1
  36. package/dist/cli/commands/status.js +45 -0
  37. package/dist/cli/commands/status.js.map +1 -1
  38. package/dist/cli/help-groups.js +3 -0
  39. package/dist/cli/help-groups.js.map +1 -1
  40. package/dist/cli/parser.js +1 -0
  41. package/dist/cli/parser.js.map +1 -1
  42. package/dist/domain/design/artifact-body.js +223 -0
  43. package/dist/domain/design/artifact-body.js.map +1 -0
  44. package/dist/domain/design/artifact.js +606 -0
  45. package/dist/domain/design/artifact.js.map +1 -0
  46. package/dist/domain/design/baseline.js +359 -0
  47. package/dist/domain/design/baseline.js.map +1 -0
  48. package/dist/domain/design/capability.js +51 -0
  49. package/dist/domain/design/capability.js.map +1 -0
  50. package/dist/domain/design/closure.js +161 -0
  51. package/dist/domain/design/closure.js.map +1 -0
  52. package/dist/domain/design/governance.js +298 -0
  53. package/dist/domain/design/governance.js.map +1 -0
  54. package/dist/domain/design/identity.js +145 -0
  55. package/dist/domain/design/identity.js.map +1 -0
  56. package/dist/domain/design/manifest.js +552 -0
  57. package/dist/domain/design/manifest.js.map +1 -0
  58. package/dist/domain/design/maturity.js +234 -0
  59. package/dist/domain/design/maturity.js.map +1 -0
  60. package/dist/domain/design/naming.js +117 -0
  61. package/dist/domain/design/naming.js.map +1 -0
  62. package/dist/domain/design/projections.js +165 -0
  63. package/dist/domain/design/projections.js.map +1 -0
  64. package/dist/domain/design/reference.js +234 -0
  65. package/dist/domain/design/reference.js.map +1 -0
  66. package/dist/domain/design/retired.js +61 -0
  67. package/dist/domain/design/retired.js.map +1 -0
  68. package/dist/domain/design/revision.js +219 -0
  69. package/dist/domain/design/revision.js.map +1 -0
  70. package/dist/domain/design/secrets.js +86 -0
  71. package/dist/domain/design/secrets.js.map +1 -0
  72. package/dist/domain/design/validation.js +75 -0
  73. package/dist/domain/design/validation.js.map +1 -0
  74. package/dist/domain/design/yaml-subset.js +390 -0
  75. package/dist/domain/design/yaml-subset.js.map +1 -0
  76. package/dist/domain/safe-path.js +23 -0
  77. package/dist/domain/safe-path.js.map +1 -0
  78. package/dist/domain/skills.js +27 -3
  79. package/dist/domain/skills.js.map +1 -1
  80. package/package.json +1 -1
  81. package/skills/w/SKILL.md +13 -11
  82. package/skills/w/artifacts/README.md +3 -4
  83. package/skills/w/artifacts/artifacts-core/CHECKPOINT.md +2 -2
  84. package/skills/w/commands/README.md +2 -0
  85. package/skills/w/commands/export-diagrams.md +1 -1
  86. package/skills/w/commands/export-manuals.md +1 -1
  87. package/skills/w/commands/export-reports.md +1 -1
  88. package/skills/w/commands/export-scripts.md +1 -1
  89. package/skills/w/commands/fix-git.md +1 -1
  90. package/skills/w/commands/generate-launch.md +2 -2
  91. package/skills/w/commands/persist.md +2 -2
  92. package/skills/w/commands/plan-exec.md +13 -7
  93. package/skills/w/commands/plan-new.md +8 -4
  94. package/skills/w/commands/plan-refine.md +8 -5
  95. package/skills/w/commands/quick.md +4 -4
  96. package/skills/w/commands/resume.md +2 -2
  97. package/skills/w/commands/spec-new.md +4 -4
  98. package/skills/w/commands/spec-refine.md +3 -2
  99. package/skills/w/commands/status.md +1 -1
  100. package/skills/w/commands/workspace-init.md +1 -1
  101. package/skills/w/context/MANIFEST.json +19 -8
  102. package/skills/w/harness/HARNESS.md +14 -10
  103. package/skills/w/loops/CHASSIS.md +9 -8
  104. package/skills/w/loops/CODE-POLICIES.md +22 -7
  105. package/skills/w/loops/README.md +1 -1
  106. package/skills/w/loops/plan-exec-loop/LOOP.md +127 -61
  107. package/skills/w/loops/plan-new-loop/LOOP.md +66 -70
  108. package/skills/w/loops/plan-refine-loop/LOOP.md +15 -7
  109. package/skills/w/loops/spec-refine-loop/LOOP.md +14 -12
  110. package/skills/w/modules/DESIGN-REFERENCES.md +109 -0
  111. package/skills/w/modules/PERSIST-ROUTING.md +1 -0
  112. package/skills/w/modules/PLAN-EXECUTION-BATCHES.md +84 -0
  113. package/skills/w/roles/README.md +7 -5
  114. package/skills/w/roles/design/ROLE.md +217 -0
  115. package/skills/w/schemas/design/design-baseline.v1.schema.json +71 -0
  116. package/skills/w/schemas/design/design-manifest.v1.schema.json +322 -0
  117. package/skills/w/schemas/design/design-review.v1.schema.json +72 -0
  118. package/skills/w/schemas/design/design-revocation.v1.schema.json +54 -0
  119. package/skills/w/schemas/design/ui-flow.v1.schema.json +211 -0
  120. package/skills/w/schemas/design/ui-screen.v1.schema.json +214 -0
  121. package/skills/w/artifacts/artifacts-design/SPEC.md +0 -42
  122. package/skills/w/modules/PLAN-DESIGN-SPECS.md +0 -12
  123. package/skills/w/modules/PLAN-REFINE-DESIGN-SPECS.md +0 -7
  124. package/skills/w/roles/ui-spec/ROLE.md +0 -147
@@ -12,7 +12,7 @@ All 6 roles, their built-in defaults, their tier, and which loops/exports compos
12
12
 
13
13
  | Role | Default built-in | Tier | Composed by |
14
14
  |---|---|---|---|
15
- | `ui-design` | [`ui-spec`](ui-spec/ROLE.md) | must | `spec-refine-loop` (when requirement involves UI) · `plan-new-loop` / `plan-refine-loop` (per-screen design SPECs) |
15
+ | `design` | [`design`](design/ROLE.md) | must | `spec-refine-loop` (when requirement involves UI) · `plan-new-loop` / `plan-refine-loop` · `plan-exec-loop` (reads, never redesigns) |
16
16
  | `sql` | `sql` | must | inline research · `plan-exec-loop` · `quick-loop` · `export-scripts` |
17
17
  | `git` | `git` | must | `plan-exec-loop` · `quick-loop` |
18
18
  | `research` | [`research`](research/ROLE.md) | should | all loops (on-demand investigation) |
@@ -25,6 +25,8 @@ All 6 roles, their built-in defaults, their tier, and which loops/exports compos
25
25
 
26
26
  > **Ambient conventions (not roles).** Code, testing and writing standards **and tool authoring** (`creating-tools`, which writes `docs/tools`) are **not Workline roles** and are never bound: they are **standalone skills the host auto-discovers by `description`** and applies when relevant. Workline is **indifferent** (it neither reads nor looks for them). Useful families live in marketplace plugins (`dev-conventions`, `tool-builder`), but Workline does **not depend** on them.
27
27
  >
28
+ > **`ui-design` and `ui-spec` are retired names.** The design slot is [`design`](design/ROLE.md), whose only output is the UI Design Package v1. Neither retired name is a role, a binding, an alias or an implementation: they are **rejected**, because two names for one capability are two contracts in disguise. There is no alias, no dual-read, no importer and no migration — a binding that names one is reported as `retired/unsupported`, and a design that is still needed is recreated over the package.
29
+ >
28
30
  > **The closing review is not a role either** (deliberate decision — a `conventions`/`rules`/`review` role was evaluated and discarded): the pre-commit **closing review gate** of `plan-exec-loop`/`quick-loop` is a **loop step**; the loop creates the **moment** and the installed ambient conventions fill it. A role that "points at the marketplace skills" would re-couple what this extraction decoupled. The **minimality / anti-over-engineering** lens is **not a role either**: it is a built-in property of the convergence gate (chassis § *Minimality*), owed with no external skill and merely *raised* by whatever ambient review skills are installed — internal essence without the coupling a role would reintroduce.
29
31
 
30
32
  ---
@@ -56,7 +58,7 @@ built-in default
56
58
  ```toml
57
59
  [skills]
58
60
  # Built-in defaults (no entry needed — listed here for reference only)
59
- # ui-design = "ui-spec"
61
+ # design = "design"
60
62
  # sql = "sql"
61
63
  # git = "git"
62
64
  # research = "research"
@@ -64,7 +66,7 @@ built-in default
64
66
  # overview = "w"
65
67
 
66
68
  # Override examples:
67
- ui-design = "acme/figma-spec" # third-party skill installed via skills.sh
69
+ design = "acme/figma-spec" # third-party skill installed via skills.sh
68
70
  diagrams = "mermaid-only" # custom built installed locally
69
71
  sql = "off" # disable the sql capability
70
72
  ```
@@ -73,7 +75,7 @@ sql = "off" # disable the sql capability
73
75
 
74
76
  ```toml
75
77
  [skills]
76
- ui-design = "acme/figma-spec"
78
+ design = "acme/figma-spec"
77
79
  ```
78
80
 
79
81
  `acme/figma-spec` must be installed on the host (e.g. via `skills.sh install acme/figma-spec`). The binding is **advisory**: the resolver emits the name as-is — it does **not** verify the skill is installed and does **not** auto-fall-back to the built-in default. A typo'd name silently leaves the role bound to a skill that does not exist. Verify the resolution with `aw skills`, which warns when a bound skill is not found in the standard skill roots.
@@ -111,7 +113,7 @@ Example output:
111
113
  ```
112
114
  Role Resolved skill Source
113
115
  ----------------- ----------------------- -----------
114
- ui-design ui-spec built-in
116
+ design design built-in
115
117
  sql sql built-in
116
118
  git git built-in
117
119
  research research built-in
@@ -0,0 +1,217 @@
1
+ ---
2
+ name: design
3
+ description: >-
4
+ UI design authoring over the **UI Design Package v1** — the durable dossier
5
+ under `docs/designs/NNN-design-<slug>/` that a spec references and a plan
6
+ implements against. Authors **flows** (the journey: nodes, edges, actors) and
7
+ **screens** (the surface: states, structure, data, accessibility) as Markdown
8
+ with versioned YAML frontmatter, plus the rules, tokens, renditions and
9
+ governance records around them. Knows the package layout, the six canonical
10
+ schemas, the maturity ladder (`outline` → `handoff`), the reference grammar
11
+ `DES-NNN/SCR-NNN@rN#anchor`, and what a document must close before an
12
+ implementation may be planned against it. Use when a loop refines a spec,
13
+ builds or refines a plan, or executes one that involves screens, forms,
14
+ dashboards, modals or any UI surface.
15
+ ---
16
+
17
+ # design — UI design over the UI Design Package v1
18
+
19
+ ## Role
20
+
21
+ `design` — this is its **built-in default implementation**, and `design` is the
22
+ **only public identity** of this capability. `ui-design` (the role this
23
+ replaces) and `ui-spec` (the skill that used to fill it) are **not** aliases,
24
+ **not** alternative implementations and **not** accepted names: a second name
25
+ for one capability is a second contract in disguise, and the day the two
26
+ disagree there is no way to say which one the package obeys.
27
+
28
+ Rebindable in `.workflow/skills.toml` to a third-party skill or `off`.
29
+ Resolution: built-in default → `~/.workflow/skills.toml` (global) →
30
+ `.workflow/skills.toml` (workspace). See [`../README.md`](../README.md).
31
+
32
+ ## Purpose
33
+
34
+ Given a UI requirement, author the **semantic** design of its journeys and
35
+ surfaces into a package that outlives the session that produced it: durable,
36
+ versioned, referenceable by digest, and complete enough that an implementation
37
+ can be planned against it without reopening the design conversation.
38
+
39
+ The package is the deliverable. A spec **references** it; it never contains it.
40
+
41
+ ## Composed by
42
+
43
+ - **`spec-refine-loop`** — the requirement involves UI: reuse a compatible
44
+ baseline or open an `outline` revision, and leave only `## Design references`
45
+ in the spec document.
46
+ - **`plan-new-loop` · `plan-refine-loop`** — the plan consumes UI: promote to
47
+ `handoff` exactly the closure the plan consumes, and write the exact roots
48
+ into each phase or task.
49
+ - **`plan-exec-loop`** — reads and validates; **never redesigns**. A design that
50
+ turns out wrong stops execution and goes back to the refining loop.
51
+
52
+ In all of them the composing loop contributes the human questions
53
+ (*structured-choice*, chassis § *Structured-choice*), the gap-driven iteration
54
+ and the curation. This skill contributes what a correct package looks like.
55
+
56
+ ## Knowledge
57
+
58
+ ### Package layout
59
+
60
+ ```
61
+ docs/designs/NNN-design-<slug>/
62
+ design-manifest.json mutable index — catalog, governance, currentness
63
+ baselines/DES-NNN-rNNN.json immutable: what the package IS at that revision
64
+ flows/FLW-NNN-rNNN-<slug>.md
65
+ screens/SCR-NNN-rNNN-<slug>.md
66
+ design-system/rules/RUL-NNN-rNNN-<slug>.md
67
+ tokens/TOK-NNN-rNNN-<slug>.tokens.json
68
+ renditions/VIS-NNN-rNNN-<slug>/rendition.json
69
+ assets/<digest>-<name>.<ext>
70
+ governance/reviews/REV-NNN.json
71
+ governance/revocations/RVK-NNN.json
72
+ PACKAGE.md · design-system/DESIGN.md regenerable projections, never sealed
73
+ ```
74
+
75
+ The revision is **in the file name**, so publishing `@r2` writes a new file and
76
+ *cannot* overwrite `@r1` — not by policy, by path. An asset carries the digest
77
+ of its own bytes, so different content can never occupy the same name.
78
+
79
+ ### The two documents this skill authors
80
+
81
+ Both are Markdown: versioned YAML frontmatter (identity, relations, trace,
82
+ unknowns) plus a **fixed list of `##` sections**, once each, in order, none
83
+ empty. A section that genuinely does not apply is declared in
84
+ `not_applicable: {key: reason}` — silence is not closure, and the **essential**
85
+ sections admit no such claim.
86
+
87
+ | | `flow` (`workline.ui-flow/v1`) | `screen` (`workline.ui-screen/v1`) |
88
+ |---|---|---|
89
+ | Answers | how the journey runs | what one surface is |
90
+ | Frontmatter core | `actors`, `entry`, `nodes`, `edges` | `default_state`, `states[]`, `flow_refs`, `dependencies` |
91
+ | Sections | Goal and outcome · Preconditions and entry · Main journey · Alternatives and recovery · Permissions and privacy · Traceability | Purpose and context · Structure and content · Components and design-system deltas · Data, permissions and validation · States and transitions · Interaction and navigation · Responsive and adaptation · Localization · Accessibility · Edge cases and degradation · Traceability |
92
+ | Essential (no waiver) | Goal and outcome · Main journey · Traceability | Purpose and context · Structure and content · States and transitions · Interaction and navigation · Accessibility · Traceability |
93
+
94
+ ### Reference grammar
95
+
96
+ `DES-001/SCR-001@r2#error` — package / artifact @ revision # state anchor. A
97
+ reference always pins the revision: **a later revision never invalidates a
98
+ reference already fixed**. Baselines are cited as `DES-001@r2` plus the digest
99
+ that seals them.
100
+
101
+ ### Maturity: `outline` → `handoff`
102
+
103
+ `outline` is a legitimate state, not a failure — it exists precisely to hold
104
+ what is not yet decided. A document may declare `handoff` only when:
105
+
106
+ - its **applicable completeness** is closed (every section says something or is
107
+ waived with a reason);
108
+ - it carries **no blocking unknown** (`unknowns[].blocking: true`);
109
+ - a flow **resolves its graph** — nodes with no edges are not a journey;
110
+ - every reference to **another package** is pinned in `external[]` by provider,
111
+ revision and digest;
112
+ - no essential section answers with a **rendition and nothing else**: an
113
+ approved image is not the current semantics and is not a WCAG conformance.
114
+
115
+ ### Governance: four independent dimensions
116
+
117
+ **Maturity** (`outline`/`handoff`), **review** (a `REV-*.json` that approves or
118
+ rejects an exact baseline *by digest*), **currentness** (derived from
119
+ `supersedes` — superseded warns and still executes) and **execution policy**
120
+ (whether the workspace demands approval) move **separately**. An approval is
121
+ never inherited: a new revision returns to `proposed`, and the only way to
122
+ forbid an intact revision is an explicit, audited revocation.
123
+
124
+ ## Operations
125
+
126
+ Five semantic operations, all over the **same** package. `create` and `update`
127
+ are one route with a different compare-and-swap base, not two formats.
128
+
129
+ | Operation | Does | Writes |
130
+ |---|---|---|
131
+ | `create` | first revision of a package | manifest, baseline, artifacts, projections |
132
+ | `update` | next revision of an existing package | idem, over a declared base |
133
+ | `validate` | judges without writing: schemas, naming, references, maturity, closure | nothing |
134
+ | `render` | regenerates the projections | `PACKAGE.md`, `design-system/DESIGN.md` — never sealed |
135
+ | `record` | seals a governance decision about a revision that exists | `governance/reviews/` · `governance/revocations/` |
136
+
137
+ None of them may invent a layout or a schema of its own. There is no «direct
138
+ package», no parallel Markdown render and no side JSON: **one format, one
139
+ authority**.
140
+
141
+ ## Canonical authority
142
+
143
+ The normative contract is the six published JSON Schemas under
144
+ [`../../schemas/design/`](../../schemas/design/) — manifest, baseline, flow,
145
+ screen, review, revocation — and the validators that implement them. The
146
+ built-in floor and **every** improvement bound to this role validate their
147
+ output against exactly those, with the same gates.
148
+
149
+ - A missing external improvement **never blocks the floor**: with nothing bound,
150
+ the role resolves to this skill and the capability keeps working.
151
+ - A contributor extends the domain by **adding fields to a schema**, never by
152
+ declaring a format of their own. Nobody redefines the canonical authority —
153
+ not a bound skill, not a host, not a workspace.
154
+
155
+ ## Boundary with Spec 014
156
+
157
+ The **transversal capability lifecycle belongs to Spec 014 and is not
158
+ reimplemented here**: skill descriptor, enable/disable lifecycle, the
159
+ `request` / `outcome` / `receipt` envelope, routing between direct and composed
160
+ paths, `off`, effects, and host-native projection are governed there.
161
+
162
+ This contract adds **only** what is proper to the design domain: fields,
163
+ validators and completeness. Where the two meet, Spec 014 decides the envelope
164
+ and this one decides the payload. Duplicating either side is the failure mode
165
+ being avoided.
166
+
167
+ ## CLI ↔ agent split
168
+
169
+ Explicit, and it is the whole point of the handshake:
170
+
171
+ - **The CLI owns** inventory, numbering, digests, validation, authorization and
172
+ **writing**. It is the only thing that touches the filesystem.
173
+ - **The agent owns** exactly one step: authoring the **semantic content**. Its
174
+ answer is *data to be validated*, never an instruction to be trusted.
175
+
176
+ Three stages, and only the third writes: `prepare` (what was read, where writing
177
+ is allowed, and an `input_digest` sealing the state seen) → `validate` (parse the
178
+ answer against that request; on survival, a preview and an `approval_digest`
179
+ over the exact bytes proposed) → `apply` (recompute the input digest, check the
180
+ approval still matches, publish all-or-nothing).
181
+
182
+ ## Output
183
+
184
+ The package itself — new artifact files plus the revision that seals them. The
185
+ **loop** writes (through the CLI), never this skill on its own.
186
+
187
+ What this skill does **not** produce: design inside a spec or a plan document.
188
+ A spec carries `## Design references` (package, baseline, digest, path hint); a
189
+ plan carries the exact roots each phase or task consumes. Embedding the design
190
+ in the document is what the package exists to end.
191
+
192
+ ## Retired path — `retired/unsupported`, and nothing else
193
+
194
+ The legacy path is **gone**: the `ui-design` binding, the `ui-spec` skill, the
195
+ spec's `## UI spec` section and the per-screen design SPECs that PLAN sessions
196
+ carried. `design` is the only identity and the package above the only format.
197
+
198
+ Presenting any of it — a binding or invocation naming a retired name, a `## UI
199
+ spec` section, a session design SPEC, an output of `ui-spec-generator` — is
200
+ reported **`retired/unsupported`**. It is never read as a contract, and never
201
+ satisfies a gate as evidence. There is **no alias, no dual-read, no importer, no
202
+ conversion, no migrate-on-touch and no bulk migration**: a design that is still
203
+ needed is **recreated** over the package from current sources.
204
+
205
+ What retirement does not do is destroy: every document already written stays
206
+ exactly where it is, byte for byte, readable by whoever opens it. Retiring an
207
+ input is not the same as deleting a record.
208
+
209
+ **`ui-spec-generator` is outside this topology.** It is not a dependency, not an
210
+ adapter and not a source of truth for anything here; nothing in Workline reads,
211
+ invokes or imports it. Whatever becomes of that repository is its own business —
212
+ cleaning it up is explicitly not part of this contract.
213
+
214
+ ## Source
215
+
216
+ Requirement: `docs/specs/013-spec-estandarizar-ui-spec.md`. Contract and
217
+ rationale: the six schemas under [`../../schemas/design/`](../../schemas/design/).
@@ -0,0 +1,71 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://workline.dev/schemas/design/design-baseline.v1.schema.json",
4
+ "title": "Workline UI Design Package v1 — baseline",
5
+ "description": "Immutable authority of one published revision: the closed selection of normative files with their revision and the SHA-256 of their bytes, sealed by a digest over canonical JSON WITHOUT the digest field. The mutable manifest, the governance records and the regenerable projections are excluded by construction, so re-indexing or re-rendering can never alter a revision published months ago.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "schema",
10
+ "package",
11
+ "revision",
12
+ "parent_baseline",
13
+ "published",
14
+ "digest",
15
+ "selection"
16
+ ],
17
+ "properties": {
18
+ "schema": {
19
+ "const": "workline.design-baseline/v1"
20
+ },
21
+ "package": {
22
+ "type": "string",
23
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})$"
24
+ },
25
+ "revision": {
26
+ "type": "integer",
27
+ "minimum": 1
28
+ },
29
+ "parent_baseline": {
30
+ "description": "The previous revision of THIS package, or null for the first. A line never forks: an intentional divergence creates another package with `derived_from`.",
31
+ "type": ["string", "null"],
32
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})@r[1-9][0-9]{0,5}$"
33
+ },
34
+ "published": {
35
+ "type": "string",
36
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
37
+ },
38
+ "digest": {
39
+ "description": "SHA-256 over canonical JSON of this document WITHOUT this field. No self-reference, so anyone can recompute and compare.",
40
+ "type": "string",
41
+ "pattern": "^sha256:[0-9a-f]{64}$"
42
+ },
43
+ "selection": {
44
+ "description": "The closed set of normative files this revision publishes together. Never empty: a published revision publishes something.",
45
+ "type": "array",
46
+ "items": {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "required": ["path", "revision", "sha256"],
50
+ "properties": {
51
+ "path": {
52
+ "description": "Package-relative path under flows/, screens/, design-system/rules/, tokens/, renditions/ or assets/.",
53
+ "type": "string",
54
+ "minLength": 1
55
+ },
56
+ "revision": {
57
+ "description": "The revision the file's own name carries; null for a content-addressed asset.",
58
+ "type": ["integer", "null"],
59
+ "minimum": 1
60
+ },
61
+ "sha256": {
62
+ "description": "Digest of the file's BYTES, not of a projection of them.",
63
+ "type": "string",
64
+ "pattern": "^sha256:[0-9a-f]{64}$"
65
+ }
66
+ }
67
+ },
68
+ "minItems": 1
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,322 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://workline.dev/schemas/design/design-manifest.v1.schema.json",
4
+ "title": "Workline UI Design Package v1 — design manifest",
5
+ "description": "Mutable discovery index of a UI Design Package. Owns nothing normative: it declares identity, where the artifacts live, which baseline is current and who consumes the package. A baseline digest excludes this file, so re-indexing never rewrites a published revision.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "schema",
10
+ "id",
11
+ "title",
12
+ "created",
13
+ "derived_from",
14
+ "current_baseline",
15
+ "baselines",
16
+ "catalog",
17
+ "currentness",
18
+ "governance",
19
+ "relations"
20
+ ],
21
+ "properties": {
22
+ "schema": {
23
+ "description": "Format version. An unknown value stops validation before any field is read.",
24
+ "const": "workline.design-manifest/v1"
25
+ },
26
+ "id": {
27
+ "description": "Package identity. Derives from nothing — not a spec, plan, session, slug, path or provider — and survives every rename or move.",
28
+ "type": "string",
29
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})$"
30
+ },
31
+ "title": {
32
+ "description": "Human name of the package.",
33
+ "type": "string",
34
+ "minLength": 1
35
+ },
36
+ "created": {
37
+ "type": "string",
38
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
39
+ },
40
+ "derived_from": {
41
+ "description": "Baseline of the package this one forked from. An intentional divergence creates another package instead of a second live baseline line.",
42
+ "type": ["string", "null"],
43
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})@r[1-9][0-9]{0,5}$"
44
+ },
45
+ "current_baseline": {
46
+ "description": "The published baseline in force. Null until the first publication. Must match its entry in `baselines`.",
47
+ "type": ["object", "null"],
48
+ "additionalProperties": false,
49
+ "required": ["revision", "path", "digest"],
50
+ "properties": {
51
+ "revision": {
52
+ "type": "integer",
53
+ "minimum": 1
54
+ },
55
+ "path": {
56
+ "$ref": "#/$defs/packagePath"
57
+ },
58
+ "digest": {
59
+ "$ref": "#/$defs/digest"
60
+ }
61
+ }
62
+ },
63
+ "baselines": {
64
+ "description": "The package's baseline line, chained by `parent_baseline`.",
65
+ "type": "array",
66
+ "items": {
67
+ "type": "object",
68
+ "additionalProperties": false,
69
+ "required": ["revision", "path", "digest", "parent_baseline", "published"],
70
+ "properties": {
71
+ "revision": {
72
+ "type": "integer",
73
+ "minimum": 1
74
+ },
75
+ "path": {
76
+ "$ref": "#/$defs/packagePath"
77
+ },
78
+ "digest": {
79
+ "$ref": "#/$defs/digest"
80
+ },
81
+ "parent_baseline": {
82
+ "type": ["string", "null"],
83
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})@r[1-9][0-9]{0,5}$"
84
+ },
85
+ "published": {
86
+ "type": "string",
87
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
88
+ }
89
+ }
90
+ }
91
+ },
92
+ "catalog": {
93
+ "description": "Every revision the package holds. Flows and screens carry maturity; rules, tokens and renditions do not; assets are content-addressed and have no ID.",
94
+ "type": "object",
95
+ "additionalProperties": false,
96
+ "required": ["flows", "screens", "rules", "tokens", "renditions", "assets"],
97
+ "properties": {
98
+ "flows": {
99
+ "type": "array",
100
+ "items": {
101
+ "$ref": "#/$defs/maturedArtifact"
102
+ }
103
+ },
104
+ "screens": {
105
+ "type": "array",
106
+ "items": {
107
+ "$ref": "#/$defs/screenArtifact"
108
+ }
109
+ },
110
+ "rules": {
111
+ "type": "array",
112
+ "items": {
113
+ "$ref": "#/$defs/revisionedArtifact"
114
+ }
115
+ },
116
+ "tokens": {
117
+ "type": "array",
118
+ "items": {
119
+ "$ref": "#/$defs/revisionedArtifact"
120
+ }
121
+ },
122
+ "renditions": {
123
+ "type": "array",
124
+ "items": {
125
+ "$ref": "#/$defs/revisionedArtifact"
126
+ }
127
+ },
128
+ "assets": {
129
+ "type": "array",
130
+ "items": {
131
+ "type": "object",
132
+ "additionalProperties": false,
133
+ "required": ["digest", "path"],
134
+ "properties": {
135
+ "digest": {
136
+ "$ref": "#/$defs/digest"
137
+ },
138
+ "path": {
139
+ "description": "`assets/<sha256>-<safe-name>.<ext>` — the digest is in the file name, so different bytes can never occupy the same path.",
140
+ "$ref": "#/$defs/packagePath"
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ },
147
+ "currentness": {
148
+ "description": "Derived from `supersedes`, cached here for discovery. Superseded warns; it never blocks — only an explicit revocation does.",
149
+ "type": "array",
150
+ "items": {
151
+ "type": "object",
152
+ "additionalProperties": false,
153
+ "required": ["ref", "state"],
154
+ "properties": {
155
+ "ref": {
156
+ "$ref": "#/$defs/artifactRef"
157
+ },
158
+ "state": {
159
+ "enum": ["current", "superseded"]
160
+ }
161
+ }
162
+ }
163
+ },
164
+ "governance": {
165
+ "description": "Index of review and revocation records. The records themselves live outside the baseline they decide on, so no digest is self-referential.",
166
+ "type": "object",
167
+ "additionalProperties": false,
168
+ "required": ["reviews", "revocations"],
169
+ "properties": {
170
+ "reviews": {
171
+ "type": "array",
172
+ "items": {
173
+ "$ref": "#/$defs/governanceEntry"
174
+ }
175
+ },
176
+ "revocations": {
177
+ "type": "array",
178
+ "items": {
179
+ "$ref": "#/$defs/governanceEntry"
180
+ }
181
+ }
182
+ }
183
+ },
184
+ "relations": {
185
+ "description": "Many-to-many links to the documents that consume this package — the backreference direction, so a consumer is found without scanning docs/.",
186
+ "type": "object",
187
+ "additionalProperties": false,
188
+ "required": ["specs", "plans"],
189
+ "properties": {
190
+ "specs": {
191
+ "type": "array",
192
+ "items": {
193
+ "type": "string"
194
+ }
195
+ },
196
+ "plans": {
197
+ "type": "array",
198
+ "items": {
199
+ "type": "string"
200
+ }
201
+ }
202
+ }
203
+ }
204
+ },
205
+ "$defs": {
206
+ "digest": {
207
+ "type": "string",
208
+ "pattern": "^sha256:[0-9a-f]{64}$"
209
+ },
210
+ "packagePath": {
211
+ "description": "Package-relative path. Never absolute, never Windows-separated, never carrying `.` or `..`.",
212
+ "type": "string",
213
+ "pattern": "^[^/\\\\][^\\\\]*$"
214
+ },
215
+ "artifactRef": {
216
+ "type": "string",
217
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})/(?:FLW|SCR|RUL|TOK|VIS|REV|RVK)-(?:[0-9]{3}|[1-9][0-9]{3,})@r[1-9][0-9]{0,5}(#[A-Za-z0-9][A-Za-z0-9_-]*)?$"
218
+ },
219
+ "revisionedArtifact": {
220
+ "type": "object",
221
+ "additionalProperties": false,
222
+ "required": ["id", "revision", "path", "supersedes"],
223
+ "properties": {
224
+ "id": {
225
+ "type": "string",
226
+ "pattern": "^(?:FLW|SCR|RUL|TOK|VIS)-(?:[0-9]{3}|[1-9][0-9]{3,})$"
227
+ },
228
+ "revision": {
229
+ "type": "integer",
230
+ "minimum": 1
231
+ },
232
+ "path": {
233
+ "$ref": "#/$defs/packagePath"
234
+ },
235
+ "supersedes": {
236
+ "type": ["string", "null"],
237
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})/(?:FLW|SCR|RUL|TOK|VIS)-(?:[0-9]{3}|[1-9][0-9]{3,})@r[1-9][0-9]{0,5}$"
238
+ }
239
+ }
240
+ },
241
+ "maturedArtifact": {
242
+ "type": "object",
243
+ "additionalProperties": false,
244
+ "required": ["id", "revision", "path", "supersedes", "maturity"],
245
+ "properties": {
246
+ "id": {
247
+ "type": "string",
248
+ "pattern": "^(?:FLW|SCR)-(?:[0-9]{3}|[1-9][0-9]{3,})$"
249
+ },
250
+ "revision": {
251
+ "type": "integer",
252
+ "minimum": 1
253
+ },
254
+ "path": {
255
+ "$ref": "#/$defs/packagePath"
256
+ },
257
+ "supersedes": {
258
+ "type": ["string", "null"],
259
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})/(?:FLW|SCR)-(?:[0-9]{3}|[1-9][0-9]{3,})@r[1-9][0-9]{0,5}$"
260
+ },
261
+ "maturity": {
262
+ "enum": ["outline", "handoff"]
263
+ }
264
+ }
265
+ },
266
+ "governanceEntry": {
267
+ "type": "object",
268
+ "additionalProperties": false,
269
+ "required": ["id", "path", "digest", "target"],
270
+ "properties": {
271
+ "id": {
272
+ "type": "string",
273
+ "pattern": "^(?:REV|RVK)-(?:[0-9]{3}|[1-9][0-9]{3,})$"
274
+ },
275
+ "path": {
276
+ "$ref": "#/$defs/packagePath"
277
+ },
278
+ "digest": {
279
+ "$ref": "#/$defs/digest"
280
+ },
281
+ "target": {
282
+ "type": "string",
283
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})@r[1-9][0-9]{0,5}$"
284
+ }
285
+ }
286
+ },
287
+ "screenArtifact": {
288
+ "type": "object",
289
+ "additionalProperties": false,
290
+ "required": ["id", "revision", "path", "supersedes", "maturity", "states"],
291
+ "properties": {
292
+ "id": {
293
+ "type": "string",
294
+ "pattern": "^(?:FLW|SCR)-(?:[0-9]{3}|[1-9][0-9]{3,})$"
295
+ },
296
+ "revision": {
297
+ "type": "integer",
298
+ "minimum": 1
299
+ },
300
+ "path": {
301
+ "$ref": "#/$defs/packagePath"
302
+ },
303
+ "supersedes": {
304
+ "type": ["string", "null"],
305
+ "pattern": "^DES-(?:[0-9]{3}|[1-9][0-9]{3,})/(?:FLW|SCR)-(?:[0-9]{3}|[1-9][0-9]{3,})@r[1-9][0-9]{0,5}$"
306
+ },
307
+ "maturity": {
308
+ "enum": ["outline", "handoff"]
309
+ },
310
+ "states": {
311
+ "type": "array",
312
+ "minItems": 1,
313
+ "uniqueItems": true,
314
+ "items": {
315
+ "type": "string",
316
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]*$"
317
+ }
318
+ }
319
+ }
320
+ }
321
+ }
322
+ }