steward-cli 0.2.0__tar.gz → 0.3.0__tar.gz

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 (45) hide show
  1. {steward_cli-0.2.0 → steward_cli-0.3.0}/CHANGELOG.md +16 -1
  2. {steward_cli-0.2.0 → steward_cli-0.3.0}/CLAUDE.md +32 -18
  3. {steward_cli-0.2.0 → steward_cli-0.3.0}/PKG-INFO +2 -1
  4. steward_cli-0.3.0/docs/perfect-patient.md +35 -0
  5. {steward_cli-0.2.0 → steward_cli-0.3.0}/docs/sibling-pattern.md +20 -10
  6. {steward_cli-0.2.0 → steward_cli-0.3.0}/pyproject.toml +4 -2
  7. {steward_cli-0.2.0 → steward_cli-0.3.0}/steward/cli/__init__.py +2 -2
  8. steward_cli-0.3.0/steward/cli/_commands/_corpus.py +522 -0
  9. steward_cli-0.3.0/steward/cli/_commands/doctor.py +472 -0
  10. {steward_cli-0.2.0 → steward_cli-0.3.0}/tests/test_cli.py +1 -1
  11. steward_cli-0.2.0/tests/test_cli_verify.py → steward_cli-0.3.0/tests/test_cli_doctor.py +28 -15
  12. steward_cli-0.3.0/tests/test_cli_doctor_siblings.py +186 -0
  13. steward_cli-0.3.0/tests/test_corpus.py +257 -0
  14. {steward_cli-0.2.0 → steward_cli-0.3.0}/uv.lock +5 -1
  15. steward_cli-0.2.0/steward/cli/_commands/verify.py +0 -228
  16. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/agent-config/SKILL.md +0 -0
  17. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/agent-config/scripts/show.sh +0 -0
  18. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
  19. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
  20. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/pr-review/SKILL.md +0 -0
  21. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/pr-review/scripts/portability-lint.sh +0 -0
  22. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/pr-review/scripts/pr-batch.sh +0 -0
  23. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/pr-review/scripts/pr-comments.sh +0 -0
  24. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/pr-review/scripts/pr-reply.sh +0 -0
  25. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/pr-review/scripts/pr-status.sh +0 -0
  26. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/pr-review/scripts/workflow.sh +0 -0
  27. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/version-bump/SKILL.md +0 -0
  28. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills/version-bump/scripts/bump.py +0 -0
  29. {steward_cli-0.2.0 → steward_cli-0.3.0}/.claude/skills.local.yaml.example +0 -0
  30. {steward_cli-0.2.0 → steward_cli-0.3.0}/.flake8 +0 -0
  31. {steward_cli-0.2.0 → steward_cli-0.3.0}/.github/workflows/publish.yml +0 -0
  32. {steward_cli-0.2.0 → steward_cli-0.3.0}/.github/workflows/tests.yml +0 -0
  33. {steward_cli-0.2.0 → steward_cli-0.3.0}/.gitignore +0 -0
  34. {steward_cli-0.2.0 → steward_cli-0.3.0}/.markdownlint-cli2.yaml +0 -0
  35. {steward_cli-0.2.0 → steward_cli-0.3.0}/LICENSE +0 -0
  36. {steward_cli-0.2.0 → steward_cli-0.3.0}/README.md +0 -0
  37. {steward_cli-0.2.0 → steward_cli-0.3.0}/docs/skill-sources.md +0 -0
  38. {steward_cli-0.2.0 → steward_cli-0.3.0}/steward/__init__.py +0 -0
  39. {steward_cli-0.2.0 → steward_cli-0.3.0}/steward/__main__.py +0 -0
  40. {steward_cli-0.2.0 → steward_cli-0.3.0}/steward/cli/_commands/__init__.py +0 -0
  41. {steward_cli-0.2.0 → steward_cli-0.3.0}/steward/cli/_commands/show.py +0 -0
  42. {steward_cli-0.2.0 → steward_cli-0.3.0}/steward/cli/_errors.py +0 -0
  43. {steward_cli-0.2.0 → steward_cli-0.3.0}/steward/cli/_output.py +0 -0
  44. {steward_cli-0.2.0 → steward_cli-0.3.0}/tests/__init__.py +0 -0
  45. {steward_cli-0.2.0 → steward_cli-0.3.0}/tests/test_skills_convention.py +0 -0
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/). This project
6
6
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.0] - 2026-04-26
9
+
10
+ ### Added
11
+
12
+ - `steward doctor --scope siblings` walks every `culture.yaml` in the workspace, scores each declared agent against a corpus-derived baseline, writes per-target feedback into `<target>/docs/steward/steward-suggestions.md` (gated by a marker line so hand-written content there is preserved), and refreshes `docs/perfect-patient.md` in the steward checkout. Diagnostic-only — corpus mode never exits non-zero on per-agent drift.
13
+ - `docs/perfect-patient.md` — committed placeholder; populated on each `--scope siblings` run with required/recommended `culture.yaml` fields, the common skills baseline, common `CLAUDE.md` sections, and corpus stats.
14
+ - `steward/cli/_commands/_corpus.py` — pure helpers (`discover_agents`, `synthesize_baseline`, `render_perfect_patient`, `score_culture_yaml_shape`, `score_agent_against_baseline`, `write_repo_report`) used by `doctor --scope siblings`. Tested in isolation by `tests/test_corpus.py`.
15
+ - `tests/test_corpus.py` and `tests/test_cli_doctor_siblings.py` — unit + end-to-end coverage for corpus mode (discovery handles both `agents:` lists and flat root-level `suffix:` shapes; baseline classification by frequency; report writer is idempotent and preserves hand-written content; JSON output shape; empty-workspace diagnostic; --no-write-reports / --no-refresh-perfect-patient gates).
16
+
17
+ ### Changed
18
+
19
+ - **Renamed `steward verify` → `steward doctor`** (single-repo mode). Same checks (`portability`, `skills-convention`), same flags (`--json`, `--check`), same exit semantics (non-zero on findings). New flags: `--scope {self,siblings}` (default `self` is backward-compatible with `verify`), `--workspace-root`, `--no-write-reports`, `--no-refresh-perfect-patient`, `--perfect-patient-out`. No `verify` alias kept — this is a breaking CLI change.
20
+ - Added `pyyaml>=6.0` as the first runtime dependency. Required to parse sibling `culture.yaml` manifests in corpus mode; the existing `agent-config` skill already shells out to a Python+PyYAML one-liner, so the dep was implicit.
21
+ - `docs/sibling-pattern.md` and `CLAUDE.md` Roadmap section rewritten to describe `doctor`'s two scopes (self / siblings) and reposition the planned `--apply` repair handlers as the next layer.
22
+
8
23
  ## [0.2.0] - 2026-04-26
