create-pmos 0.52.0 → 0.53.1

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 (229) hide show
  1. package/package.json +1 -1
  2. package/payload/KIT-VERSION +2 -2
  3. package/payload/mods/pmos-cockpit/README.md +13 -0
  4. package/payload/mods/pmos-cockpit/hooks/lib/commands.mjs +2 -1
  5. package/payload/mods/pmos-cockpit/hooks/lib/grants.mjs +41 -11
  6. package/payload/mods/pmos-cockpit/hooks/lib/guard.mjs +228 -8
  7. package/payload/mods/pmos-cockpit/hooks/register.tsx +11 -3
  8. package/payload/planning/evals/eval-calibration.md +1 -1
  9. package/payload/planning/okrs/health-budgets.md +1 -1
  10. package/payload/scripts/plan-items-stage.js +271 -0
  11. package/payload/scripts/pmos-log.sh +18 -7
  12. package/payload/scripts/workflow-state.js +28 -2
  13. package/payload/state/discoveries.md +1 -1
  14. package/payload/state/log.md +1 -1
  15. package/workspace/README.md +2 -0
  16. package/workspace/REMOTE.md +24 -63
  17. package/workspace/bin/pmos.js +19 -3
  18. package/workspace/cut-stub.js +40 -0
  19. package/workspace/first-paint-audit.js +145 -0
  20. package/workspace/fixtures/capture/requirements/capture-2026-10-04-1.md +10 -0
  21. package/workspace/fixtures/initiatives-api/list.json +176 -0
  22. package/workspace/fixtures/initiatives-api/post-403.json +5 -0
  23. package/workspace/fixtures/initiatives-api/post-ok.json +10 -0
  24. package/workspace/fixtures/initiatives-api/roadmap.json +208 -0
  25. package/workspace/fixtures/initiatives-api/sheet.json +112 -0
  26. package/workspace/fixtures/report-api/draft.json +177 -0
  27. package/workspace/fixtures/reports-page/draft-biweekly-2026-10-16.md +97 -0
  28. package/workspace/fixtures/today-api/provider-rows.json +204 -0
  29. package/workspace/fixtures/today-api/seam-probe-kinds.json +5 -0
  30. package/workspace/guide/board.md +81 -0
  31. package/workspace/guide/breakdown.md +154 -0
  32. package/workspace/guide/command-palette.md +75 -0
  33. package/workspace/guide/index.md +28 -17
  34. package/workspace/guide/initiatives-roadmap.md +130 -0
  35. package/workspace/guide/initiatives-screen.md +89 -0
  36. package/workspace/guide/initiatives-timeline.md +57 -0
  37. package/workspace/guide/integrated-work.md +94 -0
  38. package/workspace/guide/knowledge-graph.md +3 -68
  39. package/workspace/guide/launcher.md +51 -0
  40. package/workspace/guide/layout.md +102 -32
  41. package/workspace/guide/live-notes.md +3 -3
  42. package/workspace/guide/pm-only-acts.md +89 -0
  43. package/workspace/guide/pm-only-lines.md +61 -0
  44. package/workspace/guide/proactive-engine.md +21 -5
  45. package/workspace/guide/reports-page.md +80 -0
  46. package/workspace/guide/reports.md +73 -0
  47. package/workspace/guide/timeline.md +70 -0
  48. package/workspace/guide/today.md +85 -0
  49. package/workspace/guide/validate-with-typesafe.md +1 -1
  50. package/workspace/lib/actor.js +91 -0
  51. package/workspace/lib/board-cache.js +32 -2
  52. package/workspace/lib/board-cli.js +108 -0
  53. package/workspace/lib/board-fold.js +232 -0
  54. package/workspace/lib/breakdown-export.js +75 -0
  55. package/workspace/lib/brief.js +20 -2
  56. package/workspace/lib/capture.js +98 -0
  57. package/workspace/lib/engine/plan-items-stage.js +271 -0
  58. package/workspace/lib/engine/workflow-state.js +28 -2
  59. package/workspace/lib/factory-join.js +158 -0
  60. package/workspace/lib/goals.js +165 -0
  61. package/workspace/lib/grant-mint.js +113 -0
  62. package/workspace/lib/health-rules-factory.js +92 -0
  63. package/workspace/lib/health-rules-plan.js +164 -0
  64. package/workspace/lib/health.js +79 -0
  65. package/workspace/lib/initiative-cli.js +222 -0
  66. package/workspace/lib/initiative-display.js +183 -0
  67. package/workspace/lib/initiative-needs.js +127 -0
  68. package/workspace/lib/initiative-rows.js +210 -0
  69. package/workspace/lib/initiative-writer.js +141 -0
  70. package/workspace/lib/issues.js +206 -0
  71. package/workspace/lib/item-cli.js +195 -0
  72. package/workspace/lib/item-spans.js +137 -0
  73. package/workspace/lib/launcher-cli.js +207 -0
  74. package/workspace/lib/measure-cli.js +100 -0
  75. package/workspace/lib/measurements.js +189 -0
  76. package/workspace/lib/mobile-nav.js +57 -53
  77. package/workspace/lib/needs-providers.js +120 -0
  78. package/workspace/lib/placements.js +440 -0
  79. package/workspace/lib/plan-items.js +922 -0
  80. package/workspace/lib/plan-ledgers.js +85 -0
  81. package/workspace/lib/plan-rules.js +72 -0
  82. package/workspace/lib/plan-tree.js +380 -0
  83. package/workspace/lib/pm-guard.js +174 -0
  84. package/workspace/lib/pm-lines-needs.js +331 -0
  85. package/workspace/lib/pmos-verbs.js +69 -0
  86. package/workspace/lib/proactive-cli.js +58 -2
  87. package/workspace/lib/proactive.js +9 -6
  88. package/workspace/lib/qr.js +293 -0
  89. package/workspace/lib/remote-access.js +93 -1
  90. package/workspace/lib/report-cli.js +152 -0
  91. package/workspace/lib/report-draft.js +578 -0
  92. package/workspace/lib/report-needs.js +213 -0
  93. package/workspace/lib/route-modules.js +128 -0
  94. package/workspace/lib/routes-board.js +91 -0
  95. package/workspace/lib/routes-capture.js +52 -0
  96. package/workspace/lib/routes-initiatives.js +371 -0
  97. package/workspace/lib/routes-reports.js +163 -0
  98. package/workspace/lib/routes-timeline.js +197 -0
  99. package/workspace/lib/routes-today.js +32 -0
  100. package/workspace/lib/today-cli.js +99 -0
  101. package/workspace/lib/today.js +333 -0
  102. package/workspace/lib/triage.js +163 -0
  103. package/workspace/lib/verify-work-cli.js +81 -0
  104. package/workspace/lib/work-check-needs.js +99 -0
  105. package/workspace/package-lock.json +1 -1
  106. package/workspace/package.json +4 -5
  107. package/workspace/public/icons/apple-touch-icon.png +0 -0
  108. package/workspace/public/icons/icon-192.png +0 -0
  109. package/workspace/public/icons/icon-512.png +0 -0
  110. package/workspace/public/index.html +40 -19
  111. package/workspace/public/pm/app.js +330 -30
  112. package/workspace/public/pm/bd-board.js +113 -0
  113. package/workspace/public/pm/bd-drag.js +59 -0
  114. package/workspace/public/pm/bd-model.js +152 -0
  115. package/workspace/public/pm/bd-timeline.js +233 -0
  116. package/workspace/public/pm/bd-tree.js +244 -0
  117. package/workspace/public/pm/board-copy.js +57 -0
  118. package/workspace/public/pm/breakdown-api.js +58 -0
  119. package/workspace/public/pm/breakdown-copy.js +138 -0
  120. package/workspace/public/pm/components.css +3135 -0
  121. package/workspace/public/pm/cycle-review.js +125 -0
  122. package/workspace/public/pm/data.js +40 -187
  123. package/workspace/public/pm/dest-board.js +438 -0
  124. package/workspace/public/pm/dest-initiatives.js +134 -0
  125. package/workspace/public/pm/dest-reports.js +270 -0
  126. package/workspace/public/pm/dest-settings.js +217 -0
  127. package/workspace/public/pm/dest-today.js +182 -0
  128. package/workspace/public/pm/dialogs.js +88 -0
  129. package/workspace/public/pm/display-word.js +56 -0
  130. package/workspace/public/pm/dock.js +175 -0
  131. package/workspace/public/pm/fixture.js +8 -227
  132. package/workspace/public/pm/frame-copy.js +99 -0
  133. package/workspace/public/pm/handoff-box.js +82 -0
  134. package/workspace/public/pm/http.js +88 -0
  135. package/workspace/public/pm/icons.js +53 -0
  136. package/workspace/public/pm/initiative-list.js +218 -0
  137. package/workspace/public/pm/initiative-sheet.js +261 -0
  138. package/workspace/public/pm/initiatives-api.js +59 -0
  139. package/workspace/public/pm/initiatives-copy.js +215 -0
  140. package/workspace/public/pm/initiatives-timeline-copy.js +59 -0
  141. package/workspace/public/pm/initiatives-timeline.js +410 -0
  142. package/workspace/public/pm/initiatives-ui.js +123 -0
  143. package/workspace/public/pm/item-sheet.js +251 -0
  144. package/workspace/public/pm/keep-card.js +204 -0
  145. package/workspace/public/pm/lifecycle.js +7 -1
  146. package/workspace/public/pm/mobile.css +49 -20
  147. package/workspace/public/pm/mobile.js +157 -29
  148. package/workspace/public/pm/modes-live.js +7 -883
  149. package/workspace/public/pm/modes.js +32 -1024
  150. package/workspace/public/pm/new-initiative-sheet.js +74 -0
  151. package/workspace/public/pm/next-step-ui.js +3 -2
  152. package/workspace/public/pm/palette-copy.js +51 -0
  153. package/workspace/public/pm/palette.js +312 -0
  154. package/workspace/public/pm/panel-breakdown.js +702 -0
  155. package/workspace/public/pm/panel-cockpit.js +63 -295
  156. package/workspace/public/pm/panel-detail.js +25 -172
  157. package/workspace/public/pm/panel-initiatives.js +1 -19
  158. package/workspace/public/pm/panel-repos.js +31 -81
  159. package/workspace/public/pm/panel-tabs.js +200 -111
  160. package/workspace/public/pm/panel-trees.js +5 -2
  161. package/workspace/public/pm/portfolio-report.js +61 -0
  162. package/workspace/public/pm/primitives.js +656 -0
  163. package/workspace/public/pm/print.css +33 -0
  164. package/workspace/public/pm/provider-cards.js +136 -0
  165. package/workspace/public/pm/registry.js +194 -0
  166. package/workspace/public/pm/release-card.js +110 -0
  167. package/workspace/public/pm/report-view.js +309 -0
  168. package/workspace/public/pm/reports-copy.js +114 -0
  169. package/workspace/public/pm/roadmap.js +271 -0
  170. package/workspace/public/pm/sig-watch.js +41 -0
  171. package/workspace/public/pm/state.js +8 -4
  172. package/workspace/public/pm/status-banner.js +13 -5
  173. package/workspace/public/pm/tab-doc.js +2 -4
  174. package/workspace/public/pm/tab-term.js +12 -2
  175. package/workspace/public/pm/tab-web.js +3 -2
  176. package/workspace/public/pm/timeline-copy.js +48 -0
  177. package/workspace/public/pm/today-cards.js +244 -0
  178. package/workspace/public/pm/today-copy.js +126 -0
  179. package/workspace/public/pm/today-goals.js +172 -0
  180. package/workspace/public/pm/tokens.css +16 -18
  181. package/workspace/public/pm/topbar.js +102 -0
  182. package/workspace/public/pm/triage-card.js +60 -0
  183. package/workspace/public/pm/undo-hold.js +103 -0
  184. package/workspace/public/pm/view-addrepo.js +2 -1
  185. package/workspace/public/pm/view-livenotes.js +3 -1
  186. package/workspace/public/pm/view-today.js +7 -162
  187. package/workspace/public/vendor/Sortable.min.js +2 -0
  188. package/workspace/public/vendor/lucide-sprite.js +79 -0
  189. package/workspace/replaced-tests.json +2877 -0
  190. package/workspace/run-tests.js +56 -5
  191. package/workspace/server.js +446 -40
  192. package/workspace/sheet-answer.js +61 -0
  193. package/workspace/skills/measure.skill +41 -0
  194. package/workspace/skills/morning-brief.skill +15 -9
  195. package/workspace/skills/report-biweekly.skill +23 -25
  196. package/workspace/skills/tracker-refresh.skill +50 -0
  197. package/workspace/test-files.json +21 -3
  198. package/workspace/test-lists/base.json +6 -0
  199. package/workspace/test-lists/run2-a.json +6 -0
  200. package/workspace/test-lists/run2-b.json +13 -0
  201. package/workspace/test-lists/run2-c.json +19 -0
  202. package/workspace/test-lists/run2-d.json +22 -0
  203. package/workspace/test-lists/run3-0.json +5 -0
  204. package/workspace/test-lists/run3-a.json +5 -0
  205. package/workspace/test-lists/run3-b.json +6 -0
  206. package/workspace/test-lists/run3-c.json +15 -0
  207. package/workspace/test-lists/run3-d.json +6 -0
  208. package/workspace/test-lists/run4-a.json +8 -0
  209. package/workspace/test-lists/run4-b.json +6 -0
  210. package/workspace/test-lists/run4-c.json +13 -0
  211. package/workspace/test-lists/run4-d.json +9 -0
  212. package/workspace/test-lists/run5-a.json +6 -0
  213. package/workspace/test-lists/run5-b.json +6 -0
  214. package/workspace/test-lists/run5-c.json +15 -0
  215. package/workspace/test-lists/workspace-launcher.json +5 -0
  216. package/workspace/test-lists/workspace-phone-app.json +5 -0
  217. package/workspace/test-run.js +27 -1
  218. package/workspace/third-party/README.md +44 -0
  219. package/workspace/third-party/lucide-static-1.52.0.LICENSE +43 -0
  220. package/workspace/third-party/sortablejs-1.15.7.LICENSE +21 -0
  221. package/workspace/design-parity.js +0 -673
  222. package/workspace/public/pm/tab-task.js +0 -86
  223. package/workspace/public/pm/view-guide.js +0 -141
  224. package/workspace/public/pm/view-knowledge.js +0 -225
  225. package/workspace/public/pm/view-memory.js +0 -122
  226. package/workspace/public/pm/view-portfolio.js +0 -153
  227. package/workspace/public/pm/view-reports.js +0 -190
  228. package/workspace/public/pm/view-scheduled.js +0 -161
  229. package/workspace/public/pm/view-skills.js +0 -216
