dsh-archify-projects 0.0.0-stage → 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 (148) hide show
  1. package/README.md +204 -2
  2. package/cordis.patch.yml +99 -0
  3. package/dist/client.js +2261 -0
  4. package/dist/client.js.map +1 -0
  5. package/docs/CONTAINER.md +197 -0
  6. package/docs/DESIGN.md +905 -0
  7. package/docs/HANDOVER.md +391 -0
  8. package/docs/PUBLISH.md +107 -0
  9. package/icon.svg +12 -0
  10. package/lib/host/archify-skill.js +116 -0
  11. package/lib/host/archify-skill.js.map +1 -0
  12. package/lib/host/config.js +95 -0
  13. package/lib/host/config.js.map +1 -0
  14. package/lib/host/context.js +28 -0
  15. package/lib/host/context.js.map +1 -0
  16. package/lib/host/git.js +185 -0
  17. package/lib/host/git.js.map +1 -0
  18. package/lib/host/http.js +184 -0
  19. package/lib/host/http.js.map +1 -0
  20. package/lib/host/index.js +90 -0
  21. package/lib/host/index.js.map +1 -0
  22. package/lib/host/policy.js +124 -0
  23. package/lib/host/policy.js.map +1 -0
  24. package/lib/host/routes.js +667 -0
  25. package/lib/host/routes.js.map +1 -0
  26. package/lib/host/runner.js +913 -0
  27. package/lib/host/runner.js.map +1 -0
  28. package/lib/host/store.js +370 -0
  29. package/lib/host/store.js.map +1 -0
  30. package/lib/host/workspace.js +65 -0
  31. package/lib/host/workspace.js.map +1 -0
  32. package/lib/shared/format.js +138 -0
  33. package/lib/shared/format.js.map +1 -0
  34. package/lib/shared/prompt.js +257 -0
  35. package/lib/shared/prompt.js.map +1 -0
  36. package/lib/shared/protocol.js +31 -0
  37. package/lib/shared/protocol.js.map +1 -0
  38. package/lib/shared/types.js +173 -0
  39. package/lib/shared/types.js.map +1 -0
  40. package/locale/en.json +6 -0
  41. package/locale/zh.json +6 -0
  42. package/package.json +98 -4
  43. package/skills/archify/LICENSE +22 -0
  44. package/skills/archify/SKILL.md +109 -0
  45. package/skills/archify/THIRD_PARTY_NOTICES.md +69 -0
  46. package/skills/archify/assets/JetBrainsMono-OFL.txt +93 -0
  47. package/skills/archify/assets/template.html +13709 -0
  48. package/skills/archify/bin/archify.mjs +6936 -0
  49. package/skills/archify/bin/delivery-update.mjs +91 -0
  50. package/skills/archify/bin/finalize.mjs +895 -0
  51. package/skills/archify/bin/open-artifact.mjs +146 -0
  52. package/skills/archify/bin/preview.mjs +969 -0
  53. package/skills/archify/bin/recover-output.mjs +41 -0
  54. package/skills/archify/bin/visual-check.mjs +2667 -0
  55. package/skills/archify/brand-marks/README.md +31 -0
  56. package/skills/archify/brand-marks/catalog.json +131 -0
  57. package/skills/archify/delta/architecture-delta.mjs +1313 -0
  58. package/skills/archify/examples/agent-run.lifecycle.json +55 -0
  59. package/skills/archify/examples/agent-tool-call.workflow.json +74 -0
  60. package/skills/archify/examples/async-job-roundtrip.sequence.json +56 -0
  61. package/skills/archify/examples/brand-aware-delivery.architecture.json +34 -0
  62. package/skills/archify/examples/cache-miss-request.sequence.json +77 -0
  63. package/skills/archify/examples/checkout-platform.base.architecture.json +32 -0
  64. package/skills/archify/examples/checkout-platform.head.architecture.json +32 -0
  65. package/skills/archify/examples/dataflow-product-analytics.html +13820 -0
  66. package/skills/archify/examples/deployment-release.lifecycle.json +48 -0
  67. package/skills/archify/examples/event-stream.dataflow.json +52 -0
  68. package/skills/archify/examples/holiday-planning.workflow.json +143 -0
  69. package/skills/archify/examples/incident-response.workflow.json +59 -0
  70. package/skills/archify/examples/lifecycle-agent-run.html +13765 -0
  71. package/skills/archify/examples/locales/de.json +425 -0
  72. package/skills/archify/examples/locales/es.json +440 -0
  73. package/skills/archify/examples/locales/fr.json +425 -0
  74. package/skills/archify/examples/locales/fr.partial.json +22 -0
  75. package/skills/archify/examples/locales/it.json +425 -0
  76. package/skills/archify/examples/locales/ja.json +425 -0
  77. package/skills/archify/examples/locales/ko.json +440 -0
  78. package/skills/archify/examples/locales/pt.json +425 -0
  79. package/skills/archify/examples/locales/ru.json +425 -0
  80. package/skills/archify/examples/product-analytics.dataflow.json +71 -0
  81. package/skills/archify/examples/production-deployment.architecture.json +51 -0
  82. package/skills/archify/examples/release-delivery.workflow.json +57 -0
  83. package/skills/archify/examples/sequence-cache-miss-request.html +13835 -0
  84. package/skills/archify/examples/web-app-rendered.html +13808 -0
  85. package/skills/archify/examples/web-app.architecture.json +41 -0
  86. package/skills/archify/examples/workflow-agent-tool-call-rendered.html +13826 -0
  87. package/skills/archify/migrations/workflow-v2.mjs +280 -0
  88. package/skills/archify/package.json +17 -0
  89. package/skills/archify/recipes/scenarios.mjs +430 -0
  90. package/skills/archify/references/architecture-layout-repair.md +18 -0
  91. package/skills/archify/references/authoring-contract.md +419 -0
  92. package/skills/archify/references/authoring-defaults.md +41 -0
  93. package/skills/archify/references/brand-marks.md +82 -0
  94. package/skills/archify/references/delivery-contract.md +588 -0
  95. package/skills/archify/references/repository-authoring.md +105 -0
  96. package/skills/archify/references/update-awareness.md +12 -0
  97. package/skills/archify/references/viewer-runtime.md +35 -0
  98. package/skills/archify/renderers/architecture/grid.mjs +62 -0
  99. package/skills/archify/renderers/architecture/labels.mjs +215 -0
  100. package/skills/archify/renderers/architecture/render-architecture.mjs +1001 -0
  101. package/skills/archify/renderers/architecture/routing.mjs +1157 -0
  102. package/skills/archify/renderers/dataflow/README.md +105 -0
  103. package/skills/archify/renderers/dataflow/render-dataflow.mjs +544 -0
  104. package/skills/archify/renderers/lifecycle/README.md +171 -0
  105. package/skills/archify/renderers/lifecycle/grid-routing.mjs +429 -0
  106. package/skills/archify/renderers/lifecycle/render-lifecycle.mjs +938 -0
  107. package/skills/archify/renderers/sequence/README.md +129 -0
  108. package/skills/archify/renderers/sequence/render-sequence.mjs +526 -0
  109. package/skills/archify/renderers/shared/atomic-output.mjs +1982 -0
  110. package/skills/archify/renderers/shared/brand-marks.mjs +670 -0
  111. package/skills/archify/renderers/shared/cli.mjs +451 -0
  112. package/skills/archify/renderers/shared/desktop-readability.mjs +132 -0
  113. package/skills/archify/renderers/shared/diagnostics.mjs +173 -0
  114. package/skills/archify/renderers/shared/engineering-profiles.mjs +157 -0
  115. package/skills/archify/renderers/shared/generated-brand-marks.mjs +2003 -0
  116. package/skills/archify/renderers/shared/generated-validators.mjs +134 -0
  117. package/skills/archify/renderers/shared/geometry.mjs +1941 -0
  118. package/skills/archify/renderers/shared/i18n.mjs +603 -0
  119. package/skills/archify/renderers/shared/layout-report.mjs +42 -0
  120. package/skills/archify/renderers/shared/legend.mjs +217 -0
  121. package/skills/archify/renderers/shared/output-path.mjs +440 -0
  122. package/skills/archify/renderers/shared/path-semantics.mjs +1017 -0
  123. package/skills/archify/renderers/shared/portable-path.mjs +408 -0
  124. package/skills/archify/renderers/shared/repository-evidence.mjs +352 -0
  125. package/skills/archify/renderers/shared/repository-location.mjs +59 -0
  126. package/skills/archify/renderers/shared/route-quality.mjs +614 -0
  127. package/skills/archify/renderers/shared/sidecar-path.mjs +38 -0
  128. package/skills/archify/renderers/shared/spatial-grid.mjs +66 -0
  129. package/skills/archify/renderers/shared/text-fit.mjs +105 -0
  130. package/skills/archify/renderers/shared/utils.mjs +254 -0
  131. package/skills/archify/renderers/shared/validator.mjs +86 -0
  132. package/skills/archify/renderers/workflow/README.md +301 -0
  133. package/skills/archify/renderers/workflow/render-workflow.mjs +37 -0
  134. package/skills/archify/renderers/workflow/workflow-compiler.mjs +4913 -0
  135. package/skills/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
  136. package/skills/archify/schemas/README.md +256 -0
  137. package/skills/archify/schemas/architecture.schema.json +152 -0
  138. package/skills/archify/schemas/common.schema.json +181 -0
  139. package/skills/archify/schemas/dataflow.schema.json +254 -0
  140. package/skills/archify/schemas/lifecycle.schema.json +280 -0
  141. package/skills/archify/schemas/sequence.schema.json +234 -0
  142. package/skills/archify/schemas/workflow.schema.json +439 -0
  143. package/skills/archify/scripts/check-render-output.mjs +1388 -0
  144. package/skills/archify/scripts/check-update.mjs +1710 -0
  145. package/skills/archify/scripts/delivery-update-child.mjs +23 -0
  146. package/skills/archify/scripts/render-examples.mjs +26 -0
  147. package/skills/archify/scripts/update-contract.mjs +182 -0
  148. package/skills/archify/skill-release.json +10 -0