9
24
 
10
25
  ### Added
@@ -71,7 +86,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
71
86
 
72
87
  ### Fixed
73
88
 
74
- - bump.py docstring no longer overstates what gets updated; the __init__.py rewrite is conditional and is a no-op for steward (3143024085).
89
+ - bump.py docstring no longer overstates what gets updated; the `__init__.py` rewrite is conditional and is a no-op for steward (3143024085).
75
90
 
76
91
  ## [0.1.0] - 2026-04-26
77
92
 
@@ -25,7 +25,9 @@ steward/ # Python package (pip install steward-cli)
25
25
  ├── _errors.py # StewardError + EXIT_USER_ERROR / EXIT_ENV_ERROR
26
26
  ├── _output.py # emit_result / emit_error / emit_diagnostic
27
27
  └── _commands/ # subcommand modules; each has register(sub) + handler
28
- └── show.py # `steward show <target>` → wraps agent-config skill
28
+ ├── show.py # `steward show <target>` → wraps agent-config skill
29
+ ├── doctor.py # `steward doctor` → single-repo or corpus diagnosis
30
+ └── _corpus.py # corpus helpers used by `doctor --scope siblings`
29
31
  tests/ # pytest suite
30
32
  .claude/skills/ # see "Skills convention" below
31
33
  .github/workflows/ # tests.yml + publish.yml (OIDC Trusted Publishing)
@@ -63,23 +65,35 @@ Steward is a "skills supplier" for the Culture mesh. When a skill stabilizes her
63
65
 
64
66
  ## Roadmap (CLI surface)
65
67
 
