# Language Agnostic Module Representation

> Source: <https://about.a3rn.com/blog/lamp-language-agnostic-module-representation/>
> Published: 2026-07-16 22:48:21+00:00

A proposal for an intermediate representation that captures software modularity before code is generated.

## 1. Overview

### 1.1 Motivation

Agentic coding assistants generate code that compiles and passes tests. Depending on the model and context size, the generated code often lacks coherent modular structure and code hygiene.

The artifacts that feed generation don't address modularity.

- Requirements and tests describe behavior, not decomposition.
- Design and tasks describe approach, not module contracts.

Language-Agnostic Module rePresentation (LAMP) fills the gap with a reviewable artifact that commits to modular intent before code exists: what each module encapsulates and exposes, the capability contracts the agent must honor, and a modularity audit that gates generation rather than reviewing it afterward.

### 1.2 What LAMP is

LAMP sits between architectural component-level design and code. It captures a system's modular structure in a form reviewable before any implementation exists. The agent or human generating code is then constrained where it matters (module boundaries, encapsulation, observable contracts) and free where it doesn't (types, languages, data structures, concurrency). It also shrinks the context window, saving token costs.

LAMP serves two goals:

**Module Review:** a target for human review and modularity auditing before code changes.**Code Generation:** a contract the agent honors when producing code and tests.

LAMP is part of a software development pipeline:

```
DESIGN
   → decompose into modules around encapsulated decisions
LAMP
   → generate implementation honoring the contracts
CODE
```

LAMP rests on four principles drawn from established modularity practice:

**Information hiding.** Each module is organized around a design decision it encapsulates. Callers depend on the interface. The encapsulated decision can change without disturbing them.**Deep abstractions.** A module's value is proportional to how much implementation it hides behind how small an interface.**Decomposition by change axis.** Modules are drawn around what is likely to change, not around data structure or algorithm steps.**Stable contracts.** A module's interface is more stable than its implementation, and more stable than the requirements that motivated it.

## 2. Document layout

A LAMP artifact is a directory of Markdown files.

```
lamp/
  capability.md        # capability registry
  modules.md           # All module manifests
```

## A single file is the default because LAMP modules are small. When a system has many modules or capabilities and a single file grows unwieldy, split them across several files. Name a module file with a `module`

prefix (e.g., `module-<family>.md`

) to group related modules. Name a capability file with a `capability`

prefix (e.g., `capability-<family>.md`

).

## 3. The module specification

The module manifest answers three questions: *what does this module hide, what does it offer, what does it need?* Each module is a top-level section in `modules.md`

, with these subsections in order. All are required.

```
# Module: <name>

## Encapsulates
The design decision or complexity this module hides. State it in
caller irrelevant terms.

## Provider Capabilities
Markdown links into the capability registry in `capability.md`, one per
line.

  - [issue-session](capability.md#capability-issue-session)
  - [resolve-session](capability.md#capability-resolve-session)
  - [revoke-session](capability.md#capability-revoke-session)

## Consuming Capabilities
Markdown links into the capability registry, one per line.
Dependencies are on capabilities, never on other modules directly.

  - [monotonic-clock](capability.md#capability-monotonic-clock)
  - [opaque-bytes-storage](capability.md#capability-opaque-bytes-storage)
```

### 3.1 Authoring rules

**Encapsulation is named in caller-irrelevant terms.**"How sessions are stored, expired, and revoked" — good. "Uses Redis with TTL" — leaks.** Capability names don't leak implementation.**`flush_to_disk()`

leaks;`commit()`

doesn't.`cache_evict()`

leaks;`forget(handle)`

doesn't.**Dependencies are on capabilities, not modules.** Say*opaque-bytes-storage*, not*PostgresStore*.**No types, signatures, or language idioms.**`Promise<Result<Session, Error>>`

is implementation.

## 4. The capability specification

Capabilities live in `capability.md`

's registry. Each is declared once. The heading format is fixed. Module manifests link to capabilities by anchor, so the heading is part of the contract.

```
### capability: <verb-phrase-name>

Description: one sentence on what this accomplishes for a caller.

Inputs: Description of inputs.

Outputs: Description of outputs.

Requires: what must hold for the capability call to be valid.

Guarantees: what is true on successful completion.

Failure modes: caller meaningful error categories.

Providers: List one or more providers who implement the capability. The capability registry and module manifests form a navigable graph in both directions.
  - [<module-name>](modules.md#module-<module-name>)
  - [<module-name>](modules.md#module-<module-name>)
```

### 4.1 Authoring rules for capabilities

**Verb-phrased.**"issue", "resolve", "find-by-prefix" — verbs. Nouns like`session()`

are smells; usually a leaked data structure.**Inputs and outputs by role, not type.**"subject" and "handle", not`string`

and`UUID`

.**Failure modes are caller-meaningful.**"not-authorized" tells a caller something. "RedisTimeoutException" leaks.

## 5. A worked example

From a user requirement:

As a service, I want to issue, validate, and revoke session handles so I can recognize returning callers without rechecking credentials on every call.

Acceptance criteria:

- Given a valid subject, when I issue a handle, resolving it returns the original subject.
- Given a revoked handle, resolving it returns invalid.
- Given an expired handle, resolving it returns invalid.
- Two handles for the same subject are distinct and unguessable.

LAMP excerpts:

`capability.md`

capability registry:

```
### capability: issue-session

Description: produces an opaque handle representing an authenticated subject.
Inputs:
  - subject: the principal the session represents
  - claims: caller-supplied attributes
Outputs:
  - handle: opaque reference
Guarantees:
  - The handle is valid until revoked or expired.
  - The handle is distinct from every previously-issued handle.
  - The handle is not guessable from prior handles.
Failure modes:
  - capacity-exhausted
Providers:
  - [SessionStore](modules.md#module-sessionstore)

### capability: revoke-session

Description: invalidates an issued handle.
Inputs:
  - handle: an opaque reference previously returned by issue-session
Guarantees:
  - After this returns, resolve-session(handle) returns invalid.
  - Subsequent revoke-session(handle) calls are accepted with no further effect.
Providers:
  - [SessionStore](modules.md#module-sessionstore)
```

`modules.md`

(SessionStore section):

```
# Module: SessionStore

## Encapsulates
How sessions are stored, expired, and revoked. Whether storage is
in-memory, in a database, or encoded into the handle itself is hidden.
Whether revocation is push-based or pull-based is hidden.

## Provider Capabilities
- [issue-session](capability.md#capability-issue-session)
- [resolve-session](capability.md#capability-resolve-session)
- [revoke-session](capability.md#capability-revoke-session)

## Consuming Capabilities
- [monotonic-clock](capability.md#capability-monotonic-clock)
- [opaque-bytes-storage](capability.md#capability-opaque-bytes-storage)
```