@@ -0,0 +1,94 @@
1
+ ---
2
+ type: Guide
3
+ title: "Integrated work: from a merged commit to Done"
4
+ description: "How pmos verify-work marks factory work items integrated from the default branch, how a plan item then reads Done, when the Build step is done, why factory work starts only from Now, and the two factory health reasons."
5
+ timestamp: 2026-10-05
6
+ ---
7
+
8
+ # Integrated work: from a merged commit to Done
9
+
10
+ Some items of a breakdown go to the factory. The factory does the work in the product repository and opens a pull request. This page tells you how a merged pull request makes its item Done, and what the workspace shows on the way.
11
+
12
+ ## Two ledgers, one link
13
+
14
+ - The breakdown items are in `planning/runs/plan-items.jsonl`. You and the agent write this file. See [Breakdown](breakdown.md).
15
+ - The factory work items are in `planning/work-items.jsonl`. Only the factory writer adds lines to this file.
16
+ - When an item goes to the factory, its work item gets the field `plan_item`. This field holds the id of the breakdown item, for example `checkout.k3m9x2a7qd`. It is the only link between the two files.
17
+ - A breakdown line never goes into `planning/work-items.jsonl`. The checker in CI stops a `plan_item` that names no breakdown item.
18
+
19
+ ## Factory work starts only from Now
20
+
21
+ An initiative must be in Now before the factory takes work for it. This rule applies to a feature that is anchored to a KR. It does not apply to a chore, an incident or an initiative anchored to a health budget.
22
+
23
+ If the initiative is in Next or Later, the factory refuses the work and gives the reason. The factory also refuses the work when Initiatives shows "Now, unconfirmed": only a Now that you confirmed counts. To continue:
24
+
25
+ 1. Open Initiatives.
26
+ 2. Move the initiative to Now, or confirm it in Now. Only you can do this.
27
+ 3. Send the work to the factory again.
28
+
29
+ ## Mark merged work: `pmos verify-work`
30
+
31
+ A commit can name a work item in a trailer, on its own line at the end of the commit message:
32
+
33
+ ```
34
+ Work-Item: checkout.3
35
+ ```
36
+
37
+ When that commit is on the default branch, the work item is integrated. To record this, run:
38
+
39
+ ```
40
+ pmos verify-work
41
+ ```
42
+
43
+ The command does these steps:
44
+
45
+ 1. It finds the default branch in the local refs: `origin/main`, `main`, `origin/master` or `master`, in that order. It does not fetch. To see new commits, pull first (Sync).
46
+ 2. It reads the `Work-Item:` trailers on that branch.
47
+ 3. For each work item that is not integrated yet, it adds one `integrated` line to `planning/work-items.jsonl`. The line names the commit.
48
+
49
+ You can run the command again at any time. A work item that is already integrated is not written again.
50
+
51
+ Options:
52
+
53
+ - `--branch <ref>` reads only the commits up to `<ref>`. The ref must be on the default branch. A ref that is not merged is refused, and the command writes nothing.
54
+ - `--dry-run` shows what the command would write, and writes nothing.
55
+ - `--json` prints the result as JSON.
56
+ - `--root <dir>` runs in a different repository.
57
+
58
+ The command runs the repository's own copy of `scripts/verify-work.js`. A repository with no factory writer has no work items, and the command tells you so.
59
+
60
+ ### What the command does not write
61
+
62
+ The command reports these cases and writes nothing for them:
63
+
64
+ - **Refused.** The work item is merged, but the factory writer does not accept `integrated` yet. Usually the work item was not verified, or its last check failed. The line shows the reason from the writer. The command then exits with 1.
65
+ - **Unknown.** A trailer names a work item that is not in the ledger.
66
+
67
+ A commit that is only on another branch is not read.
68
+
69
+ ## What you see on the item
70
+
71
+ - **Done.** When its work item is integrated, the breakdown item reads Done. Nobody moves it by hand, and no line is added to `plan-items.jsonl`.
72
+ - **Done · your call · not merged.** You moved the item to Done, but its work item is not integrated yet. The item stays Done because you decided it. The text tells you that the work is not on the default branch.
73
+
74
+ ## When the Build step is done
75
+
76
+ An item never completes a stage, with one exception. For a code initiative, the Build step is done when every factory work item under Build is integrated. The work items under Build are the ones whose `plan_item` is a breakdown item in the Build stage.
77
+
78
+ - While one of them is not integrated, the Build step is pending. The step names the work items it waits for.
79
+ - A breakdown item that you move to Done by hand does not complete the Build step.
80
+ - A withdrawn work item, or a withdrawn breakdown item, is not counted.
81
+ - When no work item names a breakdown item under Build, the commits decide the Build step, as before.
82
+
83
+ CI, the `node scripts/workflow-state.js` command and the workspace use the same rule, so they show the same Build step.
84
+
85
+ ## Factory health
86
+
87
+ Two health reasons come from the factory. Each shows its reason as text.
88
+
89
+ - **Off track.** A factory work item failed its check, and nobody fixed it or withdrew it.
90
+ - **At risk.** The initiative is in Next or Later, but the factory claimed work for it, or commits on the trunk are attributed to it. Building starts only from Now. Move the initiative to Now, or stop the work.
91
+
92
+ ## Where to read next
93
+
94
+ - [Breakdown](breakdown.md): the items of an initiative, the Tree and the Board.
@@ -68,84 +68,19 @@ The workspace decides the category with local rules only. It uses no model and s
68
68
 
