Version: 0.3 (draft) Status: Working draft. Breaking changes expected before v1.
This document is the normative reference for the Software Architecture Manifest (SAM). The accompanying JSON Schema is the syntactic form; this document defines what conformance to that form means and what claims a SAM is asserting when it is signed.
This document is structured into nine sections:
Authoring and verification guides and lifecycle policy are deferred to a subsequent iteration of this specification.
A Software Architecture Manifest is a producer-signed, machine-readable declaration of:
A SAM is a predicate in the in-toto sense. It is intended to be signed via DSSE / sigstore / cosign and bound to its subject by content digest. The signing mechanism is not specified here; this document defines only the predicate body.
A SAM may describe an artifact (a single signed deployable), a service (a logical SLO-owning unit composed of one or more artifacts), or a product (the contractual surface composed of one or more services). The granularity is declared explicitly via subject.layer.
A SAM is not:
SAM is designed to be read by three classes of consumer:
SAM is intentionally scoped to coexist with, not replace, existing supply-chain artifacts:
| Layer | Existing standard | SAM relationship |
|---|---|---|
| Contents | SBOM (CycloneDX, SPDX) | Referenced via subject.sbomRef |
| Build provenance | SLSA, in-toto | SAM is a sibling predicate, signed via the same envelope |
| Quality model | ISO/IEC 25010:2023 | The spine of qualityAttributes |
| Vulnerabilities | CSAF, VEX | Out of scope; complementary |
| Software identity | OCI, package URLs | subject.digest and subject.name interoperate |
| Operational third-party risk | EU DORA Art. 28, NIS2, ISO/IEC 27036, NIST SP 800-161 | envelope.dependencies[] carries criticality, failure mode, jurisdiction, and data-flow metadata that consumers under these regimes need to populate their own ICT third-party risk registers |
ISO/IEC 25010:2023 is the normative anchor for qualityAttributes, and the standard text is paywalled. The following open companions give context on the model — they inform a reader’s understanding but are not a substitute for the standard:
https://en.wikipedia.org/wiki/ISO/IEC_25010 — summary-level coverage of the nine characteristics and their sub-characteristics.https://quality.arc42.org/ — an open practitioner’s guide to defining and measuring software quality, organized along ISO 25010 lines.https://csrc.nist.gov/pubs/sp/800/160/v1/r1/final — open systems-engineering guidance complementary to (not a substitute for) the quality model.This specification’s §10 — Quality characteristic definitions gives SAM’s own plain-English definition for each characteristic and sub-characteristic, using the ISO/IEC 25010:2023 names as the canonical vocabulary, with example producer claims. Those definitions are original to the SAM project (CC-BY-4.0), are informative, and are not a reproduction or replacement of the ISO standard text — §10 fixes what SAM’s schema keys mean; for the authoritative quality model, consult ISO/IEC 25010:2023. The Wikipedia / arc42 / NIST references are informational broadening, not prerequisites.
The following terms are used with the meanings given here throughout this specification.
subject with a layer discriminator.manifestVersion.predicateType field. For this version: https://software-architecture-spec.github.io/sam/v0.3.producer.name.evidence[].uri.envelope.envelope.dependencies[] with criticality, failure-mode, data-flow, and jurisdictional metadata. Distinct from envelope.network.requiredEgress[] (which is host:port-level); a single operational dependency may correspond to multiple egress entries.intent.intent.deliveryForm: one of saas, self_hosted_service, library, cli_tool, desktop_app, mobile_app, browser_extension, infrastructure, appliance. Governs how a quality claim reads (§10); the same vocabulary types an operational dependency (envelope.dependencies[].deliveryForm). Canonical IDs in /registry/delivery-forms.json. Design-context (§5.5).intent.architecturalStyle (e.g., microservices, modular_monolith). Design-context (§5.5), not a graded claim.intent.architecturalPatterns[] (e.g., circuit_breaker, saga; canonical IDs in /registry/patterns.json). Design-context (§5.5); its verifiable effect is claimed in the qualityAttributes sub-characteristic it serves.intent (deliveryForm, architecturalStyle, architecturalPatterns[]), as distinct from graded quality-attribute claims. See §5.5.industryRefs[].informationalRefs[].The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in BCP 14 (RFC 2119 and RFC 8174) when, and only when, they appear in all capitals, as shown here.
The same keywords appearing in lowercase in this document are not normative; they are used in their plain-English sense.
SAM exists to address a specific class of failure mode in modern software supply: the visual signals that once distinguished a production-grade system from a weekend prototype have collapsed. Stack choice, deployment pipeline, and surface polish no longer correlate with design maturity. A consumer — human or AI — cannot tell from inspection which signals are load-bearing.
SAM is a producer-signed declaration that restores those signals explicitly. The threats it addresses, and the threats it does not, are enumerated below.
T1 — Production-grade impersonation. Software with weak design properties (no concurrency model, no failure-mode design, no security architecture) is mistaken for production-ready because its surface signals match those of mature systems.
Mitigation: a producer-signed manifest declares which quality attributes have been specified, declared, or verified, and which are honestly unspecified. The default (status: unspecified) is informative absence; consumers learn what was not designed for as well as what was.
T2 — Operational envelope inference. Consumers cannot tell, from a deployable, whether it was designed for one user or many; whether it scales horizontally; whether it expects internet access or runs isolated; whether it requires root or runs unprivileged.
Mitigation: envelope declares each of these as a structured field. Outside the envelope, behavior is undefined by the producer’s own assertion.
T3 — Tension hiding. Distributed systems require choosing sides on CAP/PACELC, on observability cost vs. resolution, on test-suite coverage vs. maintainability. Producers often don’t declare their posture, leaving consumers to discover the trade-off during an incident.
Mitigation: tensionsDeclared makes the posture and rationale explicit at design time.
T4 — Citation drift. Informal claims like “we’re SOC 2 compliant” or “WCAG AA” travel in marketing copy without machine-readable substrate. Consumers cannot verify them programmatically.
Mitigation: industryRefs[] structures the citation (standard, version, conformance, referenceUri); evidence[] provides URIs to the verification artifacts.
T5 — Composition opacity. A product is many services; a service is many artifacts. A consumer reading a manifest at the wrong layer will misinterpret what they see (a service-layer claim of “horizontal scaling” does not imply each constituent artifact is independently scalable).
Mitigation: subject.layer declares granularity explicitly. subject.components[] makes composition explicit.
T6 — Hidden third-party dependencies. Modern software is heavily composed from external services (identity, payment, observability, infrastructure). A consumer cannot evaluate operational risk — what breaks when a dependency goes down, where data flows, what jurisdiction holds it — by inspecting binaries or even reading documentation. Regulated consumers (EU DORA, NIS2, sector-specific regimes) are required to maintain ICT third-party registers and reverse-engineer this information today.
Mitigation: envelope.dependencies[] declares operational dependencies with criticality, failure mode, data flow, jurisdiction, and substitutability. Each entry can cite DORA Art. 28, NIS2, ISO/IEC 27036, or NIST SP 800-161 anchors via industryRefs[].
N1 — Lying producers. A SAM is what the producer says. A signed declaration of verified with fabricated evidence is detectable only by inspecting the evidence. SAM is no defense against a determined liar; its contribution is to make the lie attributable to a specific producer key in retrospect.
N2 — Code-execution-time vulnerabilities. A SAM is a design artifact, not a runtime guard. It tells consumers what to expect; it does not prevent attacks against running code.
N3 — Stale claims. A SAM issued 18 months ago may not reflect the current code. The producer.validFor field is advisory; consumers SHOULD check freshness against the artifact’s current digest before relying on the manifest.
N4 — Missing claims. Honest absence (status: unspecified) is not a vulnerability. Over-claiming is. SAM cannot enforce honest claim-making; it can only make over-claiming auditable.
N5 — Out-of-band channels. A producer may make different claims in marketing materials, contract language, or sales decks than in the SAM. SAM cannot reconcile these; it provides one signed source of truth for the format and leaves reconciliation to the consumer’s contract.
N6 — License compliance. Out of scope. Use SBOM (CycloneDX or SPDX) referenced via subject.sbomRef.
N7 — Build provenance. Out of scope. Use SLSA / in-toto attestations as siblings to the SAM.
N8 — Vulnerability disclosure. Out of scope. Use CSAF / VEX as siblings.
Consumers of a SAM rely on the following trust assumptions, none of which SAM itself enforces:
industryRefs[].standard strings are interpretable in good faith. Ambiguous strings (e.g., bare "27001") are non-conforming per §5.This section defines what it means for a SAM to conform to this specification. Conformance is defined in two tiers: conforming and strictly conforming. Tooling MUST follow the consumer rules below.
A SAM is conforming if all of the following hold:
$id for the declared manifestVersion.predicateType equal to the canonical predicate type URI for the declared manifestVersion (for v0.3: https://software-architecture-spec.github.io/sam/v0.3).producer.name.subject.layer is artifact, subject.digest MUST be present and bind the manifest to the artifact via the in-toto Statement subject field.qualityAttributeClaim.status is verified, at least one entry in evidence[] MUST be present for that claim.qualityAttributeClaim.status is declared or verified, the summary field MUST be present and non-empty for that claim.evidence[].uri, informationalRefs[], subject.sbomRef, subject.components[].manifestUri, industryRefs[].referenceUri, producer.contact if a URI) MUST be syntactically valid URIs per RFC 3986.industryRefs[].standard values MUST be interpretable as references to publicly identifiable standards. A bare numeric string (e.g., "27001"), an unqualified abbreviation (e.g., "CSF" without context), or a private vendor identifier is non-conforming.producer.issuedAt MUST be a valid RFC 3339 / ISO 8601 timestamp not in the future relative to the producer’s local clock at signing time.A SAM is strictly conforming if, additionally:
tensionsDeclared[].tension values are either well-known identifiers from the registry maintained alongside this specification (a future deliverable) or use the x: prefix for vendor-specific tensions.x-* extension keys at the eight permitted locations enumerated in §7.2. The schema enforces this via patternProperties: { "^x-": {} } at those locations and additionalProperties: false everywhere else.producer.validFor is present, and the consumption time falls within [producer.issuedAt, producer.issuedAt + producer.validFor].A producer:
status: verified for a claim without at least one corresponding evidence URI.status: verified for a claim that has not actually been verified by the producer or a party the producer relies on. This is a moral, not technical, requirement; the signature attributes any violation to the producer’s key.status: unspecified honestly when no claim is being made. Honest absence is preferable to fabricated assurance.status: not_applicable only when the attribute is genuinely irrelevant to the artifact (e.g., interactionCapability for a backend API with no UI surface).industryRefs[].conformance. A self-attestation to NIST SSDF practices is not equivalent to a third-party SOC 2 Type 2 audit; the conformance string SHOULD make this distinction visible.A consumer of a SAM:
subject.digest and conflicting claims as an integrity failure requiring resolution before adoption.producer.validFor to assess freshness. A SAM beyond its validity window MAY still be informative but SHOULD be treated as advisory only.A validator:
status: verified and no evidence), but the validator’s authority extends only to what is visible in the document; it cannot adjudicate whether evidence URIs themselves substantiate the claims they support.A signer:
predicateType to the canonical URI for the manifest version being signed.A viewer:
unspecified claims with the same visual weight as declared and verified claims, so that consumers see honest absence rather than scrolling past it.declared (no evidence) from verified (evidence present) in the visual surface.SAM carries two kinds of statement, and they are read differently:
qualityAttributes (and the extensions quality blocks). Each carries a status (unspecified / declared / verified / not_applicable) and, when verified, evidence[]. This is SAM’s honesty mechanism.intent: declarative facts about how the software was designed — audience, tenancy, deliveryForm, architecturalStyle, and architecturalPatterns[]. These are not graded and carry no status or evidence[], by design.Architecture resists direct evidence: “this is microservices” or “we implement circuit_breaker” has no artifact that proves it the way a load test proves a latency claim. Forcing a status / evidence ladder onto these fields would manufacture assurance that does not exist. Instead:
architecturalStyle should be consistent with subject.layer and subject.components[]; deliveryForm is consistent-by-consequence with how the quality claims read (§10).qualityAttributes sub-characteristic it serves. circuit_breaker produces reliability.faultTolerance; cqrs produces performanceEfficiency / flexibility.scalability. The applies_to field in /registry/patterns.json records this mapping. The evidence for whether the circuit breaker actually works is the status / evidence[] on that quality claim, not on the pattern entry.architecturalStyle and architecturalPatterns[] at the layer where they are literally true — usually artifact or service. A product-layer manifest’s architecture is the composition of its components[], not a flat re-declaration.Consumers and AI agents SHOULD read intent’s design-context as declarative design signal — useful for discovery, filtering, and reasoning — and SHOULD NOT read it as evidenced. To assess whether a declared pattern delivers its intended property, follow it to the corresponding qualityAttributes claim.
This specification, the JSON Schema, and the predicate type URI are versioned together. Consumers MUST be able to rely on stable compatibility guarantees across versions; producers MUST be able to upgrade with predictable cost.
SAM uses Semantic Versioning 2.0.0 (MAJOR.MINOR.PATCH).
MAJOR is 0, this specification is a working draft. Breaking changes MAY occur in minor releases.MAJOR ≥ 1 release is the first stable version. From that point on, the compatibility commitments in §6.3 apply strictly.The version a manifest claims to conform to is declared in the top-level manifestVersion field. The same version appears in:
$id path component (e.g., .../v0.3/schema.json).https://software-architecture-spec.github.io/sam/v0.3).These three values MUST agree for a given manifest.
A change is PATCH when it is editorial and does not change the schema, the predicate type URI, or any normative requirement. Examples: typo fixes, prose clarifications, non-normative example updates. Tools MUST treat the patched and unpatched versions as interchangeable. Tools that pin to a MAJOR.MINOR.PATCH triple MUST also accept any later PATCH of the same MAJOR.MINOR.
A change is MINOR when it is additive: new optional fields, new optional sub-objects, new well-known enum values added to open enums. A manifest that conformed to MAJOR.MINOR_OLD MUST conform to any later MAJOR.MINOR_NEW of the same MAJOR. New consumers MUST be able to read manifests issued against earlier minor versions of the same major version.
A change is MAJOR when it is breaking: removing a field, narrowing a value space, changing the meaning of an existing field, changing required-vs-optional status, or changing the predicate type URI. A manifest issued at one MAJOR MAY be invalid under the schema of the next MAJOR. The predicate type URI changes (e.g., sam/v1 → sam/v2).
For any two versions A and B of this specification where A < B:
B MUST accept manifests claiming any earlier minor or patch version of the same major. A producer using version A MUST be able to upgrade to B without re-issuing existing manifests, except by their own choice.B MUST NOT silently treat a manifest claiming version A as a B manifest. The consumer SHOULD either reject the manifest, accept it in compatibility mode (validating against the A schema), or surface the version mismatch to the operator.The canonical predicate type URI for this specification is of the form:
https://software-architecture-spec.github.io/sam/v<MAJOR>[.<MINOR>]
For pre-1.0 working drafts, the URI includes the minor version (e.g. v0.2, v0.3). For stable versions (MAJOR ≥ 1), the URI includes only the major version (v1, v2); minor versions of a stable major share a single URI because they are backward compatible by §6.3.
A signing tool MUST NOT set predicateType to a URI different from the one declared in manifestVersion. A verifier MUST treat such a mismatch as an integrity failure.
A field, value, or sub-object MAY be marked deprecated in a minor version. Deprecation does not remove the field; it signals intent to remove it in the next major version. Deprecated fields:
Producers SHOULD migrate away from deprecated fields. Consumers MUST continue to accept deprecated fields in any minor version of the major in which they were deprecated.
v0.3 is a 0.x working-draft release. Per §6.1, breaking changes MAY occur in minor releases while MAJOR is 0; v0.3 uses that allowance for exactly one change. Everything else is additive (new optional fields).
intent.deliveryForm, intent.architecturalStyle, intent.architecturalPatterns[]; envelope.persistence.{replication, consistency, backup, encryption}; envelope.instantiation.{ordering, idempotency, conflictResolution}. All are experimental (§8).envelope.dependencies[].type — a single experimental enum that mixed delivery form with functional role — is replaced by two optional fields: deliveryForm (drawn from the same vocabulary as intent.deliveryForm) and role (identity_provider, payment_provider, data_provider, communication_provider, observability_provider, ml_model_provider, other). A v0.2 manifest that set dependencies[].type does not validate under v0.3 and must migrate (type: saas → deliveryForm: saas; type: payment_provider → role: payment_provider). v0.2 manifests remain valid under the frozen v0.2 schema and URIs per §6.3.SAM is intentionally narrow. Producers will need fields this specification does not provide. To allow growth without forking the schema, SAM follows the convention used by OpenAPI, CycloneDX, and Kubernetes: a vendor extension namespace.
x-* extension namespaceCustom keys MUST be prefixed with x- (lowercase x followed by a hyphen). Custom keys SHOULD include a stable namespace identifier after the prefix to avoid collisions:
x-<namespace>-<key>
Examples: x-acme-deploy-region, x-redhat-fips-mode, x-internal-cost-center.
The namespace x-sam- is reserved for future additions defined by working-group consensus on this specification. Producers MUST NOT use x-sam- for vendor-specific extensions.
Custom x-* keys MAY appear on the following objects:
qualityAttributeClaim (the inner object containing status, summary, evidence, industryRefs, informationalRefs).qualityAttributes (the object containing overall and subCharacteristics).extensions block.tensionsDeclared[].industryRefs[] and each entry in evidence[].producer object.subject.components[].Custom x-* keys MUST NOT appear on the following objects, where unknown fields would change conformance-relevant semantics:
subject (signing-relevant; changes here would invalidate the digest binding).manifestVersion.intent, envelope, and any of envelope’s sub-blocks (throughput, scaling, instantiation, privilege, network, persistence). Producers needing additional operational claims SHOULD use the extensions block instead.As of v0.2, the JSON Schema implements this policy: patternProperties: { "^x-": {} } is declared on each of the eight permitted objects above. Forbidden objects retain additionalProperties: false. Validators will reject x-* keys placed on forbidden objects (e.g., on envelope.network); validators will accept them on permitted objects without requiring schema knowledge of the specific key.
An extension MUST NOT:
x-acme-multi-tenant: true on a manifest with intent.audience: single_user is non-conforming.)An extension MAY:
x-* key on a permitted object without error.x-* keys it does not recognize, to avoid silent loss of producer intent.x-* keys distinctly from normative fields, so consumers do not mistake them for spec-defined claims.Not every field in the schema carries the same maturity. Some are well-grounded in established standards (the qualityAttributes keys come from ISO/IEC 25010:2023). Some are intentionally exploratory (the extensions block holds quality concerns ISO 25010 doesn’t yet model cleanly — observability, data lifecycle, internationalization). Consumers need to know which is which to plan their reliance.
Every field defined by this specification is in exactly one of three tiers:
MAJOR version bump. Tools MAY rely on it indefinitely within a major version.MINOR version. Tools MAY use it but SHOULD be prepared for change.MAJOR version. Tools MUST continue to accept it until that version. Producers SHOULD migrate. The deprecation notice MUST cite a successor or state “removed without replacement.”For this draft, all fields defined by this specification are experimental unless explicitly marked otherwise. The first MAJOR ≥ 1 release will mark the foundational set as stable. Consumers using v0 SHOULD plan for minor-version churn.
In the JSON Schema, a field’s stability tier is declared in its description text using the convention:
Stability: stable | experimental | deprecated [— <notes>]
Where <notes> MAY include a successor reference (see x.y.z), a deprecation rationale, or expected-change scope. Fields without an explicit annotation default to the version’s default tier (experimental while MAJOR is 0; stable after).
As of v0.2, the schema surfaces stability via two complementary mechanisms: every field’s description is prefixed with Stability: <tier>. for human readers, and the schema also attaches x-sam-stability: "stable" as a sibling of description on stable fields for tools that prefer a structured keyword. The x-sam-stability keyword is descriptive only — it has no validation behavior in v0.x, and Draft 2020-12 validators ignore it as an unknown keyword. A top-level $comment in the schema documents the keyword.
A field MAY be promoted from experimental to stable in any minor version. Promotion is non-breaking by definition.
A field MAY be demoted from stable to deprecated in any minor version. Demotion is non-breaking; the field continues to validate. Removal of a deprecated field requires a major version bump (§6.5).
A field MUST NOT move from experimental to deprecated without an intervening promotion to stable or a major version bump. (Rationale: producers should not be punished for using a field the spec said was experimental; the path to removal goes through stable.)
A conforming SAM (per §5.1) is binary — it conforms or it doesn’t. But producers and consumers also need a vocabulary for how much a SAM tells them. SLSA established this pattern for build provenance with L0–L3; this section does the same for design intent.
A subject is at exactly one SAM level at any time. Levels are cumulative — L3 implies L2 implies L1.
L0 — No manifest.
No SAM exists for the subject. The default state of most software today.
L0 is named explicitly so consumers have a clear word for “we cannot evaluate this artifact.” A consumer encountering L0 software has no producer-signed declaration of intent, envelope, or quality attributes; everything must be inferred.
Cost to producer: zero. Leverage for consumer: none. Compliance posture under DORA / NIS2 / SOC 2: the consumer must reverse-engineer.
L1 — Conforming.
A SAM exists for the subject, satisfies §5.1 conformance, and is signed and bound to its subject per §5.1.3–5.
Claims may be unspecified, declared, verified, or not_applicable — including all unspecified. Honest absence is encouraged.
What L1 tells a consumer: the producer has authored a SAM that says what the subject is, the operational envelope it was designed for, and which quality attributes the producer has thought about. For unspecified attributes, the consumer knows what the producer has not claimed; for not_applicable, the consumer knows the attribute is irrelevant by design.
Cost to producer: one authoring pass plus signing infrastructure. Leverage for consumer: a stable, machine-readable starting point for evaluation. Compliance posture: enables initial intake; deeper evaluation typically requires L2+.
L2 — Anchored.
L1, plus: every qualityAttributeClaim with status: declared or verified carries at least one industryRefs[] entry. Every envelope.dependencies[] entry of criticality: critical or important carries at least one industryRefs[] entry (typically a DORA, NIS2, ISO/IEC 27036, or NIST SP 800-161 cite).
What L2 tells a consumer: every non-trivial claim points to a publicly identifiable standard the consumer recognizes. Auditors and procurement teams can run automated mapping from SAM claims to their internal control catalogs without manual translation.
Cost to producer: per-claim research effort to identify the right industry anchor — the cost is one-time and the result is reusable across releases. Leverage for consumer: automation across procurement / audit / vendor risk surfaces. Compliance posture: sufficient for many third-party-risk processes that need machine-readable hooks.
L3 — Evidenced.
L2, plus: every qualityAttributeClaim with status: verified carries at least one evidence[] entry. tensionsDeclared is populated for every cross-attribute tension the subject’s design touches (at minimum, the well-known tensions named in §5.1.11 that apply). producer.validFor is present and the manifest is consumed within its validity window. Maps to the spec’s §5.1 strict conformance tier.
What L3 tells a consumer: every verified claim points to a verification artifact the consumer can fetch and audit (load test report, security scan, accessibility audit, chaos test, etc.); every architectural trade-off the subject makes is named with its posture and rationale; the manifest is fresh.
Cost to producer: the verification cost is real (load tests, audits, chaos tests must actually be run) but the marginal cost of declaring already-performed verification is small — the bottleneck is doing the verification, not declaring it. Leverage for consumer: the manifest substantially substitutes for direct vendor due-diligence in regulated contexts. Compliance posture: most third-party risk regimes accept evidenced declarations for non-critical providers; for critical providers, supplements rather than replaces independent verification.
A consumer determines a SAM’s level by:
unspecified/not_applicable claim has industryRefs[] and every critical/important dependency has industryRefs[]: at least L2.verified claim has evidence[], every applicable tension is in tensionsDeclared, and the manifest is within producer.validFor: L3.Consumers SHOULD report the determined level alongside any conformance result. Tooling MAY surface levels visually (badges, dashboards) — the level is the maturity signal a consumer reads at a glance.
SAM levels measure what the producer has declared and substantiated, not whether the software is good. An L3 SAM declaring “P95 latency is 30 seconds” is L3-conforming; whether 30 seconds is acceptable is a consumer judgment outside SAM’s scope. Levels are about evaluability, not quality.
A consumer SHOULD NOT treat L3 as a quality stamp. L3 means “the producer has done the work to let you evaluate”; evaluation itself remains the consumer’s responsibility.
The schema’s qualityAttributes keys correspond one-to-one with the ISO/IEC 25010:2023 quality characteristic names, and each characteristic’s subCharacteristics keys correspond with the standard’s sub-characteristic names. This section gives each name a plain-English definition in the SAM project’s own words, so the meaning of every schema key is unambiguous when it appears in a manifest.
The definitions here are not a paraphrase of the standard restated for its own sake. Each entry adds material ISO does not contain: it is framed through SAM’s declaration model (honest absence via unspecified / not_applicable, the declared / verified status ladder, and the evidence and industryRefs[] a producer would attach), and every sub-characteristic carries an illustrative producer claim written for SAM. Where a characteristic reads differently depending on how the software is delivered — an operated service (SaaS), a shipped product (COTS/on-prem), or an embedded SDK/library — the entry makes that cut explicit, because the same schema key asserts different things depending on who operates the software. The delivery form is declared in intent.deliveryForm and named canonically in /registry/delivery-forms.json; the same vocabulary types an operational dependency via envelope.dependencies[].deliveryForm (with role carrying the functional axis), so a subject’s delivery form and a dependency’s delivery form read alike. The intent is a SAM authoring reference, not a substitute standard.
Provenance and independence. These definitions are original to the SAM project and licensed CC-BY-4.0. They are informative: they fix what SAM’s schema keys mean in a manifest. They are not a reproduction, translation, or derivative of the ISO/IEC 25010:2023 standard text, and they are not a substitute for it — for the authoritative quality model, consult the ISO standard. Where SAM’s wording differs from ISO’s, the ISO standard is authoritative for interpretation of the model; this section is authoritative only for what the SAM schema’s keys mean when they appear in a manifest.
SAM is an independent project and is not affiliated with, endorsed by, or a product of ISO or IEC. “ISO” and “IEC” are trademarks of their respective organizations; ISO/IEC 25010 is referenced here nominatively, to align SAM’s vocabulary with a quality model that procurement and audit already recognize.
The degree to which the software does what it is supposed to do — provides functions that meet stated and implied user needs under specified conditions of use.
Sub-characteristics:
status: not_applicable or unspecified), not silent gaps. Example claim: “All onboarding workflows specified in the HR Tech requirements doc are implemented.”verified points at that artifact. Example claim: “Tax calculations match HMRC test vectors to the cent.” [evidence: conformance-run URI]Performance relative to the resources used under stated conditions — how the software behaves under load and how efficiently it uses CPU, memory, disk, and network. ISO 25010’s spelling (timeBehaviour, British) is preserved as the schema key.
Where this lives vs. envelope. envelope.throughput and envelope.scaling state the design target — the operational envelope the software was built for (target/max RPS, latency SLOs, concurrency, scaling axis). qualityAttributes.performanceEfficiency is the graded claim about meeting that envelope: it carries status, evidence[], and industryRefs[]. The envelope is the spec; the quality attribute is the report card against it. Put the canonical numbers in envelope.throughput and reference them from the claim summary — don’t maintain two competing sources of truth.
Operating model decides what a claim is (SaaS vs COTS). This axis governs all three sub-characteristics:
subject.layer = service or product, producer runs it) expresses performanceEfficiency as SLOs it engineers to and measures — percentile latencies and throughput per component/service, plus the scaling posture that holds them. verified means production SLI dashboards or a load test against the as-run topology. Pairs with envelope.serviceLevels and envelope.scaling.subject.layer = artifact or product, the consumer runs it) cannot promise an SLO on hardware it does not own. It instead ships sizing guidance per transaction type: the resource cost of each supported operation and tested ceilings on a named reference configuration, so the consumer can size for their own workload mix. verified means a published benchmark on a stated reference config. For this characteristic a COTS not_applicable is dishonest — the truthful posture is declared with a sizing model, or unspecified.Measurement discipline (every claim here). A latency number without the load it was measured at is meaningless — always state percentiles (P50/P95/P99) under a defined concurrency or RPS, never an average. Saturation (queue depth, pool exhaustion), not utilization, is the leading indicator of degradation. Little’s Law (concurrency ≈ throughput × latency) ties the three sub-characteristics together and is a quick consistency check across a set of claims. Anchor via industryRefs[]: Google SRE “Four Golden Signals” (latency, traffic, errors, saturation), the USE method (utilization, saturation, errors) for resourceUtilization, OpenTelemetry semantic conventions for how the signals are emitted.
Sub-characteristics:
envelope.throughput for the target. If latency is coupled to a consistency choice, declare the matching tensionsDeclared entry (cap_pacelc): does the P95 assume strong or eventual consistency, and what staleness window?[evidence: load-test report URI]bulk-import transaction is P95 < 1.2 s for 10k rows; single-lookup P95 < 15 ms. Latency scales with row count, not concurrency, up to 32 in-flight imports.”security_performance_isolation) — if the target must absorb input validation and isolation overhead, say so (see §10.6).search transactions: ~2.5 CPU-seconds, ~40 MB peak heap, ~8 MB egress. Size ingest workers at ~1 core per 400 sustained import TPS.”import TPS on the reference config; above that, throughput plateaus and P99 climbs. No tested data beyond 3× reference hardware.”The ability of the software to operate alongside other software in the same environment, and to exchange information with it through stable contracts.
Distribution form decides what “compatible” means. A service/API exchanges information over the network — compatibility is a versioned wire contract. An SDK/library is linked into a host process — compatibility is API/ABI stability and not fighting the host for resources. A COTS/appliance shares the consumer’s host or cluster — compatibility is resource and configuration co-tenancy. Declare against the form your subject.layer implies.
Sub-characteristics:
verified here means the contract is published and conformance-tested (contract tests), not merely that endpoints exist. Name the versioning strategy and what backward-compatibility means (additive-only, deprecation window, sunset dates). If downstream systems depend on the contract, its availability/latency commitments become operational obligations — state those in envelope.serviceLevels, not here. Anchor via industryRefs[]: OpenAPI 3.x, AsyncAPI, gRPC/protobuf, SemVer.[evidence: contract-test run URI]The degree to which the software supports humans in interacting with it. Renamed from “Usability” in ISO 25010:2023 to acknowledge that interaction spans more than ease-of-use — understandability, error recovery, accessibility, and engagement.
Who the “user” is decides how — and whether — this applies. For a GUI/end-user product, the user is a human at a screen and every sub-characteristic reads literally. For an SDK/library/CLI/API, the user is the integrating developer and these reinterpret as developer experience — discoverability, time-to-first-successful-call, guardrails against misuse, self-explaining errors. For a fully headless artifact with neither surface, status: not_applicable across the characteristic is the honest posture, not a gap to paper over.
Sub-characteristics:
--json for scripting.”userEngagement — Whether the interaction surface is pleasant or motivating to use. Most literal for end-user products; for infrastructure and SDKs the honest posture is often not_applicable. Example (GUI): “Workflow progress is visible on every page with completion percentage.”
verified needs an audit, not a self-assessment. Anchor via industryRefs[]: WCAG 2.2 A/AA/AAA, EN 301 549, Section 508.[evidence: audit report URI]How dependably the software performs its functions under stated conditions for a stated period of time — behavior under failure and recovery after it.
Operated vs shipped decides whether reliability is a measured outcome or a built-in capability. For operated software (saas), the producer owns the outcome: availability SLO, error budget, DR-drill results, and incident history are all measurable against the as-run system, and verified points at them. Pairs with envelope.serviceLevels (availability, rpoMinutes/rtoMinutes, incidentResponse). For shipped software (self_hosted_service, infrastructure, appliance), the producer builds the mechanisms (failover, backup/restore tooling, graceful degradation) but the consumer achieves the actual numbers — availability and RPO/RTO depend on how it is deployed. A shipped-software claim describes tested recovery behavior and the HA model, not an operated SLO the producer cannot honor on someone else’s infrastructure. For a library, reliability is fault-clean code — no state corruption or resource leaks on error, deterministic failure handling; availability and recoverability are usually the host’s concern (not_applicable).
Sub-characteristics:
tensionsDeclared entry (cap_pacelc).envelope.serviceLevels); for shipped software, the backup/restore tooling and tested restore time, since the consumer sets the cadence and owns the achieved RPO.[evidence: DR-drill report URI]saas, state it and put the SLO in envelope.serviceLevels. For shipped software, availability is the consumer’s result; the producer instead claims the HA capability that enables it (redundancy model, tested failover time), not a percentage it cannot control. Honest posture for a plain library or cli_tool: not_applicable.verified points at an incident record or public issue history.Protection of information and functions so that authorized actors have appropriate access while unauthorized access is prevented.
Who enforces the control decides what a claim asserts. For operated software (SaaS), the producer enforces controls at runtime and verified means pentest results, runtime configuration, and audit evidence against the as-run system. For shipped software (COTS/on-prem), the producer supplies secure defaults plus a hardening guide and the consumer enforces — a claim states what the artifact does out of the box vs. what the deployment must add. For an embedded SDK/library, security means not introducing a vulnerability into the host: safe defaults, no injection sinks, no secret mishandling — the consuming application owns the perimeter. A principle across all three: authorization is enforced per resource at the API, never assumed from a UI that merely hides the control.
Sub-characteristics:
observability_pii) — rich structured logs can leak PII into lower-trust log stores; declare the redaction posture.integrity — Data and functions are protected from unauthorized modification. Example claim: “All write operations signed; tampering is detectable via audit-log hash chain.”
nonRepudiation — Actions can be proven attributable to a specific actor to a third party after the fact — the evidentiary bar (signed, tamper-evident). Stronger than accountability. Example claim: “Audit log signed daily and exported to corporate SIEM; records cannot be deleted by application code.”
accountability — Each action can be internally traced to the actor who performed it — the operational bar (who did what, when). It rises to nonRepudiation only when the trail is tamper-evident enough to stand as external proof. Example claim: “Every write logged with actor, timestamp, and before/after values to an append-only store.”
verified names the mechanism and where it is enforced, not just that “auth exists.” Anchor via industryRefs[]: OIDC, OAuth 2.x, SAML, mTLS, WebAuthn/passkeys; SLSA / in-toto for artifact authenticity.industryRefs[]: OWASP ASVS L1/L2/L3, NIST SP 800-218.[evidence: pentest report URI]The ease with which the software can be modified to correct, improve, or adapt to changes.
Who maintains it decides whether this is a private or a purchased property. For closed SaaS, maintainability is the producer’s internal concern; consumers rarely see the source, so a coarse overall claim is often all that is meaningful. For OSS, SDKs, and source-available / COTS-with-extensions, maintainability is something the consumer is buying into — they will read, extend, test, and debug it — so the sub-characteristics carry real third-party weight and deserve verified evidence.
Sub-characteristics:
modularity — Components are decomposed so changes in one have minimal impact on others. Example claim: “Workflow steps are configuration-driven, not hardcoded; new step types added without touching the orchestration core.”
not_applicable.extensions.observability; an analysability claim should reference it rather than restate it.
extensions.observability for the runtime signals./docs/adr explain every architectural decision. Production issues diagnosable from telemetry alone (see extensions.observability).”modifiability — Ease of making targeted changes without breaking adjacent behavior. Example claim: “85% behavioral test coverage; contract tests catch regressions at service boundaries.”
test_suite_tension): brittle implementation-coupled tests inflate the number while blocking refactors; contract and property-based tests survive refactors. verified should point at a test-report artifact.[evidence: test-report URI]The ease with which the software can be adapted to different or changing environments, requirements, or scales. Renamed and broadened from “Portability” in ISO 25010:2023 to include adaptability and scalability.
Delivery form decides which sub-characteristics even apply. For consumer-operated software (self_hosted_service, library, cli_tool, infrastructure, appliance), flexibility is a first-class purchase decision — the consumer chooses where and how to run it, so adaptability, installability, and replaceability all carry weight. For operated software (saas), the producer controls the environment: installability is not_applicable (nothing to install — you sign up), adaptability is the producer’s internal concern, and only scalability (as an operated posture) and replaceability (can the customer leave?) matter to the consumer.
Sub-characteristics:
library, the supported language/runtime versions and platforms; for saas, usually not_applicable to the consumer.performanceEfficiency.capacity (the tested ceiling): scalability is the mechanism for moving that ceiling.
envelope.scaling and don’t restate capacity. For saas this is the operated autoscaling posture; for shipped software it is the scaling topology the consumer can deploy (replicas, sharding, read replicas) and what has been tested.performanceEfficiency.capacity).”not_applicable for saas.
industryRefs[]: OCI Image Spec, Helm chart schema.compatibility.interoperability (§10.3) for the contract itself. Every system with consumers has a replaceability story, so prefer declared over not_applicable unless there genuinely are no consumers to disrupt.Protection of human life, health, property, and the environment from harm caused by software behavior. New top-level characteristic in ISO 25010:2023; primarily relevant to safety-critical domains (automotive, medical, aviation, industrial control). For software with no safety-critical surface, status: not_applicable is the honest claim.
Sub-characteristics:
The following are deliberately deferred from this version of the specification:
industryRefs.standard.x-sam-stability validation behavior — currently descriptive; future versions may give it semantics (e.g., consumers reject manifests that promise stable and use experimental fields).subject.digest; binding them to a subject identifier without a digest is currently underspecified.These will be addressed in subsequent iterations of this specification once §§1–9 stabilize.