66
- The current CLI ships one verb (`steward show`). The next two verbs are
67
- `verify` (read-only diagnosis against the AgentCulture sibling pattern) and
68
- `doctor` (diagnose-and-fix; default dry-run, `--apply` to commit). Together
69
- they encode steward's mission as code instead of prose:
70
-
71
- - `steward verify <path>` — score a target repo against `docs/sibling-pattern.md`.
72
- Aggregates findings across all selected checks, then exits non-zero if any
73
- finding was reported. Human-readable findings go to stderr; `--json` emits
74
- the structured findings list to stdout. The first cut runs steward's own
75
- vendored `.claude/skills/pr-review/scripts/portability-lint.sh` against the
76
- target (so the target doesn't need to vendor it), plus a skills-convention
77
- check (every `SKILL.md` has a sibling `scripts/` entry-point).
78
- - `steward doctor <path>` — repair what `verify` flagged, where the repair is
79
- unambiguous (missing `scripts/` directory, missing `.markdownlint-cli2.yaml`,
80
- missing `.claude/skills.local.yaml.example`, etc.). Larger emissions (CLI
81
- scaffold) land later as additional repair handlers, eventually consuming
82
- `../afi-cli/afi/cite/_engine.py` rather than re-implementing it.
68
+ The CLI ships two verbs today: `steward show` and `steward doctor`. Doctor
69
+ runs in two modes — single-repo diagnosis (the original "verify" flow,
70
+ folded into doctor) and corpus mode (the agent-iteration flow). The
71
+ `--apply` repair mode is the next layer on top.
72
+
73
+ - `steward doctor <path>` (default `--scope self`) — score a target repo
74
+ against `docs/sibling-pattern.md`. Aggregates findings across all
75
+ selected checks, then exits non-zero if any finding was reported.
76
+ Human-readable findings go to stderr; `--json` emits the structured
77
+ findings list to stdout. Today: `portability` (runs steward's own
78
+ vendored `.claude/skills/pr-review/scripts/portability-lint.sh` against
79
+ the target, so the target doesn't need to vendor it) and
80
+ `skills-convention` (every `SKILL.md` has a sibling `scripts/`
81
+ entry-point and matching frontmatter `name`).
82
+ - `steward doctor --scope siblings` — walks every `culture.yaml` in the
83
+ workspace (`<workspace-root>/*/culture.yaml`, sibling-only by default),
84
+ tallies field/skill/CLAUDE.md-section frequency across the corpus to
85
+ synthesize `docs/perfect-patient.md`, scores every declared agent
86
+ against that baseline, and writes per-target feedback into
87
+ `<target>/docs/steward/steward-suggestions.md` (gated by a marker line
88
+ so hand-written content in that path is preserved). Diagnostic-only —
89
+ exits 0 even when individual agents drift from the baseline; that is
90
+ reported in the per-target file rather than as a CLI failure.
91
+ - `steward doctor --apply` *(planned)* — repair what diagnosis flagged,
92
+ where the repair is unambiguous (missing `scripts/` directory, missing
93
+ `.markdownlint-cli2.yaml`, missing `.claude/skills.local.yaml.example`,
94
+ etc.). Larger emissions (CLI scaffold) land later as additional repair
95
+ handlers, eventually consuming `../afi-cli/afi/cite/_engine.py` rather
96
+ than re-implementing it.
83
97
 
84
98
  Per-skill upstreams (which repo owns the canonical copy of `version-bump`,
85
99
  `pr-review`, etc.) are recorded in `docs/skill-sources.md` so `doctor` can
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: steward-cli
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Steward — aligns and maintains resident agents across Culture projects.
5
5
  Project-URL: Homepage, https://github.com/agentculture/steward
6
6
  Project-URL: Issues, https://github.com/agentculture/steward/issues
@@ -13,6 +13,7 @@ Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Classifier: Topic :: Software Development
15
15
  Requires-Python: >=3.12
16
+ Requires-Dist: pyyaml>=6.0
16
17
  Description-Content-Type: text/markdown
17
18
 
18
19
  # steward
@@ -0,0 +1,35 @@
1
+ # Perfect patient
2
+
3
+ > This file is auto-generated by `steward doctor --scope siblings`. The
4
+ > committed copy is a placeholder; run the command locally to populate it
5
+ > with real corpus statistics from the `culture.yaml` files in your
6
+ > workspace.
7
+ >
8
+ > The baseline is descriptive, not prescriptive: it describes what a
9
+ > typical healthy agent looks like in the current corpus, so drift can
10
+ > be spotted. Edit by hand only if you intend to ratchet the bar —
11
+ > `steward doctor --scope siblings` overwrites this file.
12
+
13
+ ## Required `culture.yaml` fields
14
+
15
+ Populated on first `steward doctor --scope siblings` run.
16
+
17
+ ## Recommended `culture.yaml` fields
18
+
19
+ Populated on first `steward doctor --scope siblings` run.
20
+
21
+ ## Common skills baseline
22
+
23
+ Populated on first `steward doctor --scope siblings` run.
24
+
25
+ ## Recommended skills
26
+
27
+ Populated on first `steward doctor --scope siblings` run.
28
+
29
+ ## Common `CLAUDE.md` sections
30
+
31
+ Populated on first `steward doctor --scope siblings` run.
32
+
33
+ ## Corpus stats
34
+
35
+ Populated on first `steward doctor --scope siblings` run.
@@ -2,13 +2,22 @@
2
2
 
3
3
  The shape every AgentCulture sibling repo (`steward`, `cfafi`, `ghafi`, `daria`,
4
4
  …) is expected to wear. This document is the single source of truth that
5
- `steward verify` and `steward doctor` consume.
5
+ `steward doctor` consumes.
6
6
 
7
7
  The companion file `sibling-pattern.json` (TBD; emit from this doc) is the
8
- machine-readable form. Until it lands, the checks `verify` runs are hard-coded
9
- in `steward/cli/_commands/verify.py`; this document remains the human-readable
8
+ machine-readable form. Until it lands, the checks `doctor` runs are hard-coded
9
+ in `steward/cli/_commands/doctor.py`; this document remains the human-readable
10
10
  contract that those hard-coded checks are expected to honor.
11
11
 
12
+ `steward doctor` runs in two modes:
13
+
14
+ - **`--scope self <target>`** (default) — the single-repo invariants below
15
+ (portability, skills-convention).
16
+ - **`--scope siblings`** — walks every `culture.yaml` in the workspace, scores
17
+ each declared agent against a corpus-derived baseline
18
+ (`docs/perfect-patient.md`, regenerated on each run), and writes a per-target
19
+ report into `<target>/docs/steward/steward-suggestions.md`.
20
+
12
21
  ## Required artifacts
13
22
 
14
23
  | # | Artifact | Path | Why |
@@ -29,9 +38,9 @@ contract that those hard-coded checks are expected to honor.
29
38
  ## Invariants (machine-checkable)
30
39
 
31
40
  The full set of invariants the AgentCulture sibling pattern asserts. The
32
- **Status** column reflects what is wired into `steward verify` *today*; items
33
- marked `(planned)` are described here as the contract `verify` is expected to
34
- grow into.
41
+ **Status** column reflects what is wired into `steward doctor --scope self`
42
+ *today*; items marked `(planned)` are described here as the contract `doctor`
43
+ is expected to grow into.
35
44
 
36
45
  - **portability** *(implemented as `--check portability`)* — no
37
46
  `/home/<user>/...` paths in tracked files; no `~/.<dotfile>` config refs in
@@ -52,10 +61,11 @@ grow into.
52
61
 
53
62
  ## Repairs (machine-fixable, run by `steward doctor`)
54
63
 
55
- `steward doctor` is **not yet implemented** (see `CLAUDE.md`'s Roadmap
56
- section); the table below is the contract it will honor when it lands. A
57
- repair is included only if it is **deterministic and idempotent**. Where the
58
- right answer depends on judgement, `doctor` will report the gap and stop.
64
+ `steward doctor --apply` is **not yet implemented** (see `CLAUDE.md`'s
65
+ Roadmap section); the table below is the contract it will honor when it
66
+ lands. A repair is included only if it is **deterministic and idempotent**.
67
+ Where the right answer depends on judgement, `doctor` will report the gap
68
+ and stop.
59
69
 
60
70
  | Invariant violated | Planned repair |
61
71
  |--------------------|----------------|
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "steward-cli"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "Steward — aligns and maintains resident agents across Culture projects."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -13,7 +13,9 @@ classifiers = [
13
13
  "Topic :: Software Development",
14
14
  "Intended Audience :: Developers",
15
15
  ]
16
- dependencies = []
16
+ dependencies = [
17
+ "pyyaml>=6.0",
18
+ ]
17
19
 
18
20
  [project.urls]
19
21
  Homepage = "https://github.com/agentculture/steward"
@@ -32,8 +32,8 @@ class _StewardArgumentParser(argparse.ArgumentParser):
32
32
  def _build_parser() -> argparse.ArgumentParser:
33
33
  # Deferred import to avoid coupling the parser module to the command modules
34
34
  # at import time (matches afi-cli's pattern; cheap insurance).
35
+ from steward.cli._commands import doctor as _doctor_cmd
35
36
  from steward.cli._commands import show as _show_cmd
36
- from steward.cli._commands import verify as _verify_cmd
37
37
 
38
38
  parser = _StewardArgumentParser(
39
39
  prog="steward",
@@ -47,7 +47,7 @@ def _build_parser() -> argparse.ArgumentParser:
47
47
  sub = parser.add_subparsers(dest="command", parser_class=_StewardArgumentParser)
48
48
 
49
49
  _show_cmd.register(sub)
50
- _verify_cmd.register(sub)
50
+ _doctor_cmd.register(sub)
51
51
 
52
52
  return parser
53
53