@@ -0,0 +1,419 @@
1
+ # Authoring contract
2
+
3
+ Read this reference only after the Fast authoring path calls for more detail. The schemas and examples remain authoritative.
4
+
5
+ ## Composition repair
6
+
7
+ When correcting an authored overview's abstraction, map every affected role, relationship direction, protocol, boundary, condition, and source reference to its surviving node or relationship before regrouping. A startup citation does not prove a message protocol. Preserve each claim's inspected evidence. Keep user-supplied or agreed topology fixed; fewer routes alone do not justify merging. A boundary around one node requires an explicit isolation fact and must not merely repeat its label.
8
+
9
+ ## Label repair
10
+
11
+ When a relationship label collides, move the label, adjust the route or spacing, then shorten the wording while preserving meaning. Omit wording only when both endpoints fully imply it and it conveys no protocol, action, direction, synchronous or asynchronous behavior, or cross-boundary mechanism. Spacing means clear gap rather than center distance; measured mask width takes precedence. The first-draft gap budget is in [Layout and routing](authoring-defaults.md#layout-and-routing).
12
+
13
+ For a disproportionate sublabel, keep its exact role or protocol concise and place the supplementary fact in a note or card. Preserve every required responsibility, protocol, and boundary fact. Use the first-draft node-width budget in [Layout and routing](authoring-defaults.md#layout-and-routing).
14
+
15
+ ## Schema lookup
16
+
17
+ Read both the mode schema and `schemas/common.schema.json`. The mode schemas use `$ref`, so the common file is where shared enums live.
18
+
19
+ - `componentType`: `frontend`, `backend`, `database`, `cloud`, `security`, `messagebus`, `external`
20
+ - `variant`: `default`, `emphasis`, `security`, `dashed`
21
+ - Relationship IDs use the shared identifier pattern and must be unique in their collection.
22
+
23
+ Do not invent fields. Before writing any new field, enum, or constrained text, read its schema definition, including common `$ref` targets. In particular, check boundary kinds, repository identity, and source-reference shapes. An example demonstrates structure; it does not enumerate every valid value. Author fresh IDs, wording, facts, and layout.
24
+
25
+ ## Workflow layout contracts
26
+
27
+ Use schema v2 for new workflows and keep schema v1 when an existing source must
28
+ retain fixed geometry. In both versions, `col` stays in `0..5` and semantic
29
+ edge labels are never deleted as a spacing repair. Do not change only
30
+ `schema_version` when absolute coordinates exist: follow the canonical
31
+ [migration and layout-receipt contract](../renderers/workflow/README.md#migration-and-layout-receipt).
32
+ The complete normative invariants live in the workflow renderer's
33
+ [layout contracts](../renderers/workflow/README.md#layout-contracts).
34
+ For sequential stages stacked in one container, use one v2 lane and group,
35
+ omit `meta.viewBox`, and center nodes around the lane content with symmetric
36
+ `yOffset` values such as `-90 / 0 / 90`. Keep semantic edge labels and act on
37
+ compiler diagnostics.
38
+
39
+ ## Legend contract
40
+
41
+ Omit `meta.legend` for the truthful default: `auto` lists only semantic kinds
42
+ present in typed IR. Use `mode: "all"` for a renderer reference or
43
+ `mode: "hidden"` to remove the full legend. Under `entries`, only keys listed
44
+ by the selected mode schema are valid; each key accepts `label`, `visible`, or
45
+ both. `visible: true` may show an unused supported convention, while
46
+ `visible: false` hides it. `hidden` cannot be overridden.
47
+
48
+ A label override changes reader wording only. Never infer a kind from prose or
49
+ use the legend to compensate for missing nodes, states, messages, or flows.
50
+ Long labels are measured and wrap into deterministic rows. Architecture's
51
+ implicit automatic viewBox grows from that same measured footprint. For
52
+ backwards compatibility, a legacy document with no `meta.legend` may omit an
53
+ implicit auto legend that cannot fit its explicit viewBox; this never changes
54
+ its typed topology. Adding `meta.legend` makes the presentation intentional and
55
+ strict: if its resolved labels cannot fit the authored viewBox, shorten or hide
56
+ them, or widen the viewBox using the emitted diagnostic.
57
+
58
+ ## Language consistency
59
+
60
+ Choose one primary authored language. An explicit user choice wins; otherwise
61
+ use the language of the request, or the conversation's dominant language when
62
+ the request itself is language-neutral. Separately choose the Viewer locale.
63
+ Always write the matching `meta.locale` as a well-formed language tag: `"en"`
64
+ for English, `"zh-CN"` for Simplified Chinese, `"es"` for Spanish, or any
65
+ other tag for another language. The renderer consumes the authored locale without inferring language
66
+ from diagram strings. Documents that omit it remain valid and default to
67
+ English.
68
+
69
+ `meta.locale` controls only renderer-owned reader surfaces: `<html lang>`, the
70
+ document-title suffix, default SVG description and focus labels, default legend
71
+ labels, and fixed Viewer controls, statuses, accessibility names, and errors.
72
+ It never translates authored content. Apply the primary language separately to
73
+ titles, subtitles, node and relationship copy, boundaries, lanes, groups,
74
+ legend label overrides, and cards. A bilingual diagram still
75
+ chooses one primary locale for the Viewer; follow an explicit primary-language
76
+ request, then prompt order or conversation dominance.
77
+
78
+ `en` and `zh-CN` are built-in Viewer catalogs and need nothing further. For
79
+ every other `meta.locale`, also set `meta.translations`: an object mapping the
80
+ renderer's canonical message keys (`catalogKeys()` in
81
+ `renderers/shared/i18n.mjs`) to translated strings whose `{placeholder}` tokens
82
+ match the English source exactly. Reuse suitable translations from `examples/locales/` or a previously reviewed
83
+ catalog; Spanish uses `examples/locales/es.json`. Translate missing keys or adapt terminology when the diagram needs it;
84
+ use the English source to check keys and placeholders. Example catalogs may
85
+ lag new Viewer keys; validation reports those gaps and uses English for them. A key that is missing, unrecognized, or has mismatched
86
+ placeholders falls back to its English string — `validate`/`render`/`deliver`
87
+ report the resulting coverage to stderr — rather than breaking the render or
88
+ silently shipping an untranslated string as if it were translated.
89
+
90
+ For older dev inputs using only `meta.locale: "es"`, copy the Spanish catalog
91
+ into `meta.translations` before rendering again. Existing standalone HTML
92
+ keeps its embedded translations.
93
+
94
+ For a requested language you cannot supply `meta.translations` for, do not
95
+ write a `meta.locale` with no built-in catalog and no translations. Keep every
96
+ reader-facing authored string in the requested language, omit `meta.locale` so
97
+ the renderer safely uses English, and explicitly tell the user that fixed
98
+ Viewer UI and `<html lang>` remain English and the artifact is not fully localized.
99
+ The fallback applies only to renderer-owned surfaces; it never
100
+ permits authored copy to fall back to English. Do not silently substitute
101
+ `zh-CN` for another language or Chinese locale, and do not machine-translate
102
+ `meta.translations` values without disclosing that they are unreviewed.
103
+
104
+ Keep exact product names, code identifiers, commands, protocols, API paths, and
105
+ environment names intact. Those terms may remain English inside localized copy,
106
+ but surrounding explanatory prose must still use the selected language.
107
+ Renderer-owned default legend labels follow `meta.locale`; author a
108
+ `meta.legend.entries.*.label` override only when the diagram needs different
109
+ domain wording, and keep that authored override in the primary language.
110
+
111
+ ## Visual preset default
112
+
113
+ Omit `meta.visual_preset` by default. The renderer then opens the diagram in
114
+ `classic` for both light and dark color modes. Color mode and visual preset are
115
+ independent viewer state: switching Light / Dark must preserve the current
116
+ preset. Author `signal-flow`, `blueprint`, or `editorial` only when the user
117
+ explicitly requests that visual style.
118
+
119
+ ## Engineering profile default
120
+
121
+ Omit `meta.engineering_profile` for an ordinary system architecture. Region,
122
+ cluster, and security boundary wording do not by themselves enable an
123
+ engineering profile. Enable `deployment-ownership` only when the user
124
+ explicitly asks for a production deployment topology, ownership handoff, or
125
+ fail-closed deployment review and the source facts are known. Once enabled,
126
+ do not remove the engineering profile merely to pass validation; repair the
127
+ authored facts or report the diagnostics truthfully.
128
+
129
+ ## Title hierarchy
130
+
131
+ Use one concise title and let the diagram carry the explanation. Omit
132
+ `meta.subtitle` by default, and never use it to restate the title, nodes, edges,
133
+ or cards. Include one short supporting line only when the user explicitly asks
134
+ for a subtitle; an omitted or blank subtitle must not leave an empty visual row
135
+ in the generated viewer.
136
+
137
+ ## Executable geometry rules
138
+
139
+ Generate one responsive artifact for laptops and external displays, preserving the authored SVG/viewBox, proportions, semantic geometry, and normal document flow. Use meaningful content rows and the Reader-declared readable page-scroll behavior when the complete diagram needs more height; viewport fitting does not authorize alternate topology or smaller typography.
140
+
141
+ - Node anchors start at side midpoints. `left`/`right` change the horizontal endpoint; `top`/`bottom` change the vertical endpoint. For an automatic Architecture relationship, unobstructed facing ports whose axis offset is under 16px may share one horizontal or vertical axis when both endpoints retain the 16px corner gutter. If exactly one endpoint belongs to a spread group, only its unshared counterpart moves; relationships spread at both endpoints keep their distinct ports and outside bridge unless a reciprocal facing pair can jointly use separate straight lanes while preserving endpoint spacing, labels, and all surrounding route and obstacle clearances.
142
+ - A side is a direction contract. The first and final route segment must be perpendicular and outward/inward in the named direction.
143
+ - In architecture, data-flow, and lifecycle diagrams, explicit `route: "straight"` requests one direct segment, which may be diagonal when endpoint sides are not pinned. The artifact checker preserves this intent; explicit sides, opaque-node clearance, and other quality gates still apply. `via` takes precedence and retains existing rules, including data-flow's requirement for orthogonal via segments.
144
+ - Automatic Port Spread is a default renderer behavior for architecture, workflow, data-flow, and lifecycle diagrams. Shared automatic endpoints spread deterministically and symmetrically with a 16px corner gutter. It does not apply to sequence messages, single relationships, or explicit `via`, `channelX`, `channelY`, `labelAt`, or non-`auto` routes.
145
+ - Showcase route rhythm: every nonzero segment must be at least 8px; every interior segment must be at least 16px. When spread ports are nearly parallel, the router uses a 24px endpoint stub and a 16px outside bridge instead of manufacturing a tiny dogleg.
146
+ - Showcase route compactness: an explicit Architecture route fails with `composition/excessive-route-detour` when its orthogonal length is at least 2.5 times an obstacle-aware legal route, adds at least 200px, and sends a control point at least 96px beyond the content envelope. The evidence records both lengths, ratio, excess, bounds, and excursion. Remove an unnecessary `via` or move the diagnosed corridor inward instead of enlarging the canvas. Related relationships that overlap on the same outer corridor by at least 32px are treated as an intentional bus and remain valid.
147
+ - Shared endpoint corridors are allowed only when they remain semantically unambiguous. Unrelated collinear overlap of 8px or more fails showcase.
148
+ - Container borders are intentional pass-through geometry, but a long edge running along a structural border is not.
149
+ - An edge crossing an unrelated opaque node is always a hard failure, independent of quality profile.
150
+
151
+ ### Explicit `via` coordinates
152
+
153
+ Use the resolved departure anchor `S = [sx, sy]` and arrival anchor
154
+ `T = [tx, ty]`. Anchors start at side midpoints, but automatic routing and
155
+ Port Spread can move them as described above; do not assume an anchor copied
156
+ from an automatic route is the anchor of a newly authored explicit route.
157
+ Explicit `via` routes do not receive automatic Port Spread.
158
+
159
+ For the first waypoint `F = via[0]` and last waypoint `L = via[via.length - 1]`,
160
+ use these alignments and directions (SVG y increases downward):
161
+
162
+ | Side | Departure (`fromSide`): `S` → `F` | Arrival (`toSide`): `L` → `T` |
163
+ | --- | --- | --- |
164
+ | `top` | `F[0] === sx`, `F[1] < sy` | `L[0] === tx`, `L[1] < ty` |
165
+ | `bottom` | `F[0] === sx`, `F[1] > sy` | `L[0] === tx`, `L[1] > ty` |
166
+ | `left` | `F[1] === sy`, `F[0] < sx` | `L[1] === ty`, `L[0] < tx` |
167
+ | `right` | `F[1] === sy`, `F[0] > sx` | `L[1] === ty`, `L[0] > tx` |
168
+
169
+ For example, given a bottom departure anchor `S = [180, 160]` and a left
170
+ arrival anchor `T = [360, 260]`, this relationship fragment leaves downward
171
+ and enters the target rightward:
172
+
173
+ ```json
174
+ {
175
+ "from": "source",
176
+ "to": "target",
177
+ "fromSide": "bottom",
178
+ "toSide": "left",
179
+ "via": [[180, 200], [300, 200], [300, 260]]
180
+ }
181
+ ```
182
+
183
+ The full path is `[180, 160] → [180, 200] → [300, 200] → [300, 260] → [360, 260]`.
184
+ Changing only the first waypoint to `[200, 200]` makes the departure diagonal;
185
+ changing it to `[180, 120]` keeps its x aligned but leaves upward through the
186
+ source instead of outward from its bottom. Both violate `fromSide: "bottom"`
187
+ and produce `clean-flow/endpoint-side-direction`. The example establishes
188
+ endpoint direction only: keep the full route clear of unrelated nodes and
189
+ apply the other geometry rules above.
190
+
191
+ ### Spacing and labels
192
+
193
+ In showcase Architecture, an unpinned connection label keeps its default position
194
+ when clear. If it collides, the renderer tries a bounded set of nearby positions
195
+ along the existing route, avoiding nodes, boundary titles, other labels and
196
+ other routes within the resolved canvas. Explicit `labelAt`, `labelDx`, `labelDy`
197
+ or `labelSegment` (including zero) disables this fallback. Routes and topology
198
+ stay unchanged; if no nearby position is clear, validation reports the original
199
+ collision. Inspect resolved labels with `--layout-json` before adding controls.
200
+ Standard placement retains its existing behavior.
201
+
202
+ Spacing recommendations mean clear gap between boxes, not center distance. A 200px center distance between 165px-wide nodes leaves only 35px of clear gap.
203
+
204
+ For a relationship label, require:
205
+
206
+ ```text
207
+ clear gap > label mask width + 8px breathing room
208
+ label mask width ≈ 6.5px × ASCII units + 13px
209
+ CJK characters count as two units
210
+ ```
211
+
212
+ Relationship labels are semantic data. If the gap is too small, move the label,
213
+ adjust the route or spacing, then shorten the wording while preserving meaning.
214
+ Omit only wording already fully implied by both endpoints and carrying no
215
+ protocol, action, direction, synchronous/asynchronous behavior, or
216
+ cross-boundary mechanism. Preserve every meaningful label.
217
+ Deleting it is not a spacing repair. If a relationship starts unlabeled because
218
+ its endpoints fully imply it, explain why the wording is redundant; this is a
219
+ semantic authoring choice, not a spacing repair. In workflow v2, let the compiler
220
+ allocate its measured mask before applying a diagnosed `labelAt`,
221
+ `labelDx`/`labelDy`, or `labelSegment`. Apply one diagnosed geometry control at
222
+ a time unless several edges share a constrained channel. In that case, plan the smallest coupled change from measured geometry and
223
+ validate it together. Architecture/workflow provide layout evidence through
224
+ `validate <type> <candidate.json> --layout-json`; for other types, use validation
225
+ diagnostics and the rendered SVG geometry.
226
+ Before adding manual routes, check whether unnecessary agent-added controls
227
+ disable automatic port spread; preserve user-required route intent. Use the
228
+ measured clearance rules above rather than guessing coordinates.
229
+
230
+ ### Repair evidence
231
+
232
+ For architecture, `validate architecture <input.json> --layout-json` exposes the
233
+ resolved component boxes, boundary frames, connection points, and label positions.
234
+ A measurable rejected layout also returns these fields, with `ok: false`,
235
+ `contract: "archify-architecture-layout-v1"`, diagnostics, and exit 1. This is
236
+ repair evidence, not artifact acceptance; it writes no HTML. Malformed input or
237
+ an implementation failure retains the ordinary failure receipt without layout.
238
+
239
+ Use the measured failing side for `layout/boundary-out-of-bounds`. Left/top
240
+ negative coordinates need an inward move; increasing viewBox width/height only
241
+ addresses right/bottom overflow. Boundaries may wrap members across rows. Keep
242
+ real membership intact and recheck connected routes after moving members.
243
+
244
+ Automatic architecture canvases include route points as well as nodes, frames,
245
+ and labels. An authored viewBox remains authoritative. In showcase,
246
+ `layout/route-out-of-bounds` identifies clipped route points; negative coordinates
247
+ need an inward route, while right/bottom overflow can also use a larger authored
248
+ canvas. Recheck desktop readability after enlarging a canvas.
249
+
250
+ When several crossing/corridor diagnoses involve the same nodes, consider their
251
+ placement together before adding route controls. Apply one coherent repair and
252
+ validate it; independent label nudges cannot fix a shared layout bottleneck.
253
+ Compare diagnostics by code, subject, and stage instead of total count alone.
254
+
255
+ ### Repair order
256
+
257
+ 1. Fix missing/invalid `meta.quality_profile` and schema errors.
258
+ 2. Fix node overlap or out-of-range placement.
259
+ 3. Fix edge-through-node and endpoint-direction errors.
260
+ 4. Fix crossings, ambiguous corridors, border runs, excessive detours, and route rhythm.
261
+ 5. Fix label-to-node, label-to-label, then label-to-route clearance.
262
+ 6. Fix labels that leave the canvas: move the label with `labelAt`/`labelDx`/`labelDy`/`labelSegment`, or widen `meta.viewBox`. Suggested `labelDx`/`labelDy` values replace the authored field; they are not added to it.
263
+
264
+ Run `validate` after every edit. Consume `diagnostics[]` by stable `code`, exact `subject`, measured `evidence`, and `supportedFixes`. If the diagnostic gives `labelAt`, use that point instead of estimating another offset.
265
+
266
+ ## Mode placement
267
+
268
+ ### Architecture
269
+
270
+ Choose overview or mechanism detail using [Composition and meaning](authoring-defaults.md#composition-and-meaning). Use one obvious primary reading path, which may step across meaningful rows when the requested topology needs room. Keep the overview readable at its chosen abstraction; expand implementation details when they answer the reader's question. Group only real ownership, trust, process, or deployment boundaries. Boundaries do not replace relationships.
271
+
272
+ Grid placement is preferred when the schema supports it. Free positions are appropriate for a bounded exception, not for prose-level coordinate planning. Keep external actors outside the system boundary when that is factually true.
273
+
274
+ ### Workflow
275
+
276
+ Lanes express responsibility or phase. Columns `0..5` express logical
277
+ progression. Start new workflows on `readable-v2`; retain `fixed-v1` only for
278
+ legacy geometry compatibility. Keep the happy path monotonic, preserve semantic
279
+ edge labels, and route retries and exception returns outside the main lane
280
+ corridor.
281
+
282
+ #### Workflow viewport repair
283
+
284
+ When `viewer/viewport-overflow` includes `workflowLanes`, inspect the tallest
285
+ rendered frames and their node span before changing the source. Measurements
286
+ are CSS pixels; space above/below nodes includes lane titles and routing, so it
287
+ is not a removable-space budget. Frame IDs identify rendered lane indices.
288
+
289
+ Run `validate workflow <source.json> --layout-json` and match those frames to
290
+ source lanes and nodes. Check whether many steps share the last logical column
291
+ and use large `yOffset` values. Readable-v2 currently reserves symmetric space
292
+ around offsets and shares the base content height between lanes, so increasing
293
+ one offset can enlarge otherwise sparse lanes.
294
+
295
+ Where the source's ownership and explicit geometry permit, redistribute steps
296
+ across logical columns and meaningful lanes, keeping the main path monotonic.
297
+ Preserve every required node, relationship, label and semantic check. If ownership
298
+ or absolute pins prevent reflow, report that constraint instead of merging lanes
299
+ or moving pins automatically. Validate the changed JSON, deliver a fresh HTML,
300
+ then rerun browser checks and inspect the first screen; a static pass alone does
301
+ not settle viewport fit. These are repair directions, not guaranteed coordinates.
302
+
303
+ ### Sequence
304
+
305
+ Participants are ordered by conversation role. Messages own their vertical order. Use return/async/security variants for meaning, not decoration; sequence does not use Automatic Port Spread.
306
+
307
+ ### Dataflow
308
+
309
+ Stages express transformation or custody. Rows separate parallel streams. Label only data contracts, classifications, or cross-boundary movement that is not obvious.
310
+
311
+ ### Lifecycle
312
+
313
+ Schema v2 (new diagrams): each populated lane is one row, `main` first,
314
+ `terminal` last, others in `lanes[]` order. `col` `0..4` is one shared x grid,
315
+ so a state placed in the column of the state it leaves gets a straight vertical
316
+ transition. Every transition, including the main path, is authored; there is no
317
+ implied rail. The renderer sizes the canvas, widens a column gap for a
318
+ same-row label, and routes automatic transitions orthogonally through row gaps.
319
+ Keep labels short: a gap carrying several parallel lines has little room.
320
+
321
+ Schema v1 (legacy): main phases use columns `0..4`; event and terminal bands
322
+ use columns `0..2`, and event/terminal column `N` aligns with main column
323
+ `N + 2`. Every lane other than `main` and `terminal` shares one middle band;
324
+ states in the same column there need distinct `yOffset` values.
325
+
326
+ In both versions a recoverable failure needs a real transition back to an
327
+ active state. A card saying “retry” is not topology.
328
+
329
+ ## Repository evidence
330
+
331
+ When the diagram must reflect real code, inspect repository entrypoints,
332
+ runtime boundaries, storage, transports, and deployment configuration before
333
+ authoring. Record only evidence you actually verified. `--repo-root <path>` is
334
+ accepted by `render`, `validate`, `deliver`, and `preview` for every diagram
335
+ type, by architecture `compare`, and by workflow `migrate`; every mode verifies `meta.repository` and
336
+ node `sources` the same way. Migrating a source-backed workflow requires the same
337
+ `--repo-root` so its candidate is verified before replacing the destination.
338
+ Never infer runtime causality from file proximity
339
+ or naming alone.
340
+
341
+ Declare `meta.repository.url` and one full 40-character `revision`, then attach
342
+ `sources` to the mode's node collection (Architecture `components[]`, Workflow
343
+ and Data Flow `nodes[]`, Sequence `participants[]`, Lifecycle `states[]`) with
344
+ repository-relative `path`, optional `line`, `end_line`, and `label`.
345
+ Verification reads blobs at that commit, independently of working-tree edits.
346
+ Verification ignores local Git replacement refs, including those selected by
347
+ `GIT_REPLACE_REF_BASE`, and always reads the original objects at the pinned SHA.
348
+ It does not change repository configuration or delete replacement refs.
349
+ A matching local origin, available commit, bounded path,
350
+ blob, and valid line range are required in every link mode. Verification is
351
+ local and makes no remote requests; it establishes neither public availability
352
+ nor the current reader's access rights.
353
+
354
+ `link_mode` defaults to `web`. GitHub and Gitee HTTPS repository URLs generate
355
+ revision-pinned links; their public hosts select the provider automatically.
356
+ Optional `provider: "github"` or `"gitee"` must agree with the host. Existing
357
+ GitHub declarations and default delivery receipt fields remain compatible.
358
+
359
+ ```json
360
+ {
361
+ "url": "https://gitee.com/team/service",
362
+ "revision": "0123456789abcdef0123456789abcdef01234567",
363
+ "provider": "gitee"
364
+ }
365
+ ```
366
+
367
+ For an internal or unsupported forge, select `link_mode: "local-only"`. The
368
+ Viewer retains SRC markers, searchable file paths, line ranges, and revision
369
+ labels without repository or source hyperlinks. The evidence receipt adds
370
+ `linkMode: "local-only"`. `url` remains required as the expected origin identity;
371
+ local-only disables links, not identity verification. A repository without an
372
+ origin is not supported.
373
+
374
+ ```json
375
+ {
376
+ "url": "http://git.internal:3000/Platform/Services/service",
377
+ "revision": "0123456789abcdef0123456789abcdef01234567",
378
+ "link_mode": "local-only"
379
+ }
380
+ ```
381
+
382
+ Local-only accepts HTTP(S), `git@host:path`, and `ssh://git@host[:port]/path`
383
+ addresses, including nested namespaces. Declare a credential-free address;
384
+ HTTP(S) credentials on the checkout's origin are ignored for identity and
385
+ redacted from diagnostics. Hostnames compare case-insensitively; repository
386
+ paths retain case except for the existing GitHub behavior. A trailing slash
387
+ normalizes away. Only GitHub and Gitee normalize a terminal `.git` and match
388
+ standard HTTPS/443 with Git SSH/22. For other hosts, use the actual clone address:
389
+ transport, port, `.git` suffix, and remote-relative versus absolute paths must
390
+ match. For example, `git@host:Team/repo` differs from
391
+ `ssh://git@host/Team/repo`; `git@host:/Team/repo` matches the latter. SCP-style
392
+ paths preserve literal percent escapes, while URI paths decode them. SSH host
393
+ aliases and forge-specific browse/clone prefixes are not guessed.
394
+ GitLab/Gitea/Forgejo/Bitbucket web links are not implemented in this version;
395
+ use local-only until a tested link provider is available. Unknown web providers
396
+ fail with a diagnostic rather than emitting a guessed link.
397
+
398
+ ## Hand-placed fallback
399
+
400
+ Use only when no renderer can run. Start from `assets/template.html`, keep semantic CSS classes, preserve the inline SVG/accessibility structure, and run the delivery visual checklist. Never introduce inline literal colors that break dark/light parity.
401
+
402
+ ## Node icons
403
+
404
+ For domain-specific diagrams, set an optional `icon` on architecture components,
405
+ workflow/dataflow nodes, sequence participants, or lifecycle states. Choose
406
+ `calendar`, `clock`, `person`, `briefcase`, `flag`, or `moon` for everyday concepts;
407
+ the complete catalog (including existing technical and lifecycle symbols) is
408
+ `common.schema.json#/$defs/nodeIcon`. Use `icon: "none"` to hide the corner symbol.
409
+ Omitting `icon` keeps the type-based default. These inline SVG symbols are
410
+ renderer-owned and export with the diagram; URLs and raw SVG are not accepted.
411
+
412
+ Icon selection changes only the corner symbol. The node's type still determines
413
+ color and semantic grouping; brand marks remain independent. For a holiday
414
+ workflow, pair `type: "backend", icon: "calendar"` with
415
+ `meta.legend.entries.backend.label: "假期"`, and use `icon: "briefcase"` plus
416
+ an appropriate legend label for make-up work. Keep the node label meaningful:
417
+ icons are decorative and are hidden from assistive technology.
418
+
419
+ See [holiday planning](../examples/holiday-planning.workflow.json) for a complete workflow example.
@@ -0,0 +1,41 @@
1
+ # Authoring defaults
2
+
3
+ Read once before writing a fresh candidate. An existing frozen candidate going straight to `finalize` needs this only if repair changes its authorship.
4
+
5
+ ## Composition and meaning
6
+
7
+ For Architecture, default to a system overview led by the main user journey unless the user asks for a narrower mechanism, module map, or deployment topology. Group cooperating roles in accurately named subsystems when that still explains the requested interaction. Separate roles when grouping would hide control ownership, a trust or persistence boundary, lifecycle behavior, or another distinction the reader asked about. Keep secondary and opt-in capabilities in concise sourced notes unless their path matters to the requested question. Name a deliberately narrower scope in the title.
8
+
9
+ Preserve every requested responsibility, relationship direction, protocol, and behavior-changing condition. Show approval, authorization, and state-transition gates on the affected node or relationship; a card alone cannot qualify an otherwise unconditional arrow. Keep source evidence with each asserted claim. Boundaries express real isolation, ownership, runtime, or persistence facts. Cards answer additional reader questions; they do not replace required topology. There is no node, edge, source, card, or boundary quota. If an authored overview needs regrouping after failure, use [Composition repair](authoring-contract.md#composition-repair); user-supplied or agreed topology remains fixed.
10
+
11
+ Relationship labels carry meaning. Give them clear space and preserve action, protocol, direction, async behavior, or cross-boundary meaning. A label may start absent only when both endpoints already fully imply it; a collision calls for spacing or routing repair. See [Label repair](authoring-contract.md#label-repair) when measured evidence reports a collision.
12
+
13
+ ## Layout and routing
14
+
15
+ Place Architecture nodes by their actual connections before assigning coordinates; the router cannot rearrange boxes, so placement decides whether lines stay straight. Classify each relationship first, then place:
16
+
17
+ - **Main path**: the reader's main journey, neighbors adjacent in reading order. Let a medium path step through meaningful rows instead of making a shallow horizontal strip.
18
+ - **Branch or store**: directly above or below the node that owns, reads, or writes it, centered on that node so the edge is one straight segment. Keep all stores and branches of one row on the same side of it.
19
+ - **Return** (back to an earlier main-path node): put its source on the side of the main path with no branches or stores, so it runs through an empty corridor instead of crossing them.
20
+ - **Second entrance** into a node that already has an incoming edge: place the new source so it reaches that node from another side, usually directly below or above it.
21
+ - **Fan-out**: a side with k relationships needs at least `32 + 14 × (k − 1)`px (four need 74px). Spread a hub's counterparts over two or three sides, or enlarge the hub. Center a parent on its children and align a child with its only parent.
22
+
23
+ Before writing positions, trace each non-main relationship: its straight or one-bend corridor must not pass another node or cross another relationship. If it does, move the endpoint that is off the main path. Start the main actor and its first connected step together near the canvas origin; use content rows for vertical rhythm. Omit `meta.viewBox` for a fresh Architecture so the Reader measures intrinsic height. Keep supplied fixed geometry authoritative.
24
+
25
+ Start with automatic routes and endpoint sides. Pin a side only for a necessary branch, return, or supplied geometry. Reserve `via`, `channelX`, `channelY`, and label coordinates for measured defects. Before writing positions, budget each labeled main-path edge at `6.5px × ASCII units + 21px` of clear gap, counting CJK as two units; use its own label length, not a row-wide fixed gap. Size Architecture sublabels for their preferred 9px text at `5.4px × text units + 8px`, with CJK counting twice; keep supporting copy concise without dropping required facts. Do not trade readability or meaning for fewer crossings. The [Geometry reference](authoring-contract.md#executable-geometry-rules) has measured spacing, port, canvas, and route rules for a diagnosed layout problem.
26
+
27
+ ## Evidence and schema
28
+
29
+ For a real repository, follow [Repository authoring](repository-authoring.md) while inspecting source. Freeze its credential-free origin and 40-character commit in `meta.repository`, attach inspected repository-relative `sources` to each key semantic node, and pass `--repo-root` to the first `finalize`. Each reference proves only the fact visible at that location. Follow material relationships and conditions to their actual source; do not reuse a startup citation as protocol or persistence evidence.
30
+
31
+ Examples show field shape, not legal values or source facts. Read the mode schema and shared definition before adding a field, enum, or constrained text. In particular, inspect Architecture boundary kinds. Keep longer evidence in a card while retaining the fact. See [Schema lookup](authoring-contract.md#schema-lookup) for details.
32
+
33
+ ## Presentation and modes
34
+
35
+ Use one primary authored language from the user's choice or the request/conversation. Set `meta.locale` for built-in English (`en`) or Simplified Chinese (`zh-CN`); for other languages, including Spanish (`es`), supply `meta.translations` with reusable UI translations, or disclose the fixed Viewer UI and `<html lang>` English fallback. Keep exact product, code, protocol, command, API, and environment names while localizing surrounding explanation. See [Language consistency](authoring-contract.md#language-consistency) for bilingual cases.
36
+
37
+ Omit `meta.visual_preset` for classic, `meta.subtitle` for a title-only header, `meta.legend` for truthful auto, and `meta.engineering_profile` for an ordinary system overview. Explicit styles and a subtitle require a user request. Use legend or deployment ownership under the [legend](authoring-contract.md#legend-contract) or [engineering profile](authoring-contract.md#engineering-profile-default) contracts. Branding is optional and explicit when a node names a real product; [Brand marks](brand-marks.md) gives lookup and capture rules for that branch. Never let a badge replace semantic type, label, or relationship facts. Set required `meta.output` to a portable POSIX-relative `.html` path within the working directory; see [Output path contracts](delivery-contract.md#output-path-contracts) for native path exceptions.
38
+
39
+ For new Workflow use schema v2, preserving v1 for a fixed legacy source; use its [layout contracts](../renderers/workflow/README.md#layout-contracts) when lane or group geometry needs detail. For Sequence start with fixed columns; use `spread` when a wide viewBox leaves unused horizontal space or meaningful labels need width. For new Lifecycle use schema v2: every lane is its own row (`main` first, `terminal` last) and `col` `0..4` is the same x in every row, so place an interruption or exit in the column of the state it leaves; author the main path as transitions, omit `viewBox`, and keep transition labels short; a recoverable failure needs a real transition back. Read [Mode placement](authoring-contract.md#mode-placement) when a mode-specific placement or viewport problem needs more detail.
40
+
41
+ `finalize` performs the browser gate. Keep the complete drawing comfortably readable on desktop, with zero horizontal overflow. Use meaningful vertical rows and intrinsic-height page scroll when necessary. The 6px projected-text check is a failure floor; at 1440px, aim for ordinary context text around 7.5px or larger. See [Automated browser evidence](delivery-contract.md#automated-browser-evidence) when viewport evidence fails.
@@ -0,0 +1,82 @@
1
+ # Brand marks
2
+
3
+ Use a brand mark only when a real product, provider, model family, channel, or
4
+ service identity helps the reader. Semantic `type` still explains what the node
5
+ does; `brand` explains whose product it is.
6
+
7
+ ## Agent decision path
8
+
9
+ 1. Search the built-in catalogue when the request names a recognizable brand:
10
+
11
+ ```bash
12
+ node bin/archify.mjs brands "Claude" --json
13
+ ```
14
+
15
+ 2. Put the returned canonical ID in the node, participant, or state:
16
+
17
+ ```json
18
+ {
19
+ "id": "planner",
20
+ "type": "backend",
21
+ "label": "Claude",
22
+ "brand": "claude"
23
+ }
24
+ ```
25
+
26
+ 3. If there is no catalogue match and the user supplied the official website,
27
+ capture its icon explicitly:
28
+
29
+ ```bash
30
+ node bin/archify.mjs brands capture "https://partner.example.com" --json
31
+ ```
32
+
33
+ Put the command's digest-pinned `brand` value in the authored node:
34
+
35
+ ```json
36
+ {
37
+ "id": "partner",
38
+ "type": "external",
39
+ "label": "Partner portal",
40
+ "brand": {
41
+ "url": "https://partner.example.com",
42
+ "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
43
+ }
44
+ }
45
+ ```
46
+
47
+ 4. If there is no match and no user-provided URL, omit `brand`. Do not invent a
48
+ URL or silently assign a visually similar company.
49
+
50
+ Known-brand URLs resolve to the bundled vector instead of using the network.
51
+ For discovered icon `href` attributes, capture decodes the basic named references
52
+ `amp`, `quot`, `apos`, `lt`, `gt` (and their defined uppercase aliases), plus
53
+ decimal and hexadecimal numeric references, once before URL resolution. Thus
54
+ `/icon.png?v=1&amp;size=32` requests `/icon.png?v=1&size=32`. URL percent escapes
55
+ remain intact; nested escapes are not decoded recursively. This bounded decoder
56
+ does not add a general HTML parser or support every named HTML entity.
57
+ HTML reads stop at an explicit head ending outside comments, raw-text elements
58
+ and quoted attributes, including when those tokens span network chunks. The
59
+ 256 KiB head limit and capture deadline still apply; a larger body after the
60
+ head is not read for icon discovery.
61
+ Unknown URL capture accepts only bounded raster image formats, blocks
62
+ credentials, nonstandard public ports, and private or link-local destinations,
63
+ uses bounded concurrency and one total deadline, and returns the captured
64
+ content digest. Later render and validate operations require that exact digest;
65
+ blocked, unavailable, changed, oversized, or unsafe content fails closed instead
66
+ of silently changing the artifact.
67
+
68
+ Page, icon and redirect requests send `Accept-Encoding: identity`. Capture does
69
+ not decompress response bodies: a successful response declaring another content
70
+ coding is closed and rejected explicitly. This keeps the existing byte limits
71
+ and pinned digest tied to the unencoded representation. A later usable icon may
72
+ still succeed; otherwise an encoding error is retained instead of being hidden
73
+ by an unrelated favicon 404.
74
+
75
+ The final artifact never fetches a brand asset when opened. Preset vectors and
76
+ digest-verified captured site icons remain embedded in SVG, PNG, WebP, JPEG,
77
+ Share Card, and WebM exports.
78
+
79
+ Use `node bin/archify.mjs brands --json` to inspect all canonical IDs, aliases,
80
+ categories, domains, and provenance. Current categories cover AI, cloud,
81
+ engineering, data, collaboration, business systems, channels, languages, and
82
+ frameworks.