Releases¶
RELEASES
0.57.0 — 2026-10-28¶
- New: a
TestCasecan verify architecture elements directly (REQ-TRS-TCELEM-001, #408).verifiesElement:names thePartDef,InterfaceDef,ActionDeforStateDefelements a test exercises (E102unresolved,E129wrong kind,W019when a variant removes the element). A test with onlyverifiesElement:satisfiesE013. - New:
W104reports an active, non-abstractPartDef,InterfaceDef,ActionDeforStateDefthat no activeTestCasenames inverifiesElement:and that satisfies no requirement with an active verifying test.testExempt: <rationale>on the element suppresses it; draft elements are never checked. - Changed (behaviour): existing models gain
W104on every untested active architecture element. It is a warning; addverifiesElement:links ortestExempt:rationales, or leave it, and gate CI withvalidate --deny W104once the count is zero. - New: sequence diagrams show operation calls (#365, #407, REQ-TRS-SEQ-002). A
SendAction/PerformActionthat names anoperation:is a message labelled with the operation's signature, followed by a dashed return (Real ! Faultwhenerrors:are declared) for a synchronous operation with a return type. Existing diagrams are unchanged. - New: operation call arguments are checked against the parameter's kind and unit (
E675, #398, #406). - Changed: the repository's own
.cargo/config.tomlcapsRUST_TEST_THREADSat 4 and debuginfo at line tables so the full test suite no longer exhausts memory.
0.56.0 — 2026-10-22¶
- New:
syscribe design-report <part> [--json](#371, #403, REQ-TRS-DREP-001) lays out one software part as the detailed-design (ASPICE SWE.3) work product: level and description, interface (its own operations and those of the ports it contains), behaviour (theActionDefs realising its operations), data (features with type, unit andrange), resources (ram,flash,nvm,stack,period,deadline,wcet,priority), code (implementedBy:), the requirements it satisfies, and the tests that verify it with their verdicts. An empty section saysNone.; an element that is not a software part is a usage error.
0.55.0 — 2026-10-22¶
- New: stereotypes (metadata) are typed, queryable, styleable and checkable (#374–#379, #387, #389, #390).
MetadataDefstereotypes carry tagged values, specialise one another and apply to any element;syscribe meta [--def <D>] [--group-by <field>]reports applications,[diagram.stereotypes.<Def>]styles diagrams (fill, stroke, frames, legend),[[gates.coverage]]sets a coverage threshold per stereotype, and the MCP server exposes the same surface. - New: architecture rules (#369, #388, #396). An
ArchitectureRuleelement states a constraint over the software structure:forbid-dependency,independence,allow-only,layering(withlayer:on parts andlayers:on the rule) andmax-depth. Findings areE660–E663/W662/W663; awaivers:entry with a rationale and an expiry date suppresses a finding for one element, and an expired or unused waiver isW664. - New: operations bound to behaviour (#364, #391).
errors:on an operation (E670) andrealizedBy:naming theActionDefthat implements it, whose signature must match (E671,E672). - New: operation call sites (#364, #398, #401). A
SendAction/PerformActionnames the operation it calls withoperation: <owner>::<name>; an unknown operation isE673and arguments that do not match its input parameters areE674. Types and units of the values are not yet checked. - New: data types with value constraints (#366, #393):
range:,pattern:anddefault:on anAttributeDef. - New: sequence diagrams take a part as subject through the actions it performs (#365, #392).
- New: resource budgets (#368, #394, #395).
syscribe budgets [--json]rolls up memory use (ram,flash,nvm,stackagainst*Capacityandmargin,E690/E691) and CPU load (period,deadline,wcet,priority; utilisation against the Liu–Layland bound for rate-monotonic or 1 for EDF,E692/E693). - New: deployment structure (#370, #397).
deploymentKind(soc…thread) makes a part a node; nodes nest outermost first (E730,E731), a component sits on one node unlessreplicated: true(E732), and a node may not have a lower integrity level than what it hosts (E733). - New: software design levels (#371, #400).
level: component | uniton a software part; a non-draft unit needs animplementedBy:(with a#symbol,W740), a satisfied requirement, an L1 test and a containing component (E740–E744). - New: the breakdown ADR requirement can be switched off (#399).
[traceability] require_breakdown_adr = falsein.syscribe.tomlstopsE310; a cited ADR is still checked (E311,W303) and a malformed entry isW632.
0.54.0 — 2026-10-13¶
- Changed (behaviour): a command given an option it does not know now fails with a usage error (stderr names the option and lists the valid ones, exit 1) instead of ignoring it. About 40 commands used to ignore unknown options silently, among them
audit,matrix,metrics,cyber-risk,feature-check,export-html,diff,claim,suspect,baseline,plantuml,magicgrid,safety-caseandzones, so a mistypedaudit --denywas never applied in CI.scriptsstill forwards its arguments to user scripts. A table-driven test covers about 48 commands, and the drift tests now require every accepted option to be documented on its help page. - Changed (behaviour):
impact --kinds <unknown>,export-reqif --scope <unknown>andtrade-study --config <unknown>are usage errors (exit 1);export-reqifused to write an empty document andtrade-studyan empty grid. - Fixed:
export-reqifwrote mis-nested XHTML for a body that mixed bold and inline code (<xhtml:code>…<xhtml:strong></xhtml:code>), soimport-reqifrejected the exporter's own output of the project model. The inline conversion is now nesting-safe, and the 412 requirements ofmodel/round-trip. - Fixed:
suspect accept --alland--all-unbaselinedreported links whose source is a row of a TARA or FMEA sheet as baselined, but the baseline was written to the sheet where the exploded row never reads it, so the same links were counted again on every run. These bulk commands now skip such links and list them, a singlesuspect acceptof one is an error, and the sheet file is left unchanged. - Changed:
featureaccepts aFEAT-*id as well as a qualified or bare name; thecyber-risk --formaterror lists all seven formats;feature-check --summary(accepted but ignored until now) prints counts per code and severity instead of each finding;baseline create --date,magicgrid --outputandplantuml -oare documented. -
Fixed (docs): a review of the CLI reference, the 98 help pages, the specification, the guides and the demo and qualification documents against the 0.53.0 binary. Among the corrections: the CLI reference examples were regenerated from real output; the
metrics,audit,setandsafety-casesections were rewritten; the usage-error exit codes (connectivity,follow,impactandreviewexit 2 on a missing argument) are stated; the specification no longer saysname:is the qualified-name segment, marks the checks it describes but the tool does not make (direction:values,typedBy:on a definition, unresolved multiplicity bound names, the 120-charactername:limit, built-in ignore lists, gitignore syntax in.sysmlignore) as not enforced, documentsimport-reqif, and states the realW300,W303andW039conditions; thetestLevelmeanings agree everywhere (L1 unit, L2 property/fuzz, L3 formal proof, L4 emulator integration, L5 hardware-in-the-loop);satisfiedByis documented as a computed index; the demo-model tables match the models; the tool-qualification page states that 122 of 478 test cases are evidenced by Rust tests and that the tracked TVR is a 0.43.0 snapshot;W050is documented as catalogued but not currently emitted;mkdocslists the seven design notes. -
Fixed (docs): every frontmatter field the parser accepts is now documented in both the full specification and
syscribe spec fields. 41 fields were missing from the CLI reference (the ResidualRisk, VulnerabilityReport, PlantDef, view and fault-rate fields among them) and 31 from the specification's Appendix A index (the plant, FMU,flowKind, attack-potential and common-cause fields among them). A new test,every_frontmatter_field_is_documented, reads the field names from the parser and fails when one has no entry in either document. - Changed: the LLM authoring prompt (
--agent-instructions) gains a "Discovering what the tool can do" section (help,help <command>,spec <section>,template, MCPdescribe_type/explain_finding), a table of the executable-behaviour and evidence commands (simulate,inject,mutate,eval,constraints,requirement-coverage,exec-coverage, …), rows for the 17 commands it omitted, and a Part 9e map of executable models, plants,models:, context diagrams and feature placeholders.syscribe specgainsbehaviour,evidence,diagramsandvariabilitysections (the model-guide pages, embedded so they cannot drift),spec fieldsdocuments the plant,models:,roleandflowKindfields, and the stale validation-code range in the spec index is gone. New testsagent_prompt_covers_every_commandandagent_prompt_spec_sections_existkeep the prompt in step with the command list. - Fixed: selecting a feature selects its group parents (#228): a
parameterBindings:entry on a parent no longer raisesE203when a descendant is selected, and such a parent is not reported as an orphan (W024), matching whatconfigurealready did. - Fixed:
export-htmlno longer embeds the whole namespace tree in every page (#225). Each page lists the top-level packages, the siblings along the path to the element and its own children; the complete listing is written once asall-elements.html. Themodel/site drops from about 175 MB to about 21 MB. - Fixed:
W007no longer fires for a type used only as a transitionacceptpayload, or an action used only as a state'sentryAction/doAction/exitActionor a transitioneffect(#224). -
Fixed: a
featureTree:id derived from a long name (Platform.HighPerformance) is cut to the 12-character FEAT segment limit instead of failingE006; a 1-character segment still needs an explicitid:, and theE006message now says so (#227). -
New: quantitative goal verdicts and the fault tree compared with the campaign (#343, REQ-TRS-GOALV-001, spec § Safety targets).
metricsjudges every goal with a quantified tree: the first-order PMHF/PFH when its events declarediagnosticCoverage(unchanged), else a rate-only PFH from the exact top-event probability overmissionTime, or PFDavg = Σ Π λ·(1−DC)·TI^k/(k+1) when the goal'starget:saysmode: demandwith aproofTestInterval. The limit is the goal'starget.value, else[reliability.targets]in.syscribe.toml, else the built-in table, and the report names the source. A figure whose events fail with a probability above[reliability] plausibleProbability(default 0.1) over the mission is not credible;rateSource:/rateStatus:record a rate's provenance, a verdict on unverified rates says so, andlist --rate-statusfinds them.metrics --sensitivityshows which events' rates move the verdict;auditandsafety-caseshow the figure.inject --ft <FT> --consistency [--consistency-order N] [--max-runs M]reports every cut set with its executable verdict and every defeating set missing from the tree. New codesE985(malformedtarget:),E986(rateStatus),W988(claimed rate above the bound),W989([reliability]); a rate-only or PFDavg figure gates (W033,metricsexit 2) only when the goal declarestarget:or.syscribe.tomlsets the limit; otherwise itsfailis advisory. On the grid-tie inverter SG-GTI-001's 1.4e-1 over 15 years is flagged not credible with FTE-GTI-005 its largest contributor, and the comparison finds sets the tree does not have (see the demo page). - New: richer invariants (#342, REQ-TRS-INV-001, spec §8.12.8). A composite scenario names a property with
Where <name> is <expression>and gives its degraded form for a fault set withExcept under <fault> [and <fault>…]: <expression>; a fault no clause names keeps the full property, and a set several clauses apply to needs a clause covering them all, else the run is an error, "no applicable degraded clause".Then within <d>: …must be reached by then and kept to the end,Then always …/from now on/neverhold at every settled instant.simulatesays when a scenario held only in a degraded clause, andinject, its report and its record mark such a set survived (degraded). The grid-tie invariants now state the safe state of SG-GTI-001 (gates off and both relays open) with its degraded forms; checkingalwaysfound that the sensing common cause FTE-GTI-009 alone lets the inverter energise a dead grid for 1.1 s at start-up, recorded as the proposed decision RISK-GTI-011. - New: in-process plants (#340, REQ-TRS-PLANT-001, spec §8.8.6). A
PlantDefdeclares parameters, inputs, outputs, states andder(x) = …/y := …equations in the expression language; a part becomes the plant withplant:(aPlantDef, or a library plant:Gain,FirstOrderLag,Integrator,Saturation,DelayLine,ImpedanceDivider). It runs at the composite'splantStep:with fixed-step RK4 or Euler, needs no FMI build feature or toolchain, and gives the same trace bit for bit on every platform. Faults act on plant parts:stuck/offseton outputs,silent, and the newparameterkind. The expression language gainsexp,ln,sin,cosandtanh. New codesE938,E939. The grid-tie inverter's anti-islanding check now runs against a grid impedance plant. - New: campaign evidence and residual-risk decisions (#341, REQ-TRS-RISK-001, spec §12.14).
inject --record [--run <id>] [--config <C>]keeps a fault-injection campaign in.syscribe/campaigns.json(composite hash, invariants, every set with its origin, verdict and failing invariant, sets not run, engine version);results campaigns [diff]lists and compares the records, andinject --report <file.json|file.md>writes one for an assessor with the decision and failure rates of each defeated set. A newResidualRiskelement (RISK-*:faultSet,statusproposed | accepted | mitigated | rejected,goal,mitigatedBy,approvedBy,reviewDate,expires,campaignHash) records the decision on one defeated set. A defeat no decision names isW940(gate it with--deny W940), a decision the campaign contradictsW941, a stale or expired decisionW942/W943, a record of a composite that has changedW944; malformed decisions areE942/E943/E944.safety-caseshows a solution node per campaign andauditthe unexplained defeats. The grid-tie inverter records its US and India campaigns and proposes a decision on each defeated set. - New: deterministic diagram exports (#339, REQ-TRS-VIS-032). Text is measured with Liberation Sans advance widths compiled into syscribe instead of the installed fonts, so the same model exports the same bytes on every machine (boxes come out about a tenth wider than before: the installed-font path scaled glyphs by the font's line height instead of its em, so it measured Liberation Sans about 10 % narrow and the width margin only just made up for it).
diagram export --allrenders every diagram into<model>/generated(--format,--out-dir, one--configintogenerated/<CONF-id>), rewriting only what changed, writing PlantUML style includes relative to the file, and removing only renders it recorded in.syscribe-generatedthat no diagram produces any more; a render failure fails the run.--checkwrites nothing and exits 1 naming each file that differs, is missing or is left over.model_gti/generated/holds the grid-tie renders and CI checks them. - New: diagram views (#338, REQ-TRS-VIS-031, spec §8.16.10). On a derived IBD,
include:may be a mapping ofkinds,domains,tagsandfeatures: the parts and edges it selects are drawn as usual, the parts that contain them stay as frames, and the rest is faded in every writer.style: <name>applies a[diagram.style.<name>]table of.syscribe.toml(context = "fade" | "hide",flows.<kind>,extends).layout:takesflow: left-to-right | top-to-bottomandlayers:beside its pins.diagram export --config A --config Bdraws both products in one diagram, marking what only one has. A malformed view, style or hint isW421; a missing or cyclicextendsisW419.model_gtigainsGtiPowerView,GtiProtectionViewandGtiSoftwareView. - Fixed: Mermaid output put a guard or label holding brackets (
[then],[only CONF-A]) unquoted inside an edge's|…|or a port's circle, which Mermaid cannot parse; such labels are now quoted (#338). - New: system context and external actors (#337, REQ-TRS-VIS-030, spec §12.13). A part usage marked
role: externalis an actor outside the product: derived IBDs draw it «actor» (an environment part «environment», dashed) and derived BDDs mark its definition «actor». In a context composite, a part holding an actor, a port of a product part that nothing reaches isW996. External parts are never evidence, like environment parts.model_gti/Context/GtiContextputs the inverter beside the PV array, the grid, the owner's head-end, the installer tool and the rapid-shutdown initiator, with the diagramsGtiContextBddandGtiContextIbd; the inverter gains boundary ports bound to the parts that serve them. - New: grouping and containment in derived IBDs (#336, REQ-TRS-VIS-029, spec §8.16.8.2).
depth:draws parts inside parts with their ports and connections; a deployment package allocated to hardware is drawn inside it; a safety level (silLevel:,asilLevel:, asafetystereotype) outlines a part with its level andappliesWhen:badges it optional, through the node mark, with an SVG legend when anything is marked;groupBy: domainframes the parts bydomain:(containment wins; the domain becomes a banner). A self-containing definition is opened once anddepth:is capped at 16; with several hosts a deployment package goes into the nearest; PlantUML and DOT draw the marks and containment; under--confignothing is badged optional. An unknown or misplacedgroupBy:isW420. The GTIGtiIbdshows the firmware inside the STM32 inside the control board. - New: flow kinds in diagrams (#335, REQ-TRS-VIS-028, spec §8.16.9).
flowKind:on aPortDef, a port feature or aconnections:entry (power,signal,command,data,protection,mechanical) styles the edge in SVG, sprotty, DOT, Mermaid and PlantUML; a[diagram]table in.syscribe.tomlrestyles a kind ([diagram.styles.<kind>]) and places ports by kind ([diagram.portSides]), with a port's ownside:winning. An unknown kind or side, or a malformed[diagram]entry, isW419. A model that names no flow kind draws exactly as before. The GTI model's power stage IBD now shows its DC, AC, gate-command and sensing paths. - New: executable evidence (#333, #344, REQ-TRS-EXECEV-001, spec §12.12,
docs/model-guide/executable-evidence.md).requirement-coverageruns the scenarios of every active TestCase whose subject is a machine, action or composite, in-process, and grades each requirementexecutable,executable-weak(a failing scenario, or below--min-states/--min-transitions/--min-guards/--min-score),descriptive-only,unverifiedornot-applicable(inspection, analysis, or a parent whose children all have executable evidence), with the scenarios, the coverage of the machines that carry it and mutation scores; a scenario counts only when its subject exercises what satisfies the requirement.exec-coverageshows the same evidence per software/hardware element: executable itself, modelled by, or not modelled, with its scenarios, correspondence findings and requirements by verdict. Gates--min-executable,--min-modelledand--requireexit 2. Scenarios narrow their TestCase'sverifies:with@verifies REQ-A,REQ-Btags or# verifies:step comments; a claim outsideverifies:isW994, an unclaimed requirement when every scenario is taggedW995.mutate --recordkeeps scores in.syscribe/mutation.json(stale when the machine changes);--mutatecomputes them. MCP toolsrequirement_coverageandexec_coverage.model_gti/tags its protection scenarios. - New: verification composites (#332, REQ-TRS-VCOMP-001, spec §12.11): an architecture
PartDefthat carriesexhibitsStates:is used directly in a TestCase's subject composite and needs nomodels:, counting as its own counterpart forW991and exercising its requirements forW992.role: environmenton a part usage marks the test set-up (a grid source, a stimulus): no architecture counterpart, never evidence, its ownmodels:/portMap:ignored (W993), listed with[environment]and left out of the aggregate insimulate --coverage, and listed apart ininjectwith environment-only fault sets marked. An unknownrole:or one on a port isE992. Inmodel_gti/, the grid source is an environment part andSystem::Software::Supervisorcarries the supervisor machine (SupervisorPartremoved). - New: typed ports (#331, REQ-TRS-PORTTYPE-001, spec §8.8.5): a port
typedBy:aPortDefcarries the events itsItemDefitems name, withdirection:per item andisConjugated: truereversing it. A machine that sends or accepts an event the type does not carry or carries the other way, or names a payload field the item lacks, isE932; a payload value or use of an accepted field of the wrong type or unit dimension isE935. Untyped ports are unchanged. Withmodels:, ports of the same type and conjugation correspond withoutportMap:, and differently typed counterparts areE991.model_gti/Interfaces/types the protection chain and the architecture ports alike, and fourportMap:s are gone. - New:
models:links an executable part to the architecture element it is a behavioural model of (#330, REQ-TRS-MODELS-001, spec §12.11,docs/model-guide/behaviour-models.md), withportMap:(a port name, a list, ornull),abstracts:(port names, or requirement ids the model cannot evidence) andfidelity:, on a definition or on a part usage for one-to-many. New checks, dormant withoutmodels::E990target,E991executable port correspondence and direction,W990uncovered architecture port (checked on the union of modelling parts),W991connection correspondence both ways (HW/SW boundary skipped),W992a TestCase whose subject cannot evidence a requirement it verifies. The link shows inlinks,refs,follow(models/modeledBy),impact,trace,whyand suspect-link detection.model_gti/declares it on every behaviour part. - Fixed: a state-machine placeholder for a feature parameter with no
value:/default:no longer raises a parse error at the{(#328, REQ-TRS-PROJ-009): the base model checks the expression with a stand-in of the parameter's type and reports the parameter once asW248on its FeatureDef, naming the machines.validate --configand each Configuration of--all-configscheck machines at their own bound values, without changing what suspect links and baselines hash. - Changed: a
Configurationid needs no numeric suffix, likeFEAT-*andBL-*ids (#327, REQ-TRS-ID-008):CONF-GTI-US-M3validates withoutE200/W042, and so does a bareCONF-001; the numeric formCONF-GTI-US-001still validates and an extra[ids.prefixes]prefix forConfigurationfollows the same grammar. - Changed: feature references (#325). Inline
requires:/excludes:on afeatureTree:entry resolve likecrossTreeConstraints:values, sorequires: [Protection.Afci]works;E212,E209,E222andE241name the form their field accepts and the closest match; aConfigurationfeatures:key that names no feature isE239(it used to select nothing silently). - Fixed:
W012no longer fires for amandatory: truefeature, and suggestsmandatory: truerather than the legacygroupKind: mandatory(#326, REQ-TRS-FM-007). - New: state machines can use feature parameters (#311):
{{Feature.param}}placeholders in guards, assignments and durations, with--configoncompile,mutateandinject. - New: FMEA rows can be gated by variant, and fault values can follow feature parameters (#313).
- Changed: a test plan bound to configurations is a plan for those products only, and selection skips test cases that run in none of them (#314); the escaping-reference check also skips a plan bound to other products. A
satisfieslink to a requirement the variant does not have is not an escaping reference (#312). - Changed:
mutatemakes no swap-order mutant for transitions with provably disjoint guards (#315, part a). Grid-aware literal shifts (part b) remain open. - Changed:
injectsays that higher-order cut sets were left out rather than reporting an analysis overflow (#316). - Fixed: virtual time runs on a 1 ns grid, so split delays reach timers at any absolute time (#310).
- New: analysis graphs in the Diagram IR (#223, phase 2) —
diagramKind: Traceability | ZoneConduit | ThreatGraphderive the hazard-to-test graph (HazardousEvent ← SafetyGoal ← Requirement ← … ← TestCasewith each goal's fault tree and arguments; nodes toned by the roll-up of their tests,ASIL/status/verdict shown, gaps as red badges namingW002/W003/W305/W300,no requirement,no goal), the IEC 62443 zone model (zones as compound nodes holding their parts and allocated security controls,SL target / achievedlabels, red with anSL gapbadge when short, conduits as edges labelledCD-… · SL achieved/required, weak conduits red, heavy and dashed) and the TARA chain (ThreatScenario → DamageScenario → Asset → CybersecurityGoal → SecurityControl, threats toned by risk under the configured[cyber]method,W802on an unimplemented goal). NewZonenode kind andimpacts/affects/protectedBy/implementedBy/conduit/weakConduitedge kinds; the sprotty client, SVG, Mermaid, DOT (zones as clusters,rankdirfrom the layout,#rgbcolours expanded for Graphviz) and PlantUML writers draw them. Newhara trace [<subject>] --format dot|mermaid|plantuml|svg(with the ingested test verdicts),zones --format …,cyber-risk --format dot|mermaid|plantuml|svg(the heatmd|html|jsonstay),diagram exportfor the three kinds, and the element detail panel of a hazardous event, goal, requirement that traces to a goal, zone, conduit, threat, damage scenario, asset, cybersecurity goal or control embeds the graph; the New diagram dialog offers all three. Wrong subjects are the existingW418; no new codes. Shared zone logic moved tosyscribe_model::zonesso the reports and the picture agree. Examples inmodel_auto/(new assets, zones, conduits and security-control allocations) andmodel_sil/. - Fixed:
connectivitystopped at a safety or security analysis element (#223) — a walk from aSafetyGoal,HazardousEvent,FaultTree/gate/event,AttackTree/gate,ThreatScenario,DamageScenario,CybersecurityGoalorSecurityControlnow also followshazardousEvents:,topEvent:, gateinputs:, eventref:,threatRef:,damageScenarios:,threatScenarios:,implementsGoals:,mitigatedBy:and the derived-from-goal links by default, and--kindsaccepts those link names. - Fixed:
zones --coverageshowed—in every control column (#223) — it looked for aSecurityControlamong a zone'smembers:(which must be parts,E955) and in a conduit'simplementedBy:, never at theAllocationthat binds a control to the architecture. A control now counts for a zone when it is allocated to one of its parts (members:orinZone:), the zone or a touching conduit;zonesalso countsinZone:parts as members. - Changed: safety diagrams polished (#223 follow-up) - fault-tree and attack-tree nodes are labelled with their stable id and the full name wraps beneath it (new word-wrapping in
size.rs); a gate or event is a description box with its standard symbol hung on a stub (AND flat-bottomed D, OR shield, XOR with a second arc, NOT triangle with bubble, inhibit hexagon; basic-event circle, undeveloped-event diamond, house pentagon), tree edges are routed as a bus with an arrowhead into the gate (browser and SVG alike), GSN undeveloped diamonds sit inside the node box, SVG exports carry a tone legend, and DOT output is Graphviz-valid (six-digit colours, wrapped text, undeveloped diamond). Derived GSN diagrams now show real test verdicts from.syscribe/results.jsonand the derived attack tree uses the model's[cyber]configuration, asW035does. - New: heat tables (#223) -
syscribe_model::heatbuilds a grid (rows, columns, cells with element ids, tone, label) rendered as Markdown, JSON or a standalone self-contained HTML page: FMEA severity x occurrence with RPN colouring (fmea report --format md|html|json), the HARA S/E/C -> ASIL matrix with hazardous events and safety goals placed in cells (newhara matrix [--format ...]), and the TARA impact x feasibility risk matrix under the configured[cyber]method (cyber-risk --format md|html|json).export-htmlgainsreports/heat.html(its page count now includes it) andsyscribe-serverserves/heat. Defaultfmea report/cyber-riskoutput is unchanged. - New: safety diagrams in the Diagram IR (#223, phase 1) —
diagramKind: FaultTree | AttackTree | SafetyCase(aliasGSN) derive a fault tree (IEC 61025 gate symbols, event shapes byeventKind, λ/probability labels, single points and cut-set members highlighted and the top-event probability on the root, fromfault-tree analyze), an attack tree (coloured by rolled-up feasibility, easiest path emphasised,W035badge) and a GSN argument (goal/strategy/solution/context/justification/assumption shapes, undeveloped diamonds, status/verdict overlays) from the model. New genericNode.markoverlay (status, value, tone, badges, emphasis) drawn by the sprotty client, SVG, Mermaid, DOT and PlantUML writers; newdiagram export --format dot,safety-case --format text|json|dot|mermaidandfault-tree render <FT> --format mermaid|dot|svg|plantuml(plainrenderkeeps its flowchart); the element detail panel of aFaultTree/AttackTree/SafetyGoal/Argument/ThreatScenarioembeds the derived diagram with node click-through,/api/diagrams/model/<qname>serves it without aDiagramelement, and the New diagram dialog offers the three kinds. Wrong subjects are the existingW418; no new codes. Examples inmodel_auto/(FaultTreeEngine,AttackTreeTorqueReplay,SafetyCaseEngine, plus an attack tree and a GSN argument) andmodel_sil/. - New: fault-tree analysis (#211) —
syscribe_model::fta(BDD-based; cut sets, exact top-event probability overmissionTime, Fussell-Vesely/Birnbaum/RAW importance, per-event roles, beta-factor CCF viaccfGroup:/ccfBeta:) andfault-tree analyze <FT> [--json] [--max-order N] [--no-ccf]. - New: fault-tree structural validation (#212) —
E980gate cycle/self-input,E981gate arity (NOT/XOR/inhibit),E982negativefailureRate,E983probabilityout of range,E984ccfBetaout of range,W980unreachable node,W981node outside aFaultTreedirectory,W982single-inputAND/OR,W983/W984CCF group problems,W987unparsablemissionTime. - Changed:
metricsis driven by minimal cut sets (#211, #213) — gate logic now matters (ANDvsOR), unreachable/house/negative-λ events are skipped,PMHF = λ_RF + λ_DPF(dual-point rate overmissionTime) instead of adding the latent rate, missing DC/DCl count as 0 withW985(andW986for a missingmissionTime), DC/DCl are clamped (no more LFM 2.0), SIL 1 is gated, a computed-but-untargeted goal showsno target, andmetricsexits 2 when a goal fails. - New: security-analysis validation gaps (#219, #220, #221):
E960names the offending field whensecurityProperty:/derivedFromCybersecurityGoal:has the wrong shape (both now also accept a list);TARASheetrows getE961(noid) /E962(unknown key) and a newassetTable:;E963/E964danglingAsset.assetOwner/relatedSafetyGoal;E965attack-tree cycle,W966-W968multiple roots / unscored step / duplicate input;W960-W965incomplete risk inputs, orphan or asset-lessDamageScenario,riskTreatmentconsistency;W969/W970orphanSecurityControl/CybersecurityGoal;W971-W973zone/conduit consistency;VulnerabilityReportW974-W979/E967(CVE id, status vocabulary, resolution evidence, CVSS vector/severity, threat link) with newcvssVector/cvssSeverity/fixedInfields. - Changed:
conduits --jsonreportspass: null(nottrue) whenachievedSLor a zonetargetSLis unknown;co-analysisexpands aHazardousEventhazardRefto theSafetyGoals that list it;sbomemits CycloneDXvulnerabilities(VEX) fromVulnerabilityReports, matched to components bypkg:purl or owning part, andaffectedElements:acceptspkg:URLs. - Changed: SysML v2 ingest keeps the full dotted path of
connect/bind/flowendpoints (Owner::a::b::c) instead of collapsing to the head part;W542no longer applies toconnect(#206). Endpoints of ingested.sysmlelements are now checked byE127/W056. - New:
E128— unresolvedvia/toon send/accept actions and transition accepts; flow/succession endpoints on structural elements are checked likeconnections:endpoints (#207). - New:
W068— a redefining feature'smultiplicity:is not contained in the redefined feature's (#208). - Changed:
W057/W044understand SI prefixes (kN,mm,MHz) and judge prefixed units by dimension (#209). - Changed: complete ISQ/SI/SIPrefixes/USCustomaryUnits/ScalarValues/Base name tables; an unknown bare name or membership import under a library wildcard (
import ISQ::*) is now reported (#210). - Changed (behaviour):
auditwith ingested test results now fails when a safety goal isfailing, adds a Verification results section, andW312is in the default[audit] fail_on(a project that sets its ownfail_onmust add it) (#256). - Changed (behaviour): the suspect-link projection excludes workflow state (
statuswhile progressing,claimedBy,claimedAt,assignedTo); baselines captured before this need onesuspect accept --all(#251). - Changed (behaviour): exploded TARA/FMEA rows inherit sheet-level
responsibility/appliesWhen/tags; baselines sealed over such rows drift once (#229). - Changed (behaviour):
auditno longer reports PASS for a model with a failing safety metric or an uncovered high-integrity goal:W033andW805on an ASIL C/DSafetyGoalnow fail the verdict (exit 2) by default, alongsideW306. Relax or extend this with an[audit]table in.syscribe.toml(fail_on = [...]for codes that fail at any level,[audit.fail_on_asil]mapping a code to the ASIL levels at which it fails;fail_on_asil = {}opts out). A malformed entry isW934(#216). - New:
auditgains Safety (hazards, goals by integrity level, FTA, FMEA, hardware metrics, FFI gaps) and Security (TARA artefacts, CAL distribution, vulnerabilities, IEC 62443 zones) sections in text and--json(#216). - Changed:
safety-casealways folds in the implicitderivedFromSafetyGoalRequirement chain (it was dropped whenever a goal had any Argument), walksderivedChildrentransitively down to verifying TestCases, marks undeveloped nodes[UNDEVELOPED], prints a per-goal verdict and a completeness summary (also in--json, asstatus/undeveloped/completeness), and exits 1 for an unknown goal id. The traversal now lives in the publicsyscribe_model::safety_casemodule (build,SafetyCaseNode,NodeStatus,GoalVerdict,Completeness) so diagram derivers can reuse it (#217). - New:
E881Argument cycle;W861solutionArgument with no evidence;argumentTypealso acceptscontext,justification,assumptionandundeveloped(#217). - New:
W931FMEA row without severity/occurrence/detection;W932severity >= 9 without arecommendedActionregardless of RPN; FMEA rows may carryfailureRate/diagnosticCoverage/latentDiagnosticCoverageand, viaftaRef, feed the hardwaremetrics/W033.fmea reportdrops the duplicateNamecolumn, labelsrecommendedActionasRecommended Action, lists a duplicate-id row once, and exits 1 for an unknown--fmea-sheet; an unresolved FMEArefis reported once (W904, no longer alsoE115) (#218). - New: ASIL decomposition validation (#214):
E878illegal ISO 26262-9 pair (D -> A+A,D -> B+A, ...),E879baddecomposedFrom:;asilLevel: QMis accepted, the notationasilLevel: B(D)/QM(D)and adecomposedFrom:field are supported,E010now lists the valid values, andE865/W860apply at every integrity level (not only ASIL D / SIL 4). - New: HARA checks (#215): the ASIL is derived from S/E/C (ISO 26262-3 Table 4) and shown by
showasderivedASIL;W811goal ASIL lower than derived,W812ASIL C/D or SIL 3/4 goal withoutsafeState/ftti,W813partial S/E/C set,W814mixed ISO 26262 / IEC 61508 parameters,E880invalidfttiunit. - New: configurable ISO/SAE 21434 risk and CAL (#222) — a
[cyber]table in.syscribe.tomlselectsmethod = "simple"(default, unchanged) or"annex"(built-in example tables modelled on the standard's informative annexes; not normative, verify against your copy), overrides risk-matrix / CAL / risk→CAL cells, and scores attack potential (elapsedTime,expertise,knowledge,windowOfOpportunity,equipmentonThreatScenario/AttackStep, configurable thresholds); optional per-category impact ratings onDamageScenario(overall = max).cyber-risk,W031,W032and attack-tree roll-up follow the configuration. NewW640(malformed[cyber]entry),W641,W642,E640,E641. With no[cyber]table nothing changes.
0.53.0 — 2026-10-09¶
- New: MCP/REST
create_elementtakesparentand writes<parent>/<id>.mdfor id-identified types and<dir>/_index.mdfor packages;move_elementaccepts an id as the last destination segment (#185). - New (opt-in):
W065— an id-identified element whose file stem differs from itsid. Off by default; enable with[ids] check_file_names = truein.syscribe.toml, gate with--deny W065. - Fixed: feature editor keeps typed input across re-renders and drops stale fetches (#189);
removeParameterrefuses while a[repos]peer Configuration binds the parameter (#193); MCP guarded-write baseline is dropped after a post-refusal reload that read changed inputs (#196).
0.52.0 — 2026-10-09¶
SysMLv2 modelling gaps (GH #198–#205)¶
A probe that modelled a UAV, an elevator controller and a textual .sysml round trip found validation too lenient and ingest/export lossy. Fixed:
- Fixed:
imports: [ISQ::*](or any library wildcard) on a package silenced every unresolved-reference check below it (#198). - New validation (errors):
E115unresolved behavior-field reference (sub-action/parametertypedBy,payload,includes,extends,subject,result,returnType),E116succession/binding/flow endpoint that names nothing the element declares,E117value outside a closed vocabulary (sub-action/control-nodekind,loopKind, parameterdirection) (#199).E118malformed or reversed multiplicity,E119badvisibility,E120supertype:on a usage,E121isVariantoutside a variation,E122enumeration without literals or specializing another,E123usage typed by the wrong kind of definition (andconjugates:of a non-PortDef),E124unknown enumeration literal,E125interface/connection with fewer than two ends (#200).E126unresolvedimports:/aliases:/dependsOn:,E127connection endpoint whose owning part does not exist (#201). - New validation (warnings):
W056connection endpoint port not found on its part,W057unknownISQ::/SI::name,W058name:differs from the file name,W059private element referenced from outside its package. - Fixed: inline-feature
redefines:/subsets:are resolved; aVerificationCasemay verify a SysML requirement (E104);W007counts a type used only by a sub-action or parameter;W502understandsPkg::*/Pkg::**,{target, filter}entries andViewDef. - Views:
syscribe view render <View>materialises what a view exposes (tree/table/json/mermaid), withfilterCondition:/ per-entryfilter:(@Metadata,not,and,or). PlantUML now renders Action, Allocation and UseCase diagrams.showprints ends, connections, parameters, sub-actions, time slices, imports, aliases andexpose. - SysML v2 ingest: package
imports are kept (bare imported library names no longer raiseE111); anonymousconnect,bind,perform,exhibit,interface … connect,interface defends, port directions,~PPconjugation andrefare mapped; one bad member no longer discards the whole file (W541per member); dropped body members are counted inW543; a view'sfilterbecomesfilterCondition:. Dottedconnectendpoints (eng.pwr) keep their full path asOwner::eng::pwr(GH #206): validation resolves the tail through the head'stypedBy:/supertype:chain (E127/W056for a missing member), the graph edge lands on the deepest resolvable prefix,export-sysmlwrites the dotted chain back, andconnectno longer raisesW542. - SysML v2 export: exports enumerations, library packages, allocations, use/analysis/verification cases, views, viewpoints, concerns, flows, individuals; imports/aliases, interface and connection ends, conjugation, bindings, flows, performs/exhibits, time slices, variation,
parallel, action parameters, assert/negation, requirement subject/actors/requires/assume. Output is valid SysML v2 (per-segment quoting, relative feature chains, unquoted expressions, no duplicate anonymous connection) and every field it cannot write becomes a// dropped:comment counted in the summary. - Fixed: an unreadable directory now fails the model walk instead of silently dropping its subtree (this also stabilises the LSP failed-reload test).
0.51.0 — 2026-10-09¶
Review fixes¶
- Security: the feature editor's
restoreop (POST /api/feature-model/edit, MCPedit_feature) joined a caller-supplied path onto the model root unchecked, so an absolute path or..could create or delete files anywhere the process could, even on a preview or dry run. Every path the edit engine touches is now confined to the model. - Security: Markdown bodies are no longer rendered with live HTML. Raw HTML is shown as text and a link or image with a
javascript:,vbscript:ordata:target is pointed at#(the element card, detail panel andexport-html). - Security:
syscribe-serverlistens on127.0.0.1:3000by default (it has write routes and no authentication; pass--bind 0.0.0.0:3000to expose it) and no longer sends permissive CORS headers, so another website open in the same browser can no longer drive its write API. - Fixed: an abstract feature's derived value could contradict the model. Each value is now fixed in turn so together they form one real model of the feature model (an
alternativegroup whose members are abstract no longer derives all of them off), and a configuration that breaksrequires:/excludes:no longer gets a spuriousE219on a mandatory abstract feature. - Fixed: derived abstract values are re-computed wherever configuration inheritance is rebuilt (the LSP rename gate no longer sees them vanish),
showno longer claims a derive-less configuration inherits, the load list leaves them out, andW011/W012skip abstract features. - Fixed:
setAbstractrefuses a feature some configuration already names (it would becomeE238), listing the configurations. - Fixed: MCP
apply_changesnow refusesupdate/deleteof an entry synthesized from a shared sheet, asupdate_element/delete_elementdo (adeleteremoved the whole sheet). - Fixed:
moveof an element that has a directory of children beside its file moves both (it used to strand the file and break every rewritten reference), and rewrites qualified names insideappliesWhen:/formula expressions. - Fixed: the MCP watcher stops deferring reloads for a new file that stays broken (after four deferrals it reloads and reports the file), a lagging WebSocket client is told to reload instead of going silent, the diagram tab bar works (its inline handlers were malformed and broke on a quote in a directory name), the planning board no longer fetches twice (a
?who=deep link could be overwritten), undo/redo run one at a time, and the element panel retries after a failed load and refreshes after a live reload. - Tests: every
testFunctions:name in aTestCasemust now exist (tc_test_functions), which found and fixed three stale references; regression tests for each fix above. - Fixed (second pass):
write_confinedrefuses an absolute path or..before creating any directory;PATCH /api/diagrams/layoutrefuses an element that is not a Diagram; the guarded-write candidate copy follows directory symlinks and skips dangling ones; the detail panel's Save removes a key whose line was deleted (nevertypeorid) and no longer writes the qualified name intoname:;moveno longer rewrites aname:label that happens to equal the moved name; anedit_featureundo/redo is refused when the file was changed elsewhere in between, so that change is not lost; the server skips a watcher reload for a change it already loaded (its own guarded write), keeping the cached baseline, and the page reloads once on WebSocket reconnect; the feature page serialises choices, drops overlapping selection responses (no doubled Impact block), keeps a typed configuration name after a refusal and refuses to save without an analysable model. - New: warning
W240when the model has more than 5000 features, so abstract features' derived values are not computed. - Derived abstract values need at most 5000 features in the model (the deep-analysis limit); above that an abstract feature has no derived value.
0.50.0 — 2026-10-08¶
An abstract feature's value is derived (REQ-TRS-FMED-004)¶
- Changed: an abstract feature now has a value in every configuration, derived from the concrete selection: on exactly when the feature model forces it on (a selected child, a mandatory abstract parent, a
requires:that targets it), otherwise off. Every reader of a configuration's selection sees it, so anappliesWhen:on an abstract feature is active exactly where the concrete selection entails it, projection and the matrix show it, and arequires:of an abstract feature is met by what entails it.showmarks such entries(derived), and the configurator's load list does not offer them as choices. - Removed: warning
W238(anappliesWhen:naming an abstract feature), which flagged the gap this closes. It was emitted only in 0.49.0.
0.49.0 — 2026-10-08¶
Abstract features (REQ-TRS-FMED-004)¶
- New: a feature can be marked abstract (
isAbstract: true) from the browser's Edit mode and the MCP tool (setAbstract), and it now behaves as an abstract feature does in a proper feature model: it does not distinguish products (the product count,feature-check --enumerateand the configurator count variants over concrete features only), aConfigurationmust not name it (E238, selected or not; the configurator can still select one to explore, and its Save leaves abstract features out) and is judged on its concrete features with the abstract ones completed, arequires:that targets one a configuration does not name is not anE219, anappliesWhen:that names one isW238, and one with no children isW239. The diagram draws it dashed and italic and the Inspector says "abstract".
0.48.1 — 2026-10-08¶
A bound parameter is not removed (REQ-TRS-FMED-004)¶
- Changed: removing a parameter that a
Configurationbinds is refused. The reply names the configurations, and the bindings must be removed first: the newremoveBindingoperation (a ✕ beside each binding in the Impact section in Edit mode, and in the MCPedit_featuretool) removes one. In 0.48.0 removing the parameter silently removed its bindings. Removing a whole feature still removes the choices and bindings that named it. - New: the Impact section lists the configurations' bindings of a feature's parameters, with their values.
0.48.0 — 2026-10-08¶
Feature editing everywhere, and a leaner write path (REQ-TRS-FMED-004, REQ-TRS-MCP-MEM-000)¶
- New: the MCP tool
edit_featureapplies the same semantic feature-model edits as the browser's Edit mode through the guarded write:featureDeltasays which features become dead or false-optional, whether the model becomes void and which configurations become invalid; an edit that makes things worse is held (needsConfirmation) untilaccept_worse; a commit returns itsundo. - New: parameters can be added, replaced and removed (
setParameter,removeParameter, and a form in the Edit panel); removing one removes its bindings from everyConfiguration, and removing or renaming a feature does the same for its parameters' bindings. - New: sheet entries take every edit. Rename, move, remove, constraints and parameters now work on features defined in a
featureTree:sheet, including itscrossTreeConstraints:list and the derived ids that a rename would change. Undo restores the touched files exactly. - Changed: a guarded write on a large model (3,000 elements or more) holds one model in memory instead of two, and keeps the live model's validation findings between writes instead of revalidating it before each. On a 12,000-element model the peak across writes falls from 126 to 85 MB and a write from 2.4 to 1.7 s.
0.47.0 — 2026-10-08¶
Feature model viewer, configurator, editor and analysis (REQ-TRS-FMED-001 to -007)¶
- New:
/features(header link Features) shows the product line's feature model as a feature diagram in FODA notation: mandatory and optional marks, XOR and OR group wedges,requiresandexcludesconstraints as curves, parameters inside the box. Parents are centred over their children and several trees sit side by side. Collapse and expand subtrees, search by name or id, fit to the window, and click a feature for its state, why, its constraints and its documentation. - New: the SAT analysis is overlaid on the diagram, live: core, dead and false-optional features are marked with the constraints responsible, and a void model shows its conflict and the corrections that would fix it.
GET /api/feature-model/analysisreturns the same data. - New:
diagramKind: FeatureModeldraws the same diagram from aDiagramelement (subject: a feature, a feature-model sheet or a package of features), exportable as SVG, PlantUML and Mermaid withdiagram exportand from the page; + Diagram offers it. - New: a Configure mode turns the diagram into a configurator: click to select, deselect or leave open; the model propagates the consequences at once (implied features shown as rings), counts the valid products that remain, and refuses a choice nothing can satisfy with the choices and constraints at fault. Load a stored
Configuration, or save the completed product as a new one (REQ-TRS-FMED-003). - New: an Edit mode changes the feature model from the diagram: rename, mandatory or optional, XOR/OR/free groups, add and remove features and
requires/excludesconstraints, move a feature under another or drag it there. Every edit goes through the guarded-write engine and is checked first: one that makes a feature dead, forced on, the model void or a configuration invalid is held with the exact consequences until you confirm. Undo and redo for the session (REQ-TRS-FMED-004). - New: selecting a feature shows its Impact: the elements whose
appliesWhen:names it by type (and through which packages), the configurations that select or deselect it, what requires or excludes it, and a preview of what removing it would break (REQ-TRS-FMED-005). - New: a Matrix of features against every stored configuration, with a two-way comparison that highlights where two configurations differ (REQ-TRS-FMED-006).
- Changed: the feature analysis handles 5,000 features, up from 1,000, and is several times faster: each satisfying model witnesses every feature at once instead of one solver call per feature and direction, and an unsatisfiable core is found on one incremental solver instead of rebuilding it per constraint. A 2,000-feature model is analysed in about 0.2 s and a configurator click answered in about 0.3 s. Expand level opens a large model one level at a time, and a diagram too wide to read is shown from its first root instead of as a speck (REQ-TRS-FMED-007).
- Fixed: moving or renaming an element (
syscribe mv, MCPmove_element) did not rewrite qualified names used as map keys, so aConfiguration'sfeatures:andparameterBindings:still named the old feature. - Fixed:
feature-check --deepreported a mandatory feature with the default group kind as false-optional (W018). Only an optional member can be false-optional.
0.46.0 — 2026-10-08¶
MCP server memory (REQ-TRS-MCP-MEM-000)¶
A model of 12,000 elements used 121 MB at rest and grew by 27 to 40 MB with every guarded write, reaching 342 MB after a few operations. It now uses 62 MB at rest, does not grow with writes, and peaks at 126 MB.
- Changed: an in-memory element record is 1,792 bytes instead of 7,008. Rarely-set frontmatter fields are boxed in three tiers and allocated only when an element sets one; every field is still read and written as before.
- Fixed: resident memory kept climbing after each write or reload on Linux. The server now caps glibc's per-thread malloc arenas at startup and returns free memory after every rebuild.
- New: the
server_statsMCP tool reports element count, body bytes, bytes per element record, and resident and peak resident memory (Linux). The watcher's reload log line includes the resident size. - New: a regression test loads 12,000 elements and fails if memory exceeds its budget or grows across guarded writes. Measurements and the ideas still open are in
docs/design/mcp-memory.md.
Planning dashboard (REQ-TRS-VIS-027)¶
- New:
/planning(header link Planning) is a live board of PlanningItems: counts per status, who and which agents are working now with claim ages, a column per status, and who/done filters. It refreshes on the model-reload WebSocket and a timer, soclaim,releaseand agent edits show as they happen.
Element panel in the diagram editor (REQ-TRS-VIS-026)¶
- New: clicking a shape, port or edge in a diagram opens an Element side panel with the depicted element's rendered Markdown (headings, tables, code, Mermaid), its identity and an Open full detail button; a port or part usage that is only an inline feature shows its declared properties and its type's documentation (REQ-TRS-VIS-026).
0.45.0 — 2026-10-08¶
Create diagrams in the browser; sequence diagrams, tabs and folders fixed (REQ-TRS-VIS-023, -024, -025)¶
- New: a + Diagram button in the model browser opens a dialog to create a diagram — a name, a kind, derive from a subject or blank, an optional/required subject with suggestions limited to the element types that kind accepts, and a package (default
Diagrams). It posts through the guarded-write engine, then opens the diagram in a tab. - New: a ⊕ Add existing element toolbar button opens a picker over the model and adds the chosen element to a hand-listed (manifest) diagram through
POST /api/diagrams/shapes/{qname}: one guarded write that lists it undershapes:unpinned, so ELK places it, and never touches the element's file. Refused for a derived diagram, an unresolved or already-present element, and a diagram as the element (REQ-TRS-VIS-024). - Fixed: clicking a folder in the model browser did not show its contents straight away: the first click flipped the arrow and loaded nothing, the second collapsed it and then loaded the children (so the folder looked open under a closed arrow), the third did nothing. The row's inline
onclickand an htmxhx-triggerfilter shared one piece of state and the inline handler always ran first. One handler (static/js/tree-toggle.js) now owns the arrow, the state and the request: the first click opens and loads, the next collapses, and a failed load puts the row back. The model root row, which has no children to load, no longer shows a dead arrow. - Fixed: a hand-listed
Sequencediagram withoutlayout:pins (the demo'sMissionExecutionSeq) drew piled at the origin in the browser and could not be exported (ELK layout failed: The edge needs to have exactly one edge section). It is now placed with the geometry a derived sequence diagram uses — lifelines in declaration order, one row per message, activation bars, fragments boxed around the messages whosereflies under theirs, unlabelled messages named by theirref— and ELK'sfixedalgorithm is used only when every shape is pinned (REQ-TRS-VIS-025). - Fixed: in the web UI a diagram tab opened to a blank canvas with no tab strip. The stylesheet hides
#sprotty-viewportand#canvas-tabsby default and the page script "showed" them by assigning an emptydisplay, which only removes the inline style and leaves the stylesheet'snonein force. Present since the editor first landed (2026-07-30); the editor itself, the REST routes and every exported picture were unaffected, which is why API-level tests and the exports never saw it. A new test (frontend/test/page-wiring.test.mjs) fails for any element the stylesheet hides that the page tries to show with an empty display.
0.44.1 — 2026-10-08¶
Windows release asset restored; stdio-plugin SIGPIPE fix¶
- Windows: the 0.44.0 release has no
x86_64-pc-windows-msvcasset — the PlantUML writer's snapshot files were named after qualified names containing::, which Windows cannot check out. They now use__(Diagrams__PowerSystemIBD.puml); every other 0.44.0 asset was built and published normally, including the embedded QuickJS/ELK on every cross-compiled target. - Stdio plugins: a plugin that exits without reading its stdin (
echo '{}'is a legitimate plugin) could killsyscribeoutright withSIGPIPEwhile the request was being written, because the binary restoresSIGPIPE's default disposition so that piped output exits quietly. The runtime now masks the signal for the duration of that write. This was the intermittentrun_missing_alias_entry_fails_clearlyfailure in CI; the test now reports the child's exit status and signal. - No format, schema or validation-code changes.
0.44.0 — 2026-10-08¶
Traceability export (ADR-SYS-TREX-001)¶
- New command:
syscribe trace-export [--config <C>] [--sort directory|asc|desc] [--out <file>]and the read-only MCP tooltrace_export {config?, sort?}emit one JSON document covering every requirement in the model — nativeRequirementand SysMLRequirementDef/Requirement— with its identity (qname,id,name,type,status,reqClass,reqDomain,file), derivation (derivedFrom,derivedChildren,breakdownAdr), satisfaction (satisfiedBywith type and domain), verification (verifiedBywith level, status and the ingested verdict),refinedBy, and a computedcoverageblock (leaf,satisfied,verified,integrationVerified) plus asummaryof the counts (REQ-TRS-TREX-000..004). - Why: coverage questions were answered one requirement at a time (
trace,why,who-verifies), as a grid (matrix) or by joining the whole-modelexportby hand; none of those could be restricted to a product-line variant and sorted predictably. One schema computed from the same reverse indicesvalidatemaintains —coverageapplies exactly theW300/W002/W305rules, a retired TestCase is listed but never counts, and acoverage = truelink type thatextendsa built-in link contributes — keeps an external checker and the validator in agreement. - Usage: every reference is a full qualified name plus
id; a dangling one is kept as{ "qname": "<as written>", "unresolved": true }.--configprojects onto a storedConfigurationor an ad-hoc feature set exactly asexport --configdoes (inactive elements omitted from every list;configrecords{id, qname, name, activeFeatures}; an invalid configuration is a usage error).--sortfixes the order of the requirement list and every nested list (directory, the walker order, is the default); the output is byte-identical across runs. Documented insyscribe help trace-export,docs/cliand the MCP help; qualified byREQ/TC-TRS-TREX-001..004(PI-TREX-001).
CLI diagram toolkit removed (ADR-SYS-VIS-001, REQ-TRS-VIS-013)¶
- Removed: the
syscribe diagramcommand and all of its subcommands —list,render,measure,compose,layout,seq,req— together with its taffy/Cassowary/A* layout engine,*.layout.jsonworkspace files,syscribe help diagram, thedocs/clisection, the composed-SVG workflow in the authoring prompt, and the qualification casesREQ-TRS-DIAG-004/TC-TRS-DIAG-004andREQ-TRS-META-002/TC-TRS-META-002.TC-TRS-LINK-002is retired;REQ-TRS-LINK-002will be re-verified againstsyscribe diagram export --format svgwhen it lands. - Why: the visualisation redesign (
ADR-SYS-VIS-001,docs/design/visualisation.md) makes one Diagram IR insyscribe-model::visthe only rendering path, laid out in the browser; no backwards compatibility is kept for the old renderers. Phase 0 clears the ground. - Unchanged:
render <diagram_path>,syscribe plantuml/plantuml render, everyDiagramvalidation rule (E400–E404,W400–W415), andmagicgrid --svg, which keeps its text metrics and element theme undercrates/syscribe/src/svgkit/. - Dependencies:
cassowaryandpathfindingdropped from thesyscribecrate.
Visualisation rebuilt on one Diagram IR (ADR-SYS-VIS-001, REQ-TRS-VIS-000..022)¶
- One representation: every
Diagramis built as one intermediate representation insyscribe-model::vis— from a hand-listedshapes:/edges:/layout:manifest, or derived from the model when the diagram declares onlydiagramKind:andsubject:— and every renderer and exporter reads that IR. Design:docs/design/visualisation.md. - Derived diagrams for seven kinds:
BDD(definitions, inheritance, composition, attribute/port compartments),IBD(boundary, owned parts, ports with direction, connections/flows/bindings),StateMachine(states, initial/final pseudostates, transitions labelledevent [guard] / effect), the newActionkind (steps, decision/merge, fork/join, loops, successions — SysMLv2's action-flow view),Requirement(deriveReqt/satisfy/verify/containment with satisfying and verifying context nodes),Sequence(lifelines, messages in succession order,alt/loopfragments, activations) andAllocation(logical/physical lanes).include:/exclude:narrow a derived diagram; shape ids are deterministic (s-<qualified-name-slug>) solayout:pins survive regeneration. Demo diagrams:Diagrams::*Derived*. - Browser editor: the sprotty client lays diagrams out with ELK (
sprotty-elk+elkjs, vendored, no CDN) — measured labels, orthogonal routing, ports on borders, inheritance pointing up. A dragged node becomes a pin; Pin all, Auto-layout and Save companion SVG are the three new toolbar actions; the connect gesture is port-aware and writes dotted chains relative to the subject. One style table (vis::style, stereotypes, arrowheads per spec §8.16.8, applied-MetadataDefbanners) is owned in Rust and served to the client. - The same ELK engine inside the executable: the vendored
elk.bundled.jsruns under an embedded QuickJS, with node sizes computed once in Rust from shared font metrics and sent to the browser, sodiagram export --format svg,export-html, MkDocs and MCP draw every diagram — pinned or not — with the same layout the browser shows. A committed Node-versus-QuickJS determinism test and a bundle-version pin guard it. - New command:
syscribe diagram export <qname> --format plantuml|mermaid|svg [--out <file>]; MCPrender_diagramaccepts the same formats. Mermaid output carries%% ref:annotations; SVG output carriessysml:ref/sysml:source/sysml:targetand[links]hyperlinks (REQ-TRS-LINK-002re-verified). - New API routes:
DELETE /api/diagrams/layout/{qname}(clear every pin;PATCHacceptsnullto remove one andw/hto pin a size) andPUT /api/diagrams/svg/{qname}(save a companion SVG, settingsvgMode/svgFile). - New validation codes:
E405a malformedshapes:/edges:/layout:entry (previously the diagram rendered empty, silently),W416a stalelayout:pin,W417aninclude:/exclude:entry naming no member (or filters on a manifest diagram),W418a derived diagram whosesubject:type does not fit its kind.W080now applies only to manifest-sourced sequence diagrams. - Behaviour changes: manifest
kind:values outside the spec vocabulary (TestCaseDef,flowConnection,supertype) areE405— the demo model's three were corrected;export-htmldraws the IR first and uses a companion SVG only when there is nothing to draw; the PlantUML writer takes a block's stereotype from the element's real type rather than the manifest's word for it. - Dependencies:
rquickjs(QuickJS, MIT; a C compiler is needed at build time),ab_glyph/fontdbmoved tosyscribe-model; frontend addssprotty-elkandelkjs(EPL-2.0, vendored undercrates/syscribe-model/vendor/elkjs/). Binaries grow by roughly 2.5 MB. - Qualification:
REQ/TC-TRS-VIS-001..022(plus-013for the removal and-014for coverage),TC-TRS-LINK-002revived;PI-VIS-001..012track the phases. Noted limits: a 200-node/300-edge layout takes about 7 s in a debug build under QuickJS (0.9 s under Node); release builds are faster.
0.43.0 — 2026-09-26¶
MCP guarded writes: the delta now reports every error (#187)¶
- Before:
validationDelta.newErrorsandresolvedErrorscontained only dangling references (EREF) and user-defined link-type errors (E630–E636). A change that failed a fullvalidate(for exampleE310, a derived requirement with nobreakdownAdr) came back withnewErrors: []and could be committed unnoticed. - Now: both lists contain every validator error the change introduces or resolves, and each error entry has a boolean
gating. It istrueforEREFandE630–E636only. - Commit gate unchanged: only
gating: trueerrors refuse a commit, so incomplete drafts stay creatable. The rest are reported withgating: false. - Note: some failures now list two errors, for example
EREFandE103for a danglingderivedFrom. REQ-TRS-MCP-008 / TC-TRS-MCP-008.
MCP guarded writes: no spurious findings for paths outside the model root (#186)¶
- Before: the candidate copy was validated in the system temp directory, so a model-relative path leaving the model root (
[plantuml] style_file = "../.plantuml/x.iuml",sourceFile: ../tests/t.py) never resolved there. Every write showed a spuriousW415orW004, once as new and once as resolved. - Now: the candidate is staged as a sibling of the model root (a hidden
.syscribe-mcp-cand-*directory, removed after every call), so../paths resolve as in the real tree. If the parent is not writable it falls back to the temp directory. Finding messages that named the candidate root are rewritten to the real root, so a finding present before and after cancels out of the delta.
Install script and release checksums¶
install.sh:curl -fsSL https://raw.githubusercontent.com/sjames/syscribe/main/install.sh | shinstalls the latest release binary for Linux (static musl build) or macOS into~/.local/bin(--dirorSYSCRIBE_INSTALL_DIRto change it).- Checksums: each release now publishes
<asset>.sha256next to every binary, uploaded in the same step. The installer verifies the download against it and aborts on a mismatch. A release with no checksum asset, such as 0.42.0 and earlier, installs with a warning. - Mirrors:
SYSCRIBE_DOWNLOAD_BASEoverrides the download location.
Docs¶
- README: reorganised around agent-safe writes, with a tagline, a real demo transcript and GIF (
demo/), a short quickstart,cargo install --gitinstructions, and--read-onlynext to the MCP config examples. The long feature list moved to "Full Feature List". - Example:
examples/chat-to-code/is a real agent session that took an idea to a tested library through design discussion, ADRs, requirements, tests, a plan and implementation. - Site: the docs site description and title follow the new tagline.
0.42.0 — 2026-09-25¶
MCP server reloads automatically when model files change (#181)¶
- Before:
syscribe mcploaded the model once and refreshed it only after its own write tools. Edits made by an editor, the CLI (set,claim,move),git checkoutor another agent stayed invisible until the client calledreload. - Now: a file watcher covers the model directory and any
[repos]peers. After a short quiet period it reloads, but only when the model's inputs actually changed, so the server's own writes don't reload twice. - No blocking: the fresh model is built without holding the lock, so tool calls are never blocked.
- Half-saved files: a file that newly fails to parse defers the reload (
reload_deferred) and keeps the last good model. - Clients: they get a
{"event":"reload","source":"watch"}log message andnotifications/resources/list_changed. - Controls: the
reloadtool stays, and--no-watchdisables watching. REQ-TRS-MCP-048 / TC-TRS-MCP-049.
Docs¶
- README: a "Ways to use it" overview (CLI, GitHub Action, MCP server, LSP, web browser), and copy-paste setup for connecting the MCP server to Claude Code (
claude mcp add) and tomcpServers-JSON clients. - Action description: the GitHub Action's Marketplace description is corrected and now mentions the MCP server.
0.41.0 — 2026-09-25¶
This release comes out of a full documentation and specification consistency review. The review checked the spec, the LLM prompts, the help pages and the guides against the code and the binary, found about 110 inconsistencies, and logged 37 tool bugs (#125–#179). All are fixed; #150 turned out not to be a bug. Several documented behaviours change as a result, so read the Behaviour changes section before upgrading a CI gate.
Behaviour changes¶
- Unresolved structural references are now errors. Before, they were silently accepted. The new codes are E110
supertype, E111typedBy(on the element or an inline feature), E112subsets, E113redefinesand E114satisfies.[repos]models still report them as E512. (#125) validategates:--all-configsnow applies--deny,--max-warnings,--warnings-as-errors,--profileand--fileto each variant, and--confighonours--profileand--file.- Exit codes are consistent everywhere: 0 clean, 1 errors or a usage error, 2 a gate tripped. An unresolvable
--confignow exits 1; it used to exit 2. (#126) --configon a model with no feature model: it must now name a stored Configuration, and anything else is a usage error instead of a silent whole-model fallback.trace,why,who-verifies,refsandlinksnow apply the lens. (#139)- Code renumbering: the derive pass moves to E504–E506 (derive cycles are now detected, as E504). E500–E503 are only the Allocation codes. (#127, #141)
- Argument checking: unsupported
--whereoperators, invalid enum and count values, and unknown options are now usage errors; before, they matched nothing or were silently ignored.lint-docson a missing path now fails.diagramsubcommands now fail on an unknown element. (#129, #130, #133, #168) - Removed false positives:
- W406/W407 only check inline-SVG diagrams, which removes 90 warnings from the bundled models. (#158)
- Package-registry
implementedBy:values are external, so they no longer raise W023. (#134) - Requirements derived from a safety or cybersecurity goal are not W005 orphans. (#151)
- W301 had already been retired in 0.40.x.
New and completed features¶
- Configuration inheritance through
derivedFrom:(spec §9.8), with E234–E237. (#137) repoImportsmounting: peers mount at<package>::<as>, including forsubConfigurations:and cross-tier bindings. E515 now also catches the same id exported by two peers. (#138, #146)- SysMLv2
allocation defis mapped, andallocate … to …clauses become allocation edges. (#142, #144) - New and completed fields:
about:comments on elements, with E027/W052.locale:documentation variants.- ADR
deciders:. - FaultTreeEvent
ref:, with E927. derive:is a recognised field.- The
qualifiedName:identity override is removed; it now raises W049. (#164, #160, #159, #148, #141) - Constraints now enforced: ConfirmationMeasure
status(E924), SL range (E925), Zone/Conduitstatus(E926), a transition with no endpoint (W929), a features-form allocation outside an Allocation element (W930), an FMEA row with no id (E923), and an overriddenrpn:(W928). (#136, #142, #132) - Commands:
templateworks for every element type. (#135)listmatches every type. (#167)- MCP
explain_findingexplains every code. (#128) set evidence.addno longer duplicates entries and keeps comments. (#152)summarize --no-cachedoesn't write the cache. (#169)- The attack-tree roll-up starts from the structural root. (#149)
- The report is titled from the model's root package. (#174)
- lint-docs and validate share the shape-ref rule. (#172)
- Concurrency fix: the guarded-write temp directory could collide under concurrent writes; each write now gets a unique directory. (#156)
Documentation¶
- Spec, spec digests, LLM prompt and guides now agree with the tool.
- Field names are corrected, e.g.
allocatedFrom/allocatedToanddiagramKind. - The qualified-name rule is stated correctly, and the ISO 26262/21434/61508 examples use the real schema.
- Every element type is inventoried, and Asset and Baseline get schema sections.
- Guarded by tests:
- every documented YAML example validates (287 checked);
- the validation-code catalogue, the rules page and spec §11.12 match the emitted codes;
--helpis generated from the command registry;- the CLI reference, help pages and MCP/LSP pages cover the binary, and help-page examples run.
- Site:
- The landing page, README and web-UI docs are refreshed; the retired
/canvasis gone. - Release notes for 0.1.1–0.39.0 are backfilled.
mkdocs build --strictpasses.
CI and distribution¶
- Static musl Linux binaries:
syscribe-x86_64-unknown-linux-muslandsyscribe-aarch64-unknown-linux-muslare published alongside the existing five. - More CI coverage:
- The qualification workflow now runs
cargo test --workspace, about 950 tests. (#179) - It triggers on
prompts/,spec/,docs/and workflow changes. (#154) - A SIGPIPE race that made qual harnesses flaky is fixed. (#178)
0.40.1 — 2026-09-24¶
This release replaces 0.40.0, which has been withdrawn. The 0.40.0 release accidentally committed about 23 MB of unrelated, in-progress test fixtures (crates/syscribe-model/tests/fixtures/plugins-src, including node_modules and built .wasm). The affected commits were rewritten to remove them, and the 0.40.0 tag and release were deleted. 0.40.1 contains everything listed under 0.40.0 below, plus:
- Agent instructions use valid command syntax. The LLM authoring prompt (
--agent-instructions) wrote 83 commands assyscribe model/ <cmd>, which the CLI rejects. They now usesyscribe -m model/ <cmd>, and so do 15 more examples in the model guides. Two new tests check the embedded prompts: no example passes the model root without-m, and every example names a real subcommand.
0.40.0 — 2026-09-24 (withdrawn — superseded by 0.40.1)¶
User-defined link types¶
Projects can declare their own relationship types in a [linkTypes.<name>] table of .syscribe.toml and write them on elements under a namespaced links: map (ADR-SYS-LINKTYPE-001, spec §12.10, guide).
- Declared rules: each type can set
description,inverse,sourceTypes/targetTypes,cardinality,acyclicandsuspect. The codes are E630–E636, W630 and W631. - Variants of built-in links:
extends = "satisfies" | "verifies" | "derivedFrom" | "refines"makes a type a named variant of that built-in link, with the same rules and reverse index.relax = [...]switches specific rules off for that type only (E312/E313, E104, E105/E310/W303, E316).coverage = falsekeeps the rule checks but gives no coverage credit. Built-in links are never relaxed. - Traversal:
- New
follow <elem> <link> [--reverse] [--transitive] [--depth N] [--format text|json|dot]andlink-types [--json]commands. links,refs,impact --kinds,trace,show,connectivity, the coverage reports,export-html,export-reqifandsbomall include custom links.- Findings raised by an extending link name it, e.g.
(via links.<type>). - MCP:
- New read-only
link_typesandfollowtools. - A write that would introduce an E630–E636 error is refused.
- LLM discovery:
syscribe -m <root> --agent-instructionsappends the project's declared link types.- The authoring prompt tells agents to run
link-typesand never invent a type. - E630 lists the declared types.
- Suspect links: custom links take part in suspect-link detection unless
suspect = false. - Worked example:
examples/link-types/.
W301 retired: a leaf requirement may have several satisfiers (#121)¶
- A leaf requirement satisfied by more than one element is now legitimate, for example a PartDef plus the StateDef that gives it its behaviour, or redundant channels.
- Leaf vs parent depends only on
derivedFrom. - E312 and W300 are unchanged.
Package membership is generated from the directory (#120)¶
show <package>prints a## Members (N)table. The web UI detail panel andexport-htmlpackage pages list the same members, taken from the directory rather than from_index.mdprose.- New advisory W103 in
lint-docs: an_index.mdthat hand-lists three or more of its own members. It doesn't change the exit status. - The bundled models'
_index.mdfiles were rewritten to describe purpose and scope (ADR-SYS-PKG-001).
Fixes¶
ingest-resultsmerges instead of overwriting. A session-log ingest no longer wipes earlier cargo-json/junit verdicts, or the other way round. Each format replaces only its own section of.syscribe/results.json, and legacy sidecars still load. The MCPingest_resultstool merges the same way.--configon a model with no feature model: the argument must now name a storedConfiguration, for example a MagicGrid parametric variant, in which case the whole model is used. Anything else exits non-zero instead of silently running over the whole model. This applies to every CLI--configcommand and the MCPconfigarguments (REQ-TRS-PROJ-001). A Baseline'sfrozenScope.configis unchanged.- MCP
why_activereports a config it can't resolve instead of treating it as an empty selection. - Help text:
sethelp now states that onlystatus=is byte-preserving; the list operations re-serialize the frontmatter block.
Qualification¶
- The 13 previously skipped qual TCs now have harnesses, so the suite runs 308/308 with 0 skipped.
- New TCs: TC-TRS-LINKTYPE-001..012 and TC-TRS-PKG-001/002.
- Fixed a SIGPIPE race that made grep assertions on large outputs flaky (
qual/tests/lib.sh).
0.39.0 — 2026-09-15¶
Annotated-source ingestion¶
A package _index.md can declare annotationFormat: <label> with inline marker: (a regex), include: and exclude: (globs). Syscribe then scans the matching source files in-process for comment blocks that start with the marker and parses each block with the same frontmatter schema a .md file uses (ADR-SYS-ANNOTATE-001, guide).
doc:in a marker block becomes the element's documentation body.implementedBy:is filled in from the marker's own source location when it isn't set (W563).- A native
TestCasecanverifies:an annotation-synthesized element (E104 widened a third time). - New codes E560, E561, W560–W563.
annotationFormat:is mutually exclusive withforeignFormat:andsysmlSubmodel:on the same package (W562). - New
annotations scan <qname-or-label> --dry-runscans one package without merging or validating. - Worked example:
examples/annotated-source/c-firmware/.
Session-log results for manual verification (#113)¶
ingest-results --format session-log <file> ingests a JSON array of per-Gherkin-scenario records (testCase, scenario, steps, result, timestamp). A malformed record is a hard error and nothing is written. A TestCase with no testFunctions: gets its verdict from its scenario titles: any fail is a fail, every scenario recorded as pass is a pass, and partial coverage stays unknown. trace, matrix, safety-case and testplan show these verdicts.
PlanningItem workflow¶
setcommand (#112):set <id> status=<value>,set <id> evidence.add ref=<id>|path=<path> [rationale=<text>]andset <id> achieves.add <req-id>. Values are checked before anything is written,status=rewrites only that one line, and--dry-runpreviews a diff.claim/release(#115):claim <PI-id> --by <agent-id>sets the new advisoryclaimedBy:/claimedAt:fields. It refuses adoneitem or one claimed by someone else.release <PI-id>clears both.claimedByappears inshowandlist PlanningItem --json.- W310 (#114): a
donePlanningItem whoseachieves:requirement doesn't meet the W002/W305 verification bar is flagged on the PlanningItem's own file. - W311: two active PlanningItems (
in_progressor claimed) that share anachieves:requirement or anevidence[].path.
CLI output¶
validatesummary line (#116): text output now starts with a line such as0 errors, 51 warnings. When a gate trips, the line ends inFAILand names the mechanism (--deny,--warnings-as-errors,--profileor--max-warnings).showRelated footer (#117):showlists the relevant follow-up commands for the element's type (trace,who-verifies,impact,refs,connectivity,n2).--no-relatedhides it.
Documentation¶
- Docs, templates and prompts now use the canonical
derivedFromCybersecurityGoalfield name that W804/W807 report (#84). The legacy alias still works.
0.38.0 — 2026-08-24¶
Stdio-subprocess foreign-format plugins¶
A package _index.md can declare foreignFormat: <alias> to hand its whole subtree to an external process configured under [plugins.<alias>] in .syscribe.toml (ADR-SYS-PLUGIN-002, guide). Syscribe writes one JSON request to the process's stdin and reads one {elements, diagnostics} envelope from its stdout. The plugin can be written in any language.
- Plugins are not sandboxed.
timeout_msis the only enforced limit. - Plugin elements take part in cross-references like hand-authored ones, and a native
TestCasecanverifies:a plugin-synthesized element. - New codes E550, E551 and W550–W553.
- New
plugins run <alias> --dry-runshows a plugin's raw envelope. - Worked example:
examples/stdio-plugins/toy-python/.
E108: duplicate qualified name¶
New E108 reports two elements with the same qualified name, whatever their origin. Before this, the last one silently won. It found redundant _index.md wrappers in model_sil/ and in qual fixtures, which were removed.
More SysMLv2 constructs mapped¶
Native SysMLv2 submodel ingestion now maps several more constructs onto the existing native schema:
state def/state→StateDef, with canonical transitionsaction def/action→ActionDef, with asubActions:treeview def,viewpoint defandrendering defconcern def/concernflow def/flow, which also lifts onto the owning part'sflowConnections:enum def/enumcase def,analysis defandverification def
use case def is still unmapped.
VS Code extension 0.2.0¶
The extension in editors/vscode/ is ready for the Marketplace:
- It finds or downloads the
syscribebinary automatically. The newsyscribe.versionsetting pins a release. - It is bundled with esbuild.
- Activation has a timeout and fails with a clear error instead of hanging.
- A CI workflow builds the
.vsixonvscode-v*tags.
0.37.0 — 2026-08-18¶
Derived ids for featureTree: entries¶
A featureTree: entry's id: is now optional (REQ-TRS-FM-006). When it's left out, it is derived from the entry's dotted name:, so Platform.CortexM becomes FEAT-PLATFORM-CORTEXM. An explicit id: always wins. Invalid or colliding derived ids are reported by the existing E006 and E101. A plain per-file FeatureDef still needs an id (E201). MCP describe_type now lists FeatureModel.
0.36.1 — 2026-08-18¶
- Bumped
sysml-v2-parserfrom 0.53.0 to 0.54.0, which brings upstream parser fixes. No behavior change for Syscribe models.
0.36.0 — 2026-08-18¶
Single-file feature models¶
A type: FeatureModel sheet can hold a whole feature tree as one flat featureTree: list (REQ-TRS-FM-005, spec §9.6a). The walker turns each entry into an ordinary FeatureDef.
- Entry names are dot-separated paths relative to the sheet (
Platform.CortexM), so they get the same qualified names a directory layout would. - An optional
crossTreeConstraints:list keepsrequires:/excludes:edges in one place. parameterConstraints:is accepted directly on the sheet.- New codes E231–E233 and W048.
- Worked example:
examples/single-file-feature-model/.
Fixes¶
requires:/excludes:now resolve bareFEAT-*ids. Before, they raised a false E212 and were dropped fromfeature-check --deep.parameterConstraints:no longer triggers a false W047.- The
featurestree now nests by real FeatureDef ancestry. - Write operations (
update_element,delete_elementandmove_element, in both the web server and MCP) now refuse elements that were synthesized from a shared sheet, such as FMEA/TARA rows orfeatureTree:entries. Before, they rewrote or moved the whole sheet file. - LSP go-to-definition on a
featureTree:entry now jumps to that entry's line.
0.35.0 — 2026-08-14¶
SysMLv2 submodel improvements¶
@Syscribe*metadata annotations (#92): on apart def/part, these annotations setdomain:,asilLevel:/silLevel:/plLevel:,shortName:andimplementedBy:. The existing validation then applies to them.- Doc-comment lifting (#94):
doc /* ... */comments become the synthesized element's documentation body. - Connections (#95, #99):
connect a to b (, c)*endpoints become resolvableconnections:edges. A two-segment endpoint resolves to a nested feature redeclared on the usage. New W542 warns when an endpoint is truncated to its head (#104). - Trailing doc bodies (#98): a named connection usage's own trailing doc body is lifted.
- Doc-comment directives (#100):
interface def,port defandconnection defaccept@SyscribeDomain:,@SyscribeIntegrity:,@SyscribeShortName:and@SyscribeImplementedBy:lines in their doc comment. - Scoped
n2(#97): the axis now includes qname-nested child parts. - Package-relative references (#105, #107): package-relative
typedBy:/supertype:references now resolve for W600 suppression, W007 usage tracking and the graph'sTypedByedge.
Validation and CLI¶
- Shorter ids: the category segment is now optional in
REQ,TC,ADRandPIids, soREQ-042is valid. - W600 (#101): no longer fires on a
Partusage whosetypedBy:target is documented. template PlanningItem(#102): now works on the CLI and through MCP.- Configuration reference:
spec fieldsnow has a complete.syscribe.tomlreference.
0.34.0 — 2026-08-08¶
PlanningItem assignedTo:¶
A PlanningItem can declare assignedTo: <username> (REQ-TRS-PLANITEM-008).
- The value must be a Unix-style username (E723).
- When
.syscribe.tomlhas a non-empty[users]roster (alice = "Alice Nakamura"), the username must be in it (E722). A malformed roster key is W309. showprints the display name.
0.33.0 — 2026-08-07¶
Native PlanningItem element type (#91)¶
type: PlanningItem (PI-* ids) is a work-item tree that is part of the traceability graph (ADR-SYS-PLANITEM-001).
- Fields:
status(todo | in_progress | blocked | done) and an optionalitemType(bug | task | feature). - Hierarchy: a single
parent:per item, with cycle detection. - Goals:
achieves:is required on top-level items and must nameRequirements. It is kept separate fromsatisfies:. - Variants:
appliesWhen:gating works for PlanningItems. - Evidence:
evidence:entries areref:orpath:, each with an optionalrationale:waiver. A leaf item markeddoneneeds at least one non-waived evidence entry that resolves (E719). - Dependencies:
blockedBy:names what the item is waiting on. E720 reports a dangling target, E721 a cycle, and W308 a non-emptyblockedBy:when the status isn'tblocked. - Codes: E706–E721.
- Worked example:
examples/planning-item/.
Hierarchical product-line composition¶
A Configuration can consolidate other, already-configured Configurations through subConfigurations:, locally or across [repos], at any depth (ADR-SYS-HPLE-001).
- Validity: each entry must resolve to a valid Configuration (E516–E518).
- Parameter bindings:
parameterBindings:reaches through the whole subtree. E519 and E523 reject illegal or redundant cross-tier bindings. - Open parameters: the opt-in W513 flags a required parameter left open anywhere in the subtree.
- Isolation: a lower tier never refers to the configuration that consolidates it, and
bindTo:never crosses asubConfigurations:boundary. - Worked example:
examples/hple-multitier/.
Native SysMLv2/KerML submodels (#89)¶
A package marked sysmlSubmodel: true can hold .sysml/.kerml files. They are parsed in-process and merged into the graph (guide).
- Merging and mapping: same-named packages from different files are merged, and a fixed set of element kinds is mapped.
- Traceability:
satisfy/verifycan target native Requirements, and a nativeTestCase.verifies:can target a SysMLv2 element. - Variability:
@SyscribeFeature{featureId}becomesappliesWhen:. - Codes: a stray nested
_index.mdis W540, and a parse failure is W541. - Worked example:
examples/sysmlv2-submodel/.
Web UI: diagram-driven editing, /canvas removed¶
- Editable diagrams: non-Mermaid diagrams use a new sprotty-based editor for create, delete, connect and move. Each edit goes through the guarded write engine, which now lives in
syscribe-model::mutate, and returns a validation delta. /canvasremoved: the Cytoscape.js graph explorer (/canvas,/api/graph) and the old SVG-canvas drag/layout code were removed.- JSON API: responses use camelCase throughout. A refused write returns
written: false. - Live reload: the tree and any open diagram refresh after a reload event.
Fixes (#90)¶
- W024 no longer reports a FeatureDef as an orphan when it is referenced by bare id in
appliesWhen:. Attributeelements are no longer labelledOther.- The validation report now shows
satisfies:targets written as qualified names. delete_element's reference guard and the referential-integrity gate now see nestedAllocationreferences (#87).
0.32.0 — 2026-07-23¶
Language Server (syscribe lsp)¶
A stdio Language Server for editors, using only standard LSP (ADR-SYS-LSP-001..003):
- Navigation: diagnostics, go-to-definition, references, hover and workspace symbols.
- Completion and rename: completion for cross-reference fields and enums, and rename of stable ids.
- Code lenses: counts for
verifiedBy, derived children and suspect links. - Quick fixes: for E310 (pick an accepted ADR) and W090 (accept a suspect link as reviewed).
A minimal VS Code client is included in editors/vscode/. The README now also covers suspect links, baselines and the MCP server.
0.31.0 — 2026-07-13¶
Suspect links¶
Suspect links flag a trace link whose target changed after the link was reviewed (ADR-SYS-SUSLINK-001).
- Baselines: the source element stores a
traceBaselines:map from each target to a blake3 hash of the target's normative content. A mismatch is W090. - Opt-in: links without a baseline stay silent in
validate. - CLI:
suspect list,suspect accept <src> <tgt>,suspect accept --allandsuspect accept --all-unbaselined(for onboarding). - MCP:
suspect_list, and a guardedsuspect_accept.
Release baselines¶
type: Baseline (BL-*) freezes a scope of the model into a snapshot that is content-hashed and tied to a git commit (ADR-SYS-BASELINE-001).
- Commands:
baseline create,verify,diff,listandshow. - Scope:
frozenScopecan cover the whole model, a package subtree, or type/status/tag filters. It can also project a Configuration (config=) or take the trace closure of a goal (closureFrom=). - Drift and tampering: drift is graded by status (E520 for
released, W520 forapproved). Tampering between the seal and the manifest is E521, and an unresolvedsupersedesis E522. - Output locations: configurable with
[baselines]in.syscribe.toml. - MCP: read-only
baseline_list,baseline_diffandbaseline_verify.
0.30.0 — 2026-07-04¶
Scanning large requirement sets¶
New read-only commands, each also available as an MCP tool:
stats: histograms by facet, plus coverage and orphan rollups.digest: one compact line per requirement, paged to a token budget.search-text: BM25 full-text search.summarize: a per-package summary built from excerpts.topics: distinctive keywords per package.clusters: TF-IDF k-means clustering.
All of them run offline and give the same result every time.
Schema¶
displayOrder: new optional numeric field that sets presentation order without renumbering ids.- W047: new warning for unrecognized frontmatter keys.
reqClassis now a recognized field.
Fixes¶
findno longer panics when its length cap falls in the middle of a UTF-8 character.matrixnow shows a covered-but-failing requirement as▣instead of✗.
0.29.0 — 2026-06-29¶
- Consistent coverage: MCP
coverageandcoverage_matrixnow use one shared classifier. A requirement covered only by draft TestCases isplanned, not verified, and a covered requirement whose latest verdict is fail isfailing. As a result, verified counts drop for models that rely on draft tests.
0.28.2 — 2026-06-29¶
- Added a requirement and a regression test that every MCP tool input property has an object schema.
0.28.1 — 2026-06-29¶
- MCP fix: the
fieldsargument ofcreate_element,update_elementandapply_changesnow has an object JSON schema. Strict MCP clients, including Claude Code, had rejected the whole tool list.
0.28.0 — 2026-06-29¶
Static HTML export¶
export-html [--out <dir>] [--css <file>] writes the whole model as a static site that works offline. It includes a page per element, inline diagrams, validation, coverage and traceability reports, and client-side search.
Eight more MCP tools¶
- Evidence:
ingest_results,coverage_matrix,coverage_gapsandevidence. - Diagrams and docs:
lint_docs,render_diagram,diagram_coverageandgenerate_view.
This brings MCP to 37 tools. help mcp and the CLI docs now cover all of them.
0.27.1 — 2026-06-29¶
- MCP
coveragenow reports only non-draft requirements as gaps. - The demo model gained integration-level TestCases for its approved parent requirements, which clears the W305 warnings.
0.27.0 — 2026-06-29¶
MCP server (syscribe mcp)¶
A Model Context Protocol server over stdio that lets LLM clients query and edit a model (ADR-SYS-MCP-001):
- Read and navigate:
search(with filters and full-text search),get_element,tree,trace,impact,validateand others. - Authoring helpers:
template,next_id,check_ref,coverageand others. - Guarded writes:
create_element,update_element,move_element,delete_elementand the atomicapply_changes. Writes are dry-run by default and return a validation delta and a diff. - Feature-model tools:
features,feature_check,configure,project,diff_configsandwhy_active. - Reports:
run_reportruns an allowlisted, read-only report command. - Read-only mode:
--read-onlyhides the write tools. - Coverage:
coverageseparates uncovered leaf requirements from parents that are missing integration-level (L3–L5) tests.
0.26.41 — 2026-06-22¶
- Extra id prefixes: the
[ids.prefixes]table in.syscribe.tomladds stable-id prefixes per element type. For example,Requirement = ["STK", "SYS"]makesSTK-SCHED-001valid. The built-in prefix stays valid. A malformed entry is W046 and is ignored. - All clippy lints are resolved. No behavior change.
0.26.40 — 2026-06-22¶
- CLI commands piped into a reader that exits early (
| head,| grep -q) now exit quietly instead of panicking.
0.26.39 — 2026-06-22¶
- Docs audit: docs, CLI help, spec templates and agent instructions were checked against the implementation.
- All emitted E/W codes are now documented.
- CLI help lists every subcommand.
- Missing types were added to the spec templates.
0.26.38 — 2026-06-20¶
PlantUML styling and coverage¶
- Styling: diagrams use a SysML-style colour scheme, shared via
.plantuml/sysml.iuml, with a built-in fallback. - IBDs: containers nest recursively.
- Labels: shapes and edges accept a
label:. - Links: SVGs link to
<base_url>/<path>.md, so links can point at GitHub. Links are omitted whenbase_urlisn't set. - Demo models:
model_auto/now has one example of each diagram kind.
0.26.37 — 2026-06-19¶
plantuml render¶
- Rendering:
plantuml render [--jar <path>] [--dry-run]runs PlantUML on every companion.pumlfile. It finds PlantUML via--jar, then[plantuml] jar, thenPLANTUML_JAR, thenPATH. - Image links:
plantumladds a Markdown image link to the element body when it has none. - Demo models: all example diagrams now use
pumlMode: companionwith rendered SVGs. - CI: PlantUML generation and rendering run in CI.
0.26.36 — 2026-06-19¶
PlantUML companion diagrams¶
- Generation: the new
plantumlsubcommand generates.pumlsource forDiagramelements markedpumlMode: companion(BDD, IBD, StateMachine, Sequence, Requirement). UsepumlFile:to set the output path. - Styling: configured under
[plantuml]in.syscribe.toml(theme,style_file,base_url). - Codes: new E403, E404 and W413–W415.
- Docs: the W023 docs were extended to
Interface/InterfaceDef.
0.26.34 — 2026-06-18¶
implementedBy / W023 extended to Interface and InterfaceDef¶
Interface and InterfaceDef elements now participate in the §12.8 implementation-trace chain. Add implementedBy: to link an interface definition to its header file, IDL, ROS message definition, or any other source artifact that defines the interface contract. W023 fires for missing local paths on non-draft elements, with the same opt-in, draft-suppression, and remote-URI-exemption rules that apply to Part/PartDef.
- W023 — extended to cover
InterfaceandInterfaceDef(previouslyPart/PartDefonly) template interfacedefandtemplate interfaceupdated with commented-outimplementedBy:examples- Spec, frontmatter reference, traceability guide, and LLM prompt all updated
- 11 unit tests (REQ-TRS-IFACE-000..002, ADR-SYS-IFACE-001)
0.26.33 — 2026-06-17¶
Template and spec updates for build system integration fields¶
Documentation-only follow-up to v0.26.32. The template configuration output now includes commented-out buildOverrides: and parameterBindings: examples; the spec fields PLE table documents buildExports, buildOverrides, and the buildVar parameter sub-field.
No code or validation behavior change.
0.26.32 — 2026-06-15¶
Build-system configuration from a Configuration¶
The new build-config subcommand turns a Configuration's feature selections and parameter bindings into build variables. It outputs cmake, c-header, makefile, env, json or kconfig.
- Schema:
buildExports:onFeatureDef,buildVar:on a feature parameter, andbuildOverrides:onConfiguration. - Precedence: later sources win, in this order:
buildExports:, thenbuildVar:, thenbuildOverrides:. - Flags:
--all-configsemits a JSON array for CI matrices, and--prefixnamespaces the variable names. The configuration is SAT-checked first unless you pass--no-validate. - Codes: new E050 (two features set the same variable) and the opt-in W050.
- Fixes:
spec/helpnow work after-m <root>,-mPATHis recognized, andderivedFrom:accepts a single string. - Docs: a new multi-page Practitioner Guide section.
0.26.31 — 2026-06-13¶
Documentation: multi-repository composition¶
Full documentation pass for the §14 multi-repo / git-submodule work (W510–W512):
- New guide — Multi-Repository Composition:
[repos]declaration,repoImports:mounting, cross-repo resolution, the reproducibility gates, and how[repos]composes with git submodules. Added to the site nav and the Modeling-Guide index. - Validation overview — the code-range table in
docs/validation/index.mdnow covers the whole §13–§22 backlog (TestPlan, review records, multi-repo, decomposition/budgets, trade studies, IEC 62443, behavior), and the stale qualification-suite counts were corrected. - Cross-links and the
W512row added across the rule reference, CLI reference, and frontmatter reference; theREADME"What It Supports" list now includes variability, multi-repo composition, and the expanded rule set;CLAUDE.mdgained a multi-repo commands block.
Documentation-only; no code or validation behavior change. mkdocs build --strict is clean.
0.26.30 — 2026-06-13¶
Submodule gitlink/ref consistency gate (W512, GH #62)¶
Multi-repo composition now integrates with git submodules (§14, REQ-TRS-TYPE-023). When a peer repo's path is a git submodule of the composing model's repository, validation compares the commit its ref: resolves to against the gitlink the parent repo records for that path (git ls-tree HEAD <submodule-path>) and emits W512 when they disagree — catching a .syscribe.toml ref: that has silently diverged from the .gitmodules pin. Gate CI with validate --deny W512. W512 is independent of W511 (gitlink pin vs ref:, not checkout vs ref:) and is never raised when path is not a submodule, no ref: is configured, or either commit cannot be resolved — so non-submodule compositions (sibling checkouts, monorepo paths) are unaffected. Verified by TC-TRS-TYPE-023 (4 assertions over a real parent-repo-plus-submodule). Qual 246/246; all models clean.
The two layers are complementary: a submodule provides the pinned checkout, and [repos] adds model-level cross-reference resolution plus the W511/W512 reproducibility gates on top.
0.26.29 — 2026-06-13¶
Peer-repository ref-drift gate (W511, GH #62)¶
Multi-repo composition now enforces reproducibility (§14, REQ-TRS-TYPE-022). When a peer repo in [repos] declares a ref:, validation compares the peer work tree's HEAD with the commit the ref: resolves to and emits W511 on drift — gate CI on a pinned composition with validate --deny W511. The drift state is computed once at load time (single source of truth shared by validation and the repos CLI); repos status reports the same drift and exits 2, and repos sync brings the checkout back to its ref:. Drift is never falsely reported when it cannot be determined — git unavailable, the peer is not a work tree, the ref: does not resolve, the path is absent, or no ref: is configured. Verified by TC-TRS-TYPE-022 (4 assertions over real isolated git work trees). Qual 245/245; all models clean.
0.26.28 — 2026-06-13¶
Multi-repository model composition (GH #62)¶
Large programs may now split a system model across repositories (§14, REQ-TRS-TYPE-021). A model declares peer repos in the [repos] table of its model-root .syscribe.toml (path, optional root default model/, optional ref), and a Package _index.md mounts a peer sub-tree with repoImports: [{repo, qname, as}]. Cross-repo verifies:/derivedFrom:/satisfies:/allocatedTo: references resolve against the local model first, then each loaded repo in declaration order — by global stable ID (REQ-*, TC-*, … unique across the whole composition) or qualified name.
- Validation —
E510circular repo import,E511missing path (no ref),E512dangling cross-repo trace reference,E513unknownrepoImportsalias,E514unresolved import qname,E515duplicate stable ID across repos,W510unpinned repo (opt-in,--deny W510). The whole block is inert unless[repos]is configured, so single-repo models are unaffected. - CLI —
repos list [--json](configured repos with path/ref/on-disk + sync status),repos status [--json](whether each pinned repo is at itsref; exits 2 on drift),repos sync [--all | <alias>](git fetch+git checkout <ref>). - Verified by
TC-TRS-TYPE-021(10 assertions: the seven rules, a clean cross-repo composition, andrepos list). Full qual suite 244/244; all shipped models validate clean.
This completes the §13–§22 spec-feature backlog (GH #61–#74).
0.26.27 — 2026-06-13¶
IEC 62443 Zone/Conduit model (GH #61)¶
- Native
Zone(ZN-*) andConduit(CD-*) element types (§13) for industrial cybersecurity: aZonegroups parts under a Security Level (targetSL/achievedSL,members:); aConduitconnects two zones (fromZone/toZone,achievedSL,implementedBy:controls).PartDef/Partmay carrytargetSL/achievedSL/inZone:. (REQ-TRS-TYPE-020) - Validation —
E950–E956(required fields,ZN-*/CD-*ids, conduit endpoints resolve to zones, member/inZone type checks) andW950–W953(SL gap, weak conduit boundary, isolated SL claim, approved zone with no conduit). - CLI —
zones [--coverage] [--json](zones + SL gap, or Zone × SecurityControl cross-table),conduits [--json](conduits + SL adequacy), andtemplate Zone/template Conduit. The demo model is extended with an avionics control zone, a datalink zone, and the conduit between them.
0.26.26 — 2026-06-13¶
lint-docs — diagram reference resolution (GH #74)¶
lint-docsnow validates diagram references against the model, beyond the existing prose stable-ID check (W099): a qualified name (A::B::C) inside a```mermaidblock that does not resolve raisesW100; an SVGsysml:ref="…"that does not resolve raisesW101; a local Markdown image/diagram embed path (,<img src>) that does not exist raisesW102. (REQ-TRS-LINT-002)lint-docsnow scans.svgfiles in addition to.md. Qualified names in prose remain deliberately unresolved (no false-positive regression); SVGs with nosysml:refare opaque; remote URIs (https://…) are accepted as external. All findings appear in text +--jsonand are gateable (--deny W100).
0.26.25 — 2026-06-13¶
ReqIF 1.2 export — export-reqif command (GH #73)¶
syscribe export-reqif [--output <f>] [--scope <qname>] [--config <C>] [--include-tests] [--zip]— exports nativeRequirementelements (and their packages) as a ReqIF 1.2 XML document for interchange with DOORS Next / Jama / Polarion / PTC. Read-only, export-only. (REQ-TRS-OUT-020)- Each requirement → a
SPEC-OBJECT(SYSCRIBE_ID/NAME/QUALIFIED_NAME/STATUSenum/SIL_LEVELint/ASIL_LEVEL/DOMAINenum + an XHTMLDESCconverted best-effort from the body, Gherkin omitted); packages → a nestedSPEC-HIERARCHY;derivedFrom:→DERIVED_FROMSPEC-RELATIONs;--include-testsaddsTEST_CASEobjects +VERIFIED_BYrelations. --outputwrites<file>.reqif, or<file>.reqifzwith--zip(a stored ZIP, no external deps);--scope/--configrestrict/project. Output is well-formed ReqIF 1.2 XML.
0.26.24 — 2026-06-13¶
SBOM generation — sbom command (GH #66)¶
syscribe sbom [--format cyclonedx|spdx] [--config <C>] [--output <f>] [--include-tests] [--scope <qname>]— generates a Software Bill of Materials from theimplementedBy:links onPart/PartDef(and, with--include-tests,TestCase.sourceFile:). Read-only; no new element types or rules. (REQ-TRS-OUT-019)- An
implementedBy:value matching<registry>:<package>@<version>(crates.io/npm/pypi/maven/nuget/github) becomes an external package component with a PURL (pkg:cargo/tokio@1.38.0); any other value (incl. arepo:link) is a local file component. Local components carry references back to the requirements the part satisfies (CycloneDXexternalReferencessyscribe://<REQ>/ SPDXGENERATED_FROM). --format cyclonedx(default) emits CycloneDX 1.6 JSON (serialNumber urn:uuid, tool + timestamp metadata, components);--format spdxemits SPDX 2.3 JSON (packages +DESCRIBES/CONTAINS/GENERATED_FROM).--configprojects to a variant;--outputwrites a file.
0.26.23 — 2026-06-13¶
Behavioral coverage — behavioral-coverage command (GH #72)¶
syscribe behavioral-coverage [<qname>] [--depth N] [--format text|json] [--uncovered-only] [--include-planned]— reports how completely the active TestCases exercise the behavioral elements (ActionDef/Action/StateDef/State), via four coverage paths: source overlap (sourceFileunderimplementedBy), requirement chain (verifies→satisfies→typedBy/supertype), test function (testFunctions[].fileunderimplementedBy), and allocation (allocatedTo). Read-only; no new element types or rules. (REQ-TRS-OUT-018)--include-plannedcounts draft/review/approved tests in a separate planned column;--uncovered-onlyfilters while keeping the true percentage;text/json({scope, covered, total, coverage_pct, elements}).- The demo model now links its flight-control behaviours (
TakeoffAction/MissionExecution/LandingAction) to the realizing firmware and the HIL fault test, so it reports 60% behavioral coverage out of the box. - Fixed a CLI argument bug where a value-taking flag (
--format/--depth) with no positional could be mistaken for the positional (affectedn2/impact/behavioral-coverage).
0.26.22 — 2026-06-13¶
Change impact analysis — impact command (GH #65)¶
syscribe impact <qname|id> [--direction downstream|upstream|both] [--depth N] [--format text|json|dot] [--kinds <csv>]— traverses the traceability graph from a named element and reports every reachable node, its hop distance, and the edge kind that connects it ("if I change this, what else may need to change?"). Read-only; no new element types or validation rules. (REQ-TRS-OUT-017)- Downstream follows reverse links (
specializedBy,derivedChildren,verifiedBy,satisfiedBy,refinedBy,conditionalOn,allocatedFrom,safetyGoalChildren); upstream follows forward links (supertype,derivedFrom,verifies,satisfies,refines,allocatedTo,derivedFromSafetyGoal).--depthlimits hops;--kindsrestricts edge kinds;text(indented tree) /json({root, nodes}) /dot(Graphviz). Cycle-safe; accepts qnames and stable IDs.
0.26.21 — 2026-06-13¶
N² interface matrix — n2 command (GH #64)¶
syscribe n2 [<qname>] [--depth N] [--format text|html|json] [--interfaces-only] [--allocations]— generates an N² (N-squared) interface matrix: in-scopePartDef/Partelements on the diagonal, and each off-diagonal cell(R, C)listing the named interfaces directed from R to C (from the connection'stypedBy:ConnectionDef/InterfaceDef or its name). Derived read-only from the existingconnections:,flowConnections:, and (with--allocations)allocatedTo:edges — no new element types or validation rules. (REQ-TRS-OUT-016)- Without a
<qname>the axis is every part in the model; with one it is the composite's subpart types, expanded--depthlevels.text/html(self-contained<table>) /json({ scope, elements, matrix }) formats;--interfaces-onlydrops unconnected elements.
0.26.20 — 2026-06-13¶
Native TradeStudy element — weighted-criteria evaluation (GH #63)¶
TradeStudy(TRD-*) — a first-class, profile-independent weighted-criteria evaluation of design alternatives:criteria:(weight +maximize/minimize),alternatives:(optionalelement:ref), ascores:matrix, and optionalobjective:(Requirement) /decision:(ADR). (REQ-TRS-TYPE-019)- Computed scoring — the tool computes (never writes) min-max normalised scores per criterion (direction applied), weighted by the normalised criterion weight, a total per alternative, and a rank.
- Validation —
E869–E877(required fields,TRD-*id, criteria/weight/direction, empty/unnamed alternatives, unknown score keys, non-numeric score) andW061–W064(complete-without-decision, unresolved objective, incomplete matrix, unresolved alternative element — the last three draft-suppressed). - CLI —
trade-study [<TRD-id>] [--json]lists studies or prints one's ranked normalised scoring table. When the model containsTradeStudyelements this command takes precedence; the MagicGrid MoEtrade-study(REQ-TRS-MG-007) remains for models without them.template TradeStudyadded.
Code note: the spec drafted these as
E400–E408/W400–W403, which collide with the Diagram codes; reassigned toE869–E877/W061–W064and the spec §15.5 corrected.
0.26.19 — 2026-06-13¶
Native ReviewRecord element — thin, GitHub-pointer design (GH #71)¶
ReviewRecord(RR-*) — a first-class, baselined element capturing a formal review event (design / requirements / hazard / test-readiness review, inspection, walkthrough) and the model elements it covers. Deliberately thin: arecordedAt:URI points to the external review (e.g. a GitHub PR/review) so the discussion stays in the review tool while the model keeps the auditable traceability anchor and the coverage gate. (REQ-TRS-TYPE-018)- Validation —
E700(required fields),E701(RR-* id pattern),E702(status enum),E703(reviewType enum),E704(unresolvedreviews:entry),E705(item disposition enum),W700(closed review with an open action item), andW704(a non-draftRequirement covered by no review — dormant unless ReviewRecords exist; gateable with--deny W704). - CLI —
reviews [<qname>] [--open-only] [--json],review <RR-id> [--json],reviews --coverage [--json](requirement coverage cross-table), andtemplate ReviewRecord.
Code note: the spec drafted the coverage warning as
W701, already in use (Requirement asilLevel → verificationMethod); reassigned toW704and the spec §19 corrected.E700–E705/W700were free. TherecordedAt:field was added to §19 for the thin/pointer design.
0.26.18 — 2026-06-13¶
Budget expression language for CalculationDef (GH #67)¶
bodyLanguage: budget— aCalculationDefcan now carry a restricted arithmeticbody:(+ - * /, parentheses, number literals, andfeature_refoperands resolving to inline attributevalue:/default:). The tool evaluates it without a full KerML expression evaluator. A newevaluate:field names aConstraintDefbounding the result. (REQ-TRS-BUDGET-001)- Validation —
E866(evaluate:is not aConstraintDef),E867(budget syntax error),E868(operand resolves to no numeric attribute), andW060(budget value violates theevaluate:constraint — best-effort for<lhs> <op> <number>bounds; draft-suppressed; gateable withvalidate --deny W060).
Code note: the spec drafted the errors as
E800–E802, already in use (HazardousEvent); reassigned toE866–E868and the spec §22.2 corrected.W060was free.
0.26.17 — 2026-06-13¶
ASIL D / SIL 4 decomposition pair completeness (GH #69)¶
E865— non-independent decomposition — when an ASIL D (or SIL 4) requirement's integrity-bearingderivedChildrenare all strictly lower (a decomposition claim per ISO 26262-9 §5 / IEC 61508-2 §7.4.9), two sibling channels that name the same element in theirsatisfies:lists are flagged — decomposed channels must be architecturally independent. (REQ-TRS-SAFE-012)W860— incomplete decomposition — an ASIL D / SIL 4 parent with a single uniformly-lower child is flagged (a decomposition needs ≥2 independent channels). Draft-suppressed; gateable withvalidate --deny W860.decompositionKind:field onRequirement—independent|redundant|diverse, informational; surfaced in thesafety-casereport (text + JSON) and thetemplate Requirementskeleton.
Code note: the spec drafted the error as
E860, which is already in use (ConfirmationMeasure/CybersecurityGoal, 0.26.7); it is assignedE865and the spec §22.3 is corrected.
0.26.16 — 2026-06-13¶
State machines — behavior resolution + decision transitions (Phase E; completes SysMLv2-faithful HSM)¶
W079— unresolved behavior reference — a state'sentryAction/doAction/exitActionor a transition'seffect(a qualified-name string or{typedBy:}) that resolves to no model element is flagged.accept.payloadis intentionally not resolution-checked (payloads frequently name informal event labels). Draft-suppressed; gateable withvalidate --deny W079. (REQ-TRS-SM-008)- Decision transitions guaranteed legitimate — two or more guarded transitions from the same source (SysMLv2 §8.4.13.3 decision transitions) are valid branching and do not raise
W072;W072is reserved for same-source, same-payload transitions where none is guarded. Now covered by a regression check.
This completes the state-machine work: one canonical transition schema (§8.8.3) and a recursive, hierarchy/region-aware validator covering W070–W079 over flat, parallel (orthogonal) and composite (hierarchical) machines, faithful to SysMLv2 §7.18.
0.26.15 — 2026-06-13¶
State machines — hierarchy/composite + endpoint resolution (Phase D of SysMLv2-faithful HSM)¶
- Composite (hierarchical) state machines validated recursively — a substate that carries
typedBy:or an inlinesubStates:list is a composite state (SysMLv2 §7.18). The §22.1 checks now run recursively over the hierarchy: each level's substates are checked byW070–W074with a composite substate treated as a single node, and every inline-subStates:substate is recursed into and checked as its own region (findings name the enclosing region). AtypedBy:substate is a node only — the referencedStateDefis validated as its own element. (REQ-TRS-SM-006) W076— unresolved transition endpoint — a transitionsource/targetthat names no state anywhere in the machine's hierarchy and resolves to no model element by qualified name is flagged (typos, references to removed states). Draft-suppressed; gateable withvalidate --deny W076. (REQ-TRS-SM-007)- Unified engine — the flat (Phase B), parallel (Phase C) and composite paths now share one recursive walk (
check_state_node) over one transition extractor, so a composite substate no longer suppresses its enclosing level's dead/trap checks.
0.26.14 — 2026-06-13¶
State machines — parallel/orthogonal regions (Phase C of SysMLv2-faithful HSM)¶
- Parallel state machines validated per region — an
isParallel: trueStateDef/Stateis now understood as concurrent regions (its direct substates, each a composite region per SysMLv2 §7.18). The completeness checks run per region:W073/W074(initial cardinality) and the flatW070/W071/W072apply within each region, with findings naming the region. (REQ-TRS-SM-004) W077— cross-region transition — a transition connecting substates in two different regions of a parallel state is flagged (SysMLv2 forbids transitions between the substates of a parallel state). The scan covers the parallel parent's own transitions and each region's internal transitions. (REQ-TRS-SM-005)W078— parallel arity — anisParallel: truestate with fewer than two regions is flagged. (REQ-TRS-SM-005)- Both draft-suppressed and gateable (
validate --deny W077/W078). The flat (W070–W074) and parallel paths share one transition extractor and one region checker; non-parallel composite machines still deferW070/W071to the upcoming hierarchy phase.
0.26.13 — 2026-06-13¶
State machines — flat completeness W070–W074 (Phase B; closes GH #68)¶
W070–W074state-machine completeness — single-regionStateDef/Statemachines are now checked, over the canonical transition edge model (§8.8.3), for: dead states (W070— no incoming transition, notisInitial), trap states (W071— no outgoing transition, notisFinal), non-determinism (W072— two+ transitions from one source with the sameacceptpayload and no guard), missing initial (W073), and multiple initial (W074). All draft-suppressed; gateable withvalidate --deny W07x. (REQ-TRS-SM-003)- Scope — these flat checks apply only to non-
isParallel, non-composite machines (a composite substate carriestypedBy:, an inlinesubStates:, orisParallel:). Parallel/composite machines raise none of W070–W074; their region/hierarchy-aware treatment lands in later phases. The demo machines (FlightStates,ChargingSessionStates) are clean.
0.26.12 — 2026-06-13¶
State machines — schema consolidation (Phase A of SysMLv2-faithful HSM; GH #68)¶
- One canonical transition schema —
StateDef/Statetransitions are now defined by a single SysMLv2-faithful vocabulary (source/target/accept{payload,via}/guard/effect, §8.8.3), authored either nested under asubStates:entry (implicit source) or top-level (explicitsource:). A single transition extractor yields one edge model from both placements, so downstream state-machine checks never disagree. (REQ-TRS-SM-001) W075— deprecated transition keys — the legacy top-level spellingfrom:/to:/trigger:is not SysMLv2 vocabulary. It is still accepted as aliases (from≡source,to≡target,trigger≡accept.payload) so existing models keep parsing, but now raisesW075directing migration to the canonical keys. Draft-suppressed; gateable withvalidate --deny W075. The one model using the legacy form (model_mgChargingSessionStates) is migrated to canonical and given an explicitisInitialstate. (REQ-TRS-SM-002)
This is the foundation for the hierarchy/region-aware completeness checks (W070–W078) landing in later phases.
0.26.11 — 2026-06-13¶
New features (issue #70)¶
W080— Sequence diagram send/receive completeness — atype: Diagramelement withdiagramKind: Sequencewhosesubject:resolves to anActionDefnow raisesW080for everySendAction/AcceptActionreachable through the subject's sub-action tree (subActions:/steps:, recursing intoIfActionthen:/else:branches) that noedges:entry references. A message action is "covered" when anedges:entry'sref:equals its qualified name (<ActionDef>::<action>) or its bare name. The rule (previously advisory in §8.16.8.3, now normative per §22.4) is draft-suppressed and gateable withvalidate --deny W080. (REQ-TRS-DIAG-002)
0.26.10 — 2026-06-13¶
- GitHub Action fixed: the composite action now runs
syscribe -m <model-path> validate. Its newargs:input passes extra flags, for example--profile magicgridor--deny <code>. - Per-model CI flags: CI now validates each model with its own flags, so
model_mgis checked with--profile magicgrid. - Qualification fixtures: fixed E002/E015 errors in the qualification TestCases.
- Dependencies: replaced the deprecated
serde_yamlwithserde_yaml_ng.
0.26.9 — 2026-06-13¶
- Discoverability:
spec types,spec safety,spec fields,spec validationandtemplatenow showAsset(ASSET-*) andTestCase.securityTestMethod. Both shipped in 0.26.7 but weren't listed there (#56, #59). - Dependencies: bumped petgraph, quick-xml, taffy and toml.
0.26.8 — 2026-06-13¶
New features (issue #60)¶
derive:block for computed fields — any element's YAML frontmatter now accepts an optionalderive:mapping offieldName → formula. Formulas are evaluated top-to-bottom within an element; later entries may reference earlier ones viaself.<field>. Operators:sum,max,min,count,collectoverchildren/parentcollections;elements["Qualified::Name"].<field>for cross-element refs;+,-,*,/arithmetic;??null coalesce. Derived values appear under Derived Fields insyscribe show <qname>. Errors: E501 (parse error), E502 (unknown element ref). (REQ-TRS-DERIVE-001–005)
0.26.7 — 2026-06-13¶
New features and fixes (issues #54–#59)¶
AssumptionOfUse.appliesToacceptsCybersecurityGoal— AOUs can now cross-link toCybersecurityGoalelements for ISO/SAE 21434 §9 SEooC obligations. An explicit type check (E859) fires whenappliesTotargets an element that is not a SafetyGoal, CybersecurityGoal, Argument, or Requirement. (REQ-TRS-SEC-004)ConfirmationMeasure.confirmsacceptsCybersecurityGoal— TARA review CMs can now confirm CybersecurityGoal elements. Targeting an element of an invalid type raises E860. (REQ-TRS-SEC-005)derivedFromCybersecurityGoal:field onRequirement— renamed fromderivedFromSecurityGoal:for clarity; the old key is a serde alias for backward compatibility. E831 enforces resolution to aCybersecurityGoalelement. W804 message updated. (REQ-TRS-SEC-006)- W039 extended to CAL3 CybersecurityGoals — a CAL3
CybersecurityGoalwith no I2 (or I3)cybersecurity_assessmentConfirmationMeasurenow triggers W039, per ISO/SAE 21434 §15.9. The existing CAL4→I3 check is unchanged. (REQ-TRS-SEC-007) securityTestMethod:field onTestCase— ISO/SAE 21434 §13 security-specific test methods (fuzz,penetration_test,security_regression,vulnerability_scan,threat_modeling). Invalid value → W809. (REQ-TRS-SEC-008)- Native
Assetelement type — first-class asset identification per ISO/SAE 21434 §15.3 with stableASSET-*IDs,cybersecurityProperties,assetOwner, andrelatedSafetyGoalfields.DamageScenario.assetslinks scenarios to identified assets. Validation: E861 (required fields), E862 (id pattern), E863 (invalid property), E864 (bad assets ref), W810 (unreferenced asset). (REQ-TRS-TYPE-017)
0.26.6 — 2026-06-13¶
New features (issues #48–#52)¶
fmea reportcommand — renders allFMEASheetentries as a Markdown table sorted by RPN descending.--fmea-sheet <id>restricts to one sheet;--jsonemits a JSON array. (REQ-TRS-RPT-001)fault-tree render <id>command — emits a Mermaidflowchart TDdiagram for a namedFaultTreeelement, showing gates and events with type labels and input edges. (REQ-TRS-RPT-001)list AssumptionOfUseSRAC-oriented output —list AssumptionOfUsenow shows anID | Name | Applies To | Statustable instead of the generic table.--jsonincludesappliesTo(array) andbody(string | null) for safety-manual pipeline automation. (REQ-TRS-OUT-015)lint-docscommand — scans external Markdown files or directories for stable-ID tokens (REQ-*,TC-*,ADR-*,FEAT-*,FM-*,FTE-*,AOU-*,SG-*,CM-*) that do not resolve to a known model element. Emits W099 per finding; exits non-zero for CI gating.--jsonflag for structured output. (REQ-TRS-LINT-001)safety-caseimplicit fold-in suppression — goals with at least one explicitArgumentinsupport:no longer show the duplicate implicitSafetyGoal → Requirement → TestCasechain alongside the explicit argument tree.--no-implicitsuppresses the fold-in for all goals regardless. (REQ-TRS-SAFE-011)safety-case[unknown] verdict footnote — when TestCase leaves have unknown verdicts and no results sidecar has been ingested, a one-line footnote(verdicts unknown — run syscribe ingest-results to populate)is appended. In JSON:"verdictsUnknown": trueat the top level. (REQ-TRS-SAFE-010)fmeaRef:/ftaRef:cross-reference fields —FaultTreeEventacceptsfmeaRef:pointing to the reconcilingFMEAEntry;FMEAEntryrows acceptftaRef:pointing to the correspondingFaultTreeEvent. Missing targets raise W926 / W927 respectively. Both fields are surfaced byrefs. (REQ-TRS-FMEA-003)
0.26.5 — 2026-06-13¶
Bug fix (issue #53)¶
- Fix #53A —
template AssumptionOfUsenow emits list-formappliesTo:. The template was showing scalarappliesTo: SG-PREFIX-001; multi-goal SRACs require list form. Template now emits the list variant so scaffolded files are immediately valid for multi-goal use. - Fix #53B —
spec validationnow lists ConfirmationMeasure codes (E847–E851, W038, W039) and FMEA E922. These codes were only discoverable viaspec safetyor by empirically triggering them. They now appear in thespec validationtable with their conditions. W039 description updated in all spec files to includesilLevel: 3/4alongsideasilLevel: D.
Also fixes qual CI failure for v0.26.4 (E011: TestCase gherkin blocks were missing in the two new test cases).
0.26.4 — 2026-06-13¶
Bug fixes (issues #45, #46, #47)¶
- Fix #45 — FMEA entry canonical field
fmeaSeverity:now accepted; unknown keys raise E922. The parser was readingseverity:while the spec and element schema documentedfmeaSeverity:. Both keys are now accepted (fmeaSeverity:canonical,severity:as a deprecated alias). Any key in anentries:row that is not in the recognised set raises error E922 (silent drops in a safety analysis are unacceptable). The template now emitsfmeaSeverity:. (REQ-TRS-FMEA-002) - Fix #46 — W903 RPN auto-compute now works when
rpn:is absent andfmeaSeverity:is used. The root cause was that the walker was readingseverity:for the S component; an entry written withfmeaSeverity:(the canonical key) producedS = None, disabling the auto-compute. Fixed by the same key-reading fix as #45. (REQ-TRS-FMEA-002) - Fix #47 — W039 now fires for
silLevel: 3andsilLevel: 4items. W039 was checking onlyasilLevel: D, ignoring the equivalent IEC 61508 integrity levels. W039 messages for SIL 3/4 items now reference IEC 61508-1 §8. (REQ-TRS-SAFE-009)
0.26.3 — 2026-06-13¶
New feature: list TestCase with config projection and multi-tag filtering¶
list TestCase now produces execution-oriented output tailored for CI test selection:
- Columns:
ID | Name | Level | Status | Verifies | Tagsinstead of the generic table. - JSON fields:
testLevel,verifies,tags,sourceFile,testFunctionsin--jsonoutput. --config <id>projection: filters to only test cases active in the given configuration (respectsappliesWhen:).- Repeated
--tag <t>(AND semantics):--tag integration --tag performancereturns only test cases that carry all listed tags. Enables fine-grained CI suite selection from a single command. (REQ-TRS-OUT-014,REQ-TRS-TAG-002)
0.26.2 — 2026-06-13¶
Diagnostic improvements¶
- W042 message clarity — W042 now says "qualified-name segment 'X'" instead of "name 'X'", removing the ambiguity with the free-text
name:label field. - W042 on FeatureDef cross-references E209 — When W042 fires on a
FeatureDefwith a hyphenated name, the finding now appends "a hyphen in a feature name causes E209 when the feature appears in anappliesWhenexpression", surfacing the downstream consequence where the rename is cheapest.
0.26.1 — 2026-06-13¶
Bug fixes¶
- Fix #43 —
templateoutput failed its own validation. Everysyscribe template <Type>command was still emitting the removedtitle:field instead ofname:, causing freshly scaffolded elements to immediately fail with E025. All 23 templates updated (including TARASheet inline entry rows). - Fix #44 — W042 false positives on id-identified filenames. W042 ("not a SysMLv2 basic name") was firing on elements whose filename follows the
<id>-Description.mdconvention (e.g.AOU-KERNEL-001-AmpOutsidePerimeter.mdwithid: AOU-KERNEL-001). The exemption now covers any element whose declaredid:is a stable id and whose filename stem is not the element's SysMLname:label. Name-identified types that also carry a stable id (FeatureDef) remain W042-checked as before.
0.26.0 — 2026-06-12¶
name is the universal label; title removed (E024 retired, E025 generalised)¶
name is now the single human-readable label on every element type — Requirement, TestCase, ADR, PartDef, Package, FeatureDef, the safety/security types, all of them. The earlier identity-class split (title for id-identified types, name for name-identified types — introduced in 0.21.0) is removed:
namelabels all types (≈ SysMLv2declaredName). For id-identified types (identity is a stableid≈declaredShortName)nameis required free prose — spaces and punctuation are allowed andW042does not apply. For name-identified typesnameis also the identity segment, so the basic-name rule (W042) still applies.titleis removed. Declaringtitle:on any element is now errorE025("rename it toname"). ErrorE024(formerlyname:on an id-identified type) is retired — aRequirementcarryingid+namevalidates clean. Every type that previously requiredtitlenow requiresname(same error codes).
Migration renamed title: → name: across all bundled models (model, model_auto, model_mg, model_sil) and the qual model + fixtures, including nested FMEA/TARA table-row labels. (REQ-TRS-NAME-002.)
Breaking: a model that carried a title: field now fails validation (E025) — rename it to name.
syscribe --version¶
syscribe --version (also -V, or the version subcommand) prints syscribe <semver> to stdout and exits 0, with no model directory required. (REQ-TRS-CLI-007.)
clap-based top-level router; unknown commands rejected¶
The top-level command line is now parsed by a clap router whose subcommand registry is derived from the single man-page list, so an unknown command is rejected with a clear error (error: unrecognized subcommand '<name>') and a non-zero exit — from any directory, before model resolution. Per-command flags pass through to their handlers unchanged, and man-page help (--help/-h/help <cmd>), --version, --agent-instructions, spec, and model-resolution are unchanged. The explicit report command now runs the default full validation report. (REQ-TRS-CLI-008.)
CI gates on validation of every model¶
The qualification workflow now fails the build if any bundled model (model, model_auto, model_mg, model_sil, qual) has a validation error, and its path triggers were widened to include model*/** so model-only edits are validated.
Suite at 204 test cases, all passing.
0.25.0 — 2026-06-12¶
MagicGrid visualisation — grid matrix, magicgrid --svg (word-wrapped), matrix grids¶
The MagicGrid reports now look like the grid:
magicgridopens with the recognisable 3×4 grid matrix (rowsB/W/S× the four pillars) of per-cell counts — the B3 System of Interest marked◆, empty cells marked·, and anN/12 cells populatedsummary — above the per-cell detail. The count matches--auditreadiness. (REQ-TRS-MG-015.)magicgrid --svg [-o <file>]renders the grid as a self-contained SVG — colour-banded rows, the four pillar columns, each cell's elements, the SoI highlighted, empty cells de-emphasised — laid out with the sharedtaffylayout engine and the diagram theme + font metrics for visual consistency with the other diagrams. Long cell labels are word-wrapped to the cell width (metrics-based, no truncation) and cells/rows stretch to fit. It is a drop-inDiagramcompanion (svgMode: companion), so it renders in the browser like any other diagram. (REQ-TRS-MG-016.)- The companion matrices —
matrix --allocations(sources × targets ✓ matrix with a gap rollup) andtrade-study(Configuration × MoE scored matrix with a winner) — are confirmed as 2-D grids and regression-locked. (REQ-TRS-MG-017.)
Verified by TC-TRS-MG-015/016/017; qual suite 189/189.
0.24.0 — 2026-06-12¶
--agent-instructions magicgrid — teach an LLM to model with MagicGrid¶
syscribe --agent-instructions now accepts an optional topic. With no topic it prints the general model-authoring prompt (unchanged); syscribe --agent-instructions magicgrid prints a dedicated, self-contained MagicGrid modeling prompt that teaches an LLM the method and how to express it with this tool — the mg_ overlay fields, the [profiles.magicgrid] gate, the cell-by-cell authoring workflow (stakeholder needs → use cases → system context → MoEs → system requirements → functional analysis → logical/physical architecture → allocations → configurations → trade study), the magicgrid / magicgrid --audit / trade-study / matrix --allocations commands, and the MG### codes with how to clear each. An unknown topic exits non-zero naming the available topics. (REQ-TRS-CLI-006, verified by TC-TRS-CLI-006.)
Built-in SI units, ISQ quantity types, and dimensional consistency (W044)¶
A second open/curated recognition tier (on top of the closed ScalarValues/Base of 0.22.0): the common ISQ quantity-value types (MassValue, ForceValue, EnergyValue, VoltageValue, …) and SI units (the seven base units + common derived units) are now recognised — by full name or symbol (SI::kilogram ≡ SI::kg ≡ bare kg). Recognised members resolve cleanly (no W404); unlike the closed packages, an unrecognised ISQ/SI member is lenient (never W043), and unit: stays fully permissive (USD, kWh, percent accepted). (REQ-TRS-LIB-002.)
When an element/feature declares both a recognised quantity type (typedBy: ISQ::…) and a recognised unit (unit: SI::…), the tool now checks their physical dimensions agree over the seven SI base quantities and raises new warning W044 on a mismatch — e.g. typedBy: ISQ::MassValue with unit: SI::metre. Dimensions are prefix-independent; the check is lenient when either side is unrecognised. The engine is a small in-tree dimension table (no external units crate — uom/dimensioned are type-level, rink-core is heavy with non-SysML names). (REQ-TRS-LIB-003, verified by TC-TRS-LIB-002/TC-TRS-LIB-003; qual suite 186/186.)
0.23.0 — 2026-06-12¶
Allocation: two forms over one edge model (allocatedTo + derived allocatedFrom)¶
Allocation can now be authored two ways, sharing a single unified edge model (§12.9):
allocatedTo:on the source element — the OSLC-canonical, lightweight default. The source holdsallocatedTo: <target>andallocatedFromis derived, never authored — same link direction assatisfies/verifies/refines. The target gains a computedallocatedFromreverse index, surfaced inshow(a## Allocated fromsection),links, and the exportcomputedblock.- The standalone
Allocationelement (naming both endpoints) stays first-class for documented allocations whose body carries rationale — e.g. the freedom-from-interference / deployment allocations of §12.6. No forced migration; existing models are unchanged.
A single extractor now feeds MG041, MG081, matrix --allocations, and the derived index, so the matrix and the MagicGrid gate can never disagree — and a features: entry is an edge when it carries both allocatedFrom and allocatedTo, with or without a per-entry type: Allocation (the inconsistency that previously produced false MG041/MG081). Declaring the same edge in both forms is redundant — new warning W503. (REQ-TRS-ALLOC-001, verified by TC-TRS-ALLOC-001; qual suite 183/183. The model_mg/ example's 10 simple allocations were converted to the allocatedTo form.)
0.22.0 — 2026-06-12¶
magicgrid --audit — MagicGrid findings, readiness, and a verdict¶
A new audit mode on the magicgrid command runs the gated MagicGrid validation and rolls it into one dashboard: error/warning counts, a per-code table grouped by category (Grid · Refines · Context · SoI · MoE · MoP · Layer · Variant · Coverage), the individual error and warning lines, a readiness summary (grid completeness, the System of Interest, MoE/MoP/Configuration counts), and a PASS/FAIL verdict (exit 0/2, FAIL when the gate would fail). magicgrid --audit --json emits the structured rollup for CI. (REQ-TRS-MG-013.)
MagicGrid completeness / gap-analysis checks (MG080–MG083)¶
The MagicGrid gate gains the coverage half of the method's validation — advisory warnings (draft-suppressed, gateable, promotable) surfaced by the audit:
MG080— a B1 stakeholder need neither refined by a use case nor derived into a system requirement (orphan need).MG081— a W2 functional-analysis element allocated to no logical (W3) subsystem.MG082— the model declares an external actor but nomg_soiSystem of Interest.MG083— a Measure of Effectiveness with no Measurement of Performance refining it.
(REQ-TRS-MG-014, verified by TC-TRS-MG-013/TC-TRS-MG-014; qual suite 181/181. The model_mg/ example was extended with W2→W3 functional allocations and a fourth MoP so it audits clean.)
Built-in standard-library type recognition (W043)¶
The auto-imported standard-library packages with fully-known membership — ScalarValues (Integer, Real, Natural, Boolean, String) and Base (Anything, DataValue) — are now recognised: a type reference to a known member (typedBy: ScalarValues::Real, supertype: Base::DataValue, an operation returnType/parameter typedBy, a feature parameters[].type) resolves cleanly with no W404. A reference into one of these packages to a member it does not declare (e.g. ScalarValues::Flota) is flagged as a likely typo with new warning W043, listing the package's known members — across every type-reference context (this previously passed silently). Import-only packages (SI, ISQ, …) are not enumerated and stay lenient (never W043). (REQ-TRS-LIB-001, verified by TC-TRS-LIB-001.)
0.21.1 — 2026-06-12¶
trade-study — ambiguous parameter binding is now unevaluable¶
The trade-study MoE-variable resolver no longer silently picks one of several parameterBindings keys that share a final ./:: segment. An exact key still wins; the final-segment convenience match now resolves only when exactly one binding matches — a bare token matching two or more bindings is ambiguous and the cell is reported n/a (excluded from that column's weight normalisation), rather than guessing. (REQ-TRS-MG-012, verified by TC-TRS-MG-012.)
0.21.0 — 2026-06-12¶
MagicGrid methodology support (opt-in overlay)¶
The MagicGrid MBSE method (Morkevičius/Aleksandravičienė) is now expressible as a pure overlay on the SysMLv2 model: all MagicGrid-specific data rides on custom_fields: with an mg_ prefix, and every MagicGrid-specific validation is gated behind a [profiles.magicgrid] profile (magicgrid = true) — non-MagicGrid models are entirely unaffected.
- Grid classification & report —
mg_cellplaces elements on the B/W/S × Requirements/ Behavior/Structure/Parameters grid (MG020/MG021); the newmagicgridcommand renders the grid, flags empty cells, and identifies the System of Interest (mg_soi, B3). - Traceability —
refines:is a base-format link on use cases and behavioral defs (ActionDef/StateDef) withE316(bad target),W307(a non-draft use case with no refinement, draft-suppressed) and a computedrefinedByindex. - System Context — use-case
actors:are gate-validated (MG010–MG013) with anmg_externalboundary marker and themg_soiSystem-of-Interest marker (MG060–MG062). - Measures — Measures of Effectiveness (
mg_moe/mg_moe_*,MG030–MG033) and Measurements of Performance (mg_mop/mg_mop_refines,MG050–MG052) with amopRefinedByindex linking MoPs to the MoEs they refine. - Solution architecture —
mg_layerlogical/physical layering (MG040–MG042) and the newmatrix --allocationsview (function→structure and logical→physical, with a gap rollup). - Trade study — the new
trade-studycommand scores and ranksConfigurations against the MoEs (weighted, threshold-aware). AConfigurationmarkedmg_variant: trueis a parametric variant that may omitfeatureModel:(MG070), so trade studies compare parameter-only alternatives without a feature model. - DX — an unresolved cross-reference that wrongly includes the model-root package name now carries a corrective hint (
REQ-TRS-XREF-006); the root package name is documented as excluded from qualified names.
Requirements REQ-TRS-MG-001…011 and REQ-TRS-XREF-006, verified by TC-TRS-MG-001…011 and TC-TRS-XREF-006. A complete worked example lives in model_mg/ (an EV DC fast-charging station). See the MagicGrid guide.
Author appliesWhen from the CLI (applies-when)¶
A new applies-when <element> --set "<expr>" | --clear [--dry-run] command adds, replaces, or removes an element's appliesWhen: gate. The element resolves by qualified name or stable id; each operand resolves to a FeatureDef by its FEAT-* id or its qualified name (interchangeably). The edit is refused without writing if the expression is malformed/unresolved (E209) or the placement is forbidden (E228); only the appliesWhen: key is changed (the rest of the file is byte-preserved). After a successful --set, the feature model is validated for bad configurations (feature-check --deep: void E223, dead E224, invalid configurations E225) and the command exits non-zero if any are found. (REQ-TRS-AW-001.)
With no flag, applies-when <element> is a read-only display of the element's own and effective gate — the latter including any condition inherited from an ancestor package (transitive package conditioning), or "always applies" when gated nowhere; --json emits {element, own, effective, inheritedFrom}. (REQ-TRS-AW-002.)
One label field per element, fixed by identity class (E024 / E025)¶
Every element now carries exactly one human-readable label field, determined by how it is identified — never both:
- Id-identified types (
Requirement,TestCase,TestPlan,Configuration,ADR, and the safety/security types — identity is a stableid) label viatitle. Aname:on one of these is now errorE024. - Name-identified types (all SysML structural types,
Package,Diagram,FeatureDef— identity is thename/path) label vianame. Atitle:on one of these is now errorE025.
FeatureDef stays name-labelled; the id and label axes are independent. This closes the gap left by W042 (which constrained only the characters of a name, not which label field applies); previously elements could silently drift into carrying both name and title. The bundled models and qual model were migrated to one label field each. (REQ-TRS-NAME-002.)
Mandatory feature ids (FEAT-*)¶
The FEAT-* stable id introduced in 0.20.0 is now mandatory on every FeatureDef — a feature with no id is error E201 (the shared PLE required-field error). Features stay name-identified (label/qname = name); the id is the stable reference. All bundled and fixture features were migrated to carry an id. (REQ-TRS-ID-006.) Unlike the other stable-id types, a feature id need not end in a number — FEAT-ABS, FEAT-QUADROTOR and FEAT-ABS-001 are all valid (pattern ^FEAT(-[A-Z0-9]{2,12})+$); the E023 digit-cap applies only to a numeric trailing segment.
Breaking: (1) a model that carried both name and title (or the wrong one for its type) now fails validation — remove the stray field (title for id-identified types, name for everything else); (2) a FeatureDef with no FEAT-* id now fails (E201) — add one.
Suite at 166 test cases, all passing.
0.20.0 — 2026-06-11¶
Feature stable IDs (FEAT-*)¶
A FeatureDef may now carry an optional stable id (FEAT-ABS-001) as a short-name alias, and a feature can be referenced by that id or by its qualified name — interchangeably — in appliesWhen: and in a Configuration's features: keys (they canonicalise to one key space, so appliesWhen: FEAT-ABS-001 gates identically to appliesWhen: Features::Anti_Lock). A hyphenated feature name reference still errors E209 — only the stable-id form may contain hyphens. (REQ-TRS-ID-006.)
Per-element-type tool-qualification requirements¶
New REQ-TRS-TYPE-* family: every element type now has a dedicated recognition/validation requirement + test, filling the gap for the SysML structural types (ConstraintDef/Constraint, CalculationDef/Calculation, Concern, Case/AnalysisCase/VerificationCase/UseCase, AllocationDef, SuccessionDef, RenderingDef, State/ExhibitState, Metadata, BindingConnector, LibraryPackage/Namespace, Dependency, …).
Fix¶
show/listpreviously mislabelled 9 recognised element types (ConcernDef,Concern,CaseDef,EventOccurrenceDef/EventOccurrence,SuccessionDef,RenderingDef,ExhibitState,BindingConnector) as "Other" — thetype_labelfallthrough now names them.
Suite at 163 test cases, all passing.
0.19.0 — 2026-06-11¶
Basic-name validation now covers package/directory names (GH #42)¶
W042 (SysMLv2 basic-name check) previously covered element names and _index.md-backed packages. It now also flags directories without an _index.md — their namespace segment is still a referenceable qualified-name prefix, so it must be a basic name too (e.g. a Brake-System/ directory → rename to Brake_System / BrakeSystem). Stable-id elements (REQ-, TC-, …) remain exempt; only the directories that contain them are checked.
Suite at 146 test cases, all passing.
0.18.0 — 2026-06-11¶
SysMLv2 basic-name validation (GH #42)¶
Element names now follow the SysMLv2 basic-name grammar [A-Za-z_][A-Za-z0-9_]*. Previously a hyphenated name (e.g. a FeatureDef Anti-Lock) parsed as a file/qname but failed E209 when referenced in appliesWhen: — because a hyphen is the subtraction operator in the expression grammar.
- New warning
W042: an element's own name that is not a basic name (and not a stable id, which legitimately contains-) — with a rename hint (Anti-Lock→Anti_Lock/AntiLock). Advisory and gateable, so existing models have a migration path. - The
appliesWhenparse error for-now points at the basic-name convention.
(SysMLv2 unrestricted quoted names are not supported; the convention is basic names.) Requirement-first: REQ-TRS-NAME-001 + TC-TRS-NAME-001. Suite at 146 test cases, all passing.
Internal¶
- The release workflow now uploads assets via the
ghCLI with retry (replacing a Node20 action that intermittently failed the Windows upload under matrix contention).
0.17.0 — 2026-06-10¶
Configurable stable-ID suffix width (GH #41)¶
Stable IDs (REQ-, TC-, TP-, ADR-, and all safety/security ids) previously ended in exactly 3 digits. They now accept a 3–8 digit numeric suffix by default, and the maximum is configurable:
# .syscribe.toml
[ids]
max_digits = 8 # default 8; raise (e.g. 12) or lower (e.g. 4). Minimum stays 3.
- Existing 3-digit IDs are unchanged; up to 8 digits works out of the box.
- A suffix longer than the cap is the new error
E023; shorter than 3 is stillE006. - A reference to an over-long ID still resolves — the defect surfaces on the ID-bearing element, not as a dangling reference.
Requirement-first: REQ-TRS-ID-005 + TC-TRS-ID-005. Suite at 145 test cases, all passing.
0.16.2 — 2026-06-10¶
Docs site¶
- Aligned the §9 table-of-contents anchors in the published format specification so all TOC links resolve on the site; the fix (em-dash → colon in three headings) keeps the same anchors working on GitHub's renderer too.
mkdocs build --strictis clean.
0.16.1 — 2026-06-10¶
Docs site¶
- The canonical format specification (
spec/markdown-sysml-format.md) is now published on the documentation site under Format ▸ Full Specification (a symlink — single source of truth). - Fixed two broken links on the CLI reference page that pointed outside the docs tree;
mkdocs build --strictis clean again.
0.16.0 — 2026-06-10¶
TestPlan documentation + template TestPlan¶
syscribe template TestPlan— emits a ready-to-fill TestPlan frontmatter skeleton (TP-* id, title, status, scope, atestCasesmember, withconfigurations/demonstrates/selectionshown as commented optional fields);TestPlanis now listed among thetemplatecommand's known native types.- Documentation — the
TestPlanelement (0.13.0/0.15.0) andcustom_fields(0.14.0) are now fully documented across the format spec (§8.12.6), the embeddedprompts/specandcreate-modelguides, the site format/validation references, and a new Test Plans model-guide page.
Suite at 144 test cases, all passing.
0.15.0 — 2026-06-10¶
audit --plan — scoped readiness verdict (GH #40)¶
Completes the --plan lens (deferred from #38): audit --plan TP-X scopes the readiness verdict to a TestPlan. Validation runs over the whole model — so a reference escaping the plan subset (a requirement's breakdownAdr ADR, a member's out-of-scope verifies: target) resolves and is never mistaken for a defect — and only findings on the plan's in-scope elements (in-scope requirements ∪ member TestCases ∪ their satisfying architecture) count toward the verdict. The dashboard sections are scoped to the plan but resolve references against the full model. Composes with --config; exits 1 on an unknown plan id; dormant-safe.
--plan is now available on matrix, verification-depth and audit. Suite at 144 test cases, all passing.
0.14.0 — 2026-06-10¶
User-defined custom fields (GH #39)¶
A dedicated custom_fields: frontmatter map lets you attach arbitrary user data to any element — making it intentional and addressable instead of being silently swallowed by the unknown-key catch-all.
- Schema —
custom_fields:is a flatstring → scalar | list-of-scalarsmap, accepted on every element type, serialised in stable sorted order. - Validation —
W041shape-check: a value that is not a scalar or a list of scalars (e.g. a nested map) is flagged, naming the key. Freeform keys, no registration. - Query —
--where custom.<key>onls/find/list: exact (=), regex/substring (=~), list-membership (~=), and bare presence; composes (AND) with the type/tag/status filters. - Rendering — a
## Custom Fieldssection in CLIshow, and a read-only key/value table in the web detail panel (never editable via the element editor).
Requirement-first: REQ-TRS-CFLD-001..003, TC-TRS-CFLD-001..003 with fixtures. Suite at 144 test cases, all passing.
0.13.0 — 2026-06-10¶
Native TestPlan element (GH #38)¶
A first-class TestPlan (type: TestPlan, stable TP-* id) groups TestCases into the unit a team executes and reports against. TestCases stay reusable atoms; a plan is a curated, per-product artifact.
- Schema & validation —
scope(recommended vocab + free-form),configurations:(scalar/list ofConfigurations, or absent = config-agnostic),demonstrates:(optional safety-case evidence link),testCases:+ an additiveselection:query (testLevels/domains/tags). New rulesE600–E606andW610–W616: malformed id, unresolvable member/config/demonstrates target, bad selection levels/domains, non-recommended scope, escaping member, empty plan, pinned-draft member, demonstration gap, results-gated failing member, duplicate(configurations, scope).W614honours goal-closure — demonstrating a parent goal whose leaves are tested does not false-fire (cf. GH #37). testplancommand —testplanlists every plan (scope, configs, effective-TC count, coverage %, verdict);testplan TP-Xshows members (with escaping flags), in-scope requirements, a per-config coverage grid and a rolled-up verdict (pass|fail|incomplete|empty);--jsonon both. Coverage and verdict reuse the existingmatrix/results machinery.--plan TP-Xlens — onmatrixandverification-depth: restricts rows to the plan's in-scope requirements and the TestCase universe to its members; composes with--config. (audit --planis deferred — GH #40.)matrix --confignow reduces the grid to the selected Configuration's column.
Requirement-first: REQ-TRS-PLAN-001..006, TC-TRS-PLAN-001..006 with fixtures covering every code. Suite at 141 test cases, all passing.
0.12.1 — 2026-06-09¶
Fixes¶
auditno longer mis-lists a parent requirement as unsatisfied/unverified (GH #37). A parent (aRequirementwithderivedChildren) is satisfied and verified only transitively through its leaves and can never be satisfied directly (§12.4 /E312forbid it appearing in anysatisfies:list). The orphan section nonetheless flagged every such parent underunsatisfiedRequirements(and structurally underunverifiedRequirements), disagreeing withvalidate, which already suppresses parents in W002/W300/W306. The orphan loop now skips parents from both sets; genuine gaps still surface on the leaf requirements. Covered by a new parent-rollup fixture underTC-TRS-OUT-013.
0.12.0 — 2026-06-09¶
Configuration lens on the analysis & audit commands¶
auditnow honours--config(GH #35). The dashboard was always computed over the 150% superset, so a requirement gated out of a variant still tripped the verdict.audit --config <CONF|features>now projects the entire dashboard — verdict,W306, orphan sets and coverage — onto the elements active in that Configuration, exactly likevalidate --config. Newaudit --all-configsaudits every storedConfiguration's variant and exits non-zero if any fails (the product-line CI gate).audit --configandvalidate --confignow agree (GH #36). ATestCasethat survives the projection but whoseverifies:target was projected out was mis-counted as a dangling error-severity finding. The verdict now uses the projection-awarevalidate_projectedpath, and dangling detection considers only the activeTestCases while resolving their references against the full model — so the two commands report the same error count for a variant.- The
--configlens extends to the other read-only safety/security commands.metrics,cyber-risk,co-analysis,verification-depthandsafety-caseeach accept--config <C>and compute their report over the projected active subset (dormant when no feature model; unresolvable--configexits1).
Requirement-first: REQ-TRS-OUT-013 (audit lens + #36 agreement) and new REQ-TRS-PROJ-006 (lens on the analysis commands), with TC-TRS-OUT-013 / TC-TRS-PROJ-006 harnesses and fixtures. Suite at 135 test cases, all passing.
0.11.1 — 2026-06-09¶
Fixes¶
W306no longer flags a satisfied-via-leaf parent requirement (GH #34). The "unsatisfied" sub-condition demanded a direct satisfier, contradictingE312(a parent requirement may not appear in asatisfies:list — it is satisfied transitively through its leaves). High-integrity parents were therefore permanently flagged andauditcould never PASS on a hierarchical model. The sub-condition now applies to leaf requirements only (mirroring the existing W002 parent suppression); genuine gaps still surface on the unsatisfied leaf, andstatus: draft/ active-in-no-config still apply to parents. Covered by a new satisfied-via-leaf parent fixture inTC-TRS-TRACE-010.
0.11.0 — 2026-06-09¶
A large safety/security + tooling release. Every feature is requirement-first (a REQ-TRS-* + TC-TRS-* with fixtures); the tool-qualification suite grew to 134 test cases, all passing.
Safety & security analysis (ISO 26262 / IEC 61508 / ISO/SAE 21434)¶
- Safety ↔ security co-engineering —
hazardReflinksDamageScenario/ThreatScenarioto theHazardousEvent/SafetyGoalthey endanger (E844);W030flags a safety-tagged damage scenario with no link; newco-analysiscommand shows which cyber threats can violate each safety goal. - Cybersecurity risk determination — computed risk (severity × feasibility) per
ThreatScenario,riskTreatment/residualRiskfields,W031(untreated high/critical threat) andW032(CAL below risk), newcyber-riskcommand. - Quantitative HW metrics —
diagnosticCoverage/latentDiagnosticCoverage, SPFM/LFM/PMHF computed perSafetyGoalvs ASIL/SIL target (W033), newmetricscommand. First-order FMEDA approximation. - Freedom from interference —
W034flags differing-integrity elements sharing an allocation target without anffiRationale. - Attack trees — new
AttackTree/AttackTreeGate/AttackSteptypes with weakest-link feasibility roll-up (AND=min, OR=max) reconciled against the linked threat (W035). - Confirmation measures & DIA —
responsibilityfield (W038),ConfirmationMeasuretype +W039(missing independent assessment for ASIL-D/CAL4). - GSN safety case —
Argument/AssumptionOfUsetypes and asafety-casecommand rendering the goal → argument → evidence tree. - Unsatisfied safety mechanism
W306; WCET evidenceW029+list --has-wcet.
Reports, queries & CLI¶
- New
audit(safety-readiness dashboard with PASS/FAIL),verification-depth(independence report +--min-levelsgate),connectivity(element-rooted subgraph as text/DOT/JSON),extref(lookup by external reference). list/matrixgain--status/--sil/--has-wcet/--gaps-onlyfilters, coverage-% footers, JSON, and executed-evidence glyphs/annotations inmatrix/tracefrom ingested results.- Named severity profiles —
.syscribe.toml[profiles.*](SIL/ASIL-scopable code promotion) viavalidate --profile/audit --profile. extRefcommon field (external-tool references) +W028duplicate check.- Model-root auto-discovery —
.syscribe.tomlwalk-up;-mstays primary (backward-compatible). - Detailed per-command help —
syscribe help <command>andsyscribe <command> --help/-h(man-page style for every command), plussyscribe helpindex.
Format & correctness¶
bindingTimeon feature parameters (compile/load/runtime) with ordering (E229) and value (E230) checks,W027, andW017suppression.typedBycycle/self-reference now detected (E107) — previously silently accepted.- Ports & Interfaces modeling guide (SysML v2) added to the spec,
syscribe spec types, and the LLM prompt. - Discoverability: the full safety/security field & type set is now documented in
syscribe spec fields/types/safety, and all new commands/types are in the--agent-instructionsLLM prompt.
0.10.0 — 2026-06-08¶
Model-root auto-discovery (REQ-TRS-CLI-004)¶
- With no
-m/--modelflag and noSYSCRIBE_MODEL, the tool now walks up from the current working directory to the nearest ancestor containing a.syscribe.tomland uses that directory as the model root — run any command from anywhere inside the model tree (thegit/cargoergonomics). Full resolution order:--model→SYSCRIBE_MODEL→ walk-up to.syscribe.toml→ the literalmodel/default. - The marker is the existing config file (
repo_root/[matchers]/[remote]); an empty.syscribe.tomlis a valid root marker. It is a tooling locator only — it never affects qualified-name resolution or the implicit root namespace. - Fully backward-compatible: the flag, env var, and
model/default behave exactly as before; a tree with no marker falls straight through to the default.
Tests¶
REQ-TRS-CLI-004+TC-TRS-CLI-004(discovery from a subdirectory, explicit-moverride, explicit-mon a model with no marker, and fallback-with-miss). Tool-qualification suite 115 → 116 test cases, all passing.
0.9.0 — 2026-06-08¶
Feature-parameter binding time (REQ-TRS-PARAM-004)¶
- A
FeatureDefparameter may declare an optionalbindingTime:— when its value is resolved, from the product-line-engineering triad ordered earliest→latest:compile(build / codegen) ·load(deployment / startup) ·runtime(live). Orthogonal toisFixed:/value:(a value fixed in the model); an absent binding time is unspecified and opts out of the checks. E230— an unrecognisedbindingTime:value (validate).E229— a parameter computed from aderivedFrom/bindTosource it depends on cannot bind earlier than that source (feature-check; checked only when both ends declare a binding time).W027— aConfigurationthat binds aruntimeparameter (resolved by the running system, not at configuration time); for the same reasonW017is suppressed for an unboundruntimeparameter. Thefeature/featurescards showparam [bindingTime].
External references on all elements (REQ-TRS-EXTREF-001/002)¶
- New optional common field
extRef(string or list) on every element type — marks an element as the representation of an artifact in another tool (a requirement in DOORS Next, an element in a SysML tool, a ticket). Opaque values (a URI or atool:idtoken); syntax unconstrained; never a model cross-reference target. - New
extref <ref> [--json]command looks up the element(s) carrying a reference (exact match, returns all matches, exits non-zero on a miss).W028warns when the sameextRefis declared by two or more elements.showsurfaces the field andspec fieldslists it.
Tests¶
- Requirement-first:
REQ-TRS-PARAM-004+REQ-TRS-EXTREF-001/002withTC-TRS-PARAM-004andTC-TRS-EXTREF-001/002and fixtures. Tool-qualification suite 113 → 115 test cases, all passing.
0.8.1 — 2026-06-08¶
Fixes (GH #14 re-open)¶
- Parameter
range:is now enforced byfeature-check, not onlyvalidate. The binding rules (E203–E206/E222/W017) were extracted into a shared check so a product line validated holistically (feature-check) gets the same range/binding enforcement — an out-of-range binding (e.g.99againstrange: "1..=8") now firesE205underfeature-check. - A
parameterConstraintsexpression that used the legacy::-member form (Features::F::param) was silently dropped (no error, no evaluation). It now raisesE213with a hint to use the canonical dotted formFeatures::F.param— a declared constraint can never silently no-op. - Hardened the constraint arithmetic tokenizer to reject unexpected characters (previously swallowed, so a stray operator could yield a spurious value).
Tests¶
- New
feature_modelunit tests for the constraint evaluator: all comparison operators, arithmetic precedence/parentheses/unary-minus, unresolved/malformed → no-match, andrange:parsing (incl...=). Model unit tests 33 → 40.
0.8.0 — 2026-06-07¶
Typed feature-parameter constraints enforced (closes #14)¶
E221—feature-checknow evaluatesparameterConstraintsexpressions (numeric comparison== != >= <= > <over+ - * /arithmetic of literals and parameter references) against everyConfigurationwhoseappliesWhen:predicate holds; a violation is an error.W025— the same violation when the constraint declaresseverity: warning. Both gateable with--deny.- Compound
appliesWhen:onparameterConstraintsis now boolean-parsed (and/or/not), fixing a spuriousW014. range:now accepts the inclusive form"min..=max"as well as"min..max", soE205/E202actually fire (a1..=8range was previously dropped silently).- Schema: a feature-parameter reference is now the canonical dotted form
Features::Feature.param(a single.before the parameter member) everywhere —parameterBindings:keys,parameterConstraintsexpressions, andbindTo:targets. The legacy all-::member form is rejected (E222). Existing fixtures and the demo model were migrated.
Transitive package appliesWhen (REQ-TRS-VAR-006)¶
- A
Package(_index.md) may declareappliesWhen:to gate its whole subtree — enabling/disabling a cohesive variant of requirements + architecture + tests with one declaration. An element's effective condition is its ownappliesWhen:, else the nearest ancestor package's, else always-active; conditions are never combined. E228— invalid placement (at most one declaration per root-to-leaf path): a nested declaration, orappliesWhen:on aFeatureDef/Configuration, a package whose subtree contains one, or the model root.W026— a gated package with an empty subtree.- All consumers honour the effective condition:
--configprojection, escaping refs (E226/W019),matrix,why-active(now shows "inherited from package"), feature-card gates,list --feature, andfeature-check --deepedges.
Tests¶
- The
appliesWhenboolean grammar is now covered by an exhaustive oracle (3000 random expression ASTs evaluated across all assignments), precedence-vs-parentheses checks, and operator-substring/whitespace/double-negation edge cases.
0.7.0 — 2026-06-07¶
Feature discoverability commands¶
Five read-only commands for navigating a product line, plus an orphan-feature check:
features [--json]— the feature model as a tree: eachFeatureDef'sgroupKind,requires/excludes, parameters, and a "selected in N/M configs" rollup.feature <qname> [--json]— one feature's card: doc, group, constraints, parameters, theConfigurations that select it, and every element it gates (whoseappliesWhen:names it).matrix --features— a Feature × Configuration grid (which feature ships in which product), complementing the Requirement × Configuration view.list <type> --feature <F>— restrict a listing to elements whoseappliesWhen:namesF(orthogonal to--tag/--config).why-active <element> --config <C>— explain a projection: the element'sappliesWhen:, the config's relevant selections, and aVerdict:ofactive/inactive/always active.W024—feature-checknow flags an orphan feature (referenced by noappliesWhen:and selected by noConfiguration); gate withfeature-check --deny W024. Never emitted by basevalidate.
Feature-model schema: mandatory: membership (ADR-FM-003)¶
A new optional boolean mandatory: on FeatureDef separates membership (relative to the parent) from grouping (groupKind, which now governs child layout only). A node can be both mandatory: true and groupKind: alternative — a mandatory XOR group (every product selects exactly one child). Backward compatible: the legacy groupKind: mandatory remains a shorthand for mandatory: true on a leaf.
UAV model is now a full product line¶
The bundled model/ is a runnable 150% UAV product line: a feature model (Features/) with three mandatory XOR groups (Propulsion/Payload/DataLink), an optional DualFlightController, cross-tree requires, and a typed parameter; three products (Configurations/CONF-UAV-*); variant-conditioned architecture, requirements, and tests under ADR-SYS-PLE-001; and implementedBy: traces into firmware/. Every variability command runs against it cleanly (feature-check --deep, matrix, validate --all-configs). With the new mandatory: field the earlier synthetic Base workaround feature was removed.
Documented in the variability guide, modeling guide, CLI reference, format spec §9, and syscribe spec prompts.
0.6.0 — 2026-06-07¶
Implementation trace (implementedBy:, closes #13)¶
Closes the downstream leg of the V-model: Requirement ─satisfies→ Architecture ─implementedBy→ Code ─verifies→ Test.
implementedBy:— a new optional field onPart/PartDef(string or list) linking an architecture element to the source artifact(s) that realise it. Paths resolve with the same rules as a TestCase'ssourceFile(model-/repo-relative,model:/repo:prefixes, absolute,file://, remotescheme://).- W023 — a non-
draftPart/PartDefwhoseimplementedBy:path is missing on disk (one finding per missing path). Opt-in (only whenimplementedBy:is present), draft-suppressed, remote-tolerant, and gateable withvalidate --deny W023. - Discoverability —
links <element>listsimplementedBypaths;refs <path-or-dir>reverse-maps a source path (or directory prefix) back to the declaring architecture element(s).
Documented in format spec §12.8, syscribe spec validation/spec fields, the validation-rule reference, the traceability guide, and the LLM authoring prompt.
0.5.0 — 2026-06-06¶
Configuration selections (fixes #12)¶
template Configurationnow emits the canonicalfeatures:map (wasselections:, which the parser silently ignored — every cell came back N/A).- W016 — a
Configurationthat parses zero feature selections while a feature model exists is now flagged instead of silently ignored. show <Configuration>displays parsed feature selections (andfeatureModel/appliesWhen), so a parse failure is visible locally.
Feature parameters (§9.7, single-level)¶
FeatureDef.parameters:are now validated against aConfiguration'sparameterBindings::- E203 bind for an unselected feature · E204 bind a fixed parameter · E205 value out of
range:· E206 value not inenumValues:· E222 binding path resolves to no declared parameter · W017 selected feature's required, default-less parameter left unbound. - Two-level
bindTo:propagation, derived-expression cycles, and cross-featureparameterConstraintsremain unimplemented (documented).
0.4.0 — 2026-06-06¶
Product-line variability (opt-in)¶
The variability dimension stays dormant — and changes nothing — unless the model declares a FeatureDef and links something to it.
- Boolean
appliesWhen:— conditions any element (including aTestCase) on an expression overFeatureDefqualified names:and/or/not/ parentheses. Bare QName and list (AND) forms remain valid.E209now checks every operand. TestCasevariant membership is derived fromappliesWhen:— a test runs in aConfigurationiff its condition holds for that configuration's selections (norunsInfield).syscribe matrix [--json] [--tag]— Requirement × Configuration coverage grid (covered / gap / N-A); falls back to a flat view when no feature model is present.- W015 — per-
Configurationcoverage rule: a requirement active in a configuration with no covering in-configTestCase. Honours draft suppression; gate with--deny W015. list --tag/ generic tags — free-texttags:filtering acrosslistandmatrix, orthogonal to the feature model.Configuration.features:selection maps now parse;refs <CONF>lists the TestCases that run in a configuration.
Documented in format spec §9.10–9.11, syscribe spec validation/spec fields, the CLI help, and the LLM authoring prompt (Part 9b).
0.3.0 — 2026-06-06¶
- CI severity gating for
validate(--deny,--max-warnings,--warnings-as-errors; exit codes 0/1/2) - Function-level traceability (
W009) and structured model-graphexport(JSON / NDJSON) - Gherkin scaffolding (
scaffold-gherkin) and test-result ingestion (ingest-results,W010) - Atomic
movewith reference rewriting sourceFilelocation semantics (model/repo-relative, absolute,file://, remote) with an opt-in--fetch-remotedownload hook- Active-only source-drift scoping with informational
I010
0.2.0 — 2026-05-28¶
Demo models¶
- Engine ECU (
model_auto/) — full ISO 26262 / ISO/SAE 21434 reference model: ASIL A–D safety goals, HARA, FTA, FMEA, TARA, 14 test cases - SIL 4 Computer-Based Interlocking (
model_sil/) — full IEC 61508 / EN 50128 / EN 50159 reference model: SIL 4 2oo2D architecture, formal B-Method specification obligation, quantitative FTA (< 10⁻⁸ /h), 11 test cases - Separate documentation pages for each demo model in the docs
CLI¶
- Model root is now set with
-m <path>/--model <path>or theSYSCRIBE_MODELenvironment variable — positional argument removed - New
specsubcommand:syscribe spec,syscribe spec types,syscribe spec fields,syscribe spec validation,syscribe spec traceability,syscribe spec safety— in-terminal format spec browser - New
trace,why,who-verifiescommands for traceability queries - New
next-id,template,check-ref,path-forcommands for model authoring - New
validate --jsonflag for machine-readable output - New
typesanduntypedcommands for model inspection
Validation¶
- Safety/security integrity level rules: E841/E842/E843 (ASIL/SIL consistency across inheritance and deployment), W808 (integrity level not set on safety-critical element)
- W806: SafetyGoal not grounded in any HazardousEvent or HARA element
- W305: parent Requirement must have at least one integration-level (L3/L4/L5) TestCase
- W410/W411/W412: cross-reference target existence checks
- W408/W409:
%% ref:annotation validation in Mermaid diagram blocks - Various false-positive fixes (W006, W007, W406/W407 SVG-internal IDs)
Format¶
derivedFromSafetyGoal:link from Requirement to SafetyGoal (IEC 61508 / ISO 13849)derivedFromSecurityGoal:link from Requirement to CybersecurityGoalallocatedFrom/allocatedTonow accept lists for multi-source allocation- Full Tier 4 safety analysis elements: FaultTree (file-per-node), FMEA (exploded entries), TARASheet (exploded container)
- Full safety/security analysis documentation added to the Modeling Guide
Web browser¶
- Interactive Cytoscape.js model canvas at
/canvas - Validation errors and warnings highlighted on canvas nodes
- Validation findings shown in element detail panel
- Element documentation body rendered as Markdown with embedded Mermaid diagram support
diagramCLI withcompose,layout,exposesub-commands; Cassowary-based layout solver- SEQ and REQ diagram renderers; A* obstacle-aware edge routing; full SysML edge style set
- JS dependencies vendored and served from the embedded binary (no external CDN at runtime)
- Unified engineering blueprint colour scheme across docs and canvas
0.1.4 — 2026-05-28¶
Diagram CLI¶
diagramsubcommand:list,measure,renderandcomposeproduce companion SVGs (svgMode: companion).- Layout:
diagram layoutis a Cassowary-based layout solver.composecan read aDiagramelement'sexpose:list, and--emit-placementprints the layout so an LLM can refine it. - More diagram kinds:
diagram reqdraws requirement trees anddiagram seqdraws sequence diagrams. - Rendering: IBD ports and nested ports, A* obstacle-aware edge routing, and the full SysML edge style set.
Validation and authoring commands¶
- New commands:
validateshows only errors and warnings, with--jsonand--file.list,typesanduntyped.template,next-id,path-forandcheck-ref.- New codes: W007 (unused
*Def), W008 (notype:), and E016–E018 (cycles insupertype,derivedFromandsubsets). - Fixes: stack overflow in
treecaused by the root_index.md, and W007 false positives from nestedtypedBy:.
0.1.3 — 2026-05-27¶
- Mermaid references: a
%% ref:annotation in a Mermaid diagram must resolve (W408), and a Mermaid diagram with no annotations is W409. - Link checks: new W410–W412 check
%% link:, shapelink:and SVGhrefreferences. rendercommand:render <diagram>prints a diagram with its links injected.
0.1.2 — 2026-05-27¶
- Fixed duplicate changelog entries in the release workflow.
0.1.1 — 2026-05-27¶
- Reworded the GitHub Action description in
action.yml.
0.1.0 — 2026-05-26¶
Initial public release.
Format¶
- Full Syscribe format specification (§1–§12)
- 40+ element types covering SysMLv2 structural, behavioral, and requirements constructs
- Native
Requirement(REQ-),TestCase(TC-),ADR(ADR-), andConfiguration(CONF-) elements operations:field (§8.3.4) on PortDef/InterfaceDef for synchronous operations and async receptions- Six §12 traceability rules enforced by the validator
Validation engine¶
- 80+ validation rules across 12 groups (E001–E503, W001–W601)
- Computed reverse indices:
verified_by,derived_children - CLI report tool:
syscribe -m model/— 10-section Markdown output
Web browser¶
- Axum + Askama + HTMX — no JavaScript framework
- BDD, IBD, StateMachine, and Requirement diagram rendering (SVG, server-built)
- Mermaid diagram rendering (client-side, CDN)
- Drag-to-reposition with layout persistence to
.mdfiles - WebSocket live reload on file-system changes
Demo model¶
- UAV system — 111 elements across 20 packages
- 9 native Requirements (3 parents, 6 leaves), 9 active TestCases, 2 ADRs
- Full §12 traceability: domain classification, breakdownAdr, satisfaction links
- 5 diagrams: BDD, IBD, StateMachine, Requirement, Mermaid