69
69
  When a later rule disagrees with the rule that decided, the file keeps the earlier answer. A `Reference` or `Research` file with no better evidence has no category. It shows as `undetermined`. That is not the same as `other`: `other` means the file is none of the kinds, and `undetermined` means no rule could tell.
70
70
 
71
- The Knowledge view shows the category after each document name. Point at it to see which rule decided. Press a category above the list to show only those documents, and press it again to show all. The category is advisory. `pmos kg stats` counts the files in each category.
72
-
73
- ### Ask Jev about undetermined files
74
-
75
- Jev can give a category to a file that the local rules leave `undetermined`. This is off until you turn it on. Jev never sees a file that already has a category from a local rule or from your correction. The measured pass below is the one exception for the local rules.
76
-
77
- Three things must all be on before anything is sent:
78
-
79
- 1. A TypeSafe key, saved on the Validate page.
80
- 2. Validation, switched on for this repository.
81
- 3. **Categorize with Jev**, the switch in the Knowledge view.
82
-
83
- If one of them is off, the Knowledge view tells you which one.
84
-
85
- To start:
86
-
87
- 1. Turn on **categorize with Jev**.
88
- 2. Press **ask Jev about undetermined files**. The view shows how many requests it will send, about how many characters, and the host. Nothing is sent yet.
89
- 3. Press **confirm and send** to send that number. If the files changed after you looked, even when the number is the same, the send stops and you look again.
90
-
91
- After the first confirmed send, the workspace sends only new or changed undetermined files. It does this when it reads the documents of this repository, at most once a minute. It reads them when it starts and when you open the Knowledge view. If more than 25 files wait, it does not send them. It tells you, and you confirm the count again.
92
-
93
- What is sent for each file: the title, the headings and the start of the text, at most 3,000 characters. The file path and the whole file are not sent. A file under an excluded path is not sent. A file whose start looks like a password or a key is not sent.
94
-
95
- Jev's answer shows as the category with `(jev)` after it. Point at it to see how sure Jev was, in words. If Jev was not sure, the file stays `undetermined` with `(jev unsure)` after it, and the tooltip names the two categories Jev was between. A Jev category is advisory. Each answer is kept on your computer, outside the repository, and the same text is not sent twice. Nothing is written into the repository.
96
-
97
- After a pass, the Knowledge view shows what happened to each undetermined file. Files with a problem are at the top of the list:
98
-
99
- - **failed**: the request did not succeed. The row gives the reason. The file keeps the local result, and the next pass sends it again.
100
- - **not asked**: sending stopped before this file. The row gives the reason.
101
- - **unreadable**: the workspace could not read Jev's answer. The file is not sent again until it changes.
102
- - **unsure**: Jev was not sure. The row names the two categories, and the file stays `undetermined`.
103
- - **withheld** or **excluded**: the file was not sent. The row says why.
104
- - **categorized**: Jev gave a category. The row names it.
105
-
106
- A line above the list counts the files in the view: decided by the local rules or your corrections, categorized by Jev, and still `undetermined`.
107
-
108
- If the service rejects the key two times, cannot be reached three times in a row, or sends three answers in a row that the workspace cannot read, sending stops for this repository. An answer that cannot be read is not sent again. Press **resume** to start again.
71
+ The Knowledge view is cut, so no screen lists the category of a document. The category is advisory. `pmos kg stats` counts the files in each category, and the Knowledge scope of ⌘K finds a document by its name.
109
72
 
