agentme 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,10 +14,11 @@ compatibility: Python 3.12+
14
14
  ## Overview
15
15
 
16
16
  Creates a complete Python project from scratch using `uv`, `pyproject.toml`, Ruff, Pyright,
17
- Pytest, and Makefiles. The default layout uses `src/<package_name>/`, `tests/`, and `examples/`
18
- for libraries and shared utilities.
17
+ Pytest, and Makefiles. The default layout keeps the library self-contained under `lib/`, uses a
18
+ shared root `.venv/`, redirects persistent caches into `.cache/`, and places runnable consumer
19
+ projects under the sibling `examples/` folder.
19
20
 
20
- Related EDR: [agentme-edr-014](../../014-python-project-tooling.md)
21
+ Related EDRs: [agentme-edr-014](../../014-python-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md)
21
22
 
22
23
  ## Instructions
23
24
 
@@ -42,54 +43,130 @@ Create these files first.
42
43
 
43
44
  ```makefile
44
45
  SHELL := /bin/bash
45
-
46
- PACKAGE_NAME ?= your_package
47
- MISE := mise exec --
46
+ ROOT_DIR := $(abspath .)
47
+ export UV_PROJECT_ENVIRONMENT := $(ROOT_DIR)/.venv
48
+ export UV_CACHE_DIR := $(ROOT_DIR)/.cache/uv
48
49
 
49
50
  all: build lint test
50
51
 
51
52
  install:
52
- uv sync --frozen --all-extras --dev
53
+ $(MAKE) -C lib install
53
54
 
54
- build: install
55
- uv build
55
+ build:
56
+ $(MAKE) -C lib build
56
57
 
57
58
  lint:
58
- uv run ruff format --check .
59
- uv run ruff check .
60
- uv run pyright
61
- uv run pip-audit
59
+ $(MAKE) -C lib lint
62
60
 
63
61
  lint-fix:
64
- uv run ruff format .
65
- uv run ruff check . --fix
66
- uv run pyright
67
- uv run pip-audit
62
+ $(MAKE) -C lib lint-fix
68
63
 
69
64
  test: test-unit test-examples
70
65
 
71
66
  test-unit:
72
- uv run pytest --cov=src/$(PACKAGE_NAME) --cov-branch --cov-report=term-missing --cov-fail-under=80
67
+ $(MAKE) -C lib test-unit
68
+
69
+ test-examples: build
70
+ @for dir in examples/*; do \
71
+ if [ -f "$$dir/pyproject.toml" ]; then \
72
+ echo ">>> Running $$dir"; \
73
+ UV_PROJECT_ENVIRONMENT="$(UV_PROJECT_ENVIRONMENT)" UV_CACHE_DIR="$(UV_CACHE_DIR)" uv sync --project "$$dir" --frozen || exit 1; \
74
+ UV_PROJECT_ENVIRONMENT="$(UV_PROJECT_ENVIRONMENT)" UV_CACHE_DIR="$(UV_CACHE_DIR)" uv pip install --python "$(UV_PROJECT_ENVIRONMENT)/bin/python" lib/dist/*.whl || exit 1; \
75
+ UV_PROJECT_ENVIRONMENT="$(UV_PROJECT_ENVIRONMENT)" UV_CACHE_DIR="$(UV_CACHE_DIR)" uv run --project "$$dir" python main.py || exit 1; \
76
+ fi; \
77
+ done
78
+
79
+ clean:
80
+ $(MAKE) -C lib clean
81
+ rm -rf .cache
82
+ rm -rf .venv
83
+ ```
84
+
85
+ The root `Makefile` keeps the repository clean by delegating package work to `lib/` and treating each example directory as an independent consumer project.
86
+
87
+ If the repository already uses Mise, wrap the delegated commands with `mise exec --` and pin both Python and uv in `.mise.toml`.
88
+
89
+ **`./.gitignore`**
90
+
91
+ ```gitignore
92
+ .venv/
93
+ dist/
94
+ .cache/
95
+ ```
96
+
97
+ **`./README.md`**
98
+
99
+ Keep this README focused on the repository or workspace. Put Getting Started near the top.
100
+
101
+ ````markdown
102
+ # [package-name]
103
+
104
+ [description]
105
+
106
+ ## Getting Started
107
+
108
+ ```sh
109
+ make test
110
+ ```
111
+
112
+ The published package lives in `lib/` and runnable consumer examples live in `examples/`.
113
+ ````
114
+
115
+ ### Phase 3: Create `lib/`
116
+
117
+ `lib/` contains everything the library needs: source, tests, package metadata, lockfile, build
118
+ artifacts, and library-specific Makefile targets.
119
+
120
+ **`lib/Makefile`**
121
+
122
+ ```makefile
123
+ SHELL := /bin/bash
124
+ ROOT_DIR := $(abspath ..)
125
+ export UV_PROJECT_ENVIRONMENT := $(ROOT_DIR)/.venv
126
+ export UV_CACHE_DIR := $(ROOT_DIR)/.cache/uv
127
+ export RUFF_CACHE_DIR := $(abspath .cache/ruff)
128
+ export PYTHONPYCACHEPREFIX := $(abspath .cache/pycache)
129
+ export COVERAGE_FILE := $(abspath .cache/coverage)
130
+
131
+ PACKAGE_NAME ?= your_package
132
+
133
+ all: build lint test-unit
134
+
135
+ install:
136
+ uv sync --project . --frozen --all-extras --dev
137
+
138
+ build: install
139
+ rm -rf dist
140
+ uv build --project . --out-dir dist
73
141
 
74
- test-examples:
75
- @if [ -d examples ]; then $(MAKE) -C examples test PACKAGE_NAME=$(PACKAGE_NAME); else echo "No examples/ directory. Skipping"; fi
142
+ lint: install
143
+ uv run --project . ruff format --check .
144
+ uv run --project . ruff check .
145
+ uv run --project . pyright
146
+ uv run --project . pip-audit
76
147
 
77
- run:
78
- uv run python -m $(PACKAGE_NAME)
148
+ lint-fix: install
149
+ uv run --project . ruff format .
150
+ uv run --project . ruff check . --fix
151
+ uv run --project . pyright
152
+ uv run --project . pip-audit
153
+
154
+ test-unit: install
155
+ uv run --project . pytest -o cache_dir=.cache/pytest --cov=src/$(PACKAGE_NAME) --cov-branch --cov-report=term-missing --cov-report=html:.cache/htmlcov --cov-fail-under=80
156
+
157
+ run: install
158
+ uv run --project . python -m $(PACKAGE_NAME)
79
159
 
80
160
  dev: run
81
161
 
82
162
  update-lockfile:
83
- uv lock --upgrade
163
+ uv lock --project . --upgrade
84
164
 
85
165
  clean:
86
- rm -rf .venv dist .pytest_cache .ruff_cache .coverage htmlcov
87
- find . -type d -name __pycache__ -prune -exec rm -rf {} +
166
+ rm -rf dist .cache
88
167
  ```
