-
Notifications
You must be signed in to change notification settings - Fork 0
[E] AI Language Agnostic Model
This document maps the structured workflow for generated + handcrafted systems to a language‑agnostic implementation model.
It applies equally to:
- compiled and interpreted languages,
- monoliths and microservices,
- template‑based generators and AI‑assisted generators.
The goal is to describe what must exist, not how a specific language does it.
Every sustainable generated system follows five phases:
- Architecture Design
- Metadata Definition
- Code Generation
- Handcrafted Extension
- Testing and Integration
These phases are conceptual, not tool‑specific.
Purpose: Decide structure before implementation.
- System boundaries
- Modules / services / components
- Data ownership and responsibility
- Interaction patterns (sync, async, events)
- Architecture decision records (ADRs)
- Diagrams (C4, UML, simple boxes and arrows)
- Explicit layering or service boundaries
- Java, C#, Go, Rust, Python, JavaScript
- Monoliths, modular monoliths, microservices
- Backend, frontend, and mixed systems
Invariant
Architecture constrains generation. Generation must not invent architecture.
Purpose: Define the system declaratively.
- Data schemas (tables, entities, documents)
- API contracts (requests, responses, events)
- Validation rules and constraints
- Deployment and environment metadata
- SQL catalogs / schema introspection
- OpenAPI / AsyncAPI
- JSON Schema / Protobuf / Avro
- DSLs or configuration files (YAML/JSON/TOML)
- Metadata exists independently of code
- Metadata is versioned and validated
- Multiple consumers can use the same metadata
Purpose: Transform metadata + architecture into code.
- Deterministic output
- Idempotent regeneration
- Clear ownership of generated files
- Template engines (Mustache, Jinja, Handlebars)
- Build‑time generators
- CLI‑driven generation pipelines
- AI‑assisted generation with pinned prompts
- Same inputs → same outputs
- Generators are replaceable
- Generated code is disposable
Purpose: Add human intent safely.
- Inheritance or composition
- Interfaces / ports / adapters
- Hooks, callbacks, extension points
- Partial classes or separate modules
- Domain layers separate from generated layers
- Explicit “do not edit” boundaries
- Human‑owned directories or packages
- Handwritten code is never overwritten
- Regeneration is always safe
- Human intent remains authoritative
Purpose: Validate the whole system, not just the output.
- Schema and contract validation
- Generated code compilation/linting
- Unit tests for handwritten logic
- Integration tests across boundaries
- CI pipelines validate regeneration
- Diff‑based checks (generation produces no drift)
- Automated deployment tests
- Generated and handwritten code are tested together
- Regeneration is part of CI
- Failures are traceable to source (metadata, template, or code)
| Concept | Language‑Specific Example | Language‑Agnostic Equivalent |
|---|---|---|
| Dictionary | Clarion dictionary | Schema / model definition |
| Template | Clarion / ABC templates | Generator template / prompt |
| Embed | Named embed point | Extension hook / adapter |
| Generated file | .clw |
Generated module |
| Handwritten code | Embed / parent class | Domain logic |
| Regenerate | App generation | Deterministic rebuild |
These rules apply regardless of language:
- Architecture is designed, not inferred
- Metadata is explicit and independent
- Generation is deterministic
- Handwritten code is protected
- Quality is never reduced by automation
This workflow works because it separates intent from mechanics:
- Architecture expresses intent
- Metadata encodes intent
- Generators automate mechanics
- Humans write meaning
When these roles are respected, systems:
- scale across languages,
- survive tooling changes,
- and remain maintainable for decades.
Languages change. Tools change.
This workflow endures because it encodes responsibility, not syntax.