← TomSpecs
Publishedlicense: BSD-3-Clause

tom_som_dart_v0

tom_som_dart_v0 · v1.3.2

The typed access path: a Dart API generated from the source model, so a Solution Blueprint and its detail documents can be built and read with compile-time checked types and serialized to DocSpecs YAML and markdown.

View repository → See License
Status
Published
LOC
120.8k
Tests
47
Test LOC
605

Overview

From the module readme.md file:

What it enables

Enables Typed specification authoring, YAML and markdown renditions.

Relationships

Standalone — no declared relationships.

tom_som_dart_v0 — typed TomSpecs object model for Dart

> Cross-references. > tom_specs_model/doc/som_multiplatform_spec_model.md > is the SOM authority: SOM §6 decides the split between this > typed access path and the generic one, SOM §8 decides what > this generated surface contains, SOM §4.2 decides the model > version stamp and the editing rules it enforces, and > SOM §17 decides how the package is built and published. > tom_specs_model/doc/index.md catalogues every > TomSpecs subject-matter document and owns the § citation > convention. This README says how to use this package's code; > those documents own the model, the formats and the rules, and > nothing here restates them.

Generated typed TomSpecs object model (v0). An editing facade over the generic tom_som_dart_runtime; see the meta-data file and DocSpecs schemas in this package. Regenerate with tom_specs_clitool/bin/generate_som.dart.

Where this fits

tom_som_dart_v0 is the generated typed face of the TomSpecs object model for Dart: one type per document section, so a specification is read and written through named members rather than through string paths. It exists because a string path is checked only at run time — a mistyped one reads as an absent value instead of an error — and a specification is exactly the kind of document where that failure is silent and expensive. It is one half of a pair: the hand-written tom_som_dart_runtime holds everything identical in every language (the sparse document store, the codecs, the validator) and this half holds only what changes when the model changes, so a regeneration rewrites the typed types and touches nothing else. The same pair exists for all nine SOM languages, generated from one model, so a document written through any of them reads identically through the other eight. Dart is the reference plane: the model, the generator and the conformance goldens are all authored here, and the other eight languages are transcribed from it.

Overview

A TomSpecs document is sparse and path-keyed: a value lives under the globally-unique section-id path it belongs to, and an absent key means "no value" rather than an empty one. This package holds none of those values — SpecDocument, in the runtime, does. What it holds is a typed view: each generated type wraps a document together with the path prefix it is rooted at, and its members resolve to the paths beneath that prefix. Constructing a document root also runs the model-version check (SOM §4.2), so a document stamped by a different model version is refused rather than silently misread.

Everything generated here is derived from the tom_specs_model Dart model and rewritten wholesale on every run of tom_specs_clitool/bin/generate_som.dart. Beside the typed types the package ships the lossless meta-data file (meta/spec_model.meta.json, SOM §5.3), the generated DocSpecs schemas (schemas/, SOM §13), and the metadata trees that drive the dot-notation and id-tree access surfaces (SOM §8). The hand-written trees beside them — example/, the tests, doc/ — are preserved across regeneration; the generator writes files, it never wipes the output root.

Installation

Add the dependency and let pub resolve it:

dart pub add tom_som_dart_v0

or pin it explicitly in pubspec.yaml:

dependencies:
  tom_som_dart_v0: ^1.3.2

tom_som_dart_v0 and tom_som_dart_runtime both carry version 1.3.2, taken from the TomSpecs model version — pin them together. Every other dependency route (git, path, vendored, build-from-source) is in readme_howtointegrate.md.

Features

Document roots

Each root is a whole TomSpecs document, and the first segment of every path beneath it is its section id. Construct the root you need over a SpecDocument; the 1254 model classes are reached through it.

