Every cloud security tool category — CSPM, CNAPP, SIEM, SOAR, IaC scanners, ML detection — shares the same structural limitation. They detect known problems after they occur. Policy-as-Code tools (OPA/Rego, Kyverno, CloudFormation Guard, Sentinel) come closest to breaking this pattern — they gate deployments before changes take effect, which is genuine Stage 4 feed-forward control.
But each Policy-as-Code tool is domain-scoped and implementation-coupled. OPA policies for Kubernetes don't compose with Sentinel policies for Terraform. CloudFormation Guard rules don't talk to Cedar authorization policies. Each tool verifies its own domain against its own rule format. There is no cross-domain specification layer where safety properties are declared once and verified everywhere — across providers, across tools, across the entire configuration lifecycle.
The gap isn't that feed-forward tools don't exist. It's that they aren't a platform. No tool tracks safety intent as a first-class, typed, composable entity that composes across the configuration lifecycle.
An important engineering clarification: cross-domain doesn't mean a Universal Data Model where all providers map to one schema. History is littered with failed universal models. The architecture is different: the observation contract has provider-specific schemas — an AWS S3 bucket schema, a GCS bucket schema, an Azure Blob Storage schema — each capturing that provider's configuration properties accurately. The evaluation engine is provider-agnostic — it evaluates CEL predicates against typed JSON regardless of which provider's schema produced the JSON. The cross-domain property lives in the engine, not in the data model. New provider features require extending the provider's schema, not rewriting the engine.
TRIZ's Su-Field analysis shows exactly where the structure breaks and what replaces it.
The root cause nobody names: AWS configuration is first-order logic
Before diagnosing the tooling gap, name the problem underneath it: cloud configuration — particularly AWS IAM — is expressed in first-order logic, and the engineers writing it are not aware of it.
An IAM policy statement:
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::customer-data/*",
"Condition": {"StringEquals": {"aws:PrincipalOrgID": "o-abc123"}}
}
This is a universally quantified predicate with a conditional: "For all requests where the action is s3:GetObject AND the resource matches customer-data/* AND the principal's organization ID equals o-abc123, the effect is ALLOW." That's first-order logic — quantifiers, predicates, logical conjunction, implication.
Now compose it with a resource policy on the bucket, a Service Control Policy on the account, a permission boundary on the role, and a session policy on the assumed credential. The effective permission is the logical composition of all five — evaluated in a specific order, with deny-override semantics, where explicit deny beats explicit allow, and the absence of an allow is an implicit deny.
Engineers don't think in these terms. They think procedurally: "I gave the role permission to read the bucket." They don't think: "The conjunction of the identity policy's allow, the resource policy's absence-of-deny, the SCP's absence-of-deny, the permission boundary's allow, and the session policy's absence-of-restriction, evaluated in deny-override order, produces an effective allow for this specific action-resource-principal tuple."
This is why misconfiguration is so prevalent. It's a language mismatch. The configuration language is first-order logic. The engineers writing it think in procedures. The gap between procedural thinking and logical semantics produces misconfiguration. The language for expressing what they want is a formal logic they were never trained in.
This also explains why scanners miss compositions. A scanner checks one policy statement at a time — one predicate in isolation. The security risk lives in the COMPOSITION of predicates across five policy layers. Checking individual predicates and missing the composition is like checking individual clauses of a contract and missing that two clauses contradict each other. The contradiction is in the logic, not in any individual clause.
The specification-first approach addresses this directly. Instead of asking the engineer to express their intent in the configuration language (first-order logic they don't think in), it asks them to express the PROPERTY they want to hold — in a language designed for boolean evaluation:
asset.tags.Sensitivity == "High" && asset.public_access == true
The engineer doesn't write the policy composition. They write the boundary condition. "If this bucket is sensitive AND it's publicly accessible, that's a violation." The platform evaluates this property against the RESULT of the policy composition — the effective state — rather than asking the engineer to reason about the composition itself.
The specification language (CEL) is simpler than the configuration language (IAM JSON) because it expresses the conclusion ("is this state safe?") rather than the derivation ("how do five policy layers interact to produce this state?"). The derivation is the hard part. The conclusion is the tractable part. The platform checks the conclusion mechanically, so the engineer never has to reason about the derivation.
The simplicity of asset.public_access == true is not free. Someone has to compute whether the bucket is effectively public — resolving ACLs, bucket policies, account-level blocks, and IAM into a single boolean. That computation lives in the collector (the observation layer, outside the evaluation hexagon). Steampipe, AWS Config, or a Pulumi custom collector queries the cloud APIs, resolves the multi-layer logic, and produces a snapshot where public_access is already the effective state. The CEL predicate evaluates the pre-calculated field. The complexity doesn't disappear — it moves to the collector, which is purpose-built for that computation. The engineer writes the property over the resolved state. The collector computes the resolved state. The evaluation engine checks the property. Three layers, each doing one job.
A valid concern: if the collector is opaque, the engineer can't debug a false positive — they see public_access == true but can't understand HOW that boolean was computed. Transparency is non-negotiable. The collector (Steampipe or equivalent) is open-source with visible SQL queries mapping cloud API responses to schema fields. The observation contract (JSON Schema per asset type) documents what fields exist, what they mean, and how they're derived. The snapshot itself is a JSON file the engineer can inspect directly. The path from "raw cloud API response" to "effective boolean" is visible in the collector's source, the schema documentation, and the snapshot data. Not a proprietary black box — an open-source pipeline with documented, inspectable intermediate state at every layer.
Su-Field analysis in 90 seconds
TRIZ models any functional system as an interaction between two substances (S1, S2) mediated by a field (F). The substance is any material object — a security team, a cloud configuration, a specification. The field is any energy or interaction — scanning, verifying, deliberating. A complete, functioning system has all three: two substances and a field connecting them.
When something goes wrong, Su-Field analysis identifies which element is broken: the field is insufficient, the field is harmful, a substance is missing, or the interaction produces an unwanted side effect. The TRIZ catalog of 76 standard solutions then prescribes structural fixes.
F (Field: the interaction)
│
▼
S1 ◄────────────────► S2
(Substance 1) (Substance 2)
The broken Su-Field of cloud security
The cloud security workflow has a fundamental Su-Field problem:
F: Scanning (pattern-matching against known-bad rules)
│
│ (detects known misconfigurations, misses novel ones)
▼
S1: Security Team ◄───✗───► S2: Cloud Configuration State
│
INSUFFICIENT
interaction
The security team (S1) interacts with the cloud configuration (S2) through scanning (F). The scanner checks the configuration against a rule library of known-bad patterns. If the pattern is in the library, the scanner finds it. If the pattern is novel — a composition nobody has cataloged, a drift nobody has seen, a compound risk that exists in the relationship between resources rather than in any individual resource — the scanner misses it.
The interaction between the security team and the configuration state is insufficient. The scanner sees what it's been told to look for. It can't see what it hasn't been told to look for. The field (scanning) is limited to the extensional set of known patterns.
The deeper problem: scanners generate hundreds of alerts. The security team reviews them manually. At scale, the team can't keep up — alert fatigue. The human becomes the bottleneck in a system producing alerts faster than humans can triage them. This is the same structure as every overwhelmed-reviewer problem:
Machine produces high volume → Human reviews → Human can't keep up → Damage
The standard solution: insert a specification layer
The TRIZ catalog prescribes Standard Solution 2.1.1 — Chain Su-Field. Insert a third substance (S3) between S1 and S2, creating a chain where each link uses the appropriate field:
F1: Intent Authoring F2: Mechanical Verification
(slow, deliberate, human) (fast, exhaustive, machine)
▼ ▼
S1: Security Team → S3: Safety Invariants → S2: Cloud Configuration
(new substance)
The security team (S1) authors safety invariants (S3) through deliberate specification (F1) — slow, reviewed, requiring domain expertise. The invariants (S3) are verified against configuration state (S2) through mechanical evaluation (F2) — fast, exhaustive, deterministic.
The security team no longer reviews alerts from a scanner. They author invariants that define what must always be true. The machine verifies every configuration change against every invariant, mechanically, before deployment.
The human moves from reviewing output (large, fast, overwhelming) to authoring specifications (small, slow, manageable). The machine handles the volume. The human handles the intent.
Intent, Constraint, Verification — three layers, not one
A clarification that makes the platform's architecture precise. Three terms are often conflated. They're different layers:
Intent is the "why" — the business purpose that makes a configuration decision matter. "This bucket stores PII." "This database serves regulated healthcare data." Intent is subjective and contextual. A public S3 bucket isn't inherently wrong — it could host a static website. The wrongness only exists because of the intent (to store sensitive data).
Constraint is the "what must hold" — the safety boundary derived from the intent. "No resource tagged Sensitivity: High may have public access." A constraint is objective and verifiable. A machine checks the boolean without knowing why it exists.
Verification is the "does it hold?" — the mechanical act of checking the constraint against the configuration state. CEL predicate evaluated against JSON snapshot. True or false. Deterministic.
The three-layer flow:
Intent (human declares purpose)
→ "This bucket stores PII"
→ expressed as: tag Sensitivity: High
Constraint (derived from intent)
→ "Sensitivity: High implies: no public access, encryption at rest,
MFA delete enabled, access logging on, versioning on"
→ expressed as: CEL predicates referencing the tag
Verification (mechanical)
→ Engine evaluates each constraint against the snapshot
→ PASS or VIOLATION, deterministically
This distinction separates the platform from Policy-as-Code tools like OPA:
OPA has constraints without intent-derivation. To be fair: OPA CAN express the same tag-based invariant. A Rego policy can say deny if input.resource.tags.sensitivity == "high" and input.resource.public == true. The expressiveness gap isn't in what CAN be written. The gaps are structural:
First, OPA operates at one decision point (admission control) — it doesn't evaluate the full configuration lifecycle. A resource that passes the admission check and later drifts is invisible to OPA.
Second, OPA doesn't derive constraint sets from intent. If Sensitivity: High implies 12 constraints (no public access, encryption at rest, MFA delete, access logging, versioning, cross-account restrictions, and more), an OPA user writes 12 separate Rego rules. The specification-first platform derives all 12 from the single intent declaration. Change the intent, all 12 constraints update. In OPA, you update 12 rules manually.
Third, OPA doesn't compose across providers. An OPA policy for Kubernetes admission and a Sentinel policy for Terraform live in different systems with different languages, different evaluation contexts, and no shared state. The platform evaluates per-provider predicates through a shared engine against a shared lifecycle.
The specification-first platform has intent → constraint → verification. The intent (tag: Sensitivity: High) tells the platform WHY this bucket matters. The platform derives the constraint set from the intent — not one rule but the full set of safety properties that high sensitivity implies. The verification checks all derived constraints mechanically.
A fair objection: "the engineer who can't understand IAM composition will equally mis-tag data." These are different skills. Understanding five-layer IAM policy composition is a technical formal-logic skill. Knowing that a bucket contains customer PII is a domain knowledge skill. The security architect knows the data classification. The DevOps engineer writes the infrastructure code. The platform lets them work at their respective skill levels — the architect declares intent via tags, the platform derives constraints, the engine verifies. Neither person needs the other's skill.
The mapping from intent to constraints ("Sensitivity: High implies: no public access, encryption at rest, MFA delete, access logging, versioning, cross-account restrictions...") is authored ONCE by the security team, version-controlled, reviewed, and applied across every resource, every account, every team that uses the tag. An OPA user writes 12 discrete rules per deployment context. The platform centralizes the mapping. The complexity isn't eliminated. It's authored once and consumed many times. When the mapping needs debugging, the platform's Logic Trace (per-step evaluation record) shows exactly which constraint fired and why, with the evidence from the snapshot — the deterministic counterpart to "add more logging."
When the intent changes (the bucket is repurposed from PII storage to public documentation), the tag changes, the derived constraints change, and the verification adapts — automatically, without rewriting rules. The intent is upstream of the constraints. The constraints are upstream of the verification. Change the intent, the rest follows.
This is the architectural difference between current tools and the next platform:
Stage 3: "Public buckets are usually bad" (pattern match, no intent)
Stage 4: "This specific bucket must not be public" (explicit constraint, no intent)
→5: "This bucket stores PII; therefore these (intent-derived constraints)
12 constraints apply automatically"
The platform's job is to ensure the configuration always satisfies the constraints so that the intent is never compromised. The constraint is the mechanism. The intent is the meaning. The verification is the guarantee.
The Feedback & Control Trend: why Stage 4 is inevitable
TRIZ documents a pattern that repeats across every engineering discipline that has ever solved a safety problem:
No Control → Feedback → Adaptive Feedback → Feed-Forward → Self-Adaptive
| Stage | Property added | Cloud security exemplar |
|---|---|---|
| 1. No Control | Humans are the control loop | Manual security reviews |
| 2. Feedback | System observes and reports | CSPM scans and alerts |
| 3. Adaptive Feedback | Thresholds adjust over time | Risk-scored alerts, auto-triage |
| 4. Feed-Forward | System verifies before execution, blocks violations | Invariant gate in CI — proposed config checked against safety properties before deployment |
| 5. Self-Adaptive | System discovers new constraints autonomously | Intensional Datalog queries finding novel violation classes |
A structural note on the Su-Field chain: for the chain S1 → S3 → S2 to be stable, there must be a feedback loop from S2 back to S1 — the security team must learn from observed configuration patterns to author better invariants. Without this feedback, invariants are authored in a vacuum. Stage 5 (self-adaptive) is this feedback loop: the system analyzes configuration state, discovers patterns the team hasn't cataloged, and suggests new invariants. Intensional Datalog queries — "does ANY unauthorized path exist?" — surface findings that no existing invariant covers. Those findings feed back to S1, informing the next invariant to author. The chain becomes a cycle.
Most cloud security tools are at Stage 2-3. They scan, report, and prioritize. None verifies declared safety properties against proposed changes before deployment. The missing step is Stage 4: feed-forward verification.
The trend is unidirectional. Aviation moved from autopilots (Stage 3) to fly-by-wire envelope protection (Stage 4) when aircraft got fast enough that reactive correction was too slow. Cloud configuration change — driven by automation, IaC, and CI/CD pipelines — is now fast enough that reactive scanning is too slow. The same trigger. The same jump.
Optimizing Stage 3 delays the jump to Stage 4. It does not prevent it.
An important qualification: cloud environments are open systems. Configuration state changes via CI/CD pipelines (the feed-forward gate's scope), but also via the cloud console, automated scaling, expired TTLs, and third-party integrations. A Stage 4 CI gate only blocks pipeline-originated changes. It cannot prevent console drift or cloud-side mutations.
This means Stage 4 does NOT replace Stage 2/3. Both are needed — for different purposes. Stage 4 gates the pipeline: verify proposed changes before deployment. Stage 2/3 detects drift: periodically evaluate production snapshots to catch changes that bypassed the pipeline. The paired-snapshot architecture supports both: evaluate the proposed snapshot in CI (Stage 4) AND periodically evaluate the production snapshot (Stage 2/3, but now checking against declared invariants rather than pattern-matching against known-bad rules). The scanning doesn't disappear. Its purpose changes — from find things that look bad to verify that declared properties still hold.
| Tool / approach | Stage | Gap |
|---|---|---|
| Manual security review | 1-2 | Human is the control loop |
| CSPM scanning | 2 | Observes and reports after the change |
| Risk-scored alerting | 3 | Prioritizes reactively on thresholds |
| OPA / Kyverno / Sentinel | 3-4 | Feed-forward within one domain; not cross-lifecycle, not intent-derived |
| Specification-first platform | 4 | Per-provider predicates, shared engine; intent-derived constraint sets across lifecycle |
| Intensional Datalog detection | 4→5 | System discovers new unsafe states from property definitions |
"We already have specifications" — how this differs
Specification-driven approaches exist. What's different about what the Su-Field analysis prescribes?
The Su-Field model requires a complete chain: S1 → S3 → S2, with two fields — F1 (deliberate authoring) AND F2 (mechanical verification connecting S3 to S2). Existing tools provide fragments.
GitHub spec-kit: the closest — and the clearest gap
GitHub's spec-kit (100K+ stars) structures the AI-assisted workflow as: constitution → specify → plan → tasks → implement. Specifications before code generation. Multi-step refinement. Agent-native execution. Genuine progress.
In Su-Field terms, spec-kit has S3 (the specification) and F1 (deliberate authoring). The gap: F2 — continuous mechanical verification that the system still satisfies the specification after generation. Spec-kit specifications guide generation but don't gate subsequent changes. After implementation, the spec is an archive. The specification is an INPUT to generation, not a CONSTRAINT on the system for its lifetime.
The rest of the landscape
| Existing approach | What it specifies | Su-Field gap |
|---|---|---|
| GitHub spec-kit | Feature requirements | No F2 — specs guide generation, don't verify ongoing compliance |
| OpenAPI / Protobuf | Interface structure | Not safety properties — wrong field |
| Design by Contract | Method invariants | Implementation-coupled — S3 merged with S2 |
| BDD / Gherkin | Behavioral scenarios | Extensional — enumerates cases, not properties |
| TLA+ / Alloy | System properties | Design-time only — doesn't verify running systems |
| OPA / Cedar | Authorization policies | Domain-scoped — doesn't compose across all properties |
| Terraform / Pulumi | Infrastructure state | Implementation spec — what to build, not what's safe |
In plain language
Every domain has a different name for the same thing. Cloud security calls it the "safety envelope." Aviation calls it the "flight envelope." Hardware calls it the "testbench." Each name carries jargon. The concept is simple:
You write down the rules for what correct means. The machine checks every change against the rules. Automatically. Every time. Before anything ships.
In cloud security, the rules say: "no public bucket with sensitive data," "no IAM role that allows privilege escalation," "no security group open to the internet on port 22."
In aviation, the rules say: "no flight condition that exceeds structural load limits," "no airspeed below stall threshold."
In nuclear operations, the rules say: "temperature below X, pressure below Y, neutron flux within band Z."
Different domains. Different rules. Same mechanism: a human writes down what must always be true. A machine checks whether it's true. The human is slow and accurate (writing the rules). The machine is fast and exhaustive (checking the rules). Neither does the other's job.
"Aren't specifications as hard to write as code?"
These are not full specifications. They're not complete behavioral descriptions. They're safety properties — boundary conditions that say what must NEVER be true:
Full specification (complex):
"S3 bucket access must be granted only to principals in the owning
account's IAM identity store, through policies attached at the bucket
level or inherited through the account's SCP chain, evaluated in
deny-override order, with cross-account access permitted only via
resource policies that specify explicit principal ARNs..."
Safety property (simple):
asset.tags.Sensitivity == "High" && asset.public_access == true
One line. The implementation that enforces this across API paths, bucket policies, ACLs, public access blocks, cross-account access, and VPC endpoints is hundreds of lines. The safety property doesn't describe HOW access control works. It describes ONE boundary that must never be crossed.
One dependency this creates: the invariant trusts the tags. If a developer forgets to tag a bucket Sensitivity: High, the invariant passes but the system is unsafe. The specification layer (S3) depends on the accuracy of the configuration state (S2). This circular dependency is partially resolved by meta-invariants that enforce tag presence and protection: "every bucket in the production account must have a Sensitivity tag," "only members of SecurityDataOwners may modify Sensitivity tags."
A scope boundary must be acknowledged: the platform can enforce that tags EXIST and that only authorized principals can CHANGE them. It cannot deterministically verify that the tag is CORRECT — that a bucket tagged Sensitivity: Low doesn't actually contain PII. Verifying tag correctness requires data scanning or classification (a separate capability, inherently probabilistic). The platform's guarantee is: IF the intent is declared correctly, THEN the constraints derived from it are enforced mechanically. The accuracy of the declaration is the developer's responsibility — the same way the accuracy of a legal contract's terms is the signer's responsibility. The system enforces the contract. It doesn't verify the signer's honesty.
Safety properties are tractable because they're asymmetric. The unsafe states are finite and learnable — public bucket + PII tag, privilege escalation path, ghost reference to deleted resource. The safe states are effectively infinite. You specify the small set (what must never be true) and the machine checks whether the current state is in that set.
One caveat the asymmetry claim must acknowledge: many unsafe states are emergent, not static. A private bucket (safe) + an IAM role with access to it (safe) + an external entity that can assume that role (safe) = an unauthorized access path (unsafe). The individual states are safe. The composition is not. Simple one-line CEL predicates catch individual misconfigurations. Compound risks require graph-based reachability analysis — which is why the multi-engine primitive (CEL for atomic properties, Datalog for reachability, SMT solvers for satisfiability) exists. The asymmetry holds: even compound unsafe states are specifiable as properties ("no unauthorized path from any external principal to any sensitive resource"). But the verification engine for compound properties is more sophisticated than a boolean predicate over a JSON field.
A scope clarification: the asymmetry holds for configuration state, where unsafe patterns are finite and learnable from the incident record. It does NOT hold for runtime security (zero-days, novel lateral movement techniques), where the unsafe space is effectively infinite and ever-expanding. This platform is scoped to configuration verification — the state that can be captured in a snapshot and evaluated offline. Runtime threat detection is a different problem requiring different architecture.
One operational reality must be acknowledged: cloud providers release new access paths regularly. When AWS ships S3 Access Grants or VPC Lattice, a new way to share resources exists that the observation contract doesn't yet capture. Until the schema is extended and the collector updated, the invariant returns PASS — a false negative, because the new path isn't observed.
This is a real maintenance burden. Every security tool faces it — when AWS ships a new feature, OPA doesn't know about it, CSPM scanners don't have rules for it, and policy engines don't evaluate it. The difference in the specification-first model: the gap is VISIBLE. stave gaps reports which asset properties the observation contract covers and which it doesn't. stave readiness reports how many controls can fire given the current collector's coverage. In a CSPM, the gap is invisible — you don't know what the scanner doesn't check. In the specification-first model, the gap is a measured, tracked, reportable metric. The maintenance burden is real. The visibility of the burden is the structural advantage.
A common objection: "authoring a Datalog query for 'unauthorized path' is just as complex as writing the code it checks." This is empirically false. The Datalog query is six lines:
violation(Principal, Resource, Action) :-
unauthorized_access(Principal, Resource, Action),
sensitivity(Resource, "high"),
read_action(Action).
While the query is indeed simple, the verification correctness relies on the Model Extractor (the thing that turns AWS IAM into Datalog facts). The complexity doesn't disappear; it lives in the logic that translates AWS's proprietary logic into the facts the Datalog engine processes.
The IAM policy evaluation logic it checks — role assumption chains, permission boundaries, resource policies, SCPs, session policies, cross-account trust — is thousands of lines across dozens of AWS services. The query is intensional: it defines WHAT constitutes a violation and the engine finds ALL instances, including compositions nobody enumerated. The IAM code is extensional: it implements HOW policies are evaluated, case by case. One query, all paths. The complexity traded isn't "configuration complexity for query complexity" — it's "enumerating every possible path" for "defining the property that characterizes unsafe paths." The property is always smaller than the enumeration.
"We tried specifications before. They failed."
The software industry attempted specification-driven development three times — formal methods in the 1980s (Z notation, VDM), heavyweight requirements engineering in the 1990s, and model-driven development in the 2000s. Each failed for the same reason: the specification tried to describe what the system does — its complete functionality. A complete functional specification is as complex as the implementation. Maintaining both is double the work.
This approach is structurally different because it specifies what the system must never do, not what the system does:
Past: Spec complexity ≈ Code complexity → unsustainable
Current: Spec complexity << Code complexity → tractable
Three structural differences: correctness not completeness (specs describe boundaries, not features), CI-enforced not document-maintained (machine checks on every commit, no silent drift), and simple language not formal notation (CEL is readable by any engineer, no formal-methods training needed).
The platform primitives
Each primitive is derived from the resolved Su-Field:
1. Specification as a typed, versioned entity. Not a markdown file. A structured object with a schema: the property being declared, the scope, the rationale, the verification method, the owner. Queryable, composable, diffable.
2. Rationale as structured metadata. Every specification carries its "why" — not as a comment, but as a first-class field. The legal system's written opinion, as a platform primitive.
3. Coverage as a first-class metric. What percentage of cloud resources are governed by explicit specifications? What resources have zero specs? What specs haven't been reviewed since their covered resource changed? The cognitive-debt-visible instrument.
4. Multi-engine verification. Different specs require different engines. Boolean properties go to CEL. Arithmetic properties go to SMT solvers. Reachability properties go to Datalog. The platform routes each spec to the appropriate engine.
5. Continuous contract composition. Resources have interface contracts. When a resource changes, the platform verifies that its contracts still compose with its neighbors. The aerospace ICD, as a platform primitive.
6. Specification review replaces alert triage. The deliberate, slow, high-value human activity is reviewing specification changes — new invariants, modified contracts, updated rationale. A configuration change that satisfies all existing specifications needs no human review. The specs reviewed it.
The precedents
Every domain that faced the same broken Su-Field resolved it by inserting a specification substance:
| Domain | S1 | S3 (inserted) | S2 | Resolved? |
|---|---|---|---|---|
| Nuclear operations | Operator | Operating envelope | Reactor state | Yes, since 1980s |
| Law | Judge | Written opinion | Legal precedent | Yes, since common law |
| Aerospace | Engineer | Interface Control Document | System architecture | Yes, since 1960s |
| Military | Commander | Commander's Intent | Unit decisions | Yes, since 1980s |
| Healthcare | Administrator | Outcomes metrics | Patient safety | Yes, since 2000s |
| Cloud security | Security team | ??? (not yet built) | Cloud configuration | No |
Cloud security is the last row. The specification substance doesn't exist as a platform primitive. Scanners check known patterns. No platform verifies declared safety properties against configuration state, continuously, before deployment.
The next platform fills that row.
Why code generation is the wrong unit of progress
The specification-first model for cloud security illuminates a broader pattern the software industry keeps rediscovering: the right unit of progress is the composable function with a verified interface, not the generated artifact.
In cloud security, scanners generate alerts. More rules produce more alerts. The volume increases. The signal decreases. The team drowns. The specification-first platform inverts this: instead of generating more alerts (volume), it verifies fewer invariants (properties). The invariant is a reusable function — "no public bucket with sensitive data" is checked on every configuration change, forever, without generating a new alert each time. The alert appears only on violation. The invariant is the unit, not the alert.
Unix proved the same principle for software 50 years ago. grep, sort, uniq, awk — each one is a function with a stable interface (stdin/stdout). They've survived the evolution of hardware, operating systems, and programming languages because the unit of reuse is the function, not the code. You don't generate a new grep for each project. You compose existing functions through interfaces.
Google proved it at organizational scale. When a team needs an RSS feed generator, they reuse the existing RSS function — they don't generate new code that reimplements RSS parsing. Productivity comes from composition of verified functions, not generation of new code.
The pattern across all three domains:
Alert generation: More alerts → more volume → more triage debt
Code generation: More code → more volume → more maintenance debt
Invariant composition: Same invariants, verified automatically → more safety → debt in YAML, not in code
Function composition: Same functions, composed differently → more capability → debt in interfaces, not in implementations
The specification-first platform for cloud security doesn't eliminate maintenance. Invariants need updating when business requirements change. False-positive tuning is real work. A catalog of 2,662 controls is a body of logic to maintain. But the debt is restructured: version-controlled YAML declarations reviewable in PRs, not scattered scanner rules or complex IAM compositions. The maintenance surface is visible (stave gaps, stave readiness report what's covered and what isn't) and the changes are diffable. The debt doesn't disappear. It moves to a form where it's manageable by one person.
The platform composes safety from reusable, verified, stable invariants that share a structural property with Unix tools: small, stable interface, endlessly composable, rarely regenerated.
The analogy is about the unit structure, not the function type. Unix tools transform data to create new capability. Invariants restrict state to prevent loss. Different functions. Same unit structure: small, independently useful, composable through standard interfaces, reusable across contexts without modification. The unit of progress in security is reduced risk, not increased capability — but the architectural pattern for achieving it (compose verified units rather than generate new artifacts) is the same.
A fair challenge: "an invariant is a rule — calling it an invariant is a semantic shift, not a structural one." The semantic shift is real. The structural difference is in three properties: an invariant is authored once and applied across every resource that matches its scope (a scanner rule is often implementation-coupled and tied to a specific check). An invariant is verified mechanically on every state change across the lifecycle (a scanner rule runs at scan time). An invariant composes with other invariants through the evaluation engine (scanner rules are independent checks with no composition). The word is different. The authorship model, verification model, and composition model are also different.
The Su-Field analysis makes the structural argument precise: the current cloud security workflow has an incomplete interaction between security teams and configuration state. The field that connects them (scanning) is limited to known patterns. The TRIZ standard solution is to insert a new substance (specification layer) that creates a chain: human-speed intent authoring on one side, machine-speed verification on the other.
The specification layer isn't a documentation practice. It isn't a process improvement. It's the missing substance in the Su-Field model. Without it, the interaction between security team and configuration state remains insufficient regardless of how many scanning rules you add.
With it, the security team moves from triaging alerts to authoring invariants. The machine handles the volume. The human handles the intent. The safety properties are verified on every change, before deployment, mechanically and exhaustively. The platform fills the last row in the precedents table — the one every other high-stakes domain filled decades ago.
Top comments (0)