89
168
 
90
- If the repository already uses Mise, adapt the commands to `$(MISE) uv ...` and pin both Python and uv in `.mise.toml`.
91
-
92
- **`./pyproject.toml`**
169
+ **`lib/pyproject.toml`**
93
170
 
94
171
  Replace placeholders such as `[package-name]`, `[description]`, `[author]`, and `[python-version]`.
95
172
 
@@ -130,7 +207,7 @@ select = ["E", "F", "I", "B", "UP"]
130
207
 
131
208
  [tool.pyright]
132
209
  include = ["src", "tests"]
133
- venvPath = "."
210
+ venvPath = ".."
134
211
  venv = ".venv"
135
212
  typeCheckingMode = "standard"
136
213
 
@@ -139,28 +216,14 @@ testpaths = ["tests"]
139
216
  addopts = "-q"
140
217
  ```
141
218
 
142
- Use `pyproject.toml` as the single configuration file. Do not add `requirements.txt`,
143
- `setup.py`, `setup.cfg`, `ruff.toml`, or `pyrightconfig.json` by default.
219
+ Use `lib/pyproject.toml` as the single configuration file for the package. Do not add
220
+ `requirements.txt`, `setup.py`, `setup.cfg`, `ruff.toml`, or `pyrightconfig.json` by default.
144
221
 
145
- **`./.gitignore`**
222
+ **`lib/README.md`**
146
223
 
147
- ```gitignore
148
- .venv/
149
- dist/
150
- build/
151
- .pytest_cache/
152
- .ruff_cache/
153
- .coverage
154
- htmlcov/
155
- __pycache__/
156
- *.pyc
157
- ```
224
+ This README is the published package README referenced by `lib/pyproject.toml`.
158
225
 
159
- **`./README.md`**
160
-
161
- Put Getting Started near the top.
162
-
163
- ```markdown
226
+ ````markdown
164
227
  # [package-name]