110
73
  ### Measure how well Jev categorizes
111
74
 
112
75
  The measured pass sends the files of the labelled set to Jev and compares the answers with the labels. It runs only when you start it in a terminal. The workspace never starts it.
113
76
 
114
- The measured pass also sends labelled files that a local rule already decides, because it measures Jev on them. It does not send a file that you corrected. The three switches, the excluded paths and the password and key check apply as for the Knowledge view.
77
+ The measured pass also sends labelled files that a local rule already decides, because it measures Jev on them. It does not send a file that you corrected. The switches for the repository, the excluded paths and the password and key check apply to it.
115
78
 
116
79
  1. Run `node workspace/doc-category-bench.js --jev`. It shows how many files it would send, about how many characters, the host, and a `--confirm` value. It sends nothing.
117
80
  2. Read which categories the labelled set cannot test. When a category has no label in the set, the result says nothing about that category.
118
81
  3. To send, run the command again with `--confirm` and the value it showed, for example `--confirm 40:372a…`. The value holds the count and the files. If the files changed, nothing is sent and you look again.
119
82
 
120
- It uses the key that you saved on the Validate page, or `TYPESAFE_API_KEY` in the terminal. It prints the agreement, each category, how many answers were unsure, how many files were not sent and why, and every disagreement. The labels in the set are not yet confirmed, so the result is provisional. Only one pass at a time runs for a repository. If the workspace is sending, the command stops and sends nothing.
121
-
122
- ### Correct a category
123
-
124
- When a category is wrong, set the correct one. Your correction comes before all five rules.
125
-
126
- 1. In the Knowledge view, press **fix** at the end of the document row.
127
- 2. Select the category. For a `ticket`, also select the ticket kind.
128
- 3. Press **save correction**.
129
-
130
- The category after the document name changes. Point at it: it says `decided by pm correction`. When a rule gives a different category, the text names that rule too.
131
-
132
- The workspace keeps your corrections in its runtime state directory, never in the repository. Each repository has its own corrections. A correction does not change a file. To remove a correction, press **fix** and then **clear correction**. The rules then decide again.
133
-
134
- ### Write the category into the file
135
-
136
- You can also write the category into the document, as a `category:` line in its frontmatter. This is a separate step, and it is the only step here that changes a file.
137
-
138
- 1. Press **fix** and select the category.
139
- 2. Press **write it into the file**. The workspace shows the change. It does not write yet.
140
- 3. Examine the change. Press **apply** to write it, or **cancel**.
141
-
142
- The workspace changes one `category:` line in the frontmatter block at the top of the file. For a ticket, it also changes one `ticket_kind:` line. It adds the line when there is none. No other line of the file changes.
143
-
144
- The workspace does not write when:
145
-
146
- - The file has no frontmatter block at the top. It does not add a block.
147
- - The frontmatter has two `category:` lines.
148
- - The file changed after the workspace showed you the change. Press **write it into the file** again to see the new change.
83
+ It uses the key that you saved on the Validate page (Settings › Validate consent › Open Validate), or `TYPESAFE_API_KEY` in the terminal. It prints the agreement, each category, how many answers were unsure, how many files were not sent and why, and every disagreement. The labels in the set are not yet confirmed, so the result is provisional. Only one pass at a time runs for a repository. If the workspace is sending, the command stops and sends nothing.
149
84
 
150
85
  ## Where the map is kept
151
86
 
