agentme 0.9.0 → 0.11.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.
Files changed (27) hide show
  1. package/.filedist-package.yml +2 -1
  2. package/.xdrs/agentme/edrs/application/003-javascript-project-tooling.md +41 -5
  3. package/.xdrs/agentme/edrs/application/010-golang-project-tooling.md +39 -15
  4. package/.xdrs/agentme/edrs/application/014-python-project-tooling.md +63 -5
  5. package/.xdrs/agentme/edrs/application/015-cli-tool-standards.md +25 -24
  6. package/.xdrs/agentme/edrs/application/018-ai-agent-development-standards.md +57 -64
  7. package/.xdrs/agentme/edrs/application/019-ml-dataset-structure.md +12 -12
  8. package/.xdrs/agentme/edrs/application/020-ai-agent-xdrs-knowledge-layer.md +99 -0
  9. package/.xdrs/agentme/edrs/application/021-pragmatic-hexagonal-architecture.md +112 -0
  10. package/.xdrs/agentme/edrs/application/skills/001-create-javascript-project/SKILL.md +26 -11
  11. package/.xdrs/agentme/edrs/application/skills/003-create-golang-project/SKILL.md +31 -14
  12. package/.xdrs/agentme/edrs/application/skills/005-create-python-project/SKILL.md +56 -23
  13. package/.xdrs/agentme/edrs/devops/005-monorepo-structure.md +1 -1
  14. package/.xdrs/agentme/edrs/devops/006-github-pipelines.md +1 -1
  15. package/.xdrs/agentme/edrs/devops/008-common-targets.md +2 -1
  16. package/.xdrs/agentme/edrs/devops/017-tool-execution-and-scripting.md +1 -1
  17. package/.xdrs/agentme/edrs/governance/013-contributing-guide-requirements.md +1 -1
  18. package/.xdrs/agentme/edrs/index.md +3 -1
  19. package/.xdrs/agentme/edrs/observability/011-service-health-check-endpoint.md +1 -1
  20. package/.xdrs/agentme/edrs/principles/002-coding-best-practices.md +1 -1
  21. package/.xdrs/agentme/edrs/principles/004-unit-test-requirements.md +23 -3
  22. package/.xdrs/agentme/edrs/principles/007-project-quality-standards.md +31 -3
  23. package/.xdrs/agentme/edrs/principles/009-error-handling.md +1 -1
  24. package/.xdrs/agentme/edrs/principles/012-continuous-xdr-enrichment.md +2 -2
  25. package/.xdrs/agentme/edrs/principles/016-cross-language-module-structure.md +1 -1
  26. package/.xdrs/agentme/edrs/principles/articles/001-continuous-xdr-improvement.md +5 -5
  27. package/package.json +2 -2
@@ -17,13 +17,13 @@ How should ML datasets be organized on disk so they are self-describing, easy to
17
17
 
18
18
  **A standard root layout with mandatory README.md and dataset.schema.json, plus type-specific conventions for data files**
19
19
 
20
- Every dataset must live in its own named folder and include a README and a JSON Schema file. Data files are organized according to three dataset types, each with its own placement rule.
20
+ Every dataset MUST live in its own named folder and include a README and a JSON Schema file. Data files are organized according to three dataset types, each with its own placement rule.
21
21
 
22
22
  ### Details
23
23
 
24
24
  #### 01-root-structure-is-mandatory
25
25
 
26
- Every dataset must follow this root layout:
26
+ Every dataset MUST follow this root layout:
27
27
 
28
28
  ```
29
29
  /[name-of-dataset]/
@@ -33,13 +33,13 @@ Every dataset must follow this root layout:
33
33
  ... (additional files depending on dataset type)
34
34
  ```
35
35
 