165
228
 
166
229
  [description]
@@ -177,13 +240,21 @@ from [package-name] import hello
177
240
 
178
241
  print(hello("world"))
179
242
  ```
243
+
244
+ ## Development
245
+
246
+ ```sh
247
+ make build
248
+ make lint
249
+ make test
180
250
  ```
251
+ ````
181
252
 
182
- ### Phase 3: Create the package and tests
253
+ ### Phase 4: Create the package and tests inside `lib/`
183
254
 
184
255
  Create this baseline structure.
185
256
 
186
- **`src/[package_name]/__init__.py`**
257
+ **`lib/src/[package_name]/__init__.py`**
187
258
 
188
259
  ```python
189
260
  from .core import hello
@@ -191,14 +262,14 @@ from .core import hello
191
262
  __all__ = ["hello"]
192
263
  ```
193
264
 
194
- **`src/[package_name]/core.py`**
265
+ **`lib/src/[package_name]/core.py`**
195
266
 
196
267
  ```python
197
268
  def hello(name: str) -> str:
198
269
  return f"Hello, {name}!"
199
270
  ```
200
271
 
201
- **`src/[package_name]/__main__.py`**
272
+ **`lib/src/[package_name]/__main__.py`**
202
273
 
203
274
  Use this only for CLI-oriented projects.
204
275
 
@@ -214,7 +285,7 @@ if __name__ == "__main__":
214
285
  main()
215
286
  ```
216
287
 
217
- **`tests/test_core.py`**
288
+ **`lib/tests/test_core.py`**
218
289
 
219
290
  ```python
220
291
  from [package_name].core import hello
@@ -224,26 +295,27 @@ def test_hello() -> None:
224
295
  assert hello("world") == "Hello, world!"
225
296
  ```
226
297
 
227
- If two or more test files need shared fixtures, create `tests/conftest.py` and move shared setup there.
228
-
229
- ### Phase 4: Create examples for libraries and utilities
298
+ If two or more test files need shared fixtures, create `lib/tests/conftest.py` and move shared setup there.
230
299
 
231
- If the project is a library or shared utility, add an `examples/` directory and execute it from the root `test` target.
300
+ If the module needs slower end-to-end coverage, place those tests in `lib/tests_integration/`. Put dedicated benchmark harnesses in `lib/tests_benchmark/`.
232
301
 
233
- **`examples/Makefile`**
302
+ ### Phase 5: Create examples for libraries and utilities
234
303
 
235
- ```makefile
236
- test:
237
- $(MAKE) -C basic-usage run PACKAGE_NAME=$(PACKAGE_NAME)
238
- ```
304
+ If the project is a library or shared utility, add an `examples/` directory with one subdirectory per runnable consumer example. Each example must be its own Python project.
239
305
 
240
- **`examples/basic-usage/Makefile`**
306
+ **`examples/basic-usage/pyproject.toml`**
241
307
 
242
- ```makefile
243
- run:
244
- uv run python main.py
308
+ ```toml
309
+ [project]
310
+ name = "basic-usage"
311
+ version = "0.0.0"
312
+ requires-python = ">=[python-version]"
313
+ dependencies = []
245
314
  ```
246
315
 
316
+ The root `test-examples` target installs the wheel built into `lib/dist/` before running each
317
+ example. Do not point examples back to `../../lib` or `lib/src/`.
318
+
247
319
  **`examples/basic-usage/main.py`**
248
320
 
249
321
  ```python
@@ -253,13 +325,13 @@ from [package_name] import hello
253
325
  print(hello("world"))