@@ -0,0 +1,51 @@
1
+ ---
2
+ type: Guide
3
+ title: "Start the workspace without a terminal"
4
+ timestamp: 2026-10-06
5
+ ---
6
+
7
+ # Start the workspace without a terminal
8
+
9
+ `pmos launcher` makes a PMOS app and a login item. After you set it up once, you do not need a terminal to start the workspace.
10
+
11
+ ## Set it up once
12
+
13
+ Open a terminal in the repository that the app must open. Type:
14
+
15
+ ```sh
16
+ pmos launcher on
17
+ ```
18
+
19
+ To set up a different repository, give its path: `pmos launcher on ~/code/my-product`.
20
+
21
+ This command writes two things:
22
+
23
+ | Thing | macOS | Linux |
24
+ |---|---|---|
25
+ | The PMOS app | `~/Applications/PMOS.app`. Open it from Spotlight or Launchpad, or drag it to the Dock. | An app menu entry, `~/.local/share/applications/pmos.desktop`. |
26
+ | The login item | `~/Library/LaunchAgents/com.pmos.workspace.plist` | `~/.config/autostart/pmos-workspace.desktop` |
27
+
28
+ To make only the app, without the login item, type `pmos launcher on --no-login`.
29
+
30
+ ## What each one does
31
+
32
+ - **The app** opens the workspace in your browser. When no server runs, it starts one first. It does the same thing as `pmos` in a terminal.
33
+ - **The login item** starts the workspace server when you log in. It does not open a browser window. Open the app when you want the window.
34
+
35
+ Both run `pmos up` on the repository you chose. They use the PATH that your terminal had when you typed `pmos launcher on`. That is how they find `claude`, `git` and `tmux`.
36
+
37
+ What each start printed is in `launcher.log`, in the workspace state folder (`~/Library/Application Support/pmos` on macOS, `~/.local/state/pmos` on Linux).
38
+
39
+ ## Check it
40
+
41
+ Type `pmos launcher status`. It shows the repository, the node program and the `pmos` program that the app uses, and whether the login item is installed. A path marked "not found" stops the app. If you move or upgrade node, type `pmos launcher on` again.
42
+
43
+ ## Remove it
44
+
45
+ Type `pmos launcher off`. It removes the app and the login item. It removes only files that `pmos launcher on` wrote. A file with the same name that you wrote yourself stays.
46
+
47
+ ## Limits
48
+
49
+ - The login item never starts remote (tailnet) mode, and it writes no token. To open the workspace from your phone, start remote mode yourself as `workspace/REMOTE.md` tells you.
50
+ - Native Windows is not supported. The workspace needs WSL on Windows. Type `pmos launcher on` inside WSL.
51
+ - The login item runs once, at login. If the server stops, open the app to start it again.
@@ -1,27 +1,105 @@
1
1
  ---
2
2
  type: Guide
3
3
  title: "Guide: layout"
4
- description: "The three workspace columns: navigation, detail and tabs, and what each one holds."
4
+ description: "The frame: one top bar, the place on screen, the detail and the agent dock; the phone tabs; the keys; and the older layout."
5
5
  timestamp: 2026-10-05
6
6
  ---
7
7
 
8
8
  # Guide: layout
9
9
 
10
- On a desktop screen the workspace has four columns. They are, from left to right, the repository rail, the list, the detail and the tabs. A phone, and the address option `?layout=legacy`, keep the older layout with three columns: navigation, detail and tabs. The rest of this page describes those three columns.
10
+ On a desktop screen the workspace is one frame. It has one top bar, the place on screen under it, the detail when you open one, and the agent dock at the right. There is no left sidebar.
11
11
 
12
- ## The repository rail, the list and the tools
12
+ ## The top bar
13
13
 
14
- The rail is 64 pixels wide and shows one tile for each repository. A dot on a tile means that repository has something that needs you. The selected repository has no dot, because the list beside it shows what needs you. The `+` tile adds a repository and the menu button opens the tools: knowledge, memory, skills, scheduled tasks, validate, the guide and the others.
14
+ The top bar has these parts, from left to right:
15
15
 
16
- A tool opens as a tab, not in place of the list. Choose the same tool again and the existing tab comes to the front.
16
+ - **Repository ▾** names the current repository. Press it to choose another repository, or **All repositories** to see the work of every repository at once. All repositories replaces the old Portfolio mode.
17
+ - **Today, Initiatives, Board and Reports** are the four places. Press one to show it. The Today count shows how many items need you.
18
+ - **Search or capture ⌘K** opens the command palette. Type to find an initiative, a repository, an open tab or a command.
19
+ - **Sync** shows only when the current repository is not in sync with its remote. Press it to fetch, bring in the work of the other machine, record your changes and push. When the repository is in sync, Sync is not shown.
20
+ - **Settings** opens the settings of the workspace.
17
21
 
18
- Press ⌘K (Ctrl-K) to jump to anything: an initiative, a repository, an open tab, a session or a tool. Type to filter, use the arrow keys to choose, and press Enter. Esc closes it.
22
+ Each place is drawn when its run is built. Until then the place says which run brings it, for example "Board arrives in Run 4."
23
+
24
+ ## Settings
25
+
26
+ Settings holds settings only, in five sections:
27
+
28
+ - **Repositories**: every registered repository. Press a repository to make it the current one. Press its ⋯ for **Rename** or **Remove from PMOS**. Each asks in a sheet, and a remove asks you to confirm. **Add repository** shows the scan of a folder before you add it.
29
+ - **Profiles**: the Claude profiles a session can start with. They open in the detail.
30
+ - **New sessions**: the default CLI and the default model for a new session in the dock.
31
+ - **Validate consent**: the consent of the current repository. Turn it on or off here. **Open Validate** opens the Validate page as a tab.
32
+ - **Theme**: Dark or Light.
33
+
34
+ Your work is never in Settings. It is in Today, Initiatives, Board and Reports.
35
+
36
+ ## The agent dock
37
+
38
+ The dock holds your terminals, documents, conversations, skills and web pages. It is open on Today. On every other place it is a 44-pixel rail at the right edge.
39
+
40
+ - Press ⌘J (Ctrl-J), or the button on the rail, to open the dock. Press ⌘J again, or the fold button in the dock, to fold it to the rail.
41
+ - The dock never opens by itself. A tab that opens while the dock is a rail waits in the dock until you open it.
42
+ - **+ Session** in the dock starts a new session. Its menu also has **Session with options** and one item for each skill of the repository. A skill opens in its own tab in the dock.
43
+ - The Web button in the dock opens a web page in a tab.
44
+ - To make the dock wider or narrower, drag its left edge. With the edge focused, the left and right arrow keys change the width in steps. Double-click the edge to go back to the default width. The width is kept in this browser.
45
+ - **Focus** in the dock gives the dock the whole window. The place and the detail are hidden, and the dock stays full width on every place. Press **Exit focus**, or ⌘⇧J (Ctrl-Shift-J), to show the place again. Folding the dock also ends Focus.
46
+ - **▲ scratchpad** in the bar under the tabs opens the scratchpad. The pad keeps one note for each terminal session, and one for the repository when no terminal is in front. **Send to terminal** types the note into the session in front.
47
+
48
+ Folding the dock, or going to another place, does not touch your terminals.
49
+
50
+ ## The detail
51
+
52
+ The detail shows one item in full, for example an initiative or the profiles. It opens as a column between the place and the dock when you open an item. Press × at its top, or press Esc, to close it.
53
+
54
+ ## Questions
55
+
56
+ When the workspace needs an answer from you, for example the name for a rename or a confirmation before a remove, it opens a sheet. A sheet has a title, the question, and two buttons: the one that does it and **Cancel**. Esc, the close button and a press outside the sheet all mean Cancel. The workspace never uses the browser's own dialogs.
57
+
58
+ ## Colour and size
59
+
60
+ The workspace is neutral. A primary button is the text colour on the page colour, in both themes. The one brand colour marks the Today dot and the Today count, and nothing else. The bar, the dock and the bottom bar follow the theme; only a terminal stays dark. Corners are square. Controls are icons from one set, not text symbols. On a touch screen every field is 16 pixels, so the phone does not zoom when you tap it, and every control is at least 44 pixels high.
19
61
 
