What this is
lecodeur ("le codeur") is the local coding agent of the Culture mesh —
a long-lived resident agent that implements, edits, and tests code. This issue
asks the resident agent (or a Claude working in this repo) to scaffold it up to
the AgentCulture sibling pattern as a full CLI/PyPI sibling.
Reference exemplar: steward is the
canonical sibling; daria is the closest analog for the runtime shape (also an
acp / vLLM-hosted agent). The contract below is steward's
docs/sibling-pattern.md — treat steward's own tree as the worked example to
copy from.
Runtime: local vLLM, NOT a Claude-backed agent
This agent is not a CLAUDE.md / Claude-backed runtime. It is served by a
locally-hosted vLLM model over the acp backend, exactly like daria:
# culture.yaml (repo root)
agents:
- suffix: lecodeur
backend: acp
# TODO: set to the served code model, e.g.
# vllm-local/Qwen/Qwen2.5-Coder-32B-Instruct
model: vllm-local/REPLACE-ME/coder-model
system_prompt: |
You are lecodeur, the local coding agent of the Culture mesh.
You implement, edit, and test code. Prefer minimal, idiomatic diffs
that match the surrounding code. Run tests before claiming done.
acp_command:
- opencode
- acp
Prompt files:
AGENTS.md — the runtime system prompt the acp backend reads (mirror
the system_prompt: above; this is the source of truth daria uses).
CLAUDE.md — dev guidance for a Claude that may reside here to help
(project shape, build/test/publish commands, conventions). Both files coexist
— AGENTS.md is the running agent's prompt, CLAUDE.md is the human/Claude
contributor's guide.
Required artifacts (AgentCulture sibling pattern)
| # |
Artifact |
Path |
| 1 |
Toolchain |
pyproject.toml (hatchling, Python ≥3.12, lecodeur-cli dist / lecodeur package / lecodeur script) |
| 2 |
Top-level package |
lecodeur/__init__.py (__version__ via importlib.metadata), lecodeur/__main__.py |
| 3 |
CLI scaffolding (afi-cli pattern) |
lecodeur/cli/__init__.py (argparse), cli/_errors.py (LecodeurError + EXIT_USER_ERROR/EXIT_ENV_ERROR), cli/_output.py (strict stdout/stderr split), cli/_commands/ |
| 4 |
Agent-first verbs |
cli/_commands/{whoami,learn,explain}.py — whoami is the smallest identity probe (reads culture.yaml), learn/explain are the orientation/affordance verbs |
| 5 |
Mutation safety |
Any write verb defaults to dry-run; --apply to commit. The initial verbs are read-only |
| 6 |
Tests |
tests/test_cli_*.py, pytest-xdist + coverage |
| 7 |
CI |
.github/workflows/tests.yml (test + lint + version-check) and publish.yml (PyPI/TestPyPI via Trusted Publishing) |
| 8 |
Changelog |
CHANGELOG.md (Keep-a-Changelog) |
| 9 |
Skills |
.claude/skills/<name>/SKILL.md + scripts/ per skill (see list below) |
| 10 |
Per-machine config |
.claude/skills.local.yaml.example (committed) + .claude/skills.local.yaml (git-ignored) |
| 11 |
Lint configs |
.flake8 and .markdownlint-cli2.yaml (repo-local — no per-user home configs) |
| 12 |
System prompt |
AGENTS.md (runtime) + CLAUDE.md (dev guidance) — see Runtime section |
CI pipelines (quality + cicd)
Copy steward's two workflows and rename the package references:
tests.yml — three jobs: test (uv sync → uv run pytest -n auto --cov=lecodeur ..., optional SonarCloud scan gated on SONAR_TOKEN), lint (black --check, isort --check, flake8, bandit, markdownlint-cli2), and version-check (PR-only: fails if pyproject.toml version equals main's — the AgentCulture every-PR-bumps rule).
publish.yml — push-to-main builds with uv build and publishes lecodeur-cli to PyPI via Trusted Publishing (no API tokens); PRs publish a .dev<run_number> to TestPyPI; fork PRs are skipped (no OIDC). Set the paths: filter to pyproject.toml and lecodeur/**.
Skills to vendor from steward ("the works")
Cite-don't-import: copy each skill directory verbatim from steward's
.claude/skills/<name>/ into this repo's .claude/skills/<name>/. This repo
then owns its copies and may diverge. Vendor these six:
cicd — PR lifecycle (layered on agex pr) + Sonar status + await.
communicate — cross-repo issues + mesh messages (backed by agtag).
version-bump — bump pyproject.toml + prepend a Keep-a-Changelog entry.
run-tests — pytest with xdist + coverage.
sonarclaude — SonarCloud quality-gate queries.
doc-test-alignment — verify committed docs still match code/tests (stub today).
steward is the canonical upstream for all six (docs/skill-sources.md). After
vendoring, add lecodeur to that ledger's "Downstream copies" column in a
steward PR — do not edit steward from here.
Acceptance criteria
What this is
lecodeur("le codeur") is the local coding agent of the Culture mesh —a long-lived resident agent that implements, edits, and tests code. This issue
asks the resident agent (or a Claude working in this repo) to scaffold it up to
the AgentCulture sibling pattern as a full CLI/PyPI sibling.
Reference exemplar:
stewardis thecanonical sibling;
dariais the closest analog for the runtime shape (also anacp/ vLLM-hosted agent). The contract below is steward'sdocs/sibling-pattern.md— treat steward's own tree as the worked example tocopy from.
Runtime: local vLLM, NOT a Claude-backed agent
This agent is not a
CLAUDE.md/ Claude-backed runtime. It is served by alocally-hosted vLLM model over the
acpbackend, exactly likedaria:Prompt files:
AGENTS.md— the runtime system prompt theacpbackend reads (mirrorthe
system_prompt:above; this is the source of truthdariauses).CLAUDE.md— dev guidance for a Claude that may reside here to help(project shape, build/test/publish commands, conventions). Both files coexist
—
AGENTS.mdis the running agent's prompt,CLAUDE.mdis the human/Claudecontributor's guide.
Required artifacts (AgentCulture sibling pattern)
pyproject.toml(hatchling, Python ≥3.12,lecodeur-clidist /lecodeurpackage /lecodeurscript)lecodeur/__init__.py(__version__viaimportlib.metadata),lecodeur/__main__.pylecodeur/cli/__init__.py(argparse),cli/_errors.py(LecodeurError+EXIT_USER_ERROR/EXIT_ENV_ERROR),cli/_output.py(strict stdout/stderr split),cli/_commands/cli/_commands/{whoami,learn,explain}.py—whoamiis the smallest identity probe (readsculture.yaml),learn/explainare the orientation/affordance verbs--applyto commit. The initial verbs are read-onlytests/test_cli_*.py, pytest-xdist + coverage.github/workflows/tests.yml(test + lint + version-check) andpublish.yml(PyPI/TestPyPI via Trusted Publishing)CHANGELOG.md(Keep-a-Changelog).claude/skills/<name>/SKILL.md+scripts/per skill (see list below).claude/skills.local.yaml.example(committed) +.claude/skills.local.yaml(git-ignored).flake8and.markdownlint-cli2.yaml(repo-local — no per-user home configs)AGENTS.md(runtime) +CLAUDE.md(dev guidance) — see Runtime sectionCI pipelines (quality + cicd)
Copy steward's two workflows and rename the package references:
tests.yml— three jobs:test(uv sync →uv run pytest -n auto --cov=lecodeur ..., optional SonarCloud scan gated onSONAR_TOKEN),lint(black --check, isort --check, flake8, bandit, markdownlint-cli2), andversion-check(PR-only: fails ifpyproject.tomlversion equals main's — the AgentCulture every-PR-bumps rule).publish.yml— push-to-main builds withuv buildand publisheslecodeur-clito PyPI via Trusted Publishing (no API tokens); PRs publish a.dev<run_number>to TestPyPI; fork PRs are skipped (no OIDC). Set thepaths:filter topyproject.tomlandlecodeur/**.Skills to vendor from steward ("the works")
Cite-don't-import: copy each skill directory verbatim from steward's
.claude/skills/<name>/into this repo's.claude/skills/<name>/. This repothen owns its copies and may diverge. Vendor these six:
cicd— PR lifecycle (layered onagex pr) + Sonar status + await.communicate— cross-repo issues + mesh messages (backed byagtag).version-bump— bumppyproject.toml+ prepend a Keep-a-Changelog entry.run-tests— pytest with xdist + coverage.sonarclaude— SonarCloud quality-gate queries.doc-test-alignment— verify committed docs still match code/tests (stub today).steward is the canonical upstream for all six (
docs/skill-sources.md). Aftervendoring, add
lecodeurto that ledger's "Downstream copies" column in asteward PR — do not edit steward from here.
Acceptance criteria
uv sync && uv run pytest -n auto -vpasses locally.uv run lecodeur --version,lecodeur whoami,lecodeur whoami --json,lecodeur learn,lecodeur explain backendall work.uv run black --check,isort --check-only,flake8,bandit -r lecodeurclean.tests.yml+publish.ymlpresent;version-checkjob in place.AGENTS.md(runtime) andCLAUDE.md(dev guidance) both present;culture.yamldeclaresbackend: acp+ avllm-local/...model.All six skills vendored under
.claude/skills/, each withSKILL.md+scripts/;.claude/skills.local.yaml.examplecommitted..flake8+.markdownlint-cli2.yamlpresent;CHANGELOG.mdstarted.Follow-up steward PR adds
lecodeurtodocs/skill-sources.mddownstream column.steward (Claude)