254
326
  ```
255
327
 
256
- Examples must import the built package as a consumer would. Avoid relative imports back into `src/`.
328
+ Examples must import the package as a consumer would. Avoid relative imports back into `lib/src/`.
257
329
 
258
- ### Phase 5: Verify
330
+ ### Phase 6: Verify
259
331
 
260
332
  After creating the files:
261
333
 
262
- 1. Run `uv lock`.
334
+ 1. Run `make install`.
263
335
  2. Run `make lint-fix`.
264
336
  3. Run `make test`.
265
337
  4. Run `make build`.
@@ -268,19 +340,21 @@ After creating the files:
268
340
  ## Examples
269
341
 
270
342
  **Input:** "Create a Python library called `event_tools`"
271
- - Create `pyproject.toml`, `Makefile`, `src/event_tools/`, `tests/`, and `examples/`
343
+ - Create `Makefile`, `README.md`, `lib/pyproject.toml`, `lib/Makefile`, `lib/src/event_tools/`, `lib/tests/`, and `examples/`
344
+ - Add `lib/README.md`, `.cache/` handling, and install examples from the built wheel in `lib/dist/`
272
345
  - Configure `uv`, Ruff, Pyright, Pytest, `pytest-cov`, and `pip-audit`
273
346
  - Verify with `make lint-fix`, `make test`, and `make build`
274
347
 
275
348
  **Input:** "Scaffold a Python CLI package"
276
- - Add `src/<package_name>/__main__.py`
277
- - Add `[project.scripts]` in `pyproject.toml` when the command name must differ from the module name
349
+ - Add `lib/src/<package_name>/__main__.py`
350
+ - Add `[project.scripts]` in `lib/pyproject.toml` when the command name must differ from the module name
278
351
  - Keep the same Makefile and quality checks
279
352
 
280
353
  ## Edge Cases
281
354
 
282
355
  - If the repository already has a root `.mise.toml`, pin Python and uv there instead of assuming host-installed tools.
283
356
  - If the project is fewer than 100 lines and explicitly marked as a spike or experiment, examples and linting may be skipped only when another applicable XDR allows it.
357
+ - If an example needs extra dependencies, keep them in that example's `pyproject.toml`; do not move them into `lib/pyproject.toml` unless the library truly needs them.
284
358
  - If the user asks for an app with framework-specific needs such as FastAPI or Django, keep this baseline and add the framework config on top instead of replacing it.
285
359
 
286
360
  ## References
@@ -13,9 +13,10 @@ What monorepo structure, naming conventions, tooling, and build standards should
13
13
 
14
14
  ## Decision Outcome
15
15
 
16
- **Adopt a standardized monorepo layout with top-level application folders, a shared library area, Mise-managed tooling, and Makefiles at every level so any contributor can build, lint, and test any part of the monorepo with a single, predictable command.**
16
+ **Adopt a standardized monorepo layout with top-level application folders that aggregate independent module roots, shared parent-level example and test areas, Mise-managed tooling, and Makefiles at every level.**
17
17
 
18
18
  For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/002-monorepo-setup/SKILL.md).
19
+ Module folder responsibilities, artifact locations, and test-folder conventions follow [agentme-edr-016](../principles/016-cross-language-module-structure.md).
19
20
 
20
21
  ### Policies
21
22
 
@@ -23,16 +24,26 @@ For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/
23
24
 
24
25
  ```
25
26
  /
27
+ ├── .cache/ # Optional shared cache for repo-level tooling
26
28
  ├── shared/ # Resources shared across ALL applications
27
29
  │ ├── libs/ # Reusable libraries consumed by applications
28
30
  │ └── scripts/ # Build/CI/dev scripts used across applications
29
31
 
30
32
  ├── <application>/ # One folder per application or project
31
33
  │ ├── README.md # REQUIRED
32
- │ ├── <module>/ # One folder per compilable module
34
+ │ ├── Makefile # REQUIRED
35
+ │ ├── <module>/ # One folder per buildable/publishable module
36
+ │ │ ├── Makefile # REQUIRED
37
+ │ │ ├── README.md # REQUIRED
38
+ │ │ ├── dist/ # REQUIRED when the module publishes/builds artifacts
39
+ │ │ └── .cache/ # REQUIRED when caches are not shared above
40
+ │ ├── examples/ # Optional sibling consumer examples for modules in this app
41
+ │ ├── tests_integration/# Optional cross-module integration tests for this app
42
+ │ ├── tests_benchmark/ # Optional cross-module benchmarks for this app
33
43
  │ └── shared/ # Resources shared by modules within THIS application