20
- Press ⌘↵ (Ctrl-Enter) to enter Focus. The rail and the list go out of view, the active tab takes the width, and the detail stays as a narrow slice on the right. Press Esc or Navigate to return. Focus does not restart a terminal.
62
+ ## Keys
21
63
 
22
- Today is a tool tab. It shows what needs you, with an action and a reason to dismiss each item, what is being prepared, and a Repository / All switch.
64
+ | Key | What it does |
65
+ |---|---|
66
+ | g t, g i, g b, g r | Show Today, Initiatives, Board or Reports. |
67
+ | ⌘K (Ctrl-K) | Open or close the command palette. |
68
+ | ⌘J (Ctrl-J) | Open or fold the dock. |
69
+ | ⌘⇧J (Ctrl-Shift-J) | Focus: give the dock the whole window, or show the place again. |
70
+ | j, k | Move down or up the rows of the place. |
71
+ | Enter | Open the row that has the focus. |
72
+ | Space | Tick the row. Space never opens a row. On another button of the row, for example ⋯, Space presses that button. |
73
+ | a | Do the main action of the row, when the row has one. |
74
+ | x | Dismiss the row, when the row can be dismissed. |
75
+ | Alt-Up, Alt-Down | Move the row up or down, when the row can move. |
76
+ | Esc | Close the palette, then the detail. In the open dock, Esc closes the tab in front. After a click in the place or the detail, Esc does not close a tab. |
23
77
 
24
- Each tool tab shows a board: Today, All repos, Knowledge, Memory, Skills, Scheduled tasks, Validate, the guide and Reports. Reports is in the menu, under Library, and lists only the run reports that exist. If a part of a board has no data behind it, the board does not show that part, or it says that the data is not read.
78
+ A key that you type in a field, or in a terminal, goes to the field or the terminal.
79
+
80
+ ## On a phone
81
+
82
+ A phone shows one panel at a time. The tabs at the bottom are **Today, Initiatives, Board, Reports and Agent**. Agent shows the dock, with your terminals. Search or capture ⌘K is pinned at the top of Today.
83
+
84
+ The bar at the top has Back (when you are deeper than a tab), Repository, the name of the screen, ⌘K, Sync (only when the repository is not in sync) and Settings. Settings opens over the current tab. Back returns to the tab.
85
+
86
+ Every row has a visible ⋯ button. Every control is at least 44 pixels high. Nothing works only when you hover.
87
+
88
+ ## The older layout
89
+
90
+ The address options `?layout=legacy` and `?fixture=cockpit` keep the older layouts. The rest of this page describes them. In the cockpit, the workspace has four columns: the repository rail, the list, the detail and the tabs. With `?layout=legacy` it has three columns: navigation, detail and tabs.
91
+
92
+ ### The repository rail, the list and the tools
93
+
94
+ The rail is 64 pixels wide and shows one tile for each repository. A dot on a tile means that repository has something that needs you. The selected repository has no dot, because the list beside it shows what needs you. The `+` tile adds a repository. The rail has no tools menu: the repository list and Validate are in Settings, and everything else is in ⌘K.
95
+
96
+ Today, Validate, live notes and Add repository open as a tab, not in place of the list. Choose the same one again and the existing tab comes to the front.
97
+
98
+ Press ⌘K (Ctrl-K) to jump to anything: an initiative, a repository, an open tab, a session or a tool. Type to filter, use the arrow keys to choose, and press Enter. Esc closes it.
99
+
100
+ In the older layouts, Today is a tab. It shows what needs you, with an action and a reason to dismiss each item, what is being prepared, and a Repository / All switch.
101
+
102
+ If a part of a board has no data behind it, the board does not show that part, or it says that the data is not read.
25
103
 
26
104
  The `+` tile on the rail opens Add repository as a tab. The tab shows the scan of the folder before you add it.
27
105
 
@@ -37,23 +115,23 @@ Each tab shows a dot, its title and, under the title, its initiative and its ses
37
115
 
38
116
  If many tabs are open, the strip stays one row and scrolls sideways. Use the mouse wheel on the strip to scroll it. The tab in front always scrolls into view. Press `⇅ tabs at side` to show the tabs as a list down the left of the tabs column. In the list, each tab is one row, with its title, its initiative and session, and ×. The `+ session` button is at the top of the list, and the other controls are at the bottom. Press `⇆ tabs on top` to go back to the strip. The workspace remembers your choice in this browser. A phone and `?layout=legacy` always show the strip.
39
117
 
40
- ## Navigation
118
+ ### Navigation
41
119
 
42
- The first column holds the list of repositories. Under it is the list for the current mode. When you choose a repository, its initiatives appear there. When you choose an item in the settings and tools drawer, its list replaces the initiatives. Choose a repository again to return to its initiatives.
120
+ The first column holds the list of repositories. Under it is the list for the current mode. When you choose a repository, its initiatives appear there.
43
121
 
44
122
  If you have many repositories, the repository list scrolls inside its own space. The list under it stays on screen.
45
123
 
46
124
  Drag the right edge of the column to change its width. Double-click the edge to restore the default width.
47
125
 
48
- ## Detail
126
+ ### Detail
49
127
 
50
- The second column shows one item in full. Choose an initiative, a skill, a schedule or a memory item, and its detail opens here.
128
+ The second column shows one item in full. Choose an initiative or the profiles, and its detail opens here.
51
129
 
52
- ## Tabs
130
+ ### Tabs
53
131
 
54
132
  The third column holds your terminals, documents, conversations and guide pages. Folding or resizing the other columns does not touch your terminals.
55
133
 
56
- ## Open a file
134
+ ### Open a file
57
135
 
58
136
  Press a file anywhere in the workspace to open it in a tab. Any text file opens, whatever its extension.
59
137
 
@@ -67,30 +145,22 @@ A tab for a file that is not markdown is read-only. It has no edit, diff or save
67
145
 
68
146
  If a file cannot be shown, the tab says why. The reasons are: the file is binary, it is larger than 2 MB, it is not valid text, or it is outside the workspace.