36
- - `README.md` must explain what the dataset is about, the procedures used to create it, remarks on data quality, and instructions on how to consume it with examples.
37
- - `dataset.schema.json` must be a valid [JSON Schema](https://json-schema.org/) document describing the structure of the dataset's primary data.
38
- - The dataset folder name must be lowercase, using hyphens as separators.
36
+ - `README.md` MUST explain what the dataset is about, the procedures used to create it, remarks on data quality, and instructions on how to consume it with examples.
37
+ - `dataset.schema.json` MUST be a valid [JSON Schema](https://json-schema.org/) document describing the structure of the dataset's primary data.
38
+ - The dataset folder name MUST be lowercase, using underscores as separators (e.g. `my_dataset`).
39
39
 
40
40
  #### 02-file-annotation-pairs-must-use-data-folder
41
41
 
42
- Datasets where each item is a file paired with structured JSON output (e.g. image labeling, document data extraction, medical records with known features) must store all files inside the `data/` subfolder. Each data file must have a sibling JSON annotation file named with the same filename suffixed with `.json`.
42
+ Datasets where each item is a file paired with structured JSON output (e.g. image labeling, document data extraction, medical records with known features) MUST store all files inside the `data/` subfolder. Each data file MUST have a sibling JSON annotation file named with the same filename suffixed with `.json`.
43
43
 
44
44
  ```
45
45
  /[name-of-dataset]/
@@ -56,11 +56,11 @@ Datasets where each item is a file paired with structured JSON output (e.g. imag
56
56
 
57
57
  Placing the annotation file next to its source file (same name + `.json`) keeps them adjacent even in large directories, making it easy to iterate pairs programmatically.
58
58
 
59
- Subdirectories inside `data/` are allowed when the number of files warrants grouping, but the `.json` sibling convention must be preserved at each level.
59
+ Subdirectories inside `data/` are allowed when the number of files warrants grouping, but the `.json` sibling convention MUST be preserved at each level.
60
60
 
61
61
  #### 03-tabular-datasets-must-use-csv-files-at-root
62
62
 
63
- Datasets composed of column-oriented tabular data must place CSV files at the root of the dataset folder. All tabular files must conform to the schema defined in `dataset.schema.json`, which must describe columns as named attributes with their types.
63
+ Datasets composed of column-oriented tabular data MUST place CSV files at the root of the dataset folder. All tabular files MUST conform to the schema defined in `dataset.schema.json`, which MUST describe columns as named attributes with their types.
64
64
 
65
65
  ```
66
66
  /[name-of-dataset]/
@@ -70,11 +70,11 @@ Datasets composed of column-oriented tabular data must place CSV files at the ro
70
70
  README.md
71
71
  ```
72
72
 
73
- Multiple CSV files are allowed when they represent different slices or splits of the same schema (e.g. train/test splits, subsets by source). All files in the same dataset must share the same column schema.
73
+ Multiple CSV files are allowed when they represent different slices or splits of the same schema (e.g. train/test splits, subsets by source). All files in the same dataset MUST share the same column schema.
74
74
 
75
75
  #### 04-complex-structured-datasets-must-use-jsonl
76
76
 
77
- Datasets with complex or heterogeneous per-record structures (e.g. LLM workflow evaluation sets, Q&A pairs, input → expected_output pairs) must use JSONL files (one JSON object per line) placed at the root of the dataset folder. Each line must conform to the schema defined in `dataset.schema.json`.
77
+ Datasets with complex or heterogeneous per-record structures (e.g. LLM workflow evaluation sets, Q&A pairs, input → expected_output pairs) MUST use JSONL files (one JSON object per line) placed at the root of the dataset folder. Each line MUST conform to the schema defined in `dataset.schema.json`.
78
78
 
79
79
  ```
80
80
  /[name-of-dataset]/
@@ -84,11 +84,11 @@ Datasets with complex or heterogeneous per-record structures (e.g. LLM workflow
84
84
  README.md
85
85
  ```
86
86
 
87
- Multiple JSONL files are allowed when they represent different splits or categories (e.g. easy vs. edge cases). All files in the same dataset must conform to the same line schema.
87
+ Multiple JSONL files are allowed when they represent different splits or categories (e.g. easy vs. edge cases). All files in the same dataset MUST conform to the same line schema.
88
88
 
89
89
  #### 05-referenced-files-must-live-in-data-folder
90
90
 
91
- When any dataset type (tabular, JSONL, or annotation-pair) contains references to external files as part of the data (e.g. a JSONL record that includes a file path), those referenced files must be stored inside the `data/` subfolder of the dataset. Paths inside data records must be relative to the dataset root.
91
+ When any dataset type (tabular, JSONL, or annotation-pair) contains references to external files as part of the data (e.g. a JSONL record that includes a file path), those referenced files MUST be stored inside the `data/` subfolder of the dataset. Paths inside data records MUST be relative to the dataset root.
92
92
 
93
93
  ## References
94
94
 
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: agentme-edr-policy-020-ai-agent-xdrs-knowledge-layer
3
+ description: Defines how to integrate XDRS as the runtime knowledge source of truth for AI agents — covering document placement, AGENTS.md setup, file tools, and local sandbox configuration. Apply only when the project explicitly uses XDRS to govern agent behavior.
4
+ apply-to: AI agent projects that use XDRS as the source of truth for policies and skills
5
+ valid-from: 2026-05-27
6
+ ---
7
+
8
+ # agentme-edr-policy-020: AI agent XDRS knowledge layer
9
+
10
+ ## Context and Problem Statement
11
+
12
+ AI agents need access to project-specific policies and skills at runtime to produce consistent, governed outputs. XDRS provides a file-system-based structure for capturing these decisions, but there is no standard pattern for embedding XDRS documents in agent libraries, wiring the agent to consult them, or sandboxing file access securely.
13
+
14
+ How should an AI agent project integrate XDRS as its runtime source of truth for policies and skills?
15
+
16
+ ## Decision Outcome
17
+
18
+ **Embed XDRS documents in `lib/data/.xdrs/`, instruct the agent to consult them via `AGENTS.md`, equip the agent with sandboxed file tools, and use the deepagents framework when a local sandbox is required.**
19
+
20
+ This policy MUST only be applied when the project explicitly chooses XDRS as its knowledge governance layer. It is not required by [agentme-edr-018](018-ai-agent-development-standards.md) in general.
21
+
22
+ ### Details
23
+
24
+ #### 01-xdrs-knowledge-layer
25
+
26
+ XDRS documents are the source of truth for all policies and skills that the agent must follow during its tasks. The agent MUST consult XDRS before acting, not rely on general knowledge alone.
27
+
28
+ **Placing XDRS documents in the library**
29
+
30
+ - XDRS Policy and Skill documents MUST be placed at `lib/data/.xdrs/`, using the standard XDRS scope/type/subject folder structure (following `_core-adr-policy-001`).
31
+ - They MUST be embedded in the package data manifest (e.g. `pyproject.toml` `[tool.hatch.build] include` or equivalent) so they are available at runtime.
32
+ - When exposed through a deepagents sandbox, they MUST be mounted at `/.xdrs/` inside the sandbox (see rule `03-local-sandbox`).
33
+
34
+ **AGENTS.md — mandatory XDRS consultation**
35
+
36
+ Place an `AGENTS.md` file at the root of the deepagents sandbox (i.e. alongside `/.xdrs/`). This file instructs the agent to always consult XDRS before acting. Its content MUST follow the xdrs-core AGENTS.md template:
37
+
38
+ ```markdown
39
+ # AGENTS.md
40
+
41
+ **Purpose:** This file is intentionally brief. All decisions and working instructions are captured as Policies or Skills in the XDRS structure.
42
+
43
+ ## Policy Consultation in XDRS Is Mandatory For Every Request
44
+
45
+ Before answering **any** request you MUST:
46
+
47
+ 1. Read the XDRS root index at `/.xdrs/index.md` to identify relevant Policies and Skills.
48
+ 2. Read the relevant Policy and Skill files.
49
+ 3. Base your actions on those Policies and Skills.
50
+
51
+ This rule has NO exceptions. Do not answer from general knowledge alone when a Policy may exist on the topic.
52
+ ```
53
+
54
+ The agent system prompt MUST reference `AGENTS.md` so the agent loads it at startup. Example:
55
+
56
+ ```
57
+ Read /AGENTS.md and follow all instructions in it before proceeding.
58
+ ```
59
+
60
+ #### 02-agent-file-tools
61
+
62
+ Every agent that uses the XDRS knowledge layer MUST use the file tools provided by the deepagents framework. Do not implement hand-rolled alternatives — see [agentme-edr-policy-018-ai-agent-development-standards.[09-local-sandbox]](018-ai-agent-development-standards.md) for the full sandbox and tool requirements.
63
+
64
+ These tools operate over two sandboxed roots (configured in rule `03-local-sandbox`):
65
+
66
+ | Root | Content | Source |
67
+ |---|---|---|
68
+ | `data_root` | Static files shipped with the library (`lib/data/`) | Resolved via `importlib.resources` at workflow startup |
69
+ | `temp_root` | Dynamic files generated for the current workflow run | Temporary directory created by `tempfile.mkdtemp()` at workflow startup |
70
+
71
+ `temp_root` MUST be created at workflow startup and cleaned up in the same `try/finally` block. Pass it explicitly into the workflow; do not read it from a global variable.
72
+
73
+ #### 03-local-sandbox
74
+
75
+ Follow [agentme-edr-policy-018-ai-agent-development-standards.[09-local-sandbox]](018-ai-agent-development-standards.md) for the general deepagents sandbox setup. When XDRS is in use, add the following mounts to the sandbox configuration:
76
+
77
+ | Source | Content | Deepagents sandbox path |
78
+ |---|---|---|
79
+ | `lib/data/.xdrs/` | XDRS Policy and Skill documents | `/.xdrs/` (read-only) |
80
+ | Generated at startup | `AGENTS.md` instructing the agent to consult XDRS | `/AGENTS.md` (read-only) |
81
+
82
+ XDRS documents MUST always be mounted at `/.xdrs/`. `AGENTS.md` MUST always be placed at the sandbox root (`/AGENTS.md`).
83
+
84
+ Example XDRS mount additions:
85
+
86
+ ```python
87
+ from importlib.resources import files
88
+ from pathlib import Path
89
+
90
+ data_root = str(files("myagent").joinpath("data"))
91
+ agents_md = Path(temp_root) / "AGENTS.md"
92
+ agents_md.write_text(_AGENTS_MD) # content from xdrs-core AGENTS.md template; see rule 01-xdrs-knowledge-layer
93
+
94
+ # Add these mounts alongside the base mounts from agentme-edr-018 rule 09-local-sandbox:
95
+ xdrs_mounts = [
96
+ {"src": f"{data_root}/.xdrs", "dst": "/.xdrs", "readonly": True},
97
+ {"src": str(agents_md), "dst": "/AGENTS.md", "readonly": True},
98
+ ]
99
+ ```
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: agentme-edr-policy-021-pragmatic-hexagonal-architecture
3
+ description: Defines a pragmatic variant of Hexagonal Architecture for organizing application source code into Adapters (inbound/outbound I/O boundaries) and Application (business logic) layers, with explicit naming conventions and folder structure. Use when designing or reviewing the internal layout of application modules.
4
+ apply-to: All application projects
5
+ valid-from: 2026-05-28
6
+ ---
7
+
8
+ # agentme-edr-policy-021: Pragmatic hexagonal architecture
9
+
10
+ ## Context and Problem Statement
11
+
12
+ Applications often mix business logic with infrastructure concerns (database access, HTTP handling, environment variable reading), making code hard to test, refactor, and reuse.
13
+
14
+ How should application source code be organized to separate business logic from infrastructure while avoiding unnecessary abstraction layers?
15
+
16
+ ## Decision Outcome
17
+
18
+ **Organize application source code into three conceptual layers — External (not in codebase), Adapters (inbound/outbound I/O boundaries), and Application (business logic exposed as typed library interfaces) — following a pragmatic variant of Hexagonal Architecture that avoids unnecessary abstractions.**
19
+
20
+ ### Details
21
+
22
+ #### 01-three-layer-separation
23
+
24
+ Every application is conceptually divided into three layers:
25
+
26
+ | Layer | Description |
27
+ |-------|-------------|
28
+ | **External** | Systems outside the codebase boundary (databases, third-party APIs, message brokers, filesystems, users) |
29
+ | **Adapters** | Bridge between External and Application — translate external protocols into application calls and vice versa |
30
+ | **Application** | Business logic that delegates I/O to adapters |
31
+
32
+ #### 02-adapter-naming-conventions
33
+
34
+ **Inbound adapters** receive external requests or events and trigger application logic. Each gets a flat folder under `adapters/`:
35
+
36
+ - `cli/` — command-line interface entry point
37
+ - `http/` — HTTP/REST server
38
+ - `grpc/` — gRPC server
39
+ - `ws/` — WebSocket server
40
+ - `kafka/` — Kafka consumer
41
+ - `mqtt/` — MQTT subscriber
42
+ - Additional inbound adapters are allowed with descriptive names
43
+
44
+ **Outbound adapters** are called by the application to reach external systems. They live under `adapters/connectors/` with one subfolder per external resource, named descriptively:
45
+
46
+ - e.g.: `stripe-api/`, `config-file/`, `s3-datalake/`, `whatsapp/`, `postgres/`, `redis-cache/`
47
+
48
+ **Clarification:** "inbound" means the adapter triggers application logic in response to an external stimulus. "Outbound" means the application calls the adapter to interact with an external system.
49
+
50
+ #### 03-application-layer-rules
51
+
52
+ - Expose functionality as typed library interfaces
53
+ - All inputs must be explicitly passed as typed parameters
54
+ - No global variables, no direct environment variable access in `app/` or `shared/`
55
+ - Business logic with well-defined input/output behavior
56
+ - Group related logic into subfolders (aggregation roots)
57
+ - Environment variables must be read only in the bootstrap/entry-point layer of inbound adapters, converted into typed configuration objects, and passed explicitly to all other components
58
+
59
+ #### 04-mandatory-folder-structure
60
+
61
+ ```text
62
+ mysystem/
63
+ Makefile # targets to run different inbound interfaces (e.g. run-http, run-cli)
64
+ src/
65
+ adapters/ # mandatory
66
+ cli/ # if CLI exists — bootstrap/entry point for CLI
67
+ http/ # if HTTP server exists — bootstrap/entry point for HTTP
68
+ grpc/ # if gRPC exists
69
+ connectors/ # if external resource access exists
70
+ postgres/ # one folder per external resource
71
+ stripe-api/
72
+ app/ # mandatory — core business logic
73
+ feature1.ts
74
+ feature-group/ # optional subfolders for grouping
75
+ shared/ # utilities and functions shared among adapters and app
76
+ logging.ts
77
+ errors.ts
78
+ ```
79
+
80
+ `shared/` must contain only infrastructure-agnostic utilities — not business rules or domain logic.
81
+
82
+ #### 05-pragmatic-coupling
83
+
84
+ - Application MAY import from Adapters when it simplifies the design
85
+ - Avoid excessive abstractions, interface types, and indirection layers
86
+ - Only introduce interfaces or abstract types when building a framework where the extra complexity demonstrably pays off
87
+ - Prefer concrete implementations over abstract ports — skip the purism of classic Hexagonal Architecture in favor of practicality
88
+ - Some coupling between Application and Adapters is acceptable and expected
89
+
90
+ #### 06-bootstrap-and-entry-points
91
+
92
+ - Each inbound adapter folder (`cli/`, `http/`, `grpc/`, etc.) contains the bootstrap and entry point for that interface
93
+ - The project root Makefile must have targets to run the different inbound interfaces following [agentme-edr-008](../devops/008-common-targets.md) extension conventions (e.g. `run-http`, `run-grpc`)
94
+ - Bootstrap code lives in the adapter that receives inbound requests, not in a separate wiring layer
95
+
96
+ #### 07-minimum-complexity-threshold
97
+
98
+ - Trivial scripts and single-purpose tools (fewer than ~300 lines with a single I/O boundary) MAY skip this layering
99
+ - All other projects MUST use this structure from the start
100
+
101
+ #### 08-examples-of-data-flow
102
+
103
+ ```text
104
+ HTTP request → adapters/http/ → app/create-user → adapters/connectors/postgres/
105
+ CLI command → adapters/cli/ → app/create-dir → adapters/connectors/local-fs/
106
+ Kafka message → adapters/kafka/ → app/process-event → adapters/connectors/stripe-api/
107
+ ```
108
+
109
+ ## References
110
+
111
+ - [agentme-edr-016](../principles/016-cross-language-module-structure.md) — Defines the module-root structure (Makefile, dist/, .cache/) that wraps this internal layout
112
+ - [agentme-edr-002](../principles/002-coding-best-practices.md) — File size limits and code organization practices that complement this architecture
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: agentme-edr-skill-001-create-javascript-project
3
3
  description: >
4
- Scaffolds the initial boilerplate structure for a JavaScript/TypeScript library project following
4
+ Scaffolds the initial boilerplate structure for a JavaScript/TypeScript project following
5
5
  the standard tooling and layout defined in agentme-edr-003. Activate this skill when the user
6
- asks to create, scaffold, or initialize a new JavaScript or TypeScript library project, npm
6
+ asks to create, scaffold, or initialize a new JavaScript or TypeScript project, npm
7
7
  package, or similar project structure.
8
8
  metadata:
9
9
  author: flaviostutz
@@ -13,13 +13,14 @@ compatibility: JavaScript/TypeScript, Node.js 18+
13
13
 
14
14
  ## Overview
15
15
 
16
- Creates a complete JavaScript/TypeScript library project from scratch. The layout keeps the
17
- published package self-contained in its module root (`lib/`), places runnable consumer examples in
18
- the sibling `examples/` folder, redirects persistent caches into `.cache/`, and uses Makefiles as
19
- the only entry points. Boilerplate is derived from the [filedist](https://github.com/flaviostutz/filedist)
20
- project.
16
+ Creates a complete JavaScript/TypeScript project from scratch. The layout keeps the
17
+ package self-contained in its module root (`lib/`), organizes internal code following
18
+ [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md) (`adapters/`, `app/`, `shared/`),
19
+ places runnable consumer examples in the sibling `examples/` folder, redirects persistent caches
20
+ into `.cache/`, and uses Makefiles as the only entry points. Boilerplate is derived from the
21
+ [filedist](https://github.com/flaviostutz/filedist) project.
21
22
 
22
- Related EDRs: [agentme-edr-003](../../003-javascript-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md)
23
+ Related EDRs: [agentme-edr-003](../../003-javascript-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md), [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md)
23
24
 
24
25
  ## Instructions
25
26
 
@@ -82,7 +83,7 @@ dist/
82
83
 
83
84
  ### Phase 3: Create `lib/`
84
85
 
85
- **`lib/src/index.ts`** — public API entry point:
86
+ **`lib/src/app/hello.ts`** — business logic:
86
87
 
87
88
  ```typescript
88
89
  export const hello = (name: string): string => {
@@ -90,10 +91,10 @@ export const hello = (name: string): string => {
90
91
  };
91
92
  ```
92
93
 
93
- **`lib/src/index.test.ts`** — co-located unit test:
94
+ **`lib/src/app/hello.test.ts`** — co-located unit test:
94
95
 
95
96
  ```typescript
96
- import { hello } from './index';
97
+ import { hello } from './hello';
97
98
 
98
99
  describe('hello', () => {
99
100
  it('should return a greeting', () => {
@@ -102,6 +103,20 @@ describe('hello', () => {
102
103
  });
103
104
  ```
104
105
 
106
+ **`lib/src/index.ts`** — public API re-export from `app/`:
107
+
108
+ ```typescript
109
+ export { hello } from './app/hello';
110
+ ```
111
+
112
+ **`lib/src/adapters/`** — create empty directories for the hexagonal structure:
113
+
114
+ - `lib/src/adapters/` — inbound adapters (add `cli/`, `http/`, etc. as needed)
115
+ - `lib/src/adapters/connectors/` — outbound adapters (one folder per external resource)
116
+ - `lib/src/shared/` — infrastructure-agnostic utilities
117
+
118
+ Create a placeholder `.gitkeep` in `lib/src/adapters/` and `lib/src/shared/` so the directories are tracked.
119
+
105
120
  **`lib/Makefile`**:
106
121
 
107
122
  ```makefile
@@ -12,9 +12,9 @@ compatibility: Go 1.21+
12
12
 
13
13
  ## Overview
14
14
 
15
- Creates a complete Go CLI project from scratch, following the layout from [agentme-edr-010](../../010-golang-project-tooling.md). Business logic lives in named feature packages; CLI wiring lives in `cli/<feature>/`; `main.go` is a thin dispatcher. The module root owns its `Makefile`, `README.md`, `dist/`, and `.cache/` folders.
15
+ Creates a complete Go project from scratch, following the layout from [agentme-edr-010](../../010-golang-project-tooling.md) and [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md). Business logic lives in `app/<feature>/` packages; CLI wiring lives in `adapters/cli/`; outbound integrations live in `adapters/connectors/`; `main.go` is a thin dispatcher. The module root owns its `Makefile`, `README.md`, `dist/`, and `.cache/` folders.
16
16
 
17
- Related EDRs: [agentme-edr-010](../../010-golang-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md)
17
+ Related EDRs: [agentme-edr-010](../../010-golang-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md), [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md)
18
18
 
19
19
  ## Instructions
20
20
 
@@ -67,7 +67,7 @@ import (
67
67
  "fmt"
68
68
  "os"
69
69
 
70
- cli[Feature] "[module]/cli/[feature]"
70
+ cli "[module]/adapters/cli"
71
71
  )
72
72
 
73
73
  func main() {
@@ -78,7 +78,7 @@ func main() {
78
78
 
79
79
  switch os.Args[1] {
80
80
  case "[subcommand]":
81
- cli[Feature].Run(os.Args)
81
+ cli.Run[Feature](os.Args)
82
82
  default:
83
83
  fmt.Printf("Unknown command: %s\n", os.Args[1])
84
84
  fmt.Println("Usage: [binary] [[feature]]")
@@ -216,7 +216,7 @@ coverage.out
216
216
 
217
217
  ### Phase 3: Create the feature package
218
218
 
219
- **`[feature]/[feature].go`** (replace `[feature]`, `[Feature]`):
219
+ **`app/[feature]/[feature].go`** (replace `[feature]`, `[Feature]`):
220
220
 
221
221
  ```go
222
222
  package [feature]
@@ -246,7 +246,7 @@ func Run(opts Options) (Result, error) {
246
246
  }
247
247
  ```
248
248
 
249
- **`[feature]/[feature]_test.go`** (replace `[feature]`, `[Feature]`):
249
+ **`app/[feature]/[feature]_test.go`** (replace `[feature]`, `[Feature]`):
250
250
 
251
251
  ```go
252
252
  package [feature]
@@ -267,12 +267,12 @@ func Test[Feature]Run(t *testing.T) {
267
267
 
268
268
  ---
269
269
 
270
- ### Phase 4: Create the CLI package
270
+ ### Phase 4: Create the CLI adapter
271
271
 
272
- **`cli/[feature]/[feature].go`** (replace `[module]`, `[feature]`, `[Feature]`, `[subcommand]`):
272
+ **`adapters/cli/[feature].go`** (replace `[module]`, `[feature]`, `[Feature]`, `[subcommand]`):
273
273
 
274
274
  ```go
275
- package cli[Feature]
275
+ package cli
276
276
 
277
277
  import (
278
278
  "flag"
@@ -280,11 +280,11 @@ import (
280
280
  "os"
281
281
 
282
282
  "github.com/sirupsen/logrus"
283
- "[module]/[feature]"
283
+ "[module]/app/[feature]"
284
284
  )
285
285
 
286
- // Run parses CLI flags for the [subcommand] command and calls the domain package.
287
- func Run(args []string) {
286
+ // Run[Feature] parses CLI flags for the [subcommand] command and calls the domain package.
287
+ func Run[Feature](args []string) {
288
288
  fs := flag.NewFlagSet("[subcommand]", flag.ExitOnError)
289
289
  verbose := fs.Bool("verbose", false, "Show verbose logs during processing")
290
290
 
@@ -309,6 +309,21 @@ func Run(args []string) {
309
309
  }
310
310
  ```
311
311
 
312
+ **`shared/logging.go`** (optional, scaffold if needed):
313
+
314
+ ```go
315
+ package shared
316
+
317
+ import "github.com/sirupsen/logrus"
318
+
319
+ // SetupLogging configures the global log level.
320
+ func SetupLogging(verbose bool) {
321
+ if verbose {
322
+ logrus.SetLevel(logrus.DebugLevel)
323
+ }
324
+ }
325
+ ```
326
+
312
327
  ---
313
328
 
314
329
  ### Phase 5: Verify and run
@@ -327,8 +342,10 @@ Fix any compile or lint errors before finishing.
327
342
  ## Conventions and reminders
328
343
 
329
344
  - `main.go` dispatches only — no logic.
330
- - Business logic only in `[feature]/` packages — no flag parsing, no `fmt.Println` for diagnostics.
331
- - `cli/[feature]/` owns flags, output, and calls domain. No logic here beyond reading flags and printing results.
345
+ - Business logic only in `app/<feature>/` packages — no flag parsing, no `fmt.Println` for diagnostics.
346
+ - `adapters/cli/` owns flag parsing, output formatting, and the wiring between flags and `app/` functions. No business logic lives in adapter packages.
347
+ - Outbound adapters live under `adapters/connectors/` with one subfolder per external resource (e.g., `postgres/`, `stripe-api/`, `redis-cache/`).
348
+ - `shared/` must contain only infrastructure-agnostic utilities — not business rules or domain logic.
332
349
  - All tests co-located (`*_test.go` next to the file under test).
333
350
  - Use `tests_integration/` for integration flows and `tests_benchmark/` when benchmarks need dedicated harnesses or datasets.
334
351
  - Log with `logrus`; never use `fmt.Println` for diagnostic/debug output.
@@ -1,10 +1,9 @@
1
1
  ---
2
2
  name: agentme-edr-skill-005-create-python-project
3
3
  description: >
4
- Scaffolds the initial boilerplate structure for a Python library or CLI project following the
5
- standard tooling and layout defined in agentme-edr-014. Activate this skill when the user asks
6
- to create, scaffold, or initialize a new Python package, CLI, library, or similar project
7
- structure.
4
+ Scaffolds the initial boilerplate structure for a Python project following the standard tooling
5
+ and layout defined in agentme-edr-014. Activate this skill when the user asks to create,
6
+ scaffold, or initialize a new Python package, CLI, or similar project structure.
8
7
  metadata:
9
8
  author: flaviostutz
10
9
  version: "1.0"
@@ -14,11 +13,12 @@ compatibility: Python 3.12+
14
13
  ## Overview
15
14
 
16
15
  Creates a complete Python project from scratch using Mise, `uv`, `pyproject.toml`, Ruff,
17
- Pyright, Pytest, and Makefiles. The default layout keeps the library self-contained under `lib/`,
18
- uses a shared root `.venv/`, redirects persistent caches into `.cache/`, and places runnable
19
- consumer projects under the sibling `examples/` folder.
16
+ Pyright, Pytest, and Makefiles. The layout keeps the package self-contained under `lib/`,
17
+ organizes internal code following [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md)
18
+ (`adapters/`, `app/`, `shared/`), uses a shared root `.venv/`, redirects persistent caches into
19
+ `.cache/`, and places runnable consumer projects under the sibling `examples/` folder.
20
20
 
21
- Related EDRs: [agentme-edr-014](../../014-python-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md)
21
+ Related EDRs: [agentme-edr-014](../../014-python-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md), [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md)
22
22
 
23
23
  ## Instructions
24
24
 
@@ -30,7 +30,6 @@ Ask for or infer from context:
30
30
  - **Short description** - one sentence
31
31
  - **Author** name or GitHub username
32
32
  - **Python version** - default `3.13`
33
- - **Project kind** - `library` or `cli`
34
33
  - **Primary entry point** - first module or command name to scaffold
35
34
  - **GitHub repo URL** - optional, for project metadata
36
35
  - **Confirm target directory** - default: current workspace root
@@ -105,6 +104,7 @@ The root `Makefile` keeps the repository clean by delegating package work to `li
105
104
  .venv/
106
105
  dist/
107
106
  .cache/
107
+ __pycache__/
108
108
  ```
109
109
 
110
110
  **`./README.md`**
@@ -214,11 +214,28 @@ requires = ["hatchling>=1.27.0"]
214
214
  build-backend = "hatchling.build"
215
215
 
216
216
  [tool.ruff]
217
- line-length = 100
217
+ cache-dir = ".cache/ruff"
218
+ output-format = "grouped"
219
+ line-length = 120
218
220
  target-version = "py313"
221
+ src = ["src", "tests", "tests_integration"]
222
+
223
+ [tool.ruff.format]
224
+ docstring-code-format = true
225
+ line-ending = "lf"
219
226
 
220
227
  [tool.ruff.lint]
221
- select = ["E", "F", "I", "B", "UP"]
228
+ task-tags = ["TODO"]
229
+ select = ["ERA", "FAST", "ANN", "ASYNC", "S", "BLE", "FBT", "B", "A", "COM",
230
+ "C4", "DTZ", "T10", "DJ", "EM", "EXE", "FIX", "INT", "ISC", "ICN", "LOG", "G",
231
+ "INP", "PIE", "T20", "PYI", "PT", "Q", "RSE", "RET", "SLF", "SIM", "SLOT", "TID",
232
+ "TC", "ARG", "PTH", "FLY", "I", "C90", "NPY", "PD", "N", "PERF", "E", "W",
233
+ "D", "F", "PGH", "PL", "UP", "FURB", "RUF", "TRY"]
234
+ ignore = ["ANN002", "ANN003", "ANN401", "D100", "D101", "D102", "D103", "D104",
235
+ "D105", "D106", "D107", "COM812", "D203", "D213", "D400", "D401", "D404", "D415", "FIX002"]
236
+
237
+ [tool.ruff.lint.pycodestyle]
238
+ ignore-overlong-task-comments = true
222
239
 
223
240
  [tool.pyright]
224
241
  include = ["src", "tests"]
@@ -267,29 +284,37 @@ make test
267
284
 
268
285
  ### Phase 4: Create the package and tests inside `lib/`
269
286
 
270
- Create this baseline structure.
287
+ Create this baseline structure following [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md).
271
288
 
272
289
  **`lib/src/[package_name]/__init__.py`**
273
290
 
274
291
  ```python
275
- from .core import hello
292
+ from .app.hello import hello
276
293
 
277
294
  __all__ = ["hello"]
278
295
  ```
279
296
 
280
- **`lib/src/[package_name]/core.py`**
297
+ **`lib/src/[package_name]/app/__init__.py`**
298
+
299
+ ```python
300
+ ```
301
+
302
+ **`lib/src/[package_name]/app/hello.py`**
281
303
 
282
304
  ```python
283
305
  def hello(name: str) -> str:
284
306
  return f"Hello, {name}!"
285
307
  ```
286
308
 
287
- **`lib/src/[package_name]/__main__.py`**
309
+ **`lib/src/[package_name]/adapters/__init__.py`**
288
310
 
289
- Use this only for CLI-oriented projects.
311
+ ```python
312
+ ```
313
+
314
+ **`lib/src/[package_name]/adapters/cli/__init__.py`**
290
315
 
291
316
  ```python
292
- from .core import hello
317
+ from [package_name].app.hello import hello
293
318
 
294
319
 
295
320
  def main() -> None:
@@ -300,10 +325,17 @@ if __name__ == "__main__":
300
325
  main()
301
326
  ```
302
327
 
303
- **`lib/tests/test_core.py`**
328
+ **`lib/src/[package_name]/shared/__init__.py`**
329
+
330
+ ```python
331
+ ```
332
+
333
+ Create empty `adapters/connectors/` directory with a `.gitkeep` for outbound adapters.
334
+
335
+ **`lib/tests/test_hello.py`**
304
336
 
305
337
  ```python
306
- from [package_name].core import hello
338
+ from [package_name].app.hello import hello
307
339
 
308
340
 
309
341
  def test_hello() -> None:
@@ -314,9 +346,9 @@ If two or more test files need shared fixtures, create `lib/tests/conftest.py` a
314
346
 
315
347
  If the module needs slower end-to-end coverage, place those tests in `lib/tests_integration/`. Put dedicated benchmark harnesses in `lib/tests_benchmark/`.
316
348
 
317
- ### Phase 5: Create examples for libraries and utilities
349
+ ### Phase 5: Create examples
318
350
 
319
- 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.
351
+ Add an `examples/` directory with one subdirectory per runnable consumer example. Each example must be its own Python project.
320
352
 
321
353
  **`examples/basic-usage/pyproject.toml`**
322
354
 
@@ -355,14 +387,15 @@ After creating the files:
355
387
 
356
388
  ## Examples
357
389
 
358
- **Input:** "Create a Python library called `event_tools`"
390
+ **Input:** "Create a Python project called `event_tools`"
359
391
  - Create `Makefile`, `README.md`, `lib/pyproject.toml`, `lib/Makefile`, `lib/src/event_tools/`, `lib/tests/`, and `examples/`
392
+ - Scaffold `adapters/`, `app/`, `shared/` directories inside `lib/src/event_tools/`
360
393
  - Add `lib/README.md`, `.cache/` handling, and install examples from the built wheel in `lib/dist/`
361
394
  - Configure `uv`, Ruff, Pyright, Pytest, `pytest-cov`, and `pip-audit`
362
395
  - Verify with `make lint-fix`, `make test`, and `make build`
363
396
 
364
397
  **Input:** "Scaffold a Python CLI package"
365
- - Add `lib/src/<package_name>/__main__.py`
398
+ - Add CLI entry point in `lib/src/<package_name>/adapters/cli/__init__.py`
366
399
  - Add `[project.scripts]` in `lib/pyproject.toml` when the command name must differ from the module name
367
400
  - Keep the same Makefile and quality checks
368
401
 
@@ -20,7 +20,7 @@ What monorepo structure, naming conventions, tooling, and build standards should
20
20
  For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/002-monorepo-setup/SKILL.md).
21
21
  Module folder responsibilities, artifact locations, and test-folder conventions follow [agentme-edr-016](../principles/016-cross-language-module-structure.md).
22
22
 
23
- ### Implementation Details
23
+ ### Details
24
24
 
25
25
  #### 01-top-level-directory-layout
26
26