Skip to content

Commit 1387534

Browse files
OriNachumclaude
andcommitted
fix: add sonar config, structured cli errors, mirror culture.yaml to AGENTS.md
- Add sonar-project.properties (agentculture_lepenseur) — the missing file caused the tests.yml SonarCloud step to fail (no projectKey/organization). - cli noun: propagate parser_class to nested subparsers so 'cli overview' parse errors route through the structured error contract (Qodo bug). - culture.yaml system_prompt now mirrors AGENTS.md verbatim (Qodo rule). - Add regression test for structured cli overview parse errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 788b192 commit 1387534

4 files changed

Lines changed: 73 additions & 15 deletions

File tree

culture.yaml

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,46 @@ agents:
22
- suffix: lepenseur
33
backend: acp
44
model: vllm-local/nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4
5+
# Mirrors AGENTS.md verbatim (the runtime system prompt source of truth).
56
system_prompt: |
6-
You are lepenseur ("le penseur"), the local thinking agent of the Culture
7-
mesh. You reason, plan, and analyze deeply. You are a thinker, not an actor:
8-
you do not execute code or change the world. Your entire act surface is three
9-
things — post to Culture chat, reply on Culture chat, and create files.
10-
11-
You are the reasoner of a matched pair: lecodeur ("le codeur") implements and
12-
tests code; you plan, it executes. daria observes the mesh and surfaces drift.
13-
daria notices, you reason, lecodeur builds.
14-
15-
Prefer: observation -> interpretation -> next step. Distinguish facts,
16-
inferences, and recommendations. If confidence is low, say what is uncertain.
17-
If a situation is ambiguous, ask one focused question rather than guessing.
18-
Default to a few clear sentences; never a bare single word unless asked. Be
19-
warm enough to feel present, precise enough to be trusted.
7+
You are lepenseur ("le penseur" — *the thinker*), the local thinking agent of the
8+
Culture mesh. You reason, plan, and analyze deeply.
9+
10+
You are a **thinker, not an actor.** You do not execute code, run tools, or change
11+
the world. Your entire act surface is three things: **post to Culture chat, reply
12+
on Culture chat, and create files.** Express thinking through writing — never code
13+
execution, never orchestration.
14+
15+
You are the **reasoner** of a matched pair:
16+
17+
- **lecodeur** ("le codeur" — the coder) implements, edits, and tests code. It is
18+
your closest sibling: you plan, it executes.
19+
- **daria** (awareness) observes the mesh and surfaces drift. It is the
20+
next-closest sibling.
21+
22+
The division of labor: daria notices, **you reason**, lecodeur builds.
23+
24+
## How you work
25+
26+
- Prefer: observation → interpretation → next step.
27+
- Distinguish facts, inferences, and recommendations.
28+
- If confidence is low, say what is uncertain. If a situation is ambiguous, ask
29+
one focused question rather than guessing.
30+
- Default to a few clear sentences; never a bare single word unless asked.
31+
- Be warm enough to feel present, precise enough to be trusted. Do not fake
32+
certainty or emotion.
33+
- Stay in your lane: you think and write. Anything that needs doing in the world
34+
becomes a plan for lecodeur or a message to the mesh — not an action you take.
35+
36+
## Runtime
37+
38+
You are served by a locally-hosted vLLM reasoning model
39+
(`nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4` — a 120B-total / 12B-active
40+
LatentMoE model in NVFP4 with a 1M-token context, running on DGX Spark) over the
41+
`acp` backend — not a Claude-backed runtime. It emits a reasoning trace before its
42+
answer, which suits a deep thinker. This file is your system prompt; `CLAUDE.md` is
43+
separate guidance for a Claude that resides in the repo to help build and maintain
44+
it.
2045
acp_command:
2146
- opencode
2247
- acp

lepenseur/cli/_commands/cli.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ def register(sub: argparse._SubParsersAction) -> None:
3030
)
3131
p.add_argument("--json", action="store_true", help="Emit structured JSON.")
3232
p.set_defaults(func=_no_verb, json=False)
33-
noun_sub = p.add_subparsers(dest="cli_command")
33+
# `p` is a _LepenseurArgumentParser (the top-level subparsers were built with
34+
# that parser_class); propagate it so `cli overview` parse errors route through
35+
# the structured error contract instead of argparse's default stderr/exit 2.
36+
noun_sub = p.add_subparsers(dest="cli_command", parser_class=type(p))
3437
ov = noun_sub.add_parser("overview", help="Describe the lepenseur CLI surface.")
3538
ov.add_argument("--json", action="store_true", help="Emit structured JSON.")
3639
ov.set_defaults(func=cmd_cli_overview)

sonar-project.properties

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SonarCloud project identity. Matches the project key registered on
2+
# SonarCloud and used by the cicd skill's Sonar status queries
3+
# (`agentculture_lepenseur`).
4+
sonar.projectKey=agentculture_lepenseur
5+
sonar.organization=agentculture
6+
7+
# Source layout — package lives at the top level (no src/ wrapper).
8+
sonar.sources=lepenseur
9+
sonar.tests=tests
10+
11+
# Coverage report produced in CI by `uv run pytest --cov-report=xml:coverage.xml`
12+
# (see .github/workflows/tests.yml). Path is relative to the repo root.
13+
sonar.python.coverage.reportPaths=coverage.xml
14+
sonar.python.version=3.12
15+
16+
# Don't analyze noise.
17+
sonar.exclusions=**/__pycache__/**,**/.venv/**,uv.lock

tests/test_cli_introspection.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,19 @@ def test_cli_noun_bare_is_non_empty(capsys: pytest.CaptureFixture[str]) -> None:
5858
assert capsys.readouterr().out.strip()
5959

6060

61+
def test_cli_overview_unknown_flag_structured_error(
62+
capsys: pytest.CaptureFixture[str],
63+
) -> None:
64+
# `cli overview` parse errors must route through the structured error
65+
# contract (error:/hint: + exit 1), not argparse's default stderr/exit 2.
66+
with pytest.raises(SystemExit) as exc:
67+
main(["cli", "overview", "--bogus"])
68+
assert exc.value.code == 1
69+
err = capsys.readouterr().err
70+
assert err.startswith("error:")
71+
assert "hint:" in err
72+
73+
6174
# --- doctor (stub) --------------------------------------------------------
6275

6376

0 commit comments

Comments
 (0)