34
44
 
35
45
  ├── Makefile # Root Makefile coordinating all areas
46
+ ├── .gitignore # MUST ignore dist/ and .cache/
36
47
  ├── README.md # REQUIRED — onboarding and quickstart guide
37
48
  └── .mise.toml # Mise tool version configuration
38
49
  ```
@@ -42,6 +53,7 @@ For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/
42
53
  - Represent a cohesive unit with its own lifecycle (e.g., `mymobileapp`, `graph-visualizer`).
43
54
  - **MUST** depend only on resources in `/shared/`. Direct cross-application dependencies are forbidden; use published artifacts (container images, published libraries) instead.
44
55
  - **MUST** contain a `README.md` with: purpose, architecture overview, how to build, and how to run.
56
+ - **MAY** contain `examples/`, `tests_integration/`, and `tests_benchmark/` when those artifacts apply to multiple modules inside the application.
45
57
 
46
58
  *Why:* Isolating applications prevents implicit coupling and makes the `shared/` boundary explicit and intentional.
47
59
 
@@ -50,6 +62,9 @@ For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/
50
62
  - A module is a subfolder inside an application that is independently compilable and produces a build artifact.
51
63
  - May depend on sibling modules within the same application or on `/shared/` resources.
52
64
  - **MUST NOT** depend on modules from other applications.
65
+ - **MUST** contain its own `Makefile`, `README.md`, and language/tooling configuration.
66
+ - **MUST** keep build outputs under `dist/` and persistent caches under `.cache/`, following [agentme-edr-016](../principles/016-cross-language-module-structure.md).
67
+ - **MUST NOT** keep consumer examples inside the module folder; those belong in a sibling `examples/` folder at the nearest parent aggregation root.
53
68
 
54
69
  #### 4. Naming conventions
55
70
 
@@ -61,7 +76,11 @@ For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/
61
76
 
62
77
  A `Makefile` **MUST** be present at the repository root, in every application folder, and in every module folder.
63
78
 
64
- Each Makefile **MUST** define at minimum: `build`, `lint`, and `test` targets.
79
+ All Makefiles **MUST** use the shared target vocabulary from [agentme-edr-008](008-common-targets.md).
80
+
81
+ Repository, application, and module Makefiles **MUST** define at minimum: `all`, `build`, `lint`, `test`, and `clean`.
82
+
83
+ Module Makefiles **SHOULD** also provide `lint-fix` and `install` when the underlying tooling supports them.
65
84
 
66
85
  The root `Makefile` **MUST** also define a `setup` target that guides a new contributor to prepare their machine.
67
86
 
@@ -84,7 +103,11 @@ The root `Makefile` **MUST** also define a `setup` target that guides a new cont
84
103
 
85
104
  The root `README.md` **MUST** include: overview, machine setup, quickstart, and a repository map.
86
105
 
87
- #### 8. Git tagging and artifact versioning
106
+ #### 8. Root `.gitignore`
107
+
108
+ The repository root **MUST** ignore `dist/` and `.cache/` so module artifacts and tool caches are never committed accidentally.
109
+
110
+ #### 9. Git tagging and artifact versioning
88
111
 
89
112
  All releases **MUST** be tagged using the format `<module-name>/<semver>` (e.g., `graphvisualizer/renderer/1.0.0`, `shared/libs/mylib/2.1.0`).
90
113
 
@@ -100,10 +123,14 @@ All releases **MUST** be tagged using the format `<module-name>/<semver>` (e.g.,
100
123
  |---|---|---|
101
124
  | Lowercase folder/file names | All | Yes |
102
125
  | `README.md` per application | Application folders | Yes |
103
- | `Makefile` with `build`, `lint`, `test` | All modules and applications | Yes |
126
+ | `README.md` per module | Module folders | Yes |
127
+ | `Makefile` with `all`, `build`, `lint`, `test`, `clean` | Root, applications, modules | Yes |
104
128
  | Root `Makefile` with `setup` target | Repository root | Yes |
105
129
  | Root `README.md` with setup + quickstart | Repository root | Yes |
130
+ | Ignore `dist/` and `.cache/` | Repository root | Yes |
106
131
  | Mise `.mise.toml` at root | Repository root | Yes |
107
132
  | Applications depend only on `/shared/` | Application folders | Yes |
108
133
  | Modules depend only on siblings or `/shared/` | Module folders | Yes |
134
+ | Module outputs live in `dist/` | Module folders | Yes |
135
+ | Persistent caches live in `.cache/` | Repo or module folders | Yes |
109
136
  | Git tags follow `<module-name>/<semver>` format | All modules | Yes |
@@ -14,11 +14,11 @@ metadata:
14
14
  ## Overview
15
15
 
16
16
  Creates or extends a monorepo that follows the standard layout from [agentme-edr-005](../../005-monorepo-structure.md):
17
- top-level application folders, a shared library area, Mise-managed tooling, and Makefiles at every
18
- level so any contributor can build, lint, and test any part of the monorepo with a single,
19
- predictable command.
17
+ top-level application folders, independent module roots, sibling example and multi-module test
18
+ areas, Mise-managed tooling, and Makefiles at every level so any contributor can build, lint, and
19
+ test any part of the monorepo with a single, predictable command.
20
20
 
21
- Related EDRs: [agentme-edr-005](../../005-monorepo-structure.md), [agentme-edr-013](../../../governance/013-contributing-guide-requirements.md)
21
+ Related EDRs: [agentme-edr-005](../../005-monorepo-structure.md), [agentme-edr-013](../../../governance/013-contributing-guide-requirements.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md)
22
22
 
23
23
  ## Instructions
24
24
 
@@ -51,10 +51,12 @@ golangci-lint = "1.57"
51
51
  Coordinates `build`, `lint`, and `test` across all applications. Also exposes a `setup` target.
52
52
 
53
53
  ```makefile
