agentleFS
rakaarwakyrakaarwaky/agents-arwaky/skills/aes-architecture/aes-surface/SKILL.md

aes-surface

Skill0 starsChanged 26 days agoMITView on GitHub

AES surface command and UI scaffolding for Python Rust TS. Use when creating surface files.

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Every rule is machine-checked by lint-arwaky-cli scan <layer-path> (see each HOW-TO § Verify).

    line 66
  2. Very specific:

    Surface folders carry a DESIGN.md: Every surface folder documents how its surface looks and behaves in DESIGN.md at the folder root, next …

    line 107
  3. Very specific:

    Write each row against the real code.

    line 125
  4. Distinctive:

    Ask these questions in order.

    line 136
  5. Distinctive:

    Check error handling: nothing discarded, no empty fallbacks.

    line 157

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

aes-surface

Purpose: Scaffold AES surface files — map input to VOs, call the aggregate, render results; no business logic. Audience: The agent creating or validating a surface command/controller/component. Scope: Python, Rust, and TypeScript surface_<domain>_<role> files — Smart / Utility / Passive tiers.

The layer decides which suffix, which imports, and which structure apply. Rules, templates, section contracts, and Verify blocks live in the language HOW-TUs under references/.

LanguageFocusBody ruleHOW-TO
PythonCommand / controller / componentSmart / Utility / Passive tiers; no business logicreferences/HOW-TO-MAKE-PYTHON-SURFACE.md
RustCommand / controller / componentSmart / Utility / Passive tiers; no business logicreferences/HOW-TO-MAKE-RUST-SURFACE.md
TypeScriptCommand / controller / componentSmart / Utility / Passive tiers; no business logicreferences/HOW-TO-MAKE-TYPESCRIPT-SURFACE.md

The layer chain:

surface (Smart → _aggregate, Utility/Passive → taxonomy) → agent → capabilities — never surface→capabilities directly

Each file answers one layer's job. A method or import in the wrong layer is the defect this skill exists to prevent.


Invariants

Every rule is machine-checked by lint-arwaky-cli scan <layer-path> (see each HOW-TO § Verify). A rule cannot drift from the gate. Cite the linter, not this file, when pointing at a rule.

LayerRule
NamingFile surface_<domain>_<role> — suffix in the surface allow-list; _entry is root, not surface (AES101/AES102).
TiersSmart (_command/_controller/_page): taxonomy + _aggregate + utility. Utility (_hook/_store/_action/_screen/_router): taxonomy only. Passive (_component/_view/_layout): taxonomy only (AES406 / AES201).
BehaviourZero business logic and zero computation in every tier; Smart delegates through the injected aggregate only.
ErrorsNever silently discard — no or None / unwrap_or_default() / ?? UiState…; return Ok/Err or update an error-state VO.
StateAll state fields use shared VOs — no primitives, no local domain models.
RegisterPackage module export where required.
Verifylint-arwaky-cli scan <layer-path> → 0. Language compile is fallback only.

Split details, templates, and Section Contract tables: read the language HOW-TO — do not restate them here.


Placement (AES703)

A surface_* file belongs in a surface folder — a subdirectory of a member directory (crates/, modules/, packages/) whose name matches the kind of surface it carries:

crates/api/src/surface_*_handler.rs        # HTTP API
crates/mcp/src/surface_*_tool.rs           # MCP server
crates/cli/src/surface_*_command.rs        # CLI
crates/desktop/src/surface_*_window.rs      # desktop UI
crates/tui/src/surface_*_screen.rs         # terminal UI

The folder name says what kind of surface it is. api, mcp, cli, desktop, and tui are the usual names; a surface folder whose name says nothing about the surface it serves gives the reader no way to tell which entry point uses it.

A surface folder carries surface files only. A capabilities_* or agent_* file found in one is misplaced — the folder is surface-dominated (more surface files than everything else combined), and that file must move to a feature folder. This is an AES703 violation.

Alongside the surface files a surface folder may keep utility_* helpers, root_* wiring, and barrels (lib.rs, mod.rs, __init__.py, index.ts). Those are allowed.