Section idDocumentGenerated root type
SBPSolution BlueprintD00SolutionBlueprint
CLA Current Landscape Assessment D01CurrentLandscapeAssessment
TOM Target Operating Model D02TargetOperatingModel
IFMInformation ModelD03InformationModel
RSP Requirements Specification D04RequirementsSpecification
ISCInteraction ScenariosD05InteractionScenarios
ATS Architecture & Technology Specification D06ArchitectureTechnologySpecification
IIS Integration & Interface Specification D07IntegrationInterfaceSpecification
SAS Security & Access Specification D08SecurityAccessSpecification
XDS Experience Design Specification D09ExperienceDesignSpecification
QAP Quality & Acceptance Plan D10QualityAcceptancePlan
DRMDelivery RoadmapD11DeliveryRoadmap
TRP Transition & Rollout Plan D12TransitionRolloutPlan
CGP CodeSpecs Generation Projection D13CodeSpecsProjection

Quick start

Add tom_som_dart_v0 to your pubspec.yaml (dart pub add tom_som_dart_v0), then:

import 'package:tom_som_dart_v0/tom_som_dart_v0.dart';

void main() {
  // A typed Solution Blueprint over a fresh document.
  final doc = SpecDocument();
  final blueprint = D00SolutionBlueprint(doc);

  blueprint.content = 'A platform that unifies our fragmented order systems.';
  blueprint.currentLandscape.content =
      'Three legacy systems with no shared customer record.';

  print(blueprint.content);
}

Prints A platform that unifies our fragmented order systems. — the value just written, read back through the typed getter.

Examples

SampleDemonstrates
a_typed_access.dart The generated typed facade — named members, nested-section navigation, and the typed SomList collection.
b_generic_document.dart The generic runtime underneath — string paths into a sparse store, plus JSON and YAML serialization.
c_reflection_metadata.dart The value-free reflection surface — take the whole model in one expression ( SOM §10.3 ), enumerate roots and fields, resolve a path to the model node it lands on.
d_sample_typed_access.dart The shared cross-language sample document read through typed getters.
e_sample_generic_access.dart The same sample read through raw string paths — identical output to (d).
f_sample_hybrid_access.dart Typed and generic access mixed over a single document.

example/README.md gives the run command for each.

For complete, runnable sample projects — a whole task carried end to end across several packages rather than one package's API — see tom_specs_samples/.

Usage

The generic store underneath

A facade is a view; the document is the value. Reach past the typed types whenever a path is computed rather than known — both sides address exactly the same store.

import 'package:tom_som_dart_runtime/tom_som_dart_runtime.dart';
import 'package:tom_som_dart_v0/tom_som_dart_v0.dart';

final doc = SpecDocument();
doc.setContent(
    'SBP/content', 'A platform that unifies our fragmented order systems.');

// A repeated section: append an item, then fill a content leaf under it.
final item = doc.addListItem('SBP/currentLandscape/CUOPME-OPER-LST');
doc.setContent('$item/content', 'Average order turnaround: 4.2 days.');

// The whole document serializes to the canonical wire format.
print(SpecDocumentYaml.encode(
    document: doc,
    tree: d00SolutionBlueprintMetaTree,
    modelVersion: '1.0'));

Metadata and reflection

The exported class graph answers "what can the model hold?" with no document values involved — enumerate roots and fields, or resolve a concrete path to the model node it lands on (SOM §7). The whole model is one expression — somSpecModel (SOM §10.3); it is also what toMarkdown and validateDocument take.

import 'package:tom_som_dart_runtime/tom_som_dart_runtime.dart';
import 'package:tom_som_dart_v0/tom_som_dart_v0_model.dart';

// The whole model, in one expression (`SOM §10.3`). A separate import from
// the facade: the payload is embedded, so only consumers that ask for the
// model compile it.
final reflection = SpecReflection(somSpecModel);

for (final root in reflection.roots) {
  print('${reflection.rootSegment(root)}  ${root.title}');
}

final res = reflection.resolve('SBP/currentLandscape/content')!;
print('kind=${res.kind.name}  valueLeaf=${res.isValueLeaf}');

The generated DocSpecs schemas

One schema per document root, embedded beside the model and reached by id — no file read, so it works from an AOT binary where a package-relative read returns nothing (SOM §10.3). The same schemas also ship as YAML under schemas/, which is what the other language runtimes read.

import 'package:tom_som_dart_runtime/tom_som_dart_runtime.dart';
import 'package:tom_som_dart_v0/tom_som_dart_v0_schemas.dart';