54
- .PHONY: build lint test setup
54
+ .PHONY: all build lint test clean setup
55
55
 
56
56
  APPS := <app1> <app2> # replace with actual application names
57
57
 
58
+ all: build lint test
59
+
58
60
  build:
59
61
  $(foreach app,$(APPS),$(MAKE) -C $(app) build &&) true
60
62
 
@@ -64,12 +66,25 @@ lint:
64
66
  test:
65
67
  $(foreach app,$(APPS),$(MAKE) -C $(app) test &&) true
66
68
 
69
+ clean:
70
+ $(foreach app,$(APPS),$(MAKE) -C $(app) clean &&) true
71
+ rm -rf .cache
72
+
67
73
  setup:
68
74
  @echo "Install Mise: https://mise.jdx.dev/getting-started.html"
69
75
  @echo "Then run: mise install"
70
76
  @echo "See README.md for full setup instructions."
71
77
  ```
72
78
 
79
+ #### Root `.gitignore`
80
+
81
+ Must ignore shared artifact and cache folders:
82
+
83
+ ```gitignore
84
+ dist/
85
+ .cache/
86
+ ```
87
+
73
88
  #### Root `README.md`
74
89
 
75
90
  Must include four sections:
@@ -162,10 +177,12 @@ For each application:
162
177
  3. **Create `<app>/Makefile`** that delegates to each module:
163
178
 
164
179
  ```makefile
165
- .PHONY: build lint test
180
+ .PHONY: all build lint test clean
166
181
 
167
182
  MODULES := <module1> <module2> # replace with actual module names
168
183
 
184
+ all: build lint test
185
+
169
186
  build:
170
187
  $(foreach mod,$(MODULES),$(MAKE) -C $(mod) build &&) true
171
188
 
@@ -174,10 +191,16 @@ For each application:
174
191
 
175
192
  test:
176
193
  $(foreach mod,$(MODULES),$(MAKE) -C $(mod) test &&) true
