pi-outpost 0.32.4 → 0.34.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.
- package/dist/contract/README.md +120 -1
- package/dist/contract/conformance/README.md +29 -5
- package/dist/contract/conformance/index.json +115 -0
- package/dist/contract/conformance/invalid/unknown-version.json +1 -1
- package/dist/contract/conformance/invalid/v3-timeline-comparison-without-reference.json +123 -0
- package/dist/contract/conformance/invalid/v3-timeline-contradictory-change.json +128 -0
- package/dist/contract/conformance/invalid/v3-timeline-dependency-cycle.json +124 -0
- package/dist/contract/conformance/invalid/v3-timeline-dependency-on-removed.json +125 -0
- package/dist/contract/conformance/invalid/v3-timeline-duplicate-dependency.json +125 -0
- package/dist/contract/conformance/invalid/v3-timeline-duplicate-identifier.json +120 -0
- package/dist/contract/conformance/invalid/v3-timeline-empty-task-endpoint.json +124 -0
- package/dist/contract/conformance/invalid/v3-timeline-impossible-date.json +101 -0
- package/dist/contract/conformance/invalid/v3-timeline-inverted-activity.json +120 -0
- package/dist/contract/conformance/invalid/v3-timeline-inverted-range.json +120 -0
- package/dist/contract/conformance/invalid/v3-timeline-milestone-outside-range.json +120 -0
- package/dist/contract/conformance/invalid/v3-timeline-period-outside-range.json +139 -0
- package/dist/contract/conformance/invalid/v3-timeline-presentation-property.json +121 -0
- package/dist/contract/conformance/invalid/v3-timeline-previous-outside-range.json +128 -0
- package/dist/contract/conformance/invalid/v3-timeline-previous-wrong-shape.json +128 -0
- package/dist/contract/conformance/invalid/v3-timeline-reference-outside-range.json +140 -0
- package/dist/contract/conformance/invalid/v3-timeline-self-dependency.json +124 -0
- package/dist/contract/conformance/invalid/v3-timeline-under-version-2.json +120 -0
- package/dist/contract/conformance/invalid/v3-timeline-unknown-dependency-type.json +121 -0
- package/dist/contract/conformance/invalid/v3-timeline-unresolved-dependency-endpoint.json +120 -0
- package/dist/contract/conformance/invalid/v3-timeline-unsupported-scale.json +120 -0
- package/dist/contract/conformance/invalid/v3-timeline-with-target.json +123 -0
- package/dist/contract/conformance/valid/v3-timeline-calendar.json +140 -0
- package/dist/contract/conformance/valid/v3-timeline-compared.json +142 -0
- package/dist/contract/conformance/valid/v3-timeline-empty-task-and-anonymous-separator.json +35 -0
- package/dist/contract/conformance/valid/v3-timeline-four-dependency-types.json +61 -0
- package/dist/contract/conformance/valid/v3-timeline-programme.json +44 -0
- package/dist/contract/conformance/valid/v3-timeline-quarter-scale.json +42 -0
- package/dist/contract/conformance/valid/v3-timeline-single-day-activity.json +27 -0
- package/dist/contract/conformance/valid/v3-timeline-unsatisfied-dependency.json +45 -0
- package/dist/contract/conformance/valid/v3-timeline-week-scale.json +35 -0
- package/dist/contract/conformance/version-1.lock.json +2 -2
- package/dist/contract/schemas/structured-exchange-3.json +1263 -0
- package/dist/contract/schemas/structured-exchange-profile-registry-2.json +94 -0
- package/dist/contract/structured-exchange-project-setup.md +36 -0
- package/dist/contract/validate-structured-exchange.mjs +1981 -174
- package/dist/pi-outpost-tools.mjs +4556 -1130
- package/dist/pi-outpost.mjs +5733 -1898
- package/dist/pi-outpost.sea.mjs +2 -2
- package/dist/sea-prep.blob +2 -2
- package/dist/skills/structured-exchange/SKILL.md +90 -378
- package/dist/skills/structured-exchange/references/enriched-contract.md +158 -0
- package/dist/skills/structured-exchange/references/figures.md +52 -0
- package/dist/skills/structured-exchange/references/graphs-and-tables.md +115 -0
- package/dist/skills/structured-exchange/references/proposals.md +86 -0
- package/dist/skills/structured-exchange/references/timelines.md +87 -0
- package/dist/skills/structured-exchange/structured-exchange-3.json +1263 -0
- package/dist/skills/structured-exchange/structured-exchange-profile-registry-2.json +94 -0
- package/dist/skills/structured-exchange-project/SKILL.md +22 -0
- package/dist/web/assets/{PdfViewer-DHIy06i5.js → PdfViewer-9kadnb9W.js} +2 -2
- package/dist/web/assets/{abnfDiagram-VCTEODGH-0IqI620v.js → abnfDiagram-YUKMZFIV-BUZ7jF1I.js} +1 -1
- package/dist/web/assets/architecture-WOLXFQ4H-CxBmyj2Z.js +1 -0
- package/dist/web/assets/architectureDiagram-47P4ROYG-BAvert-J.js +36 -0
- package/dist/web/assets/{blockDiagram-OSKFZWR5-sw0nzjYC.js → blockDiagram-E7TT5TSB-CXQT_J2x.js} +16 -5
- package/dist/web/assets/c4Diagram-CRA5TL53-Byqo5aDs.js +38 -0
- package/dist/web/assets/channel-D3nE3SyW.js +1 -0
- package/dist/web/assets/chunk-2BW5OAIV-D9dSVCv2.js +10 -0
- package/dist/web/assets/chunk-3YJQHVM4-D6IQcIQB.js +2 -0
- package/dist/web/assets/chunk-4EA7E6EY-BxZ_5HMn.js +1 -0
- package/dist/web/assets/{chunk-F27PBJKO-C6rqX2gT.js → chunk-7TKQ45FW-G9TsFldk.js} +1 -1
- package/dist/web/assets/{chunk-SVP7TREG-CYXVRfc0.js → chunk-AW2ZBBNX-nmg5rsd5.js} +3 -3
- package/dist/web/assets/{chunk-GVQU2GXP-BtSmWzHA.js → chunk-DBDB3WZW-BwVIGLtu.js} +1 -1
- package/dist/web/assets/chunk-DUW6YSOI-Dgx8z5s3.js +1 -0
- package/dist/web/assets/chunk-E2ZNV5FY-VD95O25Z.js +72 -0
- package/dist/web/assets/chunk-EU5HNXII-CSnybkPb.js +213 -0
- package/dist/web/assets/chunk-FVRAUYC3-TBqluQ8N.js +2 -0
- package/dist/web/assets/{chunk-PWAF6VOD-Dup_NAkl.js → chunk-HJ2JQQFS-BiLMpVsO.js} +1 -1
- package/dist/web/assets/chunk-HTAEGDNF-QDOAuhR5.js +1 -0
- package/dist/web/assets/chunk-J5ZVWO5B-oDCd-gWO.js +1 -0
- package/dist/web/assets/{chunk-POPQ4Y6H-BrnPOTT-.js → chunk-KQW6MTUR-_WxFaX97.js} +1 -1
- package/dist/web/assets/chunk-NGNAAXSQ-BW1P8EP7.js +136 -0
- package/dist/web/assets/chunk-NTY3LDVX-BI0Pj8F6.js +1 -0
- package/dist/web/assets/chunk-VPRB5NB3-BBDlNNll.js +129 -0
- package/dist/web/assets/chunk-XC4XBNZT-Ba1ra4Jd.js +62 -0
- package/dist/web/assets/classDiagram-v2-K4WV4PDN-CksBjG_q.js +217 -0
- package/dist/web/assets/{conversationExport-CfUybHMU.js → conversationExport-q-9NUHuj.js} +1 -1
- package/dist/web/assets/cynefin-EF2NZ3EQ-ucJDz_S5.js +1 -0
- package/dist/web/assets/{cynefinDiagram-5FMLGOSQ-BKvXEDID.js → cynefinDiagram-3GCD6N5R-qPxcNdaa.js} +1 -1
- package/dist/web/assets/dagre-W4DXFKR2-ChflYJGj.js +4 -0
- package/dist/web/assets/diagram-2UJZ2QOL-Bi9ngdu2.js +200 -0
- package/dist/web/assets/{diagram-VX7I27RA-D5POkb-9.js → diagram-OVF4WLC6-iSSbF5Cd.js} +10 -10
- package/dist/web/assets/{diagram-S7CK7UJ4-DTvEAe9r.js → diagram-PFPMY2P6-BeEOD8rR.js} +2 -2
- package/dist/web/assets/{diagram-Z3DM3KII-CC2Mxm4H.js → diagram-UMYRVEAY-BckO6iZI.js} +1 -1
- package/dist/web/assets/{diagram-UQ7AKVKN-CVGEkml-.js → diagram-YEKJPTXX-BzzDIAmO.js} +2 -2
- package/dist/web/assets/diagram-ZIFT7M5P-ByjWOPbN.js +3 -0
- package/dist/web/assets/{docxExport-ErgwApAZ.js → docxExport-BO7j3Xnv.js} +1 -1
- package/dist/web/assets/{ebnfDiagram-PWID7BFC-CbDy2vxX.js → ebnfDiagram-VR2GEFS7-DRp-A5JC.js} +1 -1
- package/dist/web/assets/elk-IJKZMXRS-QzeiQ3l1.js +27 -0
- package/dist/web/assets/{erDiagram-2YWLMYGG-DUdStx-7.js → erDiagram-O2IAPWRE-BewZvI56.js} +15 -15
- package/dist/web/assets/eventmodeling-K75KTNOO-CX7X0bsf.js +1 -0
- package/dist/web/assets/flowDiagram-OXPTDLAJ-CSIHFoeR.js +1 -0
- package/dist/web/assets/ganttDiagram-R7TSEDQI-BT8Lcdwc.js +292 -0
- package/dist/web/assets/gitGraph-VSP46ZUC-BxYbaxeg.js +1 -0
- package/dist/web/assets/gitGraphDiagram-XJZIOB7I-B0fqVCqP.js +106 -0
- package/dist/web/assets/index-DcqvxkHN.css +2 -0
- package/dist/web/assets/index-eTp_lQUc.js +350 -0
- package/dist/web/assets/info-OHQRW6UA-DV3PDKXA.js +1 -0
- package/dist/web/assets/infoDiagram-5W2HQ5XZ-DfHpZ9RG.js +2 -0
- package/dist/web/assets/{ishikawaDiagram-5VMMS53U-D-gYpOUM.js → ishikawaDiagram-K3B6WC7H-DuwLwL9k.js} +2 -2
- package/dist/web/assets/{journeyDiagram-EYS64GPL-B0WqOtZ4.js → journeyDiagram-COXZFDF6-CMOfweZO.js} +4 -4
- package/dist/web/assets/{kanban-definition-UXKFOSKX-DIrVFtP3.js → kanban-definition-P3RFRI5V-DjHhlDbk.js} +9 -9
- package/dist/web/assets/{line-CuEhAU65.js → line-CGIAMPkR.js} +1 -1
- package/dist/web/assets/loadReferencedImage-DZ5eApE4.js +2 -0
- package/dist/web/assets/{mermaid-parser.core-CzCh9EE1.js → mermaid-parser.core-C18KmsD9.js} +6 -6
- package/dist/web/assets/mermaid.core-C9srNL3b.js +44 -0
- package/dist/web/assets/{mindmap-definition-THT77NOG-CBH0Z9AJ.js → mindmap-definition-LZFPQGKD-C38HXkG2.js} +24 -24
- package/dist/web/assets/packet-JDAUHWVQ-Br-8ADK6.js +1 -0
- package/dist/web/assets/{pdf-6mG9havR.js → pdf-C3f6Vjz7.js} +1 -1
- package/dist/web/assets/{pegDiagram-XKGWAZYB-BNpTWHo8.js → pegDiagram-BGZESJAR-Be49dM_b.js} +1 -1
- package/dist/web/assets/pie-XZMESJXO-68ykK6i1.js +1 -0
- package/dist/web/assets/{pieDiagram-E7YTZNPT-CZ34Q1W-.js → pieDiagram-CAPJLFHJ-DVOWjXQ_.js} +2 -2
- package/dist/web/assets/{quadrantDiagram-AXDQQJYC-C5aFQsIe.js → quadrantDiagram-GDMTTRAM-8la_R53U.js} +3 -3
- package/dist/web/assets/radar-ABXABTNO-K00ZGu13.js +1 -0
- package/dist/web/assets/railroad-I3PHUGI6-W7QuDysT.js +1 -0
- package/dist/web/assets/railroad-abnf-LNEFI6M7-DR6CNkaK.js +1 -0
- package/dist/web/assets/railroad-ebnf-DWYD2UWJ-dAhaGv5L.js +1 -0
- package/dist/web/assets/railroad-peg-JR7BVNR7-DwoiiDdE.js +1 -0
- package/dist/web/assets/{railroadDiagram-O6MQD6OU-B0ctRtRT.js → railroadDiagram-SM67HX2B-BuSjCs02.js} +1 -1
- package/dist/web/assets/{requirementDiagram-IS5BZ75X-BuOtNPGm.js → requirementDiagram-X7JNWC4A-3uq8m_5E.js} +11 -11
- package/dist/web/assets/{sankeyDiagram-P5KCCOFB-CybICPpQ.js → sankeyDiagram-UM26HJRW-BB9_G8bN.js} +3 -3
- package/dist/web/assets/sequenceDiagram-ZO4K6R2Y-CGehVq9k.js +169 -0
- package/dist/web/assets/stateDiagram-v2-TBUQTH76-CwMywh5s.js +291 -0
- package/dist/web/assets/swimlanes-N4OXWK64-CqjihurI.js +1 -0
- package/dist/web/assets/swimlanesDiagram-K3J5GTZL-Blk5ohUI.js +8 -0
- package/dist/web/assets/timeline-definition-YOQAKGHF-BtKnuY5Y.js +120 -0
- package/dist/web/assets/treeView-D4JQ5SDB-Dy4jC4wa.js +1 -0
- package/dist/web/assets/treemap-SAJKECNS-CHtGJD8P.js +1 -0
- package/dist/web/assets/usecaseDiagram-VIAY4XPW-BjnstWbR.js +328 -0
- package/dist/web/assets/vennDiagram-BLWOH2XV-o_EtJWVA.js +34 -0
- package/dist/web/assets/wardley-7MLQ67FV-BTheL3FW.js +1 -0
- package/dist/web/assets/{wardleyDiagram-VM6X3IG4-CzB2tR_t.js → wardleyDiagram-YMQ3BMBF-Bp_sv2v4.js} +3 -3
- package/dist/web/assets/xychartDiagram-TAQBALBS-C0IpEfij.js +7 -0
- package/dist/web/index.html +2 -2
- package/package.json +3 -3
- package/dist/web/assets/architecture-7GRP2DOG-BqTZwqCY.js +0 -1
- package/dist/web/assets/architectureDiagram-5GKGNRK7-BEGSAGSn.js +0 -36
- package/dist/web/assets/c4Diagram-7LVT6UL2-C6wQYxBC.js +0 -38
- package/dist/web/assets/channel-CbMG5PZq.js +0 -1
- package/dist/web/assets/chunk-3NF5O7KM-Dni31-nE.js +0 -168
- package/dist/web/assets/chunk-4HAMMTFA-hiqoLVtf.js +0 -62
- package/dist/web/assets/chunk-75Z2AOVW-1k7HRGrm.js +0 -2
- package/dist/web/assets/chunk-DU6HZSFF-Dy05V--k.js +0 -127
- package/dist/web/assets/chunk-FOHPRMQF-DHwB1DNv.js +0 -161
- package/dist/web/assets/chunk-GMAD6QVW-Bi5Ne8OE.js +0 -72
- package/dist/web/assets/chunk-HLEWEB6X-yamDqy1M.js +0 -206
- package/dist/web/assets/chunk-L3NEJ4N5-CQSamtuJ.js +0 -1
- package/dist/web/assets/chunk-OSK3NFVY-S95igUko.js +0 -10
- package/dist/web/assets/chunk-P2QGCYS3-BPor-azX.js +0 -1
- package/dist/web/assets/chunk-ZLD2IHE6-D0uZMMWb.js +0 -231
- package/dist/web/assets/classDiagram-CYGNFDIV-2Yl201cv.js +0 -1
- package/dist/web/assets/classDiagram-v2-TLXNO2FR-2Yl201cv.js +0 -1
- package/dist/web/assets/cynefin-OW5HDTMX-ua6bZIWp.js +0 -1
- package/dist/web/assets/dagre-OS7QT2EB-BRxaZdm2.js +0 -4
- package/dist/web/assets/dagre-PrKaheQc.js +0 -1
- package/dist/web/assets/diagram-VSXAHHWV-Dkh-RvzE.js +0 -3
- package/dist/web/assets/eventmodeling-NTZA5JFV-Bw8wULv_.js +0 -1
- package/dist/web/assets/flowDiagram-T62WH6J4-Dp4v9IDN.js +0 -1
- package/dist/web/assets/ganttDiagram-EL5Y4UJY-6dI1H52q.js +0 -292
- package/dist/web/assets/gitGraph-4MIJSDKK-UXnB0IFr.js +0 -1
- package/dist/web/assets/gitGraphDiagram-WWUBYQGX-B_wXPpx0.js +0 -106
- package/dist/web/assets/index-9y9n2Dul.css +0 -2
- package/dist/web/assets/index-COu8CnNa.js +0 -350
- package/dist/web/assets/info-A6RAGUB7-C2WWyNzF.js +0 -1
- package/dist/web/assets/infoDiagram-FKFFQAWI-DY65_ndC.js +0 -2
- package/dist/web/assets/loadReferencedImage-DgHMXQNZ.js +0 -2
- package/dist/web/assets/mermaid.core-BmGW_v8T.js +0 -44
- package/dist/web/assets/packet-AYTQ26CC-BYG_KViO.js +0 -1
- package/dist/web/assets/pie-WAS4IAKB-wBoUHr8R.js +0 -1
- package/dist/web/assets/radar-RG4KPBEZ-D4K5XP7X.js +0 -1
- package/dist/web/assets/railroad-74A4TZTK-Haum25Us.js +0 -1
- package/dist/web/assets/railroad-abnf-HS5TGJTU-D-kbOsoZ.js +0 -1
- package/dist/web/assets/railroad-ebnf-LZEXJU2U-CWtixpZf.js +0 -1
- package/dist/web/assets/railroad-peg-WCYAUIDC-BeY7arxf.js +0 -1
- package/dist/web/assets/sequenceDiagram-WJ2MYXX4-Dvo8sl8e.js +0 -162
- package/dist/web/assets/stateDiagram-XQSTLZYL-BcM-hGJa.js +0 -1
- package/dist/web/assets/stateDiagram-v2-IH3M54BS-hYgwFLzv.js +0 -1
- package/dist/web/assets/swimlanes-V6O3JKXN-mOOjKnlm.js +0 -1
- package/dist/web/assets/swimlanesDiagram-JKAHXJPX-C_yinM3f.js +0 -8
- package/dist/web/assets/timeline-definition-24CTP7MA-DuwMztTy.js +0 -120
- package/dist/web/assets/treeView-Q6P3EWNA-BT4vRttT.js +0 -1
- package/dist/web/assets/treemap-WGGIJYW6-Df6GHCE2.js +0 -1
- package/dist/web/assets/vennDiagram-4TSXK5OY-BbcbGn7o.js +0 -34
- package/dist/web/assets/wardley-WFR3VGLG-L_G3ydHA.js +0 -1
- package/dist/web/assets/xychartDiagram-S5SC5T6Z-CKHwJboP.js +0 -7
package/dist/pi-outpost.sea.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/dist/pi-outpost.sea.mjs
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 38386180 bytes
|
|
4
|
+
sha256: 5dd3975707387d78afef8c9d81c9ae669fd9c80ce088d0c4a8255dac3144f473
|
package/dist/sea-prep.blob
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/dist/sea-prep.blob
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 38385218 bytes
|
|
4
|
+
sha256: ee8f6c6d18b4c2713ab8648883b4ef96b45053bcf34a065c7e8ad4d2ea624257
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: structured-exchange
|
|
3
|
-
description: Author a structured-exchange document — a graph, sequence, or
|
|
3
|
+
description: Author a structured-exchange document — a graph, sequence, table or planning timeline the interface renders natively, such as a table of requirements with their attributes, a programme schedule with milestones and dependencies, or a proposal to change one an external authority holds — and write figures of one into a document you are authoring. Read it before calling present_structure or write_structure_figure. Use when asked to draw or diagram a structure, to present requirements or other typed items, to plan or show a schedule, roadmap or Gantt chart, to propose an evolution of an existing model, to illustrate a report you are writing, when a project's profile refuses a kind, attribute or value, or when a result would otherwise be a hand-written diagram.
|
|
4
4
|
allowed-tools: Bash(node:*)
|
|
5
5
|
license: MIT
|
|
6
6
|
metadata:
|
|
@@ -13,22 +13,21 @@ Emit **data**, not a diagram. The interface renders the diagram from your data;
|
|
|
13
13
|
diagram you draw by hand is syntax it has to guess at, and cannot be approved,
|
|
14
14
|
validated, or applied.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
> tool answers `0 changed`, this is what happened.
|
|
16
|
+
This page is what every document needs. The rest is in a `references` folder next to this
|
|
17
|
+
file — the path you read this page at, with `SKILL.md` replaced by `references/<name>.md`.
|
|
18
|
+
**Read the one for the job before writing the document**, and only that one.
|
|
19
|
+
|
|
20
|
+
| To… | Read |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| plan or show a schedule, roadmap or Gantt chart, compare two versions of a plan | `references/timelines.md` |
|
|
23
|
+
| propose a change to something that already exists (`target`, `ref`, `set`, `removals`) | `references/proposals.md` |
|
|
24
|
+
| group elements, colour a table's rows by what a change did, declare viewpoints | `references/graphs-and-tables.md` |
|
|
25
|
+
| carry attributes, expectations, locations, artifact links, or a requirements table with headings and traceability (version 2) | `references/enriched-contract.md` |
|
|
26
|
+
| put a diagram or a table into a document you are writing | `references/figures.md` |
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
The normative contracts sit in this directory too — `structured-exchange-1.json`,
|
|
29
|
+
`-2.json`, `-3.json` — read one when a detail is not enough, and do not go hunting
|
|
30
|
+
elsewhere in the workspace for it.
|
|
32
31
|
|
|
33
32
|
## The tool validates for you
|
|
34
33
|
|
|
@@ -49,11 +48,10 @@ refused, never corrected — correcting it would produce a document you did not
|
|
|
49
48
|
}
|
|
50
49
|
```
|
|
51
50
|
|
|
52
|
-
`kind` is `graph`, `sequence`, or `table
|
|
53
|
-
can be shown and reasoned about, never proposed
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
contract**).
|
|
51
|
+
`kind` is `graph`, `sequence`, or `table` — and, under version 3, `timeline`. Under
|
|
52
|
+
version 1 a table is a projection: it can be shown and reasoned about, never proposed.
|
|
53
|
+
Under version 2 its rows can carry an identity, so a table can be proposed like
|
|
54
|
+
anything else (`references/enriched-contract.md`).
|
|
57
55
|
|
|
58
56
|
Each carries its own `data`:
|
|
59
57
|
|
|
@@ -74,116 +72,66 @@ Each carries its own `data`:
|
|
|
74
72
|
A message declares a `label` and no `kind` — the label *is* what is being sent.
|
|
75
73
|
Message order is the order you write them in; nothing sorts them for you.
|
|
76
74
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
A table cannot be proposed, but it can *report* on a change it projects. Any row
|
|
80
|
-
may say what it plays, and the interface colours it the way it colours an added or
|
|
81
|
-
changed element in a graph:
|
|
82
|
-
|
|
83
|
-
```jsonc
|
|
84
|
-
"data": {
|
|
85
|
-
"columns": ["id", "requirement", "status"],
|
|
86
|
-
"rows": [
|
|
87
|
-
{ "role": "added", "cells": ["REQ-5", "Log every actuation.", "draft"] },
|
|
88
|
-
{ "role": "changed", "cells": ["REQ-2", "Signal a fault within 200 ms.", "in review"] },
|
|
89
|
-
{ "role": "removed", "cells": ["REQ-3", "Read battery voltage at 10 Hz.", "withdrawn"] },
|
|
90
|
-
{ "cells": ["REQ-1", "Stop the vehicle within 40 m.", "approved"] } // context
|
|
91
|
-
]
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
`role` is one of `added`, `changed`, `context`, `removed`. A row that declares none
|
|
96
|
-
reads as context when any other row declares one. Both row forms are accepted, so
|
|
97
|
-
`["REQ-1", "…"]` and `{ "cells": ["REQ-1", "…"] }` are the same row, and a table
|
|
98
|
-
that declares no role anywhere is rendered exactly as before roles existed.
|
|
99
|
-
|
|
100
|
-
Declare the role — do not put it in a column and expect the colours. A `status`
|
|
101
|
-
column is your data and is rendered as data; nothing infers a role from it.
|
|
102
|
-
|
|
103
|
-
## Grouping: containers
|
|
104
|
-
|
|
105
|
-
A graph or a sequence may declare **containers** — subsystems, layers, teams,
|
|
106
|
-
whatever the domain groups things into — and each element or participant may say
|
|
107
|
-
which one it belongs to.
|
|
75
|
+
A timeline is version 3 and a whole envelope of its own. Start from this one — it holds
|
|
76
|
+
what most plans need:
|
|
108
77
|
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
|
|
114
|
-
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"schema": "urn:structured-exchange:3",
|
|
81
|
+
"kind": "timeline",
|
|
82
|
+
"data": {
|
|
83
|
+
"title": "Bench test campaign",
|
|
84
|
+
"time": { "start": "2027-03-01", "end": "2027-05-31", "scale": "week" },
|
|
85
|
+
"rows": [
|
|
86
|
+
{ "type": "separator", "label": "Bench" },
|
|
87
|
+
{ "type": "task", "id": "T1", "label": "Bench setup", "items": [
|
|
88
|
+
{ "type": "activity", "id": "setup", "start": "2027-03-01", "end": "2027-03-19", "label": "Install and calibrate" }
|
|
89
|
+
] },
|
|
90
|
+
{ "type": "task", "id": "T2", "label": "Test runs", "items": [
|
|
91
|
+
{ "type": "milestone", "id": "trr", "date": "2027-03-22", "kind": "TRR", "label": "Test Readiness Review" },
|
|
92
|
+
{ "type": "activity", "id": "runs", "start": "2027-03-23", "end": "2027-05-14", "label": "Campaign" }
|
|
93
|
+
] }
|
|
94
|
+
],
|
|
95
|
+
"dependencies": [{ "from": "setup", "to": "trr" }, { "from": "trr", "to": "runs" }],
|
|
96
|
+
"periods": [{ "start": "2027-03-29", "end": "2027-04-02", "label": "Easter closure", "kind": "closure" }],
|
|
97
|
+
"references": [{ "date": "2027-05-28", "label": "Contractual delivery" }]
|
|
98
|
+
}
|
|
115
99
|
}
|
|
116
100
|
```
|
|
117
101
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
-
|
|
121
|
-
|
|
122
|
-
- **Relationships ignore grouping entirely.** They connect elements, they cross
|
|
123
|
-
container boundaries freely, and an endpoint is never a container id. Naming a
|
|
124
|
-
container as `from` or `to` is refused.
|
|
125
|
-
- **Containers do not nest.** A member names a container, never a chain of them.
|
|
126
|
-
- **A container nobody joins is fine.** Declare the group first and fill it later
|
|
127
|
-
if that is what you mean; it is drawn as an empty box.
|
|
128
|
-
|
|
129
|
-
Naming a container the document does not declare is refused rather than quietly
|
|
130
|
-
ungrouped — an element shown outside a group it belongs to would misstate the
|
|
131
|
-
system you are describing.
|
|
102
|
+
- `scale` is `week` for a few months, `month` for a year or two, `quarter` beyond.
|
|
103
|
+
- A closure or a holiday is a **period**, never an activity: it belongs to no task.
|
|
104
|
+
- Every item falls inside `time`; a milestone is one `date`; give an item an `id` if
|
|
105
|
+
anything depends on it.
|
|
132
106
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
the first member of a container met brings the rest of that container with it,
|
|
136
|
-
and anything belonging to no container keeps its place. Declare participants in
|
|
137
|
-
the order you want them read.
|
|
107
|
+
Read `references/timelines.md` for the rest: dependency types, comparing two versions of
|
|
108
|
+
a plan, and putting a timeline in a report.
|
|
138
109
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
When a graph will be read in more than one way — power, then control, then what is
|
|
142
|
-
safety-relevant — declare those readings as `viewpoints` on the envelope, rather than
|
|
143
|
-
leaving the reader to rebuild each one from the key:
|
|
110
|
+
A table of requirements with headings, typed rows and traceability is version 2 — start from
|
|
111
|
+
this one, and read `references/enriched-contract.md` for attributes, expectations and links:
|
|
144
112
|
|
|
145
113
|
```json
|
|
146
114
|
{
|
|
147
115
|
"schema": "urn:structured-exchange:2",
|
|
148
|
-
"kind": "
|
|
149
|
-
"viewpoints": [
|
|
150
|
-
{
|
|
151
|
-
"id": "power",
|
|
152
|
-
"label": "Power distribution",
|
|
153
|
-
"concern": "Where energy is stored, converted and consumed",
|
|
154
|
-
"elementKinds": ["source", "load"],
|
|
155
|
-
"relationshipKinds": ["power"]
|
|
156
|
-
}
|
|
157
|
-
],
|
|
116
|
+
"kind": "table",
|
|
158
117
|
"data": {
|
|
159
|
-
"
|
|
160
|
-
|
|
161
|
-
{ "
|
|
162
|
-
{ "id": "
|
|
118
|
+
"columns": ["id", "requirement", "status"],
|
|
119
|
+
"rows": [
|
|
120
|
+
{ "heading": "1. Braking", "depth": 1 },
|
|
121
|
+
{ "id": "r1", "ref": "REQ-1", "kind": "requirement",
|
|
122
|
+
"cells": ["REQ-1", "Stop within 40 m", "approved"],
|
|
123
|
+
"attributes": { "verification": "test" } },
|
|
124
|
+
{ "id": "r2", "ref": "REQ-2", "kind": "requirement",
|
|
125
|
+
"cells": ["REQ-2", "Read wheel speed at 100 Hz", "approved"] }
|
|
163
126
|
],
|
|
164
|
-
"
|
|
165
|
-
{ "from": "
|
|
166
|
-
{ "from": "
|
|
127
|
+
"relations": [
|
|
128
|
+
{ "from": { "id": "r1" }, "to": { "id": "r2" }, "kind": "derives" },
|
|
129
|
+
{ "from": { "id": "r1" }, "to": { "ref": "TEST-9" }, "kind": "verifiedBy" }
|
|
167
130
|
]
|
|
168
131
|
}
|
|
169
132
|
}
|
|
170
133
|
```
|
|
171
134
|
|
|
172
|
-
- **A viewpoint says what it retains.** Name the element kinds, the relationship kinds,
|
|
173
|
-
or both — at least one list. A list you leave out keeps that whole vocabulary.
|
|
174
|
-
- **Only kinds the document has.** Every kind you retain must be the kind of some
|
|
175
|
-
element (or, for `relationshipKinds`, some relationship) in this document. A typo is
|
|
176
|
-
refused, not corrected, and the refusal says when the word exists in the other list.
|
|
177
|
-
- **Always give the concern.** It is printed inside every figure drawn for the
|
|
178
|
-
viewpoint — write it as the question that reading answers.
|
|
179
|
-
- **Graphs only**, and at most twenty per document.
|
|
180
|
-
- **Something with no kind survives every viewpoint.** If an element must drop out of a
|
|
181
|
-
reading, give it a kind.
|
|
182
|
-
|
|
183
|
-
When you write a report with one chapter per reading, write one figure per viewpoint:
|
|
184
|
-
`write_structure_figure` with `viewpoint: "power"`. Do not rebuild the same selection
|
|
185
|
-
from hide lists — the viewpoint carries both the selection and the reason for it.
|
|
186
|
-
|
|
187
135
|
## Two identities, never confused
|
|
188
136
|
|
|
189
137
|
Every element carries an `id`, and may carry a `ref`.
|
|
@@ -242,23 +190,23 @@ A physical architecture might use `battery`, `converter`, `motor`, `controller`,
|
|
|
242
190
|
model whatever its profile defines. Relationships likewise: `power`, `thermal`,
|
|
243
191
|
`communication` on a physical model, `calls`, `writes`, `publishes` on a software one.
|
|
244
192
|
|
|
245
|
-
##
|
|
246
|
-
|
|
247
|
-
Name the artifact in `target`. Then:
|
|
193
|
+
## Changing something that exists
|
|
248
194
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
195
|
+
> **The one rule that trips everyone up.** When you propose a change to something
|
|
196
|
+
> that already exists, the fields you write beside its `ref` say *what it is called
|
|
197
|
+
> now*. They are not applied. The new value goes in `set`.
|
|
198
|
+
>
|
|
199
|
+
> ```json
|
|
200
|
+
> { "id": "ledger", "ref": "EL-7", "label": "Ledger",
|
|
201
|
+
> "set": { "label": "General Ledger" } }
|
|
202
|
+
> ```
|
|
203
|
+
>
|
|
204
|
+
> Writing `"label": "General Ledger"` on its own does **not** rename anything — it
|
|
205
|
+
> claims that is already its name, and the proposal silently does nothing. If the
|
|
206
|
+
> tool answers `0 changed`, this is what happened.
|
|
255
207
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
> and nothing else — it cannot look up what `REL-88` stood for, so without them the
|
|
259
|
-
> approval gate reads "relationship: REL-88" and asks someone to approve deleting
|
|
260
|
-
> something they cannot see. These fields describe and never identify: `ref` is still
|
|
261
|
-
> what names the thing.
|
|
208
|
+
A whole proposal — one element kept as context, one renamed, one added, one relationship
|
|
209
|
+
removed and said what it was:
|
|
262
210
|
|
|
263
211
|
```json
|
|
264
212
|
{
|
|
@@ -281,142 +229,10 @@ Name the artifact in `target`. Then:
|
|
|
281
229
|
}
|
|
282
230
|
```
|
|
283
231
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
- **The removal** names `REL-88` and says what it is: the `calls` from Ledger to
|
|
287
|
-
Billing. The reader sees what goes, rather than an identifier.
|
|
288
|
-
|
|
289
|
-
- **`billing`** has a `ref` and a name, no `set` → **context**. It exists, it is shown
|
|
290
|
-
so you can see where the new thing attaches, and nothing happens to it.
|
|
291
|
-
- **`ledger`** has a `ref`, its current name, and a `set` → **a change**. The reader
|
|
292
|
-
sees `Ledger → General Ledger`, which is what makes it approvable.
|
|
293
|
-
- **`audit`** has no `ref` → **new**. With nothing to describe, its `label` is simply
|
|
294
|
-
its value.
|
|
295
|
-
|
|
296
|
-
**Include as much context as the reader needs.** That is what the default is for: an
|
|
297
|
-
element you include to make the picture legible costs nothing and changes nothing.
|
|
298
|
-
Leaving it out to be safe is the wrong instinct — a proposal nobody can situate is a
|
|
299
|
-
proposal nobody should approve.
|
|
300
|
-
|
|
301
|
-
### Two rules that catch people out
|
|
302
|
-
|
|
303
|
-
**Never put a `set` on something with no `ref`.** There is nothing to change; its
|
|
304
|
-
fields are already its values. Refused.
|
|
305
|
-
|
|
306
|
-
**Never both `set` and remove the same `ref`.** That states two intentions at once and
|
|
307
|
-
is refused rather than resolved — decide which you meant.
|
|
308
|
-
|
|
309
|
-
**A relationship always declares `from` and `to`**, even when it carries a `ref`. Its
|
|
310
|
-
endpoints are its identity, not something you patch. To re-attach a relationship,
|
|
311
|
-
remove it and declare a new one.
|
|
312
|
-
|
|
313
|
-
**Moving something between containers is an ordinary change**: `"set": { "container":
|
|
314
|
-
"electrical" }` on an element that carries a `ref`, like any other field you change.
|
|
315
|
-
Containers themselves are not patched — they are declared afresh in every document.
|
|
316
|
-
|
|
317
|
-
## What the reader sees, and what the model sees
|
|
318
|
-
|
|
319
|
-
The structured document is rendered for the human and **does not reach the model** —
|
|
320
|
-
not even yours, on a later turn. So the result's ordinary text must stand on its own:
|
|
321
|
-
summarise what the structure says, well enough that the next question can be answered
|
|
322
|
-
without it. A document with a rich diagram and a one-line text is a document you
|
|
323
|
-
cannot reason about afterwards.
|
|
324
|
-
|
|
325
|
-
You also do not choose how a graph is arranged. It is laid out across the page while it
|
|
326
|
-
fits the reading column and down the page when it does not, and the reader can turn it
|
|
327
|
-
either way. Do not describe a diagram's direction in your summary — say what it shows, not
|
|
328
|
-
which way it runs.
|
|
329
|
-
|
|
330
|
-
## Putting a diagram in a document you are writing
|
|
331
|
-
|
|
332
|
-
`present_structure` shows a document in the conversation. When you are *writing* a
|
|
333
|
-
file — a report, a design note, a README — a diagram belongs in that file instead,
|
|
334
|
-
and `write_structure_figure` puts it there:
|
|
335
|
-
|
|
336
|
-
```
|
|
337
|
-
write_structure_figure(
|
|
338
|
-
path: "models/vehicle.json",
|
|
339
|
-
output_path: "figures/power-train.svg",
|
|
340
|
-
hide_relationship_kinds: ["diagnostic"]
|
|
341
|
-
)
|
|
342
|
-
```
|
|
232
|
+
An element you do not mention is left alone; never put a `set` on something with no
|
|
233
|
+
`ref`. Read `references/proposals.md` for the rest of the rules that refuse a proposal.
|
|
343
234
|
|
|
344
|
-
|
|
345
|
-
`.svg`. Reference it from your Markdown as a relative path — `` — and the interface renders it in the preview.
|
|
347
|
-
|
|
348
|
-
Three things about it are worth knowing before you use it.
|
|
349
|
-
|
|
350
|
-
**The two hide lists are different vocabularies.** `hide_element_kinds` hides boxes by
|
|
351
|
-
their `kind`; `hide_relationship_kinds` hides arrows by theirs. The same name in both
|
|
352
|
-
means two unrelated things, and naming one where you meant the other hides nothing,
|
|
353
|
-
draws a perfectly valid figure of the whole document, and looks like it worked.
|
|
354
|
-
|
|
355
|
-
**Write one figure per view worth having.** A narrowed figure is the reason the tool
|
|
356
|
-
takes a narrowing at all: three figures each about one thing beat one figure of
|
|
357
|
-
everything, which is the diagram nobody reads. A figure that shows less than its
|
|
358
|
-
document says so, inside the picture, so a figure separated from its source is never
|
|
359
|
-
mistaken for the whole of it.
|
|
360
|
-
|
|
361
|
-
**A relationship whose endpoint you hid goes with it.** An arrow to a box that is not
|
|
362
|
-
drawn cannot be drawn. The result tells you how much of the document the figure shows,
|
|
363
|
-
so a narrowing that took more than you meant is visible in the answer rather than in
|
|
364
|
-
the file.
|
|
365
|
-
|
|
366
|
-
A table has no figure — it is data. To put one in a document you are writing,
|
|
367
|
-
`write_structure_table` writes it as Markdown:
|
|
368
|
-
|
|
369
|
-
```
|
|
370
|
-
write_structure_table(
|
|
371
|
-
path: "requirements/braking.json",
|
|
372
|
-
output_path: "reports/braking-requirements.md"
|
|
373
|
-
)
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
It reads a table from the workspace and writes a new `.md` file — each chapter a heading
|
|
377
|
-
followed by a Markdown table of its rows — which you can include in the document or hand on.
|
|
378
|
-
It never overwrites an existing file, and a table the project's profile or rules refuse is not
|
|
379
|
-
written. The reader can also export a table they are shown as a spreadsheet or as Markdown.
|
|
380
|
-
|
|
381
|
-
## The enriched contract: `urn:structured-exchange:2`
|
|
382
|
-
|
|
383
|
-
Everything above is version 1 and still works exactly as written. Declare version 2
|
|
384
|
-
instead when you need any of what follows. Nothing is removed: change the identifier and
|
|
385
|
-
a version 1 document is a version 2 document, except that `target` becomes an object
|
|
386
|
-
(`"target": { "ref": "architecture-v4" }`), which is what lets it name a revision.
|
|
387
|
-
|
|
388
|
-
**Emit version 1 unless you need something below.** The reader cannot tell which you
|
|
389
|
-
used and neither contract is better; there is simply no reason to reach for the larger
|
|
390
|
-
vocabulary to say a smaller thing.
|
|
391
|
-
|
|
392
|
-
### Attributes: the properties your domain owns
|
|
393
|
-
|
|
394
|
-
Any element, relationship or row may carry `attributes` — bounded, typed properties
|
|
395
|
-
whose names belong to your domain, not to this contract.
|
|
396
|
-
|
|
397
|
-
```json
|
|
398
|
-
{ "id": "battery", "label": "Battery", "kind": "source",
|
|
399
|
-
"attributes": { "voltage": 400, "chemistry": "LFP", "serviceable": true,
|
|
400
|
-
"suppliedBy": [{ "ref": "ORG-3" }] } }
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
A value is a string, a finite number, a boolean, `null`, a reference (`{ "ref": "…" }`),
|
|
404
|
-
or one flat list of those. **Lists never nest and no other object shape is allowed.** A
|
|
405
|
-
quantity with a unit is two attributes or one string — `"mass_kg": 3.4`, not
|
|
406
|
-
`{ "value": 3.4, "unit": "kg" }`, which is refused.
|
|
407
|
-
|
|
408
|
-
Name the vocabulary those names come from with `profile` on the envelope:
|
|
409
|
-
|
|
410
|
-
```json
|
|
411
|
-
{ "schema": "urn:structured-exchange:2", "kind": "graph", "profile": "acme/electrical", "data": { … } }
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
The profile is **a name and nothing more**. It is never fetched, resolved or executed,
|
|
415
|
-
and a reader who does not know it still sees every attribute, rendered generically. Do
|
|
416
|
-
not invent one to look official; use the identifier your domain actually uses, or omit
|
|
417
|
-
it.
|
|
418
|
-
|
|
419
|
-
### When the project holds you to a profile
|
|
235
|
+
## When the project holds you to a profile
|
|
420
236
|
|
|
421
237
|
A project may register profiles — its own data model: the kinds that exist, the attributes
|
|
422
238
|
each kind carries, the values each enumeration allows, the kinds each relationship joins.
|
|
@@ -460,122 +276,18 @@ A profile may declare **viewpoints** too. `write_structure_figure` accepts one b
|
|
|
460
276
|
even when the document does not declare it, and its result says whether the viewpoint came
|
|
461
277
|
from the document or from the profile.
|
|
462
278
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
Version 1 already separates *describing* a referenced thing from *changing* it. Version
|
|
466
|
-
2 adds a third, and confusing them is the mistake that matters:
|
|
467
|
-
|
|
468
|
-
```json
|
|
469
|
-
{ "id": "r1", "ref": "REQ-1",
|
|
470
|
-
"label": "Stop within 40 m",
|
|
471
|
-
"expect": { "revision": "rev-9", "attributes": { "status": "approved" } },
|
|
472
|
-
"set": { "label": "Stop within 35 m", "attributes": { "status": "in review" },
|
|
473
|
-
"removeAttributes": ["waiver"] } }
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
- **beside `ref`** — what it is called *now*. How the reader recognises it. Applied to
|
|
477
|
-
nothing.
|
|
478
|
-
- **`expect`** — what you believe is currently true, for the receiving authority to check
|
|
479
|
-
before it applies anything. You are not asserting it is true; you are saying what you
|
|
480
|
-
assumed. If you did not read the current state, do not write an `expect`.
|
|
481
|
-
- **`set`** — the only thing that changes anything.
|
|
482
|
-
- **`removeAttributes`** — takes properties away. **`null` does not delete.** Writing
|
|
483
|
-
`"waiver": null` sets the property to null; to unset it, name it here. Naming the same
|
|
484
|
-
attribute in both `set.attributes` and `removeAttributes` is refused rather than
|
|
485
|
-
resolved, because there is no precedence worth inventing.
|
|
486
|
-
|
|
487
|
-
Put the revision you prepared against on the target: `"target": { "ref": "REQ-DOC-1",
|
|
488
|
-
"revision": "rev-9" }`. A revision and an `expect` are only allowed in a proposal —
|
|
489
|
-
there is no authority to check them against otherwise.
|
|
490
|
-
|
|
491
|
-
### Locations: where it is, never what it is
|
|
492
|
-
|
|
493
|
-
```json
|
|
494
|
-
"locations": [{ "uri": "file:///src/brakes.ts", "revision": "abc123",
|
|
495
|
-
"range": { "startLine": 10, "endLine": 42 } }]
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
A hint for a reader, zero-based. It takes no part in identity: `ref` says what something
|
|
499
|
-
**is**, a location says where a copy of it can be found today. Never encode a path into a
|
|
500
|
-
`ref` to save writing one — moving the file would then change the thing's identity.
|
|
501
|
-
|
|
502
|
-
Nothing is opened until a reader asks, and only through the application's existing rules
|
|
503
|
-
about what may be opened at all.
|
|
504
|
-
|
|
505
|
-
### Artifacts: linked, digested, not attached
|
|
506
|
-
|
|
507
|
-
```json
|
|
508
|
-
"artifacts": [{ "rel": "verifies", "uri": "https://ci.example/report.json",
|
|
509
|
-
"sha256": "sha256:<64 hex characters>", "mediaType": "application/json" }]
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
The digest is mandatory, and it is the point: it binds an approval to specific bytes
|
|
513
|
-
even when the URI serves different ones later. If you cannot compute a digest, you do not
|
|
514
|
-
have an artifact link — use a location instead. Never inline the content; the envelope
|
|
515
|
-
carries references, and a payload pasted into it is a document nobody can read and a
|
|
516
|
-
ceiling you will hit.
|
|
517
|
-
|
|
518
|
-
### Tables that carry a document
|
|
519
|
-
|
|
520
|
-
A row may declare an identity and a type of its own, which is what makes a requirements
|
|
521
|
-
table more than a grid:
|
|
522
|
-
|
|
523
|
-
```json
|
|
524
|
-
{ "id": "r1", "ref": "REQ-1", "kind": "requirement",
|
|
525
|
-
"cells": ["REQ-1", "Stop within 40 m", "approved"] }
|
|
526
|
-
```
|
|
527
|
-
|
|
528
|
-
Headings organise it, and are rows of their own — not a data row with empty cells:
|
|
529
|
-
|
|
530
|
-
```json
|
|
531
|
-
{ "heading": "1. Braking", "depth": 1 }
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
Traceability between rows is declared beside them, with each end stated explicitly:
|
|
535
|
-
|
|
536
|
-
```json
|
|
537
|
-
"relations": [
|
|
538
|
-
{ "from": { "id": "r1" }, "to": { "id": "r2" }, "kind": "derives" },
|
|
539
|
-
{ "from": { "id": "r1" }, "to": { "ref": "TEST-9" }, "kind": "verifiedBy" }
|
|
540
|
-
]
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
`{ "id": … }` is a row of this document and must exist — a typo is refused, not quietly
|
|
544
|
-
drawn pointing at nothing. `{ "ref": … }` is something outside it and is accepted as
|
|
545
|
-
leaving the document, which is the normal case for the test that verifies a requirement.
|
|
546
|
-
Relation kinds are opaque, like every other kind: `derives`, `verifiedBy`, `satisfies` —
|
|
547
|
-
whatever your domain says.
|
|
548
|
-
|
|
549
|
-
**Do not state coverage you have not been told.** A requirement with no relation is a
|
|
550
|
-
requirement with no relation; the application reports what you declared and infers
|
|
551
|
-
nothing about what is missing.
|
|
279
|
+
## What the reader sees, and what the model sees
|
|
552
280
|
|
|
553
|
-
|
|
281
|
+
The structured document is rendered for the human and **does not reach the model** —
|
|
282
|
+
not even yours, on a later turn. So the result's ordinary text must stand on its own:
|
|
283
|
+
summarise what the structure says, well enough that the next question can be answered
|
|
284
|
+
without it. A document with a rich diagram and a one-line text is a document you
|
|
285
|
+
cannot reason about afterwards.
|
|
554
286
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
"profile": "acme/requirements",
|
|
560
|
-
"data": {
|
|
561
|
-
"columns": ["id", "requirement", "status"],
|
|
562
|
-
"rows": [
|
|
563
|
-
{ "heading": "1. Braking", "depth": 1 },
|
|
564
|
-
{ "id": "r1", "ref": "REQ-1", "kind": "requirement",
|
|
565
|
-
"cells": ["REQ-1", "Stop within 40 m", "approved"],
|
|
566
|
-
"attributes": { "verification": "test" },
|
|
567
|
-
"locations": [{ "uri": "file:///specs/brakes.md", "range": { "startLine": 10, "endLine": 12 } }] },
|
|
568
|
-
{ "heading": "1.1 Sensing", "depth": 2 },
|
|
569
|
-
{ "id": "r2", "ref": "REQ-2", "kind": "requirement",
|
|
570
|
-
"cells": ["REQ-2", "Read wheel speed at 100 Hz", "approved"] }
|
|
571
|
-
],
|
|
572
|
-
"relations": [
|
|
573
|
-
{ "from": { "id": "r1" }, "to": { "id": "r2" }, "kind": "derives" },
|
|
574
|
-
{ "from": { "id": "r1" }, "to": { "ref": "TEST-9" }, "kind": "verifiedBy" }
|
|
575
|
-
]
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
```
|
|
287
|
+
You also do not choose how a graph is arranged. It is laid out across the page while it
|
|
288
|
+
fits the reading column and down the page when it does not, and the reader can turn it
|
|
289
|
+
either way. Do not describe a diagram's direction in your summary — say what it shows, not
|
|
290
|
+
which way it runs.
|
|
579
291
|
|
|
580
292
|
## Size
|
|
581
293
|
|