planning-control-plane 0.1.3__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.
- planning_control_plane-0.1.3/LICENSE +21 -0
- planning_control_plane-0.1.3/PKG-INFO +499 -0
- planning_control_plane-0.1.3/README.md +470 -0
- planning_control_plane-0.1.3/pyproject.toml +50 -0
- planning_control_plane-0.1.3/setup.cfg +4 -0
- planning_control_plane-0.1.3/src/planning_control_plane/__init__.py +40 -0
- planning_control_plane-0.1.3/src/planning_control_plane/cli.py +1261 -0
- planning_control_plane-0.1.3/src/planning_control_plane/context.py +501 -0
- planning_control_plane-0.1.3/src/planning_control_plane/generator.py +840 -0
- planning_control_plane-0.1.3/src/planning_control_plane/graph.py +226 -0
- planning_control_plane-0.1.3/src/planning_control_plane/i18n.py +540 -0
- planning_control_plane-0.1.3/src/planning_control_plane/loader.py +702 -0
- planning_control_plane-0.1.3/src/planning_control_plane/model.py +457 -0
- planning_control_plane-0.1.3/src/planning_control_plane/templates/base.html +132 -0
- planning_control_plane-0.1.3/src/planning_control_plane/templates/ideas.html +88 -0
- planning_control_plane-0.1.3/src/planning_control_plane/templates/index.html +221 -0
- planning_control_plane-0.1.3/src/planning_control_plane/templates/node.html +301 -0
- planning_control_plane-0.1.3/src/planning_control_plane/templates/static/app.js +438 -0
- planning_control_plane-0.1.3/src/planning_control_plane/templates/static/style.css +1902 -0
- planning_control_plane-0.1.3/src/planning_control_plane/validator.py +410 -0
- planning_control_plane-0.1.3/src/planning_control_plane.egg-info/PKG-INFO +499 -0
- planning_control_plane-0.1.3/src/planning_control_plane.egg-info/SOURCES.txt +46 -0
- planning_control_plane-0.1.3/src/planning_control_plane.egg-info/dependency_links.txt +1 -0
- planning_control_plane-0.1.3/src/planning_control_plane.egg-info/entry_points.txt +2 -0
- planning_control_plane-0.1.3/src/planning_control_plane.egg-info/requires.txt +5 -0
- planning_control_plane-0.1.3/src/planning_control_plane.egg-info/top_level.txt +1 -0
- planning_control_plane-0.1.3/tests/test_agents.py +89 -0
- planning_control_plane-0.1.3/tests/test_cli.py +256 -0
- planning_control_plane-0.1.3/tests/test_context.py +284 -0
- planning_control_plane-0.1.3/tests/test_demo_zh.py +132 -0
- planning_control_plane-0.1.3/tests/test_dogfood_assets.py +40 -0
- planning_control_plane-0.1.3/tests/test_generator.py +164 -0
- planning_control_plane-0.1.3/tests/test_graduate.py +488 -0
- planning_control_plane-0.1.3/tests/test_graph.py +172 -0
- planning_control_plane-0.1.3/tests/test_html_smoke.py +346 -0
- planning_control_plane-0.1.3/tests/test_i18n.py +209 -0
- planning_control_plane-0.1.3/tests/test_idea_filename.py +92 -0
- planning_control_plane-0.1.3/tests/test_ideas.py +828 -0
- planning_control_plane-0.1.3/tests/test_ideas_next_id.py +172 -0
- planning_control_plane-0.1.3/tests/test_ideas_ui.py +526 -0
- planning_control_plane-0.1.3/tests/test_init.py +123 -0
- planning_control_plane-0.1.3/tests/test_lang_v012.py +374 -0
- planning_control_plane-0.1.3/tests/test_loader.py +246 -0
- planning_control_plane-0.1.3/tests/test_review_fixes.py +356 -0
- planning_control_plane-0.1.3/tests/test_skill_asset.py +62 -0
- planning_control_plane-0.1.3/tests/test_ui_v011.py +380 -0
- planning_control_plane-0.1.3/tests/test_validator_rules.py +198 -0
- planning_control_plane-0.1.3/tests/test_validator_structure.py +217 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PCP Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: planning-control-plane
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Repository-native planning context and progress control tool (pcp)
|
|
5
|
+
Author: PCP Contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/LuneHaven/planning-control-plane
|
|
8
|
+
Project-URL: Repository, https://github.com/LuneHaven/planning-control-plane
|
|
9
|
+
Project-URL: Changelog, https://github.com/LuneHaven/planning-control-plane/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/LuneHaven/planning-control-plane/issues
|
|
11
|
+
Keywords: planning,roadmap,decision-tracking,context-management
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Natural Language :: English
|
|
17
|
+
Classifier: Natural Language :: Chinese (Simplified)
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: PyYAML>=6.0
|
|
25
|
+
Requires-Dist: Jinja2>=3.1
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# Planning Control Plane
|
|
31
|
+
|
|
32
|
+
English | [简体中文](README.zh-CN.md)
|
|
33
|
+
|
|
34
|
+
**Keep long-running planning context in your repository instead of in chat
|
|
35
|
+
transcripts.**
|
|
36
|
+
|
|
37
|
+
PCP is a command-line tool that stores the planning process of an
|
|
38
|
+
AI-assisted project (objectives, decisions, scope, progress) as YAML files
|
|
39
|
+
under `.planning/`, versioned with git; `pcp build` renders them into a
|
|
40
|
+
fully offline static dashboard.
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
## Why PCP?
|
|
45
|
+
|
|
46
|
+
Discussing long-running plans in chat sessions usually runs into three
|
|
47
|
+
recurring problems:
|
|
48
|
+
|
|
49
|
+
- **Context loss**: a new session (or a new week) no longer knows the
|
|
50
|
+
parent constraints and the decisions that were already made.
|
|
51
|
+
- **Decision drift**: later discussions silently overturn frozen
|
|
52
|
+
decisions, because nobody re-reads message 40 of a 400-message thread.
|
|
53
|
+
- **Scope drift**: the discussion quietly grows past what this round was
|
|
54
|
+
supposed to decide.
|
|
55
|
+
|
|
56
|
+
A task tracker answers "who is doing what?"; PCP answers "where did the
|
|
57
|
+
discussion's context and boundaries go?" Task assignment stays in your
|
|
58
|
+
tracker; PCP only manages the planning process.
|
|
59
|
+
|
|
60
|
+
## The Core Idea
|
|
61
|
+
|
|
62
|
+
1. **Planning data is source; HTML is a projection.** The Planning Graph
|
|
63
|
+
lives in `.planning/` as plain YAML, committed with your repository.
|
|
64
|
+
`pcp build` renders it into a disposable static site you can delete and
|
|
65
|
+
regenerate at any time.
|
|
66
|
+
2. **Decisions cascade down the tree.** Nodes form a planning tree
|
|
67
|
+
(`PROGRAM → PHASE → STRATEGY → …`). Every child node *inherits and
|
|
68
|
+
displays* the frozen decisions and scope boundaries made at its parent,
|
|
69
|
+
so they stay visible instead of being argued over again.
|
|
70
|
+
3. **You can always pick up where you left off.** At any moment, exactly
|
|
71
|
+
one node is the current focus. `pcp context` emits a **Context
|
|
72
|
+
Capsule**: a compact, self-contained resume block you paste into a new
|
|
73
|
+
AI session (or send to a teammate) to continue working immediately.
|
|
74
|
+
4. **Deterministic and offline.** Same planning source + same PCP version =
|
|
75
|
+
byte-identical output. The generated site references no CDN and no
|
|
76
|
+
remote fonts, and makes no network requests at all; it works when opened
|
|
77
|
+
directly via `file://`.
|
|
78
|
+
|
|
79
|
+
## Features
|
|
80
|
+
|
|
81
|
+
- **Planning Graph**: nodes with parent / dependency / blocking / related
|
|
82
|
+
/ supersedes edges, validated as a graph (cycle detection included)
|
|
83
|
+
- **Current Focus**: the single node the next session should work on,
|
|
84
|
+
highlighted in the dashboard and the tree
|
|
85
|
+
- **Frozen / Open / Blocking / Deferred Decisions**: categorized,
|
|
86
|
+
inherited down the tree, never silently lost
|
|
87
|
+
- **Scope Boundary**: explicit *in scope / out of scope* lists per node;
|
|
88
|
+
entries declared by ancestors are inherited and displayed, showing where
|
|
89
|
+
the boundary lies
|
|
90
|
+
- **Three independent tracks**: discussion, writeback and implementation
|
|
91
|
+
status are stored separately and never derived from each other
|
|
92
|
+
- **Context Capsule**: `pcp context <node>` prints a paste-ready resume
|
|
93
|
+
capsule; the node page has a one-click Copy Context button
|
|
94
|
+
- **Static dashboard**: deterministic, offline, dark-mode-capable HTML
|
|
95
|
+
with progressive disclosure
|
|
96
|
+
- **Bilingual UI**: English and 简体中文, switchable at runtime in the
|
|
97
|
+
browser
|
|
98
|
+
- **Authority boundary**: PCP owns planning only; your canonical documents
|
|
99
|
+
stay yours, linked but never replaced
|
|
100
|
+
- **Idea layer**: `.planning/ideas/` captures thinking that is not yet
|
|
101
|
+
committed; `pcp ideas` lists and filters it, and a malformed idea file
|
|
102
|
+
degrades to a single validation issue that never blocks the plan
|
|
103
|
+
|
|
104
|
+
## Installation
|
|
105
|
+
|
|
106
|
+
PCP is not yet on PyPI; install from source (Python 3.11+). System Python
|
|
107
|
+
installs on many distributions are externally managed (PEP 668), so use a
|
|
108
|
+
virtual environment:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
git clone https://github.com/LuneHaven/planning-control-plane.git # or download and extract the source
|
|
112
|
+
cd planning-control-plane
|
|
113
|
+
python3 -m venv .venv
|
|
114
|
+
source .venv/bin/activate # Windows PowerShell: .venv\Scripts\activate
|
|
115
|
+
pip install -e .
|
|
116
|
+
pcp --help
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Runtime dependencies are just PyYAML and Jinja2.
|
|
120
|
+
|
|
121
|
+
## Quick Start
|
|
122
|
+
|
|
123
|
+
In your own repository:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
cd my-project
|
|
127
|
+
|
|
128
|
+
pcp init # creates .planning/{project.yaml, roadmap.yaml, nodes/, .gitignore}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Create your first planning node, `.planning/nodes/N1.yaml`:
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
id: N1
|
|
135
|
+
title: Choose the deployment approach
|
|
136
|
+
type: DISCUSSION
|
|
137
|
+
status: DISCUSSING
|
|
138
|
+
|
|
139
|
+
objective: >
|
|
140
|
+
Decide how this service gets deployed, given the constraints we froze
|
|
141
|
+
at the program level.
|
|
142
|
+
|
|
143
|
+
scope:
|
|
144
|
+
- Deployment tooling
|
|
145
|
+
- Environment topology
|
|
146
|
+
out_of_scope:
|
|
147
|
+
- Application refactoring
|
|
148
|
+
- Team staffing
|
|
149
|
+
|
|
150
|
+
next_action: >
|
|
151
|
+
Compare the two candidate toolchains against the readiness criteria.
|
|
152
|
+
|
|
153
|
+
discussion_status: IN_PROGRESS
|
|
154
|
+
writeback_status: N/A
|
|
155
|
+
implementation_status: N/A
|
|
156
|
+
last_updated: 2026-08-18
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Then:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
pcp focus N1 # set the current focus (written to project.yaml)
|
|
163
|
+
pcp validate # structural + consistency checks
|
|
164
|
+
pcp build # generate .planning/dist/
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Open `.planning/dist/index.html` in a browser (double-clicking works; the
|
|
168
|
+
site is fully offline). Continue in the terminal with:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
pcp status # overview: focus, blockers, progress counts
|
|
172
|
+
pcp context # the resume capsule for the current focus
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
To explore a ready-made example instead, see
|
|
176
|
+
[`examples/demo-project`](examples/demo-project): a fictional demo
|
|
177
|
+
repository whose seven-node planning tree is ready to `pcp build`
|
|
178
|
+
immediately. Its counterpart
|
|
179
|
+
[`examples/demo-project-zh`](examples/demo-project-zh) is the same kind of
|
|
180
|
+
scenario written in Chinese; the two are independent planning data sets, not
|
|
181
|
+
translations of each other (see [Localization](#localization)).
|
|
182
|
+
|
|
183
|
+
## CLI
|
|
184
|
+
|
|
185
|
+
| Command | What it does |
|
|
186
|
+
| --- | --- |
|
|
187
|
+
| `pcp init` | Create the `.planning/` skeleton; never overwrites existing files (`--force` only fills in missing files) |
|
|
188
|
+
| `pcp agents` | Print a paste-ready AGENTS.md section teaching AI harnesses this repository's PCP workflow. Read-only; append it with `pcp agents >> AGENTS.md` |
|
|
189
|
+
| `pcp validate` | Structural + planning-consistency validation, one issue per line (`ERROR`/`WARNING` + node + rule + reason) |
|
|
190
|
+
| `pcp build` | Validate, then deterministically rebuild the HTML output directory |
|
|
191
|
+
| `pcp build --check` | Regenerate in a temp directory and compare, to detect stale output (for CI) |
|
|
192
|
+
| `pcp status` | Terminal overview: project, current focus, decision counts, progress counts |
|
|
193
|
+
| `pcp context [node] [--full]` | Print the session resume capsule (default: the current focus) |
|
|
194
|
+
| `pcp focus [node]` | Show or switch the current focus (line-oriented edit of `project.yaml`; comments preserved) |
|
|
195
|
+
| `pcp ideas [--status S] [--for NODE [--subtree]]` | List the idea layer, grouped by status. `--for` selects ideas related to a node or its ancestors; `--subtree` switches to the node's subtree. Under `--for` without `--status`, only OPEN and PARKED are listed. The last line prints the next free idea id |
|
|
196
|
+
| `pcp graduate IDEA --to NODE [--note TEXT]` | Graduate an idea: write `status: PROMOTED` + `outcome` into the idea file and copy its ref-carrying justification entries into the node's `evidence_sources` (comments preserved; the node must already exist; both files roll back on failure) |
|
|
197
|
+
|
|
198
|
+
Global option `-p/--project-root PATH` sets the target repository root
|
|
199
|
+
(other commands search upward for `.planning/`).
|
|
200
|
+
|
|
201
|
+
Exit codes: `0` success · `1` business failure (validation errors, unknown
|
|
202
|
+
node, stale output) · `2` usage/load error.
|
|
203
|
+
|
|
204
|
+
## AI Harness Integration
|
|
205
|
+
|
|
206
|
+
Two assets tell an AI coding harness when to use `pcp`:
|
|
207
|
+
|
|
208
|
+
1. **AGENTS.md section**: `pcp agents >> AGENTS.md`, once per repository. It
|
|
209
|
+
records two kinds of content: the repository's own rules (document
|
|
210
|
+
naming, the registration convention) and the session workflow.
|
|
211
|
+
AGENTS.md is the open standard most harnesses read natively (Codex,
|
|
212
|
+
Cursor, Gemini CLI, ZCode, …). Claude Code is the exception: it reads
|
|
213
|
+
`CLAUDE.md` only, so bridge it with a `CLAUDE.md` whose sole content
|
|
214
|
+
is `@AGENTS.md`.
|
|
215
|
+
2. **Skill**: [`integrations/skills/pcp/SKILL.md`](integrations/skills/pcp/SKILL.md)
|
|
216
|
+
is the manual for the tool itself. One copy, several install locations:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# user level, shared across harnesses (ZCode scans ~/.agents/skills/)
|
|
220
|
+
mkdir -p ~/.agents/skills/pcp
|
|
221
|
+
curl -fsSL https://raw.githubusercontent.com/LuneHaven/planning-control-plane/main/integrations/skills/pcp/SKILL.md \
|
|
222
|
+
-o ~/.agents/skills/pcp/SKILL.md
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Claude Code does not scan `~/.agents/`; give it its own copy under
|
|
226
|
+
`~/.claude/skills/pcp/`. To share the skill with a team instead, commit it
|
|
227
|
+
into the repository at `.agents/skills/pcp/SKILL.md`.
|
|
228
|
+
|
|
229
|
+
The skill ships with the repository, not with the Python package: it is a
|
|
230
|
+
harness asset, not part of the PCP runtime; runtime adapters and plugins
|
|
231
|
+
remain out of scope (see Roadmap).
|
|
232
|
+
|
|
233
|
+
This division removes the duplication: repository rules are written only in
|
|
234
|
+
`AGENTS.md` and the command manual only in `SKILL.md`, so there is nothing
|
|
235
|
+
to keep in sync.
|
|
236
|
+
|
|
237
|
+
## Idea Layer
|
|
238
|
+
|
|
239
|
+
Planning nodes are a *post-decision* control system: a node exists because
|
|
240
|
+
something was already committed to. The idea layer carries what comes
|
|
241
|
+
before that: captured thinking that does not yet qualify for the plan.
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
.planning/ideas/IDEA-0007.yaml # one file per idea (directly under ideas/, .yaml suffix)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
```yaml
|
|
248
|
+
id: IDEA-0007
|
|
249
|
+
title: Add a trend comparison view to the dashboard
|
|
250
|
+
status: OPEN # OPEN | PARKED | PROMOTED | DISCARDED
|
|
251
|
+
detail: One paragraph. Capture asks for no structure.
|
|
252
|
+
relates_to: [P2] # planning nodes this idea touches
|
|
253
|
+
benchmark_sources: # what mature products actually do
|
|
254
|
+
- ref: docs/benchmarks/grafana-panels.md
|
|
255
|
+
note: Grafana's time-compare panel shows the demand is stable
|
|
256
|
+
- note: Stripe's month-over-month dashboard # outside the repo: note only
|
|
257
|
+
methodology_sources: # why it holds, decoupled from any product
|
|
258
|
+
- ref: docs/method/heuristics.md
|
|
259
|
+
outcome: ~ # set when the idea graduates into a node
|
|
260
|
+
created: 2026-08-27
|
|
261
|
+
last_updated: 2026-08-27
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Four properties are deliberate:
|
|
265
|
+
|
|
266
|
+
- **Capture has no gate.** Empty `benchmark_sources` /
|
|
267
|
+
`methodology_sources` are a valid state, and produce no WARNING.
|
|
268
|
+
- **A single entry point.** An idea enters the planning graph only by
|
|
269
|
+
graduating: create the node, then point the idea's `outcome.node` at that
|
|
270
|
+
node, by hand or with `pcp graduate IDEA-0007 --to P2-A5`, which also
|
|
271
|
+
copies the idea's ref-carrying justification entries into the node's
|
|
272
|
+
`evidence_sources`. Nodes never reference ideas back, so reading the
|
|
273
|
+
plan never involves unfinished thinking.
|
|
274
|
+
- **Ideas cannot break the plan.** A malformed idea file becomes a
|
|
275
|
+
validation issue and is skipped; `pcp status`, `pcp context` and
|
|
276
|
+
`pcp build` keep working, and idea-layer errors never block a build.
|
|
277
|
+
- **Ideas are never in a capsule.** `pcp context` carries planning data
|
|
278
|
+
only; `pcp ideas --for <node>` is the separate, deliberate second lookup.
|
|
279
|
+
|
|
280
|
+
The generated site gets an `ideas.html` page and a sidebar entry, but only
|
|
281
|
+
when the project actually has ideas.
|
|
282
|
+
|
|
283
|
+
One rule runs through the idea layer: the `id` is the identity, the file
|
|
284
|
+
name is only an index. Two consequences follow. When a file name does not
|
|
285
|
+
match its `id`, `pcp validate` reports the `idea-filename-mismatch`
|
|
286
|
+
WARNING (advisory, never blocking); rename the file to fix it. And the last
|
|
287
|
+
line of `pcp ideas` prints the next free `IDEA-<NNNN>`, computed from both
|
|
288
|
+
loaded ids and the file names on disk, so it never points at a file that
|
|
289
|
+
already exists.
|
|
290
|
+
|
|
291
|
+
## Planning Model
|
|
292
|
+
|
|
293
|
+
- **Node types** (controlled enum): `PROGRAM`, `PHASE`, `STRATEGY`,
|
|
294
|
+
`DISCUSSION`, `DECISION`, `INVESTIGATION`, `IMPLEMENTATION`, `CLOSURE`.
|
|
295
|
+
- **Node status** (planning lifecycle, not a kanban): `NOT_STARTED`,
|
|
296
|
+
`DISCUSSING`, `INVESTIGATING`, `DECIDED`, `WRITEBACK_PENDING`,
|
|
297
|
+
`WRITEBACK_DONE`, `READY`, `IMPLEMENTING`, `BLOCKED`, `DONE`, `DEFERRED`.
|
|
298
|
+
- **Three independent tracks** per node: `discussion_status`,
|
|
299
|
+
`writeback_status`, `implementation_status` ∈ `NOT_STARTED`,
|
|
300
|
+
`IN_PROGRESS`, `DONE`, `N/A`. A pure discussion node can be
|
|
301
|
+
Discussion `DONE` + Writeback `DONE` + Implementation `N/A`.
|
|
302
|
+
- **Decisions** come in four lists per node:
|
|
303
|
+
- *Frozen*: settled; children inherit them and must not silently overturn them
|
|
304
|
+
- *Open*: identified, not yet settled
|
|
305
|
+
- *Blocking*: unresolved and preventing closure (`DONE` + blocking → validation ERROR)
|
|
306
|
+
- *Deferred*: deliberately postponed
|
|
307
|
+
- **Scope Boundary**: `scope` / `out_of_scope` lists per node; entries
|
|
308
|
+
declared by ancestors are inherited and displayed, showing where the
|
|
309
|
+
boundary lies.
|
|
310
|
+
|
|
311
|
+
## `.planning/` Structure
|
|
312
|
+
|
|
313
|
+
```
|
|
314
|
+
.planning/
|
|
315
|
+
├── project.yaml # project id/name, current_focus, authority roots, ui.locale
|
|
316
|
+
├── roadmap.yaml # optional inline nodes list
|
|
317
|
+
├── nodes/ # one YAML file per planning node
|
|
318
|
+
└── dist/ # generated site (gitignored, disposable)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Example Node
|
|
322
|
+
|
|
323
|
+
From `examples/demo-project/.planning/nodes/P2-A4.yaml`:
|
|
324
|
+
|
|
325
|
+
```yaml
|
|
326
|
+
id: P2-A4
|
|
327
|
+
title: Rollout Readiness Preflight
|
|
328
|
+
type: DISCUSSION
|
|
329
|
+
parent: P2-A
|
|
330
|
+
status: NOT_STARTED
|
|
331
|
+
objective: >
|
|
332
|
+
Run the readiness preflight for the first wave ...
|
|
333
|
+
scope:
|
|
334
|
+
- First-wave readiness verification
|
|
335
|
+
- Blocking-issue escalation
|
|
336
|
+
out_of_scope:
|
|
337
|
+
- Changing the readiness criteria (frozen at P2-A2)
|
|
338
|
+
open_decisions:
|
|
339
|
+
- id: OD-401
|
|
340
|
+
summary: How much readiness evidence is enough to declare the first wave ready?
|
|
341
|
+
blocking_decisions:
|
|
342
|
+
- id: BD-401
|
|
343
|
+
summary: Must a blocking gate owner sign off before rollout execution starts?
|
|
344
|
+
depends_on: [P2-A3]
|
|
345
|
+
canonical_sources:
|
|
346
|
+
- docs/rollout/readiness-criteria.md
|
|
347
|
+
evidence_sources:
|
|
348
|
+
- docs/notes/2026-08-15-sequencing-review.md
|
|
349
|
+
next_action: >
|
|
350
|
+
Resolve BD-401 with the gate owners, then walk the criteria checklist.
|
|
351
|
+
discussion_status: NOT_STARTED
|
|
352
|
+
writeback_status: N/A
|
|
353
|
+
implementation_status: N/A
|
|
354
|
+
last_updated: 2026-08-17
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Dashboard & Progressive Disclosure
|
|
358
|
+
|
|
359
|
+

|
|
360
|
+
|
|
361
|
+
- The **sidebar** carries the full planning tree, including status, focus
|
|
362
|
+
marker and expand/collapse.
|
|
363
|
+
- The **dashboard** answers four questions only: where are we (Current
|
|
364
|
+
Focus), is anything blocked (Needs Attention), what is around the focus
|
|
365
|
+
(Focus Branch), and what can start next (Ready Queue).
|
|
366
|
+
- The **node page** is ordered by control-plane priority: sticky header
|
|
367
|
+
(id, status, three tracks, Copy Context) → Next Action → Objective →
|
|
368
|
+
Scope Boundary → decisions (Blocking → Open → Frozen, inherited groups
|
|
369
|
+
collapsed per ancestor) → relations → sources → Resume This Work.
|
|
370
|
+
- Details that would obscure the essentials start collapsed (inherited
|
|
371
|
+
frozen decisions, deferred decisions, the full capsule) with counts
|
|
372
|
+
always visible.
|
|
373
|
+
|
|
374
|
+
## Context Recovery
|
|
375
|
+
|
|
376
|
+
The **Context Capsule** hands the current state of the planning graph to
|
|
377
|
+
your next working session:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
pcp context # compact capsule for the current focus
|
|
381
|
+
pcp context P2-A4 # any node
|
|
382
|
+
pcp context --full # adds ancestor summaries, relations, deferred decisions
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Paste the capsule into a new AI session as the opening context. It carries
|
|
386
|
+
only what a new session needs: the node's objective, inherited frozen
|
|
387
|
+
decisions, scope boundaries, open and blocking decisions, sources and
|
|
388
|
+
track status, and nothing else. The node page's **Resume This Work**
|
|
389
|
+
panel shows the same capsule with a copy button.
|
|
390
|
+
|
|
391
|
+
## Recommended AI Agent Workflow
|
|
392
|
+
|
|
393
|
+
```
|
|
394
|
+
1. pcp build → open the dashboard, read Current Focus
|
|
395
|
+
2. pcp context → paste the capsule into a new agent session
|
|
396
|
+
3. Discuss only that branch; record outcomes as decisions in the node YAML
|
|
397
|
+
4. Write conclusions that belong in specs back into the canonical docs;
|
|
398
|
+
keep only links in the node
|
|
399
|
+
5. Update status / tracks / next_action / last_updated
|
|
400
|
+
6. pcp validate → fix ERRORs
|
|
401
|
+
7. pcp build (CI: pcp build --check)
|
|
402
|
+
8. pcp focus <next-node> → repeat
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Every artifact of the loop is on disk, so it can be interrupted anywhere
|
|
406
|
+
and resumed later.
|
|
407
|
+
|
|
408
|
+
## Localization
|
|
409
|
+
|
|
410
|
+
The UI ships in English and 简体中文.
|
|
411
|
+
|
|
412
|
+
- **Project default**: `ui.locale` in `.planning/project.yaml`:
|
|
413
|
+
|
|
414
|
+
```yaml
|
|
415
|
+
ui:
|
|
416
|
+
locale: zh-CN # or en (default)
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
- **Runtime switch**: the top bar has a `English / 中文` toggle. Switching
|
|
420
|
+
happens instantly in the browser: no rebuild, no refresh, no network. The
|
|
421
|
+
preference is stored in `localStorage` and survives navigation and
|
|
422
|
+
reloads; clearing it falls back to the project default. `project.yaml`
|
|
423
|
+
is never modified.
|
|
424
|
+
- **Language never touches data**: node ids, decision ids, stored enum
|
|
425
|
+
values, user-written titles/summaries and the `pcp context` capsule stay
|
|
426
|
+
exactly as written in any locale. Detailed status views show
|
|
427
|
+
`localized label + RAW_ENUM` (e.g. `未开始 NOT_STARTED`), so machine-facing
|
|
428
|
+
values remain searchable.
|
|
429
|
+
|
|
430
|
+
> The language switch localizes PCP's interface.
|
|
431
|
+
> It does not translate your project planning content.
|
|
432
|
+
> Planning data remains exactly as authored.
|
|
433
|
+
|
|
434
|
+
That boundary is why this repository ships two demo projects rather than one:
|
|
435
|
+
[`examples/demo-project`](examples/demo-project) holds English planning data
|
|
436
|
+
and [`examples/demo-project-zh`](examples/demo-project-zh) holds Chinese
|
|
437
|
+
planning data. The Chinese screenshots in
|
|
438
|
+
[README.zh-CN.md](README.zh-CN.md) come from the Chinese demo, not from the
|
|
439
|
+
English demo viewed through a Chinese UI.
|
|
440
|
+
|
|
441
|
+
## Architecture
|
|
442
|
+
|
|
443
|
+
| Layer | Location | Owner |
|
|
444
|
+
| --- | --- | --- |
|
|
445
|
+
| PCP engine | `src/planning_control_plane/` (this repository) | standalone pip-installed tool |
|
|
446
|
+
| Planning data | `<your-repo>/.planning/{project.yaml, roadmap.yaml, nodes/}` | your repository |
|
|
447
|
+
| Generated HTML | `<your-repo>/.planning/dist/` | your repository (disposable) |
|
|
448
|
+
|
|
449
|
+
Modules: `model.py` (enums + data model) · `loader.py` (tolerant YAML
|
|
450
|
+
loading) · `graph.py` (tree/graph operations) · `validator.py` (rules) ·
|
|
451
|
+
`context.py` (capsule) · `i18n.py` (UI translations, the single source
|
|
452
|
+
embedded into each page) · `generator.py` + `templates/` (deterministic
|
|
453
|
+
HTML) · `cli.py`.
|
|
454
|
+
|
|
455
|
+
## Authority Boundary
|
|
456
|
+
|
|
457
|
+
PCP is authoritative **only** for planning structure and planning progress.
|
|
458
|
+
Normative product, governance, architecture and implementation semantics
|
|
459
|
+
remain owned by your project's own documents; PCP links to them
|
|
460
|
+
(`canonical_sources` / `evidence_sources`) and never copies or judges them.
|
|
461
|
+
Every generated page states this in its footer.
|
|
462
|
+
|
|
463
|
+
## Current Status
|
|
464
|
+
|
|
465
|
+
**Current release: V0.1.3** is a usable MVP validated through real-project
|
|
466
|
+
self-use: the engine, CLI, validator, capsule and bilingual UI all work, and
|
|
467
|
+
the automated test suite has 409 tests. PCP is **not yet published on PyPI**;
|
|
468
|
+
install from source as shown above.
|
|
469
|
+
|
|
470
|
+
## Roadmap
|
|
471
|
+
|
|
472
|
+
Deliberately **not** in scope: multi-user collaboration, server/cloud sync,
|
|
473
|
+
database, GitHub/PR integration, AI plugins, automatic summarization or
|
|
474
|
+
decision-making, semantic search, Jira/Notion replacement.
|
|
475
|
+
|
|
476
|
+
Named extension points reserved for later versions (no interfaces yet):
|
|
477
|
+
`pcp prompt`, `pcp close`, `pcp reopen`, Git/GitHub adapters, Claude Code /
|
|
478
|
+
Codex / ChatGPT adapters, multi-project workspace.
|
|
479
|
+
|
|
480
|
+
V0.2 candidates (none of them is implemented, and none is a promise):
|
|
481
|
+
|
|
482
|
+
- close / reopen workflow
|
|
483
|
+
- prompt generation
|
|
484
|
+
- integration status
|
|
485
|
+
- search / filter
|
|
486
|
+
- multi-project workspace
|
|
487
|
+
|
|
488
|
+
## Contributing
|
|
489
|
+
|
|
490
|
+
Issues and pull requests are welcome. For development:
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
pip install -e ".[dev]"
|
|
494
|
+
python -m pytest
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
## License
|
|
498
|
+
|
|
499
|
+
[MIT](LICENSE)
|