Surface folders carry a DESIGN.md. Every surface folder documents how its surface looks and behaves in DESIGN.md at the folder root, next to its source. A surface-dominated folder carrying no DESIGN.md is an AES703 violation — the linter names the folder and you write the file.

The file is written for the developer who arrives before you and has to change something without reading every source file. It carries six sections:

SectionAnswers
## KindWhich surface this is — api, mcp, cli, desktop, tui — and what the layer does and does not own.
## Entry PointsOne row per entry: the file, what the user or caller invokes, and which aggregate it reaches.
## Request ShapeWhat a request looks like once it arrives, and what has already been resolved.
## StatesEach state a caller can observe, the condition that produces it, and what the user sees.
## Error StatesEach failure mode, where it is caught, and what the caller gets.
## InvariantsThe rules a change must not break.
## Change ChecklistWhich files to touch for which kind of change.

Write each row against the real code. A DESIGN.md that restates the layer definition instead of naming this folder's files has told the reader nothing they could not get from ARCHITECTURE.md, and AES703 will pass while the file stays useless.

Feature folders carry two documents instead — FRD.md and BACKLOG.md — recording what the feature does and where its work stands. shared/ folders carry neither.


Diagnostic Tree

Ask these questions in order. The first "No" dictates your next action.

  1. What tier is this — Smart / Utility / Passive?
    • Smart → inject aggregate; Utility/Passive → taxonomy-only imports.
  2. Is the suffix in the surface allow-list (never _entry)?
    • No → rename to a legal surface suffix (or root_*_entry if it bootstraps).
  3. Any business logic, computation, or direct capability calls?
    • Yes → move logic down; surface only maps and delegates.
  4. Any silently discarded errors or primitive state fields?
    • Yes → propagate errors; wrap state in VOs.
  5. Does lint-arwaky-cli scan <layer-path> exit 0?
    • No → fix findings, re-scan.

Workflow

  1. Determine the tier (Smart / Utility / Passive) and pick the matching suffix.
  2. Resolve the feature surface dir. Run lint-arwaky-cli scan <layer-path> — findings are your work list.
  3. Draft from the language HOW-TO § Template / § Section Contract; Smart injects the aggregate via DI.
  4. Enforce that tier's import rules; strip business logic and computation.
  5. Check error handling: nothing discarded, no empty fallbacks; state fields are VOs.
  6. Register the module where required, verify with lint-arwaky-cli scan, then wire via aes-root.

Verification

Machine Checks

lint-arwaky-cli scan <layer-path>   # AES101/102, AES201–205, AES401–406 → must be 0
# Fallback only: language compile (python -c import / cargo check / npx tsc --noEmit)

```text

A pass means naming, imports, primitives, and roles are clean. Structural judgement
(tier choice, block order, helper-vs-utility, "orchestration only") is **manual** — see HOW-TO § Rules.

### Human Checks

A machine pass does not mean the file is right. Layer purpose, structural order, and
"only what this layer may do" still need a reader (HOW-TO § Rules).

---

## Pre-flight Checklist

- [ ] `lint-arwaky-cli scan <layer-path>` exits 0.
- [ ] Every touched HOW-TO's `Verify` block was executed.
- [ ] File registered in `__init__.py` / `mod.rs` / `index.ts`.
- [ ] Language fallback compile clean if the HOW-TO lists it.
- [ ] Related skills considered for the next layer up/down.

---

## Common Mistakes (Anti-Patterns)

The linter covers naming, imports, and primitives. These need a reader (HOW-TO § Rules):

- **`_entry` used as a surface suffix**: entry points are root (`root_*_entry`).
- **Surface importing capabilities or protocol directly**: Smart→aggregate only; Utility/Passive→taxonomy only.
- **Silently discarded errors**: forbidden in every tier.
- **Restating HOW-TO rules in SKILL.md**: delegate — this file only routes.

---

## Related Skills

- `aes-agent`
- `aes-contract`
- `aes-root`

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.