69
147
 
70
- ## The rule for where things open
148
+ ### The rule for where things open
71
149
 
72
150
  A list or a directory opens in the navigation column, under the repository list. A detail opens in the detail column. A file-like row opens in a tab, as any document does.
73
151
 
74
152
  | Item | Kind | Opens in |
75
153
  |---|---|---|
76
154
  | Initiatives | list | navigation |
77
- | Memory | list | navigation |
78
- | Knowledge | list | navigation |
79
- | Portfolio | list | navigation |
80
- | Guide | list | navigation |
81
155
  | Validate | list | navigation |
82
- | Today | list | navigation |
83
- | Focus | list | navigation |
84
- | Skills | list | navigation |
85
- | Scheduled tasks | list | navigation |
86
156
 
87
157
  What a row in a list opens:
88
158
 
89
- - A row in Initiatives, Portfolio or Focus opens the initiative in the detail column.
90
- - A row in Skills, Knowledge, Guide or Validate opens the file in a tab, beside your terminals.
91
- - Scheduled tasks, Memory and Today are used inside the list. They have no separate detail.
159
+ - A row in Initiatives opens the initiative in the detail column.
160
+ - Validate opens as a tab, beside your terminals.
161
+ - A Knowledge, Memory or Guide result in ⌘K opens a document in a tab, or a memory entry in a sheet.
92
162
 
93
- ## Folding
163
+ ### Folding
94
164
 
95
165
  On a desktop screen, the list and the detail each have a `⟨` button. The list's button is at the right of `+ New initiative`. The detail's button is at its top right. Press it to fold that column to a thin strip. Press the strip to open the column again. The rail does not fold.
96
166
 
@@ -102,10 +172,10 @@ In the older layout:
102
172
 
103
173
  The workspace remembers which columns are open and how wide the navigation column is.
104
174
 
105
- ## Light theme
175
+ ### Light theme
106
176
 
107
- In the light theme, the tabs column stays dark, because a terminal is dark in both themes. The tab strip and the bar under the tabs use light text on that dark band.
177
+ In the light theme, the whole workspace is light: the top bar, the dock, the tab strip and the bar under the tabs follow the theme. Only the terminal stays dark, because a terminal is dark in both themes.
108
178
 
109
- ## On a phone
179
+ ### On a phone
110
180
 
111
- A phone shows one panel at a time. The bottom bar moves between them.
181
+ In the older layouts, a phone also shows one panel at a time. The tabs at the bottom move between them.
@@ -12,7 +12,7 @@ The Live notes view takes notes during a meeting. Each thing that is said become
12
12
  ## Open the view
13
13
 
14
14
  1. Select the repository in the navigation column.
15
- 2. Open the menu and select **live notes** under **Library**. The view opens as a tab for that repository.
15
+ 2. Press ⌘K, type **live notes** and press Enter. The view opens as a tab for that repository.
16
16
  3. Press **New session**. A session is one meeting.
17
17
 
18
18
  If the repository has more than 255 open initiatives, the view asks you to select an anchor first. The session then uses only the initiatives of that anchor.
@@ -57,8 +57,8 @@ A point that looks like a secret, such as a key or a token, is withheld. The vie
57
57
 
58
58
  Jev checks a point only when all three of these are true:
59
59
 
60
- 1. A TypeSafe key is saved (open **validate** in the settings and tools drawer).
61
- 2. Validation is turned on for this repository (also under **validate**).
60
+ 1. A TypeSafe key is saved (open Settings, then **Open Validate** under Validate consent).
61
+ 2. Validation is turned on for this repository (also in Settings, under Validate consent).
62
62
  3. **Check with Jev** is on in the Live notes view. It applies to this repository only.
63
63
 
64
64
  If one is missing, the view says which one, in words.
