codexspec 0.7.9__tar.gz → 0.7.11__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.
- {codexspec-0.7.9 → codexspec-0.7.11}/PKG-INFO +3 -1
- {codexspec-0.7.9 → codexspec-0.7.11}/README.md +2 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/pyproject.toml +1 -1
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/__init__.py +1 -1
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/commands/installer.py +18 -4
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/distill.md +40 -5
- codexspec-0.7.11/templates/commands/onboard.md +89 -0
- codexspec-0.7.11/templates/commands/release-notes.md +212 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/.gitignore +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/LICENSE +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/codexspec-icon.svg +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/codexspec-logo-dark.svg +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/codexspec-logo-light.svg +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/bash/check-i18n-completeness.sh +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/bash/check-i18n-structure.sh +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/bash/check-prerequisites.sh +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/bash/common.sh +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/bash/create-new-feature.sh +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/bash/review-context.sh +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/powershell/check-prerequisites.ps1 +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/powershell/common.ps1 +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/powershell/create-new-feature.ps1 +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/scripts/powershell/review-context.ps1 +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/commands/__init__.py +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/i18n.py +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/idea.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/integrations/__init__.py +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/integrations/base.py +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/integrations/claude.py +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/integrations/codex.py +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/profile.py +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/src/codexspec/translator.py +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/analyze.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/checklist.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/clarify.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/commit-staged.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/config.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/constitution.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/debug.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/evolve.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/generate-spec.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/implement-tasks.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/plan-to-tasks.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/pr.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/quick.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/review-code.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/review-design.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/review-plan.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/review-spec.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/review-tasks.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/spec-to-design.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/spec-to-plan.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/specify.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/commands/tasks-to-issues.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/checklist-template.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/constitution-template.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/design-template.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/plan-template-detailed.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/plan-template-simple.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/requirements-template.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/spec-template-detailed.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/spec-template-simple.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/tasks-template-detailed.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/docs/tasks-template-simple.md +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/translations/de.json +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/translations/en.json +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/translations/es.json +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/translations/fr.json +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/translations/ja.json +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/translations/ko.json +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/translations/pt-BR.json +0 -0
- {codexspec-0.7.9 → codexspec-0.7.11}/templates/translations/zh-CN.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codexspec
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.11
|
|
4
4
|
Summary: CodexSpec - A Requirements-First SDD toolkit for Claude Code
|
|
5
5
|
Project-URL: Homepage, https://github.com/Zts0hg/codexspec
|
|
6
6
|
Project-URL: Repository, https://github.com/Zts0hg/codexspec
|
|
@@ -608,6 +608,7 @@ Implementation follows **conditional TDD workflow**:
|
|
|
608
608
|
| --- | --- |
|
|
609
609
|
| `/codexspec:distill` | Distill reusable cross-feature knowledge into `.codexspec/profile/` |
|
|
610
610
|
| `/codexspec:evolve` | Compile profile knowledge into a command/skill and contribute upstream via a reviewed PR |
|
|
611
|
+
| `/codexspec:onboard` | Cold-start the project profile by scanning an existing codebase (conventions + constraints) |
|
|
611
612
|
|
|
612
613
|
#### Git Workflow Commands
|
|
613
614
|
|
|
@@ -615,6 +616,7 @@ Implementation follows **conditional TDD workflow**:
|
|
|
615
616
|
| -------------------------- | ------------------------------------------------- |
|
|
616
617
|
| `/codexspec:commit-staged` | Generate commit message from staged changes |
|
|
617
618
|
| `/codexspec:pr` | Generate PR/MR description (auto-detect platform) |
|
|
619
|
+
| `/codexspec:release-notes` | Generate release notes from git history (maintain CHANGELOG.md + release body)|
|
|
618
620
|
|
|
619
621
|
#### Code Review Commands
|
|
620
622
|
|
|
@@ -563,6 +563,7 @@ Implementation follows **conditional TDD workflow**:
|
|
|
563
563
|
| --- | --- |
|
|
564
564
|
| `/codexspec:distill` | Distill reusable cross-feature knowledge into `.codexspec/profile/` |
|
|
565
565
|
| `/codexspec:evolve` | Compile profile knowledge into a command/skill and contribute upstream via a reviewed PR |
|
|
566
|
+
| `/codexspec:onboard` | Cold-start the project profile by scanning an existing codebase (conventions + constraints) |
|
|
566
567
|
|
|
567
568
|
#### Git Workflow Commands
|
|
568
569
|
|
|
@@ -570,6 +571,7 @@ Implementation follows **conditional TDD workflow**:
|
|
|
570
571
|
| -------------------------- | ------------------------------------------------- |
|
|
571
572
|
| `/codexspec:commit-staged` | Generate commit message from staged changes |
|
|
572
573
|
| `/codexspec:pr` | Generate PR/MR description (auto-detect platform) |
|
|
574
|
+
| `/codexspec:release-notes` | Generate release notes from git history (maintain CHANGELOG.md + release body)|
|
|
573
575
|
|
|
574
576
|
#### Code Review Commands
|
|
575
577
|
|
|
@@ -44,7 +44,7 @@ from .profile import ensure_profile_scaffold, inject_profile_block
|
|
|
44
44
|
from .translator import SUPPORTED_LANGUAGES, translate
|
|
45
45
|
|
|
46
46
|
# Version info
|
|
47
|
-
__version__ = "0.7.
|
|
47
|
+
__version__ = "0.7.11"
|
|
48
48
|
__author__ = "CodexSpec Team"
|
|
49
49
|
|
|
50
50
|
# Constitution file path constants
|
|
@@ -47,8 +47,8 @@ def get_commands_metadata() -> list[CommandMetadata]:
|
|
|
47
47
|
|
|
48
48
|
Returns:
|
|
49
49
|
List of CommandMetadata dictionaries sorted by category priority:
|
|
50
|
-
core (11) -> enhanced (
|
|
51
|
-
Total:
|
|
50
|
+
core (11) -> enhanced (8) -> git (3) -> review (1) -> utility (2)
|
|
51
|
+
Total: 25 commands
|
|
52
52
|
"""
|
|
53
53
|
return [
|
|
54
54
|
# Core Commands (11)
|
|
@@ -129,7 +129,7 @@ def get_commands_metadata() -> list[CommandMetadata]:
|
|
|
129
129
|
"category": "core",
|
|
130
130
|
"file_name": "implement-tasks.md",
|
|
131
131
|
},
|
|
132
|
-
# Enhanced Commands (
|
|
132
|
+
# Enhanced Commands (8)
|
|
133
133
|
{
|
|
134
134
|
"name": "clarify",
|
|
135
135
|
"display_name": "/codexspec:clarify",
|
|
@@ -172,6 +172,13 @@ def get_commands_metadata() -> list[CommandMetadata]:
|
|
|
172
172
|
"category": "enhanced",
|
|
173
173
|
"file_name": "evolve.md",
|
|
174
174
|
},
|
|
175
|
+
{
|
|
176
|
+
"name": "onboard",
|
|
177
|
+
"display_name": "/codexspec:onboard",
|
|
178
|
+
"description": "扫描现有代码库冷启动项目 profile(提取 conventions 与 constraints)",
|
|
179
|
+
"category": "enhanced",
|
|
180
|
+
"file_name": "onboard.md",
|
|
181
|
+
},
|
|
175
182
|
{
|
|
176
183
|
"name": "debug",
|
|
177
184
|
"display_name": "/codexspec:debug",
|
|
@@ -179,7 +186,7 @@ def get_commands_metadata() -> list[CommandMetadata]:
|
|
|
179
186
|
"category": "enhanced",
|
|
180
187
|
"file_name": "debug.md",
|
|
181
188
|
},
|
|
182
|
-
# Git Workflow Commands (
|
|
189
|
+
# Git Workflow Commands (3)
|
|
183
190
|
{
|
|
184
191
|
"name": "commit-staged",
|
|
185
192
|
"display_name": "/codexspec:commit-staged",
|
|
@@ -194,6 +201,13 @@ def get_commands_metadata() -> list[CommandMetadata]:
|
|
|
194
201
|
"category": "git",
|
|
195
202
|
"file_name": "pr.md",
|
|
196
203
|
},
|
|
204
|
+
{
|
|
205
|
+
"name": "release-notes",
|
|
206
|
+
"display_name": "/codexspec:release-notes",
|
|
207
|
+
"description": "从 git 历史生成发布说明:更新 CHANGELOG.md + 用户向发布正文(不决定版本)",
|
|
208
|
+
"category": "git",
|
|
209
|
+
"file_name": "release-notes.md",
|
|
210
|
+
},
|
|
197
211
|
# Code Review Commands (1)
|
|
198
212
|
{
|
|
199
213
|
"name": "review-code",
|
|
@@ -54,17 +54,27 @@ Four **category directories**, each holding **one record per file** (`<id>.md`)
|
|
|
54
54
|
Every record MUST separate the distilled claim from the evidence it rests on:
|
|
55
55
|
|
|
56
56
|
- `id` — **type letter + full source-feature id + local sequence**, e.g. `P-2026-0812-14054p-1` or `Con-2026-0812-14054p-1`. It is **both** the record's `### <id>: <title>` heading **and its filename** (`pitfalls/P-2026-0812-14054p-1.md`). The **source-feature id** is the distilling feature's full spec-dir id `{YYYY-MMDD-HHMM}{rr}` (e.g. `2026-0812-14054p`); it is globally unique by the timestamp+random scheme spec directories use, so records distilled on parallel feature branches never collide on id **or filename** (they merge with no conflict). Keep the **full** id (not a short tail) so the record is self-describing: the date supports recency/staleness reading, and the feature id ties the record to its originating change for decision context and scope. When distilling with no feature context, generate a fresh `{YYYY-MMDD-HHMM}{rr}` id now (same convention as create-new-feature). **Never** use a bare sequential id such as `P-001` — those collide across parallel branches.
|
|
57
|
-
- `claim` — one-sentence reusable
|
|
57
|
+
- `claim` — one-sentence reusable **summary** (a title line, not the actionable body — for a `pitfall` the usable content lives in the three body parts below, not in this sentence).
|
|
58
58
|
- `type` — `convention` | `constraint` | `pitfall` | `decision` (`constraint` = highest priority).
|
|
59
59
|
- `scope/when` — natural-language applicability condition (e.g. "when editing Python code"); omit for global. **No formal syntax.**
|
|
60
60
|
- `evidence.facts` — the concrete observations behind it; **quote the user's original words, do not paraphrase**.
|
|
61
61
|
- `evidence.state` — the context/validity when true (feature / commit / config; still valid?).
|
|
62
|
-
- `provenance` — source feature/session, trigger, timestamp, `derivation = explicit | inferred`.
|
|
63
|
-
- `status` — `vetted`
|
|
62
|
+
- `provenance` — source feature/session, trigger, timestamp, `derivation = explicit | inferred`, `confidence = high | medium | low`. `derivation` records only **how the claim was first obtained** (the user's own words vs inferred); it is **not** a gate on `status` (see below).
|
|
63
|
+
- `status` — `candidate` | `vetted` | `conflict/needs-adjudication`. A record is `vetted` **only** when BOTH (a) it was **verified by an outcome** (a test passed, a workaround worked) AND (b) a **human endorsed it** — either it came from the user's own words (`derivation: explicit`) **or** the user approved it in `/distill review`. `derivation` is **not** itself a gate: an `inferred` record that is outcome-verified and human-approved becomes `vetted` and is eligible for `evolve`. Un-verified speculation MUST NOT be `vetted`. `conflict/needs-adjudication` marks a deferred conflict (see Conflict adjudication) and is not `evolve`-eligible. Only `vetted` records are eligible for `evolve`.
|
|
64
|
+
|
|
65
|
+
**Pitfall records carry more than a claim.** A `pitfall` (or any trap-type record) MUST, beyond `claim` and `evidence`, spell out three body parts — a bare "here is the trap" record is a defect (the next person just re-hits it):
|
|
66
|
+
|
|
67
|
+
- `root-cause` — *why* the trap happens (the underlying mechanism), not merely what it is.
|
|
68
|
+
- `workaround` — the concrete way around it, with the code / paths / commands to apply.
|
|
69
|
+
- `lesson` — the transferable takeaway that generalizes beyond this one instance.
|
|
70
|
+
|
|
71
|
+
If you cannot state all three, the pitfall is not yet understood well enough to record. `convention` / `constraint` / `decision` records usually need only `claim` + `evidence`; this three-part body is required specifically for traps.
|
|
72
|
+
|
|
73
|
+
> **onboard variant**: `/codexspec:onboard` writes to this same store and format, with one difference — its records are inferred from code, so `evidence.facts` holds a verbatim **code observation** (path + snippet) instead of a user quote, `provenance` marks the onboard scan, and `derivation` is always `inferred`. onboard therefore writes `status: candidate` **at write time** (it never writes `vetted` itself); such a record can still be promoted to `vetted` later once it is outcome-verified and approved in `/distill review` — its `inferred` origin is not a barrier (per the `status` rule above).
|
|
64
74
|
|
|
65
75
|
This separation is what makes a later error locatable as **misread** (facts wrong) vs **overreach** (claim over-generalized) vs **stale** (state no longer holds).
|
|
66
76
|
|
|
67
|
-
Example
|
|
77
|
+
Example — a `convention` (claim + evidence is enough), file `conventions/Con-2026-0809-2219gg-1.md`:
|
|
68
78
|
|
|
69
79
|
```markdown
|
|
70
80
|
### Con-2026-0809-2219gg-1: Prefer absolute imports
|
|
@@ -73,10 +83,26 @@ Example entry — file `conventions/Con-2026-0809-2219gg-1.md`:
|
|
|
73
83
|
- scope/when: Python modules under `src/`
|
|
74
84
|
- evidence.facts: "Use absolute imports; relative ones broke the packaged wheel last time."
|
|
75
85
|
- evidence.state: confirmed at feature 2026-0809-2219gg; commit a1b2c3d
|
|
76
|
-
- provenance: distill @implement-tasks, 2026-08-09, derivation: explicit
|
|
86
|
+
- provenance: distill @implement-tasks, 2026-08-09, derivation: explicit, confidence: high
|
|
77
87
|
- status: vetted
|
|
78
88
|
```
|
|
79
89
|
|
|
90
|
+
Example — a `pitfall` (note the required `root-cause` / `workaround` / `lesson` body), file `pitfalls/P-2026-0810-1330ab-1.md`:
|
|
91
|
+
|
|
92
|
+
```markdown
|
|
93
|
+
### P-2026-0810-1330ab-1: `re.sub` with a string replacement corrupts blocks containing backslashes
|
|
94
|
+
- claim: Inject a rendered block with a function replacement in `re.sub`, never a string.
|
|
95
|
+
- type: pitfall
|
|
96
|
+
- scope/when: upserting a rendered block into a file via `re.sub` in `src/`
|
|
97
|
+
- root-cause: a string replacement passed to `re.sub` interprets `\g<...>` and backslash escapes, so any such sequence inside the block silently corrupts the output.
|
|
98
|
+
- workaround: pass a callable replacement — `pattern.sub(lambda _m: block, text)` — so the block is inserted verbatim.
|
|
99
|
+
- lesson: whenever the replacement is data (not a pattern), use the callable form; the same trap applies in any language whose replace interprets `$1` / `\1`.
|
|
100
|
+
- evidence.facts: the injected block contained `\g<0>` and rendered as garbage until switched to the lambda form.
|
|
101
|
+
- evidence.state: confirmed at feature 2026-0810-1330ab; commit c0ffee1. Still valid.
|
|
102
|
+
- provenance: distill @implement-tasks, 2026-08-10, derivation: inferred, confidence: high
|
|
103
|
+
- status: candidate
|
|
104
|
+
```
|
|
105
|
+
|
|
80
106
|
## Extraction
|
|
81
107
|
|
|
82
108
|
Read the interaction segment and extract, per the dimensions above, only **verified** knowledge — prefer facts confirmed by outcomes over speculation; speculation MUST NOT become `vetted`.
|
|
@@ -106,6 +132,15 @@ git history is the audit ledger. Do **NOT** keep a retired file or a retired sec
|
|
|
106
132
|
|
|
107
133
|
Auto-distill writes `candidate` records non-interactively and **never prompts**. Promote them through the **manual review mode** — `/distill review` (or `/distill` with no new segment to distill): list every pending `candidate` compactly (claim + evidence + provenance) and let the user approve inline — "vet all", "vet 1,3", "edit 2", "drop 4". Apply the choices by editing each record's `status` (a `replace`). **The user never hand-edits the profile files.**
|
|
108
134
|
|
|
135
|
+
The user's approval here **is** the human endorsement half of the `vetted` gate: an approved `candidate` that is already outcome-verified becomes `vetted` **regardless of its original `derivation`** (an `inferred` record is not blocked from vetting). If a candidate has not yet been outcome-verified, approval keeps it `candidate` (or the user may attest the outcome to complete the gate). This is the path by which `inferred` knowledge — including everything `/codexspec:onboard` writes — reaches `vetted` and becomes `evolve`-eligible.
|
|
136
|
+
|
|
137
|
+
## Self-check before finishing
|
|
138
|
+
|
|
139
|
+
A lightweight judgment pass (not an engineered lint) over what you just wrote:
|
|
140
|
+
|
|
141
|
+
- **Not hollow** — every `pitfall` states `root-cause` + `workaround` + `lesson`, not just a `claim`. If it collapses to one line, either flesh it out or drop it.
|
|
142
|
+
- **Links resolve** — any `[[id]]` cross-link points to an existing record file under `.codexspec/profile/`, or is an intentional forward reference to one you are also writing now. Don't leave a link to a record that will never exist.
|
|
143
|
+
|
|
109
144
|
## Output
|
|
110
145
|
|
|
111
146
|
Report concisely in the interaction language: which records were added / replaced / removed and in which file, any `conflict` records deferred, or "nothing to distill" on early-exit. distill **never** gates the caller.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Cold-start the project profile by scanning an existing codebase for conventions and constraints
|
|
3
|
+
argument-hint: "[path]"
|
|
4
|
+
allowed-tools: Read, Grep, Glob, Bash(git:*), Bash(ls/cat/find:*), Edit, Write
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Codebase Onboarding
|
|
8
|
+
|
|
9
|
+
## Language Preference
|
|
10
|
+
|
|
11
|
+
Read `.codexspec/config.yml`. Two independent language controls apply (each falls back to `language.output`, then English):
|
|
12
|
+
|
|
13
|
+
- **Interaction language** (`language.interaction`): language for all conversation with the user — questions, explanations, status messages, and `codexspec` CLI terminal output.
|
|
14
|
+
- **Document language** (`language.document`): language for generated artifact files (the profile records).
|
|
15
|
+
|
|
16
|
+
Converse in the interaction language and author artifacts in the document language. Apply the project's translation standard to both: translate by meaning (not word-for-word), keep English for terms with no good native equivalent, and write as if originally in that language. **Exception**: `evidence.facts` records a verbatim code observation (path + snippet) and MUST NOT be translated.
|
|
17
|
+
|
|
18
|
+
## User Input
|
|
19
|
+
|
|
20
|
+
`$ARGUMENTS`
|
|
21
|
+
|
|
22
|
+
## Role and Operating Model
|
|
23
|
+
|
|
24
|
+
`onboard` is the **cold-start / bulk counterpart to `distill`**. Where `distill` writes the project profile incrementally from interaction, `onboard` scans an **existing codebase** once and batch-writes the reusable knowledge that is **implicit in the code and not already recorded accessibly** into the shared store `.codexspec/profile/`. It exists to bootstrap a brownfield project's profile so accumulated project knowledge is grounded immediately, instead of only after enough work has flowed through `distill`.
|
|
25
|
+
|
|
26
|
+
`onboard` is **read-only on the codebase** and **write-only to `.codexspec/profile/`**: it never modifies source, tests, git state, or the constitution. It is a **standalone, user-invoked command** — not an SDD pipeline stage: it has **no auto-next successor** and **no automatic hook**, and it leaves no persistent document beyond the profile records (no map, no walkthrough — those, if ever wanted, belong to a separate `explain`).
|
|
27
|
+
|
|
28
|
+
## Prerequisite & Scaffold
|
|
29
|
+
|
|
30
|
+
Before scanning:
|
|
31
|
+
|
|
32
|
+
- If `.codexspec/` is **absent**, the project is not codexspec-initialized. **Stop** and direct the user to run `codexspec init`. Do not scaffold a whole project.
|
|
33
|
+
- If `.codexspec/` is present but the profile store is missing, **ensure the canonical scaffold** — the four category directories `.codexspec/profile/{constraints,conventions,pitfalls,decisions}/` (matching what `codexspec init` produces) — before writing.
|
|
34
|
+
- git is **not required**. onboard runs on a plain directory.
|
|
35
|
+
|
|
36
|
+
## Codebase Scan
|
|
37
|
+
|
|
38
|
+
Scan strategy is **high-signal-first over the whole repository in a single pass**:
|
|
39
|
+
|
|
40
|
+
- Respect `.gitignore`. When there is **no git / no `.gitignore`**, fall back to sensible defaults that skip vendored, build, and dependency directories (e.g. `node_modules`, `dist`, `build`, `.venv`, `target`), and say so in the summary.
|
|
41
|
+
- **Deep-read high-value sources**: directory structure; build / dependency / lint / formatter / type-checker config; entry points; existing docs (README, CONTRIBUTING, ADRs); test layout; and the frequently-imported core modules. **Shallow-sample** the bulk of business code rather than reading every file.
|
|
42
|
+
- **Stream findings to the store as you go** — write each convention as soon as it is confirmed — so the scan is **interruptible and resumable**. Do **not** block until the whole scan finishes before writing or interacting; a run interrupted mid-scan keeps what it already wrote and can be re-run to continue.
|
|
43
|
+
- An optional `[path]` argument (from `$ARGUMENTS`) **narrows** the scan to a single subdirectory or module.
|
|
44
|
+
- Never claim full coverage when you sampled — the summary distinguishes deep-read from sampled areas.
|
|
45
|
+
|
|
46
|
+
## What onboard Extracts — and What It Must NOT
|
|
47
|
+
|
|
48
|
+
Extraction uses your **flexible judgment over what the code actually shows** — not a fixed checklist of filenames or markers. onboard actively extracts **only two** of the four profile categories:
|
|
49
|
+
|
|
50
|
+
- **`conventions`** (the primary yield) — the code's observable regularities: directory/module structure, naming schemes, import style, the tech stack and toolchain (read from manifests), lint/format/type configuration, test framework and layout, and patterns repeated across the codebase. **Observable architecture / tech-stack facts** are captured here as fact-plus-steering, not as ADR-style decisions.
|
|
51
|
+
- **`constraints`** (narrow, high-risk) — **only** config-level **explicit hard prohibitions**: lint/type rules set to *error* that ban imports or APIs, `do not edit` / generated-file / managed-block markers, and CODEOWNERS / protected-path conventions. Every constraint candidate carries a **precise evidence anchor** (`file:line` or a config snippet). **Absent an explicit prohibition signal, propose no constraint** — silence, never a guess.
|
|
52
|
+
|
|
53
|
+
onboard **never** extracts `decisions` or `pitfalls`. A documented decision or pitfall is already readable in the repo (redundant to copy); an undocumented one is unreliable to infer from a cold scan (pitfalls are experiential; decision rationale would be fabricated). Those two categories remain `distill`'s channels, where the rationale and lived experience are available.
|
|
54
|
+
|
|
55
|
+
## Record Format
|
|
56
|
+
|
|
57
|
+
onboard **reuses `distill`'s profile store and record format verbatim** — one record per file under a category directory (`conventions/<id>.md`, `constraints/<id>.md`), ids namespaced by the source-feature id, and `claim` physically separated from `evidence`. See `distill.md` for the canonical format. onboard writes with these **deltas**:
|
|
58
|
+
|
|
59
|
+
- `provenance` marks the **onboard scan** as the source (distinct from `distill`), with `derivation: inferred` — always, because the knowledge is inferred from code, never quoted from the user.
|
|
60
|
+
- An onboard record's `status` is always **`candidate`** at write time — onboard **never** writes `vetted` itself. Its `inferred` origin is **not** a permanent barrier: such a record can later be promoted to `vetted` via `/distill review` once it is outcome-verified and the user approves it (the `evolve` gate remains `vetted`). See the `status` rule in `distill.md`.
|
|
61
|
+
- `evidence.facts` holds the **concrete code observation** — the file path plus the relevant snippet or config anchor — instead of a user quote.
|
|
62
|
+
|
|
63
|
+
## Integration with the Existing Profile
|
|
64
|
+
|
|
65
|
+
Before writing, **read the existing profile** and integrate:
|
|
66
|
+
|
|
67
|
+
- **De-duplicate** — skip anything already covered by an existing record (by judgment, not an algorithm).
|
|
68
|
+
- **Adjudicate conflicts** per `distill`'s order (recency → specificity → scenario-decoupling → defer); if genuinely unresolvable, write the record `status: conflict/needs-adjudication` and surface it — never block, never guess.
|
|
69
|
+
- **Never clobber.** onboard MUST NOT overwrite or delete any existing `vetted`, hand-authored, or `distill`-written record. It only **adds** new files (namespaced ids merge with zero conflict) or edits **its own** candidate file. This makes re-running onboard (whole repo, or a narrowed `[path]`) safe and **idempotent** — it augments without destroying.
|
|
70
|
+
|
|
71
|
+
## Safety Gate — quick review for high-risk, immediate effect for the rest
|
|
72
|
+
|
|
73
|
+
`candidate` records take local effect immediately (weighted with caution); vetting only gates `evolve`, not local effect. Because onboard is high-volume cold inference, it gates the one high-risk category and lets the bulk flow:
|
|
74
|
+
|
|
75
|
+
- **`conventions` → written immediately as `candidate`.** They take effect at once and are refined later, asynchronously and at your pace, via `/distill review`. No synchronous audit.
|
|
76
|
+
- **`constraints` → held for a quick in-session review at the end of the scan.** Because a wrong, top-weighted constraint would otherwise take honored-first effect unreviewed, onboard accumulates constraint candidates and, at the end, presents them for a fast review. This is a **persist / do-not-persist** decision for *this scan's* constraints — **not** a promotion to `vetted`, and **not** an invocation of `/distill review`. For each candidate you may **persist**, **edit then persist**, or **drop**; only persisted ones are written (as `candidate`). If the scan found **no** constraint candidates, there is no synchronous step.
|
|
77
|
+
|
|
78
|
+
The user reviews only the small high-risk set here; the ongoing, backlog-wide vetting of any `candidate` remains the separate asynchronous `/distill review` channel.
|
|
79
|
+
|
|
80
|
+
## Output Summary
|
|
81
|
+
|
|
82
|
+
Report concisely in the interaction language: the records added / updated per category and file, any `conflict` records deferred, and **which areas were deep-read versus sampled** (never imply full coverage when you sampled). On an empty or knowledge-free scan, write nothing and report "nothing to onboard".
|
|
83
|
+
|
|
84
|
+
## Boundaries (recap)
|
|
85
|
+
|
|
86
|
+
- Read-only on code; write-only to `.codexspec/profile/`; no source / test / git / constitution mutation.
|
|
87
|
+
- Standalone: no auto-next, no automatic hook, and **no Automatic Distillation step** (onboard is not a wrap-up command).
|
|
88
|
+
- Writes only `conventions` and `constraints`; never `decisions` or `pitfalls`.
|
|
89
|
+
- Produces no persistent document beyond profile records.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate release notes from git history — maintain a Keep a Changelog CHANGELOG.md entry and emit a user-facing release body, without deciding versions or mutating git state
|
|
3
|
+
allowed-tools: Bash(git branch:*), Bash(git tag:*), Bash(git describe:*), Bash(git log:*), Bash(git diff:*), Bash(git rev-parse:*), Bash(git remote:*), Bash(ls:*), Bash(cat:*), Read, Edit, Write
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Constitution Compliance (MANDATORY)
|
|
7
|
+
|
|
8
|
+
**Before generating release notes:**
|
|
9
|
+
|
|
10
|
+
1. **Check for Constitution File**: Look for `.codexspec/memory/constitution.md`
|
|
11
|
+
2. **If Constitution Exists**:
|
|
12
|
+
- Load and read relevant principles (especially documentation and versioning standards)
|
|
13
|
+
- Ensure the generated notes align with constitutional guidelines
|
|
14
|
+
3. **If No Constitution Exists**: Proceed with the defaults below
|
|
15
|
+
|
|
16
|
+
## Language Preference
|
|
17
|
+
|
|
18
|
+
**IMPORTANT**: Before generating output, read the project's language configuration from `.codexspec/config.yml`.
|
|
19
|
+
|
|
20
|
+
**Generated-content language priority**:
|
|
21
|
+
|
|
22
|
+
1. If `language.commit` is set, use that language for the CHANGELOG entry and release body
|
|
23
|
+
2. Otherwise, use `language.output` as fallback
|
|
24
|
+
3. If neither is configured, default to English
|
|
25
|
+
|
|
26
|
+
**Note**:
|
|
27
|
+
|
|
28
|
+
- Section headings that are format keywords (`Added`, `Changed`, `Fixed`, etc.) and technical terms
|
|
29
|
+
(API, JWT, OAuth) may remain in English when appropriate.
|
|
30
|
+
- The `## [Unreleased]` / `## [X.Y.Z]` version markers and ISO dates are format, not prose — keep them
|
|
31
|
+
as-is.
|
|
32
|
+
|
|
33
|
+
## User Input
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
$ARGUMENTS
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Role
|
|
40
|
+
|
|
41
|
+
You generate **release notes** from git history for **this project**, whatever its release process.
|
|
42
|
+
You make **no assumption** about how the project releases: there may be no `publish.sh`, no CI, no
|
|
43
|
+
particular hosting platform, and no particular versioning scheme (semver, CalVer, and date tags are
|
|
44
|
+
all possible). Every behavior below degrades gracefully when such an assumption does not hold.
|
|
45
|
+
|
|
46
|
+
You produce two layered outputs from the same analysis:
|
|
47
|
+
|
|
48
|
+
1. A developer **CHANGELOG.md** entry in Keep a Changelog format.
|
|
49
|
+
2. A user-facing **release body** derived from it.
|
|
50
|
+
|
|
51
|
+
You **own no versioning** and **mutate no git state** (see Forbidden Operations).
|
|
52
|
+
|
|
53
|
+
## Forbidden Operations (CRITICAL)
|
|
54
|
+
|
|
55
|
+
This command is a **generator**, sharing the safety discipline of `commit-staged` and `pr`.
|
|
56
|
+
|
|
57
|
+
**UNDER NO CIRCUMSTANCES**:
|
|
58
|
+
|
|
59
|
+
- `git add` / `git commit` / `git reset` / `git checkout` / `git restore` / `git stash` / `git rm` —
|
|
60
|
+
the command MUST NEVER modify the git staging area and MUST NEVER create a commit.
|
|
61
|
+
- Overwrite `CHANGELOG.md` wholesale with `Write`, or rewrite / reorder / delete any existing
|
|
62
|
+
CHANGELOG entry.
|
|
63
|
+
- Decide or "own" a version bump; tag; publish; or create a GitHub/GitLab release.
|
|
64
|
+
- Include any AI attribution in generated content — no `Co-Authored-By`, "Generated with", robot
|
|
65
|
+
emoji, or references to AI tools/agents.
|
|
66
|
+
|
|
67
|
+
The **only** permitted file writes are: the safe additive `CHANGELOG.md` insertion described in
|
|
68
|
+
**CHANGELOG.md Maintenance**, and — only when `--output <file>` is given — writing the release body to
|
|
69
|
+
that user-directed path.
|
|
70
|
+
|
|
71
|
+
## Parameters
|
|
72
|
+
|
|
73
|
+
Parse `$ARGUMENTS` for the following optional parameters:
|
|
74
|
+
|
|
75
|
+
| Parameter | Default | Description |
|
|
76
|
+
|-----------|---------|-------------|
|
|
77
|
+
| `--version <X.Y.Z>` | (none) | Stamp this version on the new section; short-circuits all version inference/suggestion |
|
|
78
|
+
| `--from <ref>` | (resolved) | Explicit range start (overrides Range Resolution) |
|
|
79
|
+
| `--to <ref>` | `HEAD` | Explicit range end |
|
|
80
|
+
| `--output <file>` | (terminal) | Write the release body to a file instead of stdout |
|
|
81
|
+
| `--spec <feature>` | (none) | Enrich the "why" from that feature's `spec.md` / `tasks.md` |
|
|
82
|
+
|
|
83
|
+
- If `--version` is present, **validate** it is a well-formed version string. If it is malformed,
|
|
84
|
+
**reject** with a clear validation message and do **not** write a malformed section.
|
|
85
|
+
- If `--spec` is present but does not resolve to an existing feature/path, **degrade gracefully**:
|
|
86
|
+
proceed from git alone and report the unresolved path. Do not fail.
|
|
87
|
+
|
|
88
|
+
## Range Resolution
|
|
89
|
+
|
|
90
|
+
Determine the commit range `<from>..<to>` (default `<to>` is `HEAD`):
|
|
91
|
+
|
|
92
|
+
1. **Explicit override**: if `--from` (and optionally `--to`) is given, use it directly.
|
|
93
|
+
2. **Latest tag**: otherwise, the default range is `latest tag..HEAD` — resolve the latest tag via
|
|
94
|
+
`git describe --tags --abbrev=0`.
|
|
95
|
+
3. **No reachable tag → CHANGELOG fallback**: if the repository has no reachable tag, fall back to
|
|
96
|
+
"after the last version recorded in `CHANGELOG.md`" (anchor on the most recent versioned section).
|
|
97
|
+
4. **No tag and no CHANGELOG (or no anchorable version) → full history**: if neither a tag nor an
|
|
98
|
+
anchorable CHANGELOG version exists (for example the only prior section is `Unreleased`, which has
|
|
99
|
+
no commit anchor), summarize the **full history**.
|
|
100
|
+
|
|
101
|
+
Always apply `--no-merges` so merge commits are excluded. Route the Edge Cases below before analysis.
|
|
102
|
+
|
|
103
|
+
## Git Context Collection
|
|
104
|
+
|
|
105
|
+
Over the resolved range, collect:
|
|
106
|
+
|
|
107
|
+
1. **Commits**: `git log --no-merges --pretty=format:"%H %s" <from>..<to>`
|
|
108
|
+
2. **Full diff**: `git diff <from>..<to>` (to understand what each commit actually changed)
|
|
109
|
+
3. When `--spec` resolves: read that feature's `spec.md` / `tasks.md` for intent ("why").
|
|
110
|
+
|
|
111
|
+
## Change Categorization
|
|
112
|
+
|
|
113
|
+
Group the changes into **Keep a Changelog** categories, including only those that apply:
|
|
114
|
+
|
|
115
|
+
- `### Added` — new features
|
|
116
|
+
- `### Changed` — changes to existing functionality
|
|
117
|
+
- `### Deprecated` — soon-to-be-removed features
|
|
118
|
+
- `### Removed` — removed features
|
|
119
|
+
- `### Fixed` — bug fixes
|
|
120
|
+
- `### Security` — security fixes
|
|
121
|
+
|
|
122
|
+
**Conventional commits are used when present but are NOT required.** When commits do not follow the
|
|
123
|
+
convention, **infer** the category and wording from the **diff and commit subjects** (the "diff is the
|
|
124
|
+
source of truth" approach of `commit-staged` / `pr`).
|
|
125
|
+
|
|
126
|
+
**User-facing vs contributor split**: the user-facing lists lead with user-visible changes
|
|
127
|
+
(`feat` / `fix` / `perf`, and anything a user would notice). Internal / contributor-only changes
|
|
128
|
+
(`chore` / `refactor` / `test` / `ci` / `build`, internal docs) go **only** under a separate
|
|
129
|
+
`### For contributors` subsection. When commit types are absent, infer visibility from the diff.
|
|
130
|
+
|
|
131
|
+
## Completeness Cross-Check
|
|
132
|
+
|
|
133
|
+
After drafting, **cross-check** the entry against the commit list: **every non-merge commit in the
|
|
134
|
+
selected range must map to at least one bullet.** If any commit is unrepresented, add it. Do not pad
|
|
135
|
+
with bullets that correspond to no commit.
|
|
136
|
+
|
|
137
|
+
## Version Handling
|
|
138
|
+
|
|
139
|
+
Choose the new section's label:
|
|
140
|
+
|
|
141
|
+
- **Default**: `## [Unreleased]` — with **no date** (the Keep a Changelog convention for accumulating
|
|
142
|
+
changes before a version is assigned).
|
|
143
|
+
- **`--version X.Y.Z` given**: stamp `## [X.Y.Z] - <YYYY-MM-DD>` (today's ISO date) and **skip all
|
|
144
|
+
version inference and suggestion**.
|
|
145
|
+
|
|
146
|
+
**Guarded advisory** (only when `--version` is absent): print a console-only suggested next version
|
|
147
|
+
**only when** the project is detected to use **semver AND conventional commits** — i.e. existing
|
|
148
|
+
tags/versions are semver-shaped *and* the range's commits carry conventional-commit prefixes. In that
|
|
149
|
+
case print the suggested next version, the reasoning (e.g. counts of `feat` / `fix` / breaking), and
|
|
150
|
+
an explicit "override with `--version`" note. **Otherwise stay silent** on version suggestions.
|
|
151
|
+
|
|
152
|
+
The command MUST **never write a version number into the file on its own** — the file section is only
|
|
153
|
+
ever `## [Unreleased]` or a user-provided `--version`.
|
|
154
|
+
|
|
155
|
+
## CHANGELOG.md Maintenance
|
|
156
|
+
|
|
157
|
+
Maintain `CHANGELOG.md` at the repository root with a **safe, additive** edit:
|
|
158
|
+
|
|
159
|
+
1. **Create if absent**: if `CHANGELOG.md` does not exist, create it with the **standard Keep a
|
|
160
|
+
Changelog header**:
|
|
161
|
+
|
|
162
|
+
```markdown
|
|
163
|
+
# Changelog
|
|
164
|
+
|
|
165
|
+
All notable changes to this project will be documented in this file.
|
|
166
|
+
|
|
167
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
168
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
2. **Insert additively**: read the entire existing `CHANGELOG.md` first. Insert the new section at a
|
|
172
|
+
single insertion point — into an existing `## [Unreleased]` section when one is present (merge the
|
|
173
|
+
new bullets in rather than duplicating the section), else immediately above the most recent
|
|
174
|
+
versioned section, else directly after the header. **Never rewrite, reorder, or delete any
|
|
175
|
+
existing entry.**
|
|
176
|
+
3. **Edit, never overwrite**: perform the insertion with a precise `Edit` (exact `old_string` match)
|
|
177
|
+
— **never** use `Write` to overwrite the whole `CHANGELOG.md`.
|
|
178
|
+
|
|
179
|
+
This is the command's only mutation of `CHANGELOG.md`, and it never touches git state.
|
|
180
|
+
|
|
181
|
+
## Release Body Generation
|
|
182
|
+
|
|
183
|
+
Derive the user-facing **release body** from the same categorized model:
|
|
184
|
+
|
|
185
|
+
- Lead with what the user **can now do** — "You can now…", plain language, not implementation detail.
|
|
186
|
+
- Keep internal/contributor changes under a `### For contributors` subsection, out of the main list.
|
|
187
|
+
- Flag breaking changes visibly (`**Breaking change:**`).
|
|
188
|
+
- The body is **generic markdown**, platform-agnostic — the user pastes it into GitHub / GitLab / any
|
|
189
|
+
release page. The command does **not** publish it.
|
|
190
|
+
|
|
191
|
+
## Output Modes
|
|
192
|
+
|
|
193
|
+
- **Terminal (default)**: print the release body to the terminal wrapped in a markdown code block so
|
|
194
|
+
the raw markdown can be copied.
|
|
195
|
+
- **`--output <file>`**: write the raw release body to that file (the one user-directed file write
|
|
196
|
+
permitted besides the CHANGELOG insertion).
|
|
197
|
+
|
|
198
|
+
The `CHANGELOG.md` entry is written in both modes.
|
|
199
|
+
|
|
200
|
+
## Edge Cases
|
|
201
|
+
|
|
202
|
+
- **Not a git repository**: report "Not a git repository." and take no action.
|
|
203
|
+
- **Empty range** (no commits since the resolved start): report "No changes to release." — do not
|
|
204
|
+
fabricate entries and do not error.
|
|
205
|
+
- **Detached HEAD**: report that the branch cannot be determined and stop, rather than guessing.
|
|
206
|
+
- **Unresolved `--spec`**: proceed from git alone and report the unresolved path (see Parameters).
|
|
207
|
+
- **Malformed `--version`**: reject with a clear validation message; write no malformed section.
|
|
208
|
+
|
|
209
|
+
## Automatic Distillation
|
|
210
|
+
|
|
211
|
+
This command has **no** Automatic Distillation step. It is a generator, not an interaction that
|
|
212
|
+
produces reusable cross-feature knowledge.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|