194
+
195
+ clean:
196
+ $(foreach mod,$(MODULES),$(MAKE) -C $(mod) clean &&) true
197
+ rm -rf .cache
177
198
  ```
178
199
 
179
200
  4. **Create `<app>/shared/`** — leave empty if no cross-module shared code exists yet.
180
201
 
202
+ 5. **Create sibling aggregation folders when needed**: `<app>/examples/`, `<app>/tests_integration/`, and `<app>/tests_benchmark/` for artifacts that apply to multiple modules.
203
+
181
204
  ---
182
205
 
183
206
  ### Phase 5: Scaffold each module
@@ -186,11 +209,15 @@ For each module inside an application:
186
209
 
187
210
  1. **Create the module folder** using lowercase, hyphen-separated names (e.g., `data-loader`).
188
211
 
189
- 2. **Create `<app>/<module>/Makefile`** with the three required targets, adapted to the module's language:
212
+ 2. **Create `<app>/<module>/README.md`** with consumer usage first and short developer commands at the end.
213
+
214
+ 3. **Create `<app>/<module>/Makefile`** with the common targets, adapted to the module's language. Redirect persistent caches into `.cache/` and write distributable artifacts to `dist/`.
190
215
 
191
216
  **Go:**
192
217
  ```makefile
193
- .PHONY: build lint test
218
+ .PHONY: all build lint test clean
219
+
220
+ all: build lint test
194
221
 
195
222
  build:
196
223
  go build ./...
@@ -200,11 +227,16 @@ For each module inside an application:
200
227
 
201
228
  test:
202
229
  go test ./... -cover
230
+
231
+ clean:
232
+ rm -rf dist .cache
203
233
  ```
204
234
 
205
235
  **Node.js / TypeScript:**
206
236
  ```makefile
207
- .PHONY: build lint test
237
+ .PHONY: all build lint test clean
238
+
239
+ all: build lint test
208
240
 
209
241
  build:
210
242
  npm run build
@@ -214,11 +246,16 @@ For each module inside an application:
214
246
 
215
247
  test:
216
248
  npm test
249
+
250
+ clean:
251
+ rm -rf dist .cache
217
252
  ```
218
253
 
219
254
  **Python:**
220
255
  ```makefile
221
- .PHONY: build lint test
256
+ .PHONY: all build lint test clean
257
+
258
+ all: build lint test
222
259
 
223
260
  build:
224
261
  pip install -e .
@@ -228,9 +265,14 @@ For each module inside an application:
228
265
 
229
266
  test:
230
267
  pytest
268
+
269
+ clean:
270
+ rm -rf dist .cache
231
271
  ```
232
272
 
233
- 3. **Add source files** appropriate to the language, placing them inside the module folder.
273
+ 4. **Add source files** appropriate to the language, placing them inside the module folder.
274
+
275
+ 5. **Place module-specific integration tests and benchmarks predictably**: `<module>/tests_integration/` and `<module>/tests_benchmark/` when they are not co-located by language convention.
234
276
 
235
277
  ---
236
278
 
@@ -242,8 +284,10 @@ After scaffolding, run the following checks and fix any issues:
242
284
  - `make lint` at the repository root passes.
243
285
  - `make test` at the repository root passes.
244
286
  - All folder and file names are lowercase and use hyphens.
287
+ - The root `.gitignore` ignores `dist/` and `.cache/`.
245
288
  - A `CONTRIBUTING.md` exists at the repository root and covers bugs, feature discussions, pull requests, Conventional Comments, and small focused changes.
246
289
  - Every application folder has a `README.md` covering all four required sections.
290
+ - Every module folder has a `README.md`, `Makefile`, `dist/` location, and `.cache/` strategy.
247
291
  - A `.mise.toml` exists at the repository root with all required tool versions pinned.
248
292
 
249
293
  ---
@@ -256,8 +300,10 @@ After scaffolding, run the following checks and fix any issues:
256
300
  pcb-devices/
257
301
  ├── README.md
258
302
  ├── Makefile
303
+ ├── examples/
259
304
  ├── shared/
260
305
  └── firmware/
306
+ ├── README.md
261
307
  └── Makefile
262
308
  ```
263
309
 
@@ -13,6 +13,7 @@ Foundational standards, principles, and guidelines.
13
13
  - [agentme-edr-007](principles/007-project-quality-standards.md) - **Project quality standards**
14
14
  - [agentme-edr-009](principles/009-error-handling.md) - **Error handling**
15
15
  - [agentme-edr-012](principles/012-continuous-xdr-enrichment.md) - **Continuous xdr improvement policy**
16
+ - [agentme-edr-016](principles/016-cross-language-module-structure.md) - **Cross-language module structure**
16
17
 
17
18
  ## Articles
18
19