2. Conformance
Contents of ATD 0.1
- A description conforms to ATD 0.1 when every file of it parses with the grammar of section 4 under the version it declares (section 5.4) and the checker of section 14 reports no finding of severity
errorfor it. - A checker conforms when, for every description, it reports exactly the findings of sections 14 and 15, by code, severity, file, line and column. The refused corpus beside this document (
refused/, section 19.3) is the contract: a conforming checker gives each refused file exactly the findings its.findings.jsonstates, and each example beside this document no finding. - A language server conforms when it reports, for the same text, the same diagnostics as a conforming checker (FR-054), and offers the capabilities FR-051 of spec 035 lists (colouring, completion, definition, references, rename, diagnostics, hover, formatting and an outline) in the parts of a file that parse when another part does not.
- A runtime conforms when it runs a description that checks without errors, and, for every conformance fixture of that description, produces the readings, findings, splices, drawings and bytes the fixture states (section 2.3), with no code of its own for any tool type, apart from the capabilities of section 13.
The key words of the status section apply to every normative section. A requirement on "a reader" applies to a checker, a language server and a runtime alike.
A conformance fixture is one case of one tool type: input files, the gestures made on them, and what the reference host produced for each. It extends FBL's round-trip fixture (FBL §15.3) with gestures, readings, findings, splices, drawings and the provenance of each part. A case is a folder definitions/<kind>s/conformance/<type>/<case>/ holding conformance.json (atd.schema.json#/$defs/ConformanceFixture) and its files.
toolis the tool type's origin;descriptionthe path of the root.atd, relative to the case's folder.recordedFromis the kind of host that recorded the case:modulewhen the tool type's module opens its own documents,declared, the default, when the tool is drawn from its specification. A recorder MUST writemodulefor a case recorded from such a module.inputsnames the input files by role (body,registration, and for a folder body each file); they are kept byte for byte, and Git never converts them (.gitattributes:-text).readis what reading the inputs yields: the elements with their type, parent and the attributes compared; the relations with their ends; the findings (each with its rule or code and its line); and the parts the reader could not read.drawingis the scene after reading (section 2.4), inline or as{"$ref": "<file>"}beside the case.stepsare the gestures, in order. A step has exactly one ofaction(withargs, afterselect),property,move,create,connect,delete,outside,undoandredo, and states what it produces:splices(FBL$defs/Splice, UTF-8 byte offsets into the body before the step), the body's bytes after it (expectinline, orexpectFile),findings,drawing, orrefusedwith the reason the gesture was refused with.idslists the ids the reference host generated in the step, in order; a runtime MUST be given them, in that order, in place of ids of its own, so that bytes can be equal.- A
createstep'stypeand aconnectstep'stypename what the gesture is, as the tool's toolbox or its binding's wire form names it, or the element or relation type: a type alone cannot choose between tools that create one type.atis where acreatelands.args.valueanswers a prompt the gesture raises; on anaction,args.atis the canvas point it is made at. Aconnectto an end that does not exist yet carries that end as acreatein the same step, the one exception to a step's having one gesture. - A step never carries a target string only one host understands. A gesture these steps cannot state is named when the case is recorded, and either ATD gains a step for it or the case leaves it out.
- A
refusedreason is compared exactly, unless the case's is a host's or a module's own sentence that a gesture is not offered:Unknown action '<id>'.,'<id>' does not apply to this selection.,'<id>' cannot be edited on this selection.andThat action is not available for this item., a closed set. Such a sentence says only that the tool refuses the step, and no description could have written it, so any reason given for refusing that step counts as the same refusal: the runtime's own sentence, or the description's own reason. A step one tool refuses and the other makes stays a difference, and a reason of the case's that is not one of these sentences is compared exactly. - A
movestep moveselementto a place,xandy, by a distance from where it is drawn,dxanddy, or intoparent: before the child atindexthere, counted among the parent's children as they are before the move, the element itself included, or after the last whenindexis -1 or absent, as the reference host's gesture placed it. - An
outsidestep writes a file of the case as another program or an agent would, replacing the first occurrence offrominfilebyto, and tells the host the file changed, as its watcher does; the history starts afresh with it, so no step before it can be undone, and a refused step leaves the bytes as they were. A designer's gesture on its page is anactionnaming the operation, with the entry it is made on inselectand the operation's parameters inargs. - An
undoMUST give back the bytes before the step it undoes exactly, and aredothe bytes after it. provenancenames, for each part (bytes,reading,findings,drawing), the host and repository that produced it,commit, the reference commit whose behaviour it records,recordedWith, for a recorded part the commit of the recorder, andsource, a standalone host's golden oratd record. The reference host differs by part: the standalone host for bytes, as the desktop host's parity goldens record them, and the desktop host at its reference commit for readings, findings and drawings (spec 035, Q5). A tool type the desktop host did not have at its reference commit (the Hierarchical Requirement Designer, added by spec 036) takes its readings and findings from the desktop host at the commit that records them, whichcommitandrecordedWiththen both name. A designer's page has no recording painter, so a designer's case states no drawing.- A fixture changes only by recording it again, never by hand. A runtime passes a fixture when every part of every step equals what the fixture states, bytes byte for byte, a reading and a drawing recorded from a module as the next paragraph and section 2.4 compare them; a difference is reported with its step, its part, the expected and the actual value (for bytes, the first line that differs) and the construct of the description that produced the value (section 15.1,
ATD9001). - A case whose
recordedFromismodulestates its reading in the module's own terms, so itsread.elementsandread.relationsMUST be compared by what they mean, in place of exactly (spec 067, FR-012). Each is keyed byid. An element or relation the case states MUST be in the reading, with the sameparent,sourceandtarget, unless the case's own drawing does not draw it and the reading does not have it: that is the module's own presentation, such as an element that stands for a view or a boundary. One the reading has and the case does not MUST be one the description's drawing does not draw, since a module reads the view it shows and a description the whole body. Values MUST be compared for the attributes both sides can state: those the description's model declares on the element's type, not derived, that the case states on some element or relation of its reading; an absent value is the empty text on either side, so neither side can drop a value unnoticed. A list of the reading whose case states attributes and has none of them in common with the description is a difference, counting only what an element or relation states beyond the names DISL §2.2 reserves and the painted values, the values a module writes for its own drawing:role,label,badges,widthandheight. A painted value the description does declare is compared like any other.type, and every other attribute, MUST NOT be compared.splices, bytes,findingsandrefusedare compared exactly in every case, and a case recorded from a declared tool is compared exactly in every part.
fixtures/mindmap/basic/ beside this document is a worked example, written by hand for the example mindmap.atd: a read, one action and its undo.
A drawing is the scene of one view after a reading or a step, in the vocabulary of the desktop host's scene (adp-scene), never pixels (atd.schema.json#/$defs/Drawing):
elements: each drawn element with itsid,type,shape,bounds(x,y,w,h),labels(text, the font token, position),style(paints resolved to colours, with the token names they came from),childrenandstate;edges: each drawn edge with itsid,type,source,target,route(points),markersandlabels;chrome: bands, notices, legends, headers and rulers;order: the ids of everything drawn, in drawing order.
Positions and sizes are in the canvas's domain units, rounded to 0.01. Two drawings are equal when their elements and their edges are equal as sets keyed by id, their chrome is equal, and their order lists are equal. fixtures/mindmap/basic/drawing.read.json is a worked example.
A drawing recorded from a module that opens its own documents (recordedFrom is module, section 2.3) MUST be compared by which elements appear and where, in place of exactly: two drawings then agree when their elements have the same ids and the same bounds, and their edges the same ids, source and target. An element's type, shape, labels, style, children and state, an edge's type, route, markers and labels, the chrome and the order are the module's painting, and MUST NOT be compared.
A trace is the file <name>.trace.json beside a tool description (atd.schema.json#/$defs/Trace). It shows that the description is complete (FR-021 to FR-023):
companionnames the type's companion file and the sections of it whose items the description must state, and, inreports, any further companion file beside it, such as a conversion's report, that is read with it. An item is each###heading and each top-level list item under a named section, numbered from 1 in each section; its id is<section-slug>/<n>, the slug being the section's heading in lowercase with every run of other characters than letters and digits made one-.itemslists every item exactly once, with itstext(the item's heading or the start of its line), and one ofstatedBy, the part of the description that states it;hostConcern, one of section 17's concerns, with itsreason; oropen, the address of the etalii.adp issue that adds to ATD the construct the item needs, with itsreason, for an item no construct of this version can state. Anopenitem is not stated: it records a gap of the language rather than of the description, and it is closed by the change that adds the construct, which states the item and dropsopen.hostCodelists every behaviour read in a host's code at its reference commit:host,repository,commit,path,linesand a one-sentencebehaviour, and eitherstatedBy(the reference host's behaviour, which the description states), ordivergesFrom(another host's behaviour that differs from the reference host's and is not stated; it names thestatedByof the reference behaviour the description states instead), orhostConcernwith itsreason, oropenwith itsreason, the address of the etalii.adp issue that adds the construct the reference host's behaviour needs, for a behaviour no construct of this version can state.
A statedBy names a construct as <keyword> <name>, with the names of its enclosing constructs where one name is not enough (fn siblingName, operation addSibling, binding freeplane element node, notation node Node label text, capability layout.twoSidedTree, algorithm mindmap). Every statedBy and divergesFrom MUST resolve in the description (atd check --trace), and every item of the named sections MUST be traced exactly once (validate-examples.py). mindmap.trace.json with its companion mindmap.md is a worked example.
A capability (section 13) is specified in capabilities/<name>/ beside this document:
contract.json(atd.schema.json#/$defs/Capability): itsname(<extension point>.<algorithm or format>), itsversion(semver), itsextensionPoint, itsinputandoutput(references to$defsofatd.schema.json), itsargs(each with its type, values, default and documentation), itslaws(deterministic,pinnedStay,stable,readingNeverFails,minimalSplices,pure), itsexceptionsto the determinism of section 12.5 with their reasons, itsfallbackand itsstatus(provisional,standard,deprecated);fixtures/<case>.json($defs/CapabilityFixture): aninput, theargsand the expectedoutput.
A host MUST pass every fixture of a capability before it offers it. capabilities/layout.twoSidedTree/contract.json is a worked example; its fixtures are recorded from the code that lays the mind map out today.