@@ -0,0 +1,89 @@
1
+ ---
2
+ type: Guide
3
+ title: "PM-only acts: what only you can do"
4
+ description: "Which acts only the PM can do, how the workspace checks that a press comes from your page or your terminal, what to do when a press is refused, and what an agent can and cannot write."
5
+ timestamp: 2026-10-05
6
+ ---
7
+
8
+ # PM-only acts: what only you can do
9
+
10
+ Some acts decide what the work is and when it is done. Only you, the PM, can do them. An agent cannot do them, even when you ask it to in a chat.
11
+
12
+ ## The acts
13
+
14
+ | Act | Where you do it |
15
+ |---|---|
16
+ | Accept a run, approve or return a review, approve a document | Not on the page yet. In your own terminal, run `node scripts/record-acceptance.js`. |
17
+ | Accept or send back a step that an agent ran | Not on the page yet. A later run adds it. |
18
+ | Approve a contract | Not on the page yet. In your own terminal, run `node scripts/log-run.js` with `PM_approved: true` in the contract. |
19
+ | Record a D60 disposition of a prototype | Not on the page yet. A later run adds it. |
20
+ | Hold, close, cancel or reopen an initiative | The initiative's lifecycle menu |
21
+ | Keep the items an agent proposed | The Keep card in the Breakdown or on Today |
22
+ | Move an initiative to Now, or adopt an agent's proposal to move it | Initiatives (arrives with the Initiatives screen) |
23
+ | Change the anchor (`parent_kr`) of an initiative | The document editor, or the confirm step of Add a repository |
24
+ | Bind a session to an initiative | The session's initiative menu, or + session on an initiative |
25
+ | Issue a report | Reports (arrives in Run 5) |
26
+ | Release a batch of factory work | The Board (arrives in Run 4) |
27
+
28
+ Each line that the workspace server writes for one of these acts says who wrote it (`by: pm:wawan`) and how (`via: ui` from the page, `via: cli` from a terminal).
29
+
30
+ ## How the workspace checks a press
31
+
32
+ When the workspace server starts, it makes a new random value for this launch. It puts the value in the page that it serves to your browser. It does not put the value in any terminal session, and it does not write the value to a log.
33
+
34
+ Each press from the page sends three things: the page's own address (the Origin), the launch value, and the request. The server refuses the press when:
35
+
36
+ - the request has no Origin, or the Origin is a different site or a different port;
37
+ - the launch value is missing or wrong.
38
+ The server also refuses a request that sets a field that only the server sets, for example `by`, `via`, `at` or `grant`.
39
+
40
+ A press that is refused writes nothing.
41
+
42
+ The terminal on the page sends the launch value when it connects. A session that you start with + session on an initiative is bound to that initiative only when the value is correct. If it is not correct, the session starts without an initiative and the terminal says why.
43
+
44
+ ### When a press is refused
45
+
46
+ If the workspace started again after you opened the page, the page reads the new launch value and sends your press again, one time. You do not have to do anything.
47
+
48
+ If a press shows "the workspace restarted, so reload the page, then try again", reload the page, then press again.
49
+
50
+ ## Acts from a terminal
51
+
52
+ A command that does a PM-only act asks you to type a word first, usually the initiative id. Type the id exactly, then press Enter. If the text does not match, the command writes nothing.
53
+
54
+ The command refuses the act when:
55
+
56
+ - it runs inside an agent session (the session has a `PMOS_SESSION` value);
57
+ - it does not run in an interactive terminal, for example in a pipe or a script.
58
+
59
+ Any other command that runs without a terminal is recorded as `agent:unknown`, not as you.
60
+
61
+ ## Change many initiatives at once
62
+
63
+ You can change the lifecycle of up to 20 initiatives in one press. The press makes one grant for the change, and each lifecycle line names that grant. Until the grant writer is available, the workspace refuses the press and writes nothing.
64
+
65
+ You cannot move initiatives to Now or change an anchor in one press for many initiatives. Do these one at a time.
66
+
67
+ ## What an agent can write
68
+
69
+ An agent can:
70
+
71
+ - add items, and order, date, start and finish the items of its session (with evidence);
72
+ - move an item that you handed to that session with Hand to agent. It cannot move any other item that you own;
73
+ - create an initiative (it lands in Later), write report text, and record a measurement with a source;
74
+ - propose a change for you to keep or drop.
75
+
76
+ An agent cannot:
77
+
78
+ - do any act in the table above;
79
+ - change the title, stage, dates or owner of an item that you own (owner "you"), or mark it blocked. It asks you instead;
80
+ - withdraw an item that it did not add.
81
+
82
+ ## What this does not prevent
83
+
84
+ A program that runs as your own user can read the page, as your browser does, and send a press. A program that fakes a terminal can type the id. The workspace closes the paths that an agent's tools use by default.
85
+
86
+ Some paths are still open:
87
+
88
+ - A program can connect to the terminal socket without the launch value. It cannot bind a session to an initiative, but it can start a session and type into any terminal, including your own shell. A `pmos` command that it types in your shell runs as you.
89
+ - An agent's `pmos item` commands are not yet checked against the initiative that its session is bound to, and a session value that names no session is not refused. The repository's checks find the other lines later, when they reach a pull request. See [Breakdown](breakdown.md) for the items and the Keep card.
@@ -0,0 +1,61 @@
1
+ ---
2
+ type: Guide
3
+ title: "PM-only lines: how the workspace checks your acts"
4
+ description: "Which acts only you can do, how each one is recorded, what the Today card 'A PM-only line is not attested' means, what to do about it, and the grants for a bulk lifecycle change and a Release."
5
+ timestamp: 2026-10-05
6
+ ---
7
+
8
+ # PM-only lines: how the workspace checks your acts
9
+
10
+ Some acts are yours only. An agent can propose them, but it cannot do them. These acts are PM-only:
11
+
12
+ - Move to Now, and adopt an agent's proposal.
13
+ - Issue a report.
14
+ - Accept a run, approve or return a review, approve a document or a contract, and record a D60 disposition.
15
+ - Change the lifecycle of an initiative.
16
+ - Change the anchor of an initiative.
17
+ - Keep the items that an agent proposed.
18
+ - Release a factory batch.
19
+
20
+ Each act adds one line to a ledger in the repository. The line records who did the act (`by`) and how (`via`). `via` is `ui` for a press in the workspace and `cli` for a command that you confirm at your own terminal.
21
+
22
+ ## How the acts are protected
23
+
24
+ - **In the workspace.** A press sends a value that the workspace makes each time it starts. A request without it is refused.
25
+ - **At a terminal.** A PM-only `pmos` command asks you to type a confirmation. An agent's tool has no terminal, so the command refuses it.
26
+ - **In an agent session.** The cockpit mod stops an agent that calls a PM-only route, runs a PM-only `pmos` command, or loads a ledger's writer from its own code.
27
+ - **In CI.** The Initiative Gate runs `scripts/check-pm-lines.js`. It fails on a PM-only line that is not attested (see below). It needs the full git history: on a shallow clone it fails and asks for `fetch-depth: 0`.
28
+
29
+ These checks find a forged line. They do not make a forgery impossible. A program that runs as your own user can still write a line that looks like yours.
30
+
31
+ ## The Today card "A PM-only line is not attested"
32
+
33
+ Today shows a needs-repair card for each PM-only line that fails a check. The card names the file and the line number, for example `planning/runs/placements.jsonl line 12`. Press **Show line** to see the line. The cause is one of these:
34
+
35
+ | Cause | What it means | What to do |
36
+ |---|---|---|
37
+ | … has no via | The line was written after `via_required_from` and does not say how. A writer always adds `via`, so a person or a program added the line by hand. | If you did the act, do it again from the workspace or the terminal, then remove the hand-written line in a commit. If you did not do it, remove the line. |
38
+ | … cites a grant that grants.jsonl does not hold | The line names a grant that does not exist. | Remove the line. Do the act again; the press mints a new grant. |
39
+ | … cites a grant that does not cover it | The grant exists, but it is for a different act: another scope, another state or initiative, or a time outside the grant's 120 minutes. | Remove the line. Do the act again; the press mints a new grant. |
40
+ | … is written by an agent | A line that only you may write has an agent in `by`. An agent's placement is always a proposal. | Remove the line. If you agree with the change, make it yourself. |
41
+ | … arrived in an agent-authored commit | A commit by an agent added a PM-only line. This is how a line that a script wrote, or a patch added with `git apply`, arrives. | Look at the commit. If the act is yours, commit the ledger line yourself, without an agent trailer. Otherwise remove the line. |
42
+
43
+ A line can have more than one cause. The card then lists each one.
44
+
45
+ ## Older lines
46
+
47
+ `via_required_from` in `planning/plan-rules.json` is the time from which a PM-only line must say how it was written. Lines written before that time have no `via`. The gate counts them once for each file and does not fail on them. A line counts as older only when both of these are true:
48
+
49
+ - Its own time is before `via_required_from`.
50
+ - The commit that added it comes before the commit that set `via_required_from`, in the git history.
51
+
52
+ The gate does not use the dates of a commit, because the person or program that makes a commit can set them. While the value is `null`, every line counts as older.
53
+
54
+ ## Grants for a bulk change and a Release
55
+
56
+ Some presses mint a grant: your permission for one action, used once, for 120 minutes.
57
+
58
+ - **A bulk lifecycle change.** In the Initiatives list, select up to 20 initiatives and change their lifecycle. The press mints one `lifecycle-bulk` grant that names the state and each initiative. Each lifecycle line cites that grant. Move to Now and an anchor change are never bulk acts.
59
+ - **A Release.** A Release of a factory batch mints one `release` grant for that batch.
60
+
61
+ To mint a grant at a terminal in a cockpit session, type `/pmos-grant release:<initiative>:<batch-id>` or `/pmos-grant lifecycle-bulk:<state>:<id>,<id>`. The state is one of `active`, `closed`, `on-hold` and `cancelled`.