Axiomatic Reasoning for LLMs

Implementation Plan on Scala

1. Overview

This plan defines a specification‑driven development methodology for Scala. The methodology separates intent, structural specification, and implementation into distinct layers. Implementation artifacts are generated from machine‑readable specifications and automatically verified against architectural constraints. Development proceeds in phases, each phase committing a fixed premise (versioned specification + dependencies) for recursive refinement.

All principles are mapped to executable Scala constructs and toolchain integrations.

2. Core Principles to Scala Mapping

Principle Scala Implementation Tooling
Intent–Structure–Implementation Separation Opaque types, package layering, traits (specification) + concrete classes (implementation) Scala 3 compiler
Generative Conformance Code generation from Smithy IDL / OpenAPI / Protobuf Smithy4s, OpenAPI Generator, sbt-protoc
Skeleton–Tissue Architecture Abstract classes with final template methods, control‑flow functions, ZIO Layers Scala standard library, ZIO
Validation Gates Compiler flags, Scalafix custom rules, sbt-dependency-graph, MiMa, TASTy-MiMa scalac, Scalafix, MiMa
Recursive Refinement Git tags, semantic versioning, API compatibility checks Git, sbt‑version‑policy

3. Structural Specification Layer

The specification is expressed in a machine‑readable format and stored under specification/.

Scope Format Tool
API boundaries (HTTP/REST) Smithy IDL (preferred) or OpenAPI 3.0+ YAML Smithy4s, OpenAPI Generator
Internal module contracts Scala traits + opaque types Scala 3 compiler
Data models Smithy structures or JSON Schema Smithy4s, zio‑schema

Selection rule: Use Smithy IDL for all service boundaries. It is protocol‑agnostic and generates both client and server code. Use opaque types for internal type‑level contracts.

4. Skeleton–Tissue Architecture

4.1 Skeleton Layer (Manual, Immutable)

The skeleton owns the invariant control flow and cross‑cutting concerns. It is written once by humans and never modified by generated code.

Pattern A: Template Method (abstract class + final)

// skeleton/PipelineSkeleton.scala
abstract class PipelineSkeleton:
  final def execute(input: Input): Output =
    val validated = validate(input)
    val processed = transform(validated)
    val persisted = save(processed)
    log(persisted)
  
  protected def validate(input: Input): Validated
  protected def transform(validated: Validated): Transformed
  protected def save(processed: Transformed): Persisted
  protected def log(persisted: Persisted): Output

Pattern B: Control‑Flow Function + Interface (no inheritance)

// skeleton/RunLoop.scala
trait Steps[F[_]]:
  def init: F[Unit]
  def step: F[Int]
  def cleanup: F[Unit]

object RunLoop:
  final def run[F[_]: Monad](steps: Steps[F]): F[Int] =
    for
      _ <- steps.init
      result <- steps.step
      _ <- steps.cleanup
    yield result

Pattern C: Opaque Type for Boundary Enforcement

// specification/Ids.scala
package specification:
  opaque type UserId = UUID
  object UserId:
    def apply(id: UUID): UserId = id
    extension (uid: UserId) def value: UUID = uid

4.2 Tissue Layer (Generated)

The tissue implements the skeleton interfaces. It is fully generated from the structural specification.

// tissue/PipelineImpl.scala (generated)
class PipelineImpl extends skeleton.PipelineSkeleton:
  override protected def validate(input: Input): Validated = // generated
  override protected def transform(validated: Validated): Transformed = // generated
  override protected def save(processed: Transformed): Persisted = // generated
  override protected def log(persisted: Persisted): Output = // generated

4.3 Dependency Direction

5. Code Generation Tools

Tool Input Output Use Case
Smithy4s Smithy IDL Service traits, DTOs, client/server stubs API contracts (preferred)
OpenAPI Generator OpenAPI YAML Scala client (sttp4 + jsoniter) External API clients
sbt-protoc + ScalaPB .proto Case classes, gRPC stubs Internal RPC
zio‑schema Scala case classes (derived) Schemas, codecs, migrations Data contract evolution
Scala 3 macros Inline definitions Method implementations Boilerplate reduction