// A second opt-in import, for the same reason as the model: the fourteen
// schemas are embedded, so only consumers that ask for one compile them.
final schema = somDocSpecsSchema('solution-blueprint');

final violations = DocSpecsValidator(schema).validateMarkdown(markdown);
print('${violations.length} violation(s)');

print(somDocSpecsSchemaIds.join(', '));

Regenerating

This package is output. When the model changes, regenerate it rather than editing it — every file carrying the GENERATED … do not edit by hand banner is overwritten:

dart run tom_specs_clitool/bin/generate_som.dart

Architecture

  tom_som_dart_v0          the typed path — this package
    D00SolutionBlueprint …        one type per document root
            │  extends
            ▼
     SomNode / SomScalar / SomList     editing-facade bases
            │  bound to
            ▼
      SpecDocument                sparse, path-keyed value store
            │                     (tom_som_dart_runtime)
            ▼
  SpecReflection · SpecValidator · YAML + Markdown codecs
            ▲
            │  described by
      SomMetaTree  ◀── meta/spec_model.meta.json
TypeResponsibility
D00SolutionBlueprint … The generated document roots — one per row of the table above, each the typed entry point to a whole document.
SomNode The base every generated section type extends: a document plus the path prefix this section is rooted at.
SomScalar A typed leaf — parse and format at the store boundary, so int / bool / enum members read as themselves.
SomList A typed repeated section — append, index and enumerate items whose paths the store generates.
SomMetaTree / SomMetaNode The generated metadata trees ( SOM §7 ): the model's shape as data, behind the dot-notation and id-tree access surfaces.
SomEditability The SOM §4.2 version-check outcome — whether a stamped document may be edited by this facade.
SpecDocument The value store itself. Lives in tom_som_dart_runtime ; every type above is a view onto it.

Ecosystem

  tom_specs_model          the Dart model — the source of truth
         │
         ▼  generate_som
  tom_specs_clitool        the generator
         │
         ▼  emits
  tom_som_dart_v0   ← this package (typed)
         │
         ▼  depends on
  tom_som_dart_runtime  (generic, hand-written)
         │
         ▼  validated against
  tom_som_conformance      the shared cross-language corpus

The same shape repeats for all nine languages; the corpus at the bottom is shared, which is what makes "identical in every language" a measured claim rather than an intention (SOM §19).

Further documentation

TomSpecs subject matter — the authorities this package implements:

DocumentAuthority for
index.md The catalogue of every TomSpecs subject-matter document, and the § citation convention.
som_multiplatform_spec_model.md The two access paths, what this generated surface contains, the version stamp and editing rules, the *.md and *.docspecs.yaml formats, and the conformance corpus.
som_toolchains.md This language plane's build and verify toolchain, and the reference host.
tom_specs_model_meta_schema.md The on-disk schema of meta/spec_model.meta.json.

This package — its own guides:

GuideCovers
doc/tutorial.md A Dart walkthrough end to end — add the dependency, open a document, read and edit a section, validate it, and serialize to *.docspecs.yaml and Markdown.
readme_howtointegrate.md Every dependency route, how to pin the version, and building from source.
example/README.md The runnable samples and how to run each.

Siblings — packages you will reach for next:

PackageWhat it is
tom_som_dart_runtime The generic runtime this facade is a view over — reach for it directly to drive a document by path.
tom_som_conformance The shared corpus and the cross-language drivers that run every port against it.
tom_specs_clitool The generator that writes this package.

Status

Version 1.3.2, tracking the TomSpecs model version and matching tom_som_dart_runtime. Generated surface: 14 document roots, 1254 model classes. Verify the package with:

dart pub get
dart analyze
./run_tests.sh   # dart test + the three samples

A generated README states no fixed test count: the count moves with the model, and a number this file could not update would go stale the first time the model did. The command above is the standing answer — it runs this package against the shared cross-language corpus (SOM §19).

License
BSD 3-Clause License

Copyright (c) 2024-2026, Peter Nicolai Alexis Kyaw
Find me on LinkedIn under Alexis Kyaw
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.