Recommendation: Use Smithy4s as the primary generator. It produces a complete skeleton (service traits) from a single specification and supports multiple protocols.

6. Validation Gates (Four Layers)

Layer 1: Compile‑time

// build.sbt
ThisBuild / scalacOptions ++= Seq(
  "-Xfatal-warnings",      // warnings → errors
  "-Xsource:3",            // Scala 3 migration warnings
  "-language:explicitNulls", // explicit null safety
  "-Wconf:cat=scala3-migration:e" // migration warnings as errors
)

Layer 2: Static Analysis (Scalafix)

Custom rule to enforce skeleton‑tissue dependency direction:

// custom-rules/src/main/scala/fix/LayerEnforcer.scala
class LayerEnforcer extends SyntacticRule("LayerEnforcer") {
  override def fix(implicit doc: SyntacticDocument): Patch = {
    doc.tree.collect {
      case imp @ Importee.Name(Name("tissue")) 
          if doc.input.syntax.contains("skeleton/") =>
        Patch.lint(Diagnostic("", "Skeleton cannot import tissue", imp.pos))
    }.asPatch
  }
}

Run in CI: sbt "scalafix --check"

Layer 3: Dependency Graph

Detect circular dependencies using sbt-dependency-graph:

sbt dependencyTree | grep -q "cycle" && exit 1

Layer 4: Runtime Tests

Standard ScalaTest / Specs2 suites. Generated tissue code must pass all unit and integration tests.

Compatibility Gates (Phase Boundaries)

// build.sbt
mimaPreviousArtifacts := Set("com.example" %% "module" % "1.0.0")
tastyMiMaPreviousArtifacts := Set("com.example" %% "module" % "1.0.0")

7. Recursive Refinement Workflow

Each phase follows this sequence:

  1. Plan – Define changes to structural specification (Smithy IDL, OpenAPI, etc.)
  2. Generate – Run code generators (Smithy4s, OpenAPI Generator, sbt-protoc)
  3. Validate – Execute all four validation gates + compatibility checks
  4. Commit – If all pass, commit specification + generated code as a fixed premise (Git tag)
  5. Repeat – Next phase

Rollback: git checkout <previous-tag> && sbt clean compile

Parallel phases: Use Git worktree for concurrent specification branches.

8. Implementation Phases and Timeline

Phase Scope Deliverable Duration
0 Infrastructure SBT multi‑module layout, Scalafmt, Scalafix base config 2 weeks
1 Skeleton design Abstract classes, control‑flow functions, opaque types 3 weeks
2 Structural specification Smithy IDL files for one module 2 weeks
3 Generation pipeline Smithy4s integration, generated code in tissue/ 3 weeks
4 Validation gates Scalac flags, Scalafix rule, MiMa, CI workflow 3 weeks
5 Pilot project Apply to one service, measure regeneration and bug rates 4 weeks

9. Directory Structure

project-root/
├── specification/
│   └── api/
│       └── service.smithy
├── skeleton/
│   └── core/
│       ├── ServiceInterface.scala   (generated by Smithy4s)
│       └── TemplateMethodBase.scala (manual)
├── tissue/
│   └── generated/
│       └── ServiceImpl.scala        (generated)
├── project/
│   ├── build.sbt
│   └── plugins.sbt
└── .scalafix.conf

10. Constraints and Mitigations

Constraint Mitigation
Scala 3 macros cannot generate top‑level definitions Use Smithy4s for top‑level generation; macros for intra‑file expansions
TASTy‑MiMa is less mature Combine with manual API review for critical modules
ZIO dependency for environment‑type pattern Provide non‑ZIO alternative (constructor injection)
Cross‑build with Scala 2.13 Restrict to Scala 3.3+; use separate build modules for legacy code
Smithy IDL learning curve Provide templates and tooling documentation

11. Conclusion

Scala 3 provides all necessary features to implement a specification‑driven, AI‑assisted development workflow:

The methodology eliminates implementation‑level bugs caused by interface mismatches, enables safe refactoring through specification‑only changes, and keeps cognitive overhead independent of codebase size. The plan is ready for production use in server‑side Scala, microservices, and data pipeline projects.