@zalom/plastic 2.0.0-alpha.9 → 2.0.2

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 (326) hide show
  1. package/PLASTIC.md +13 -136
  2. package/README.md +357 -133
  3. package/agents/plastic-enforcer.md +21 -16
  4. package/agents/plastic-executor.md +15 -4
  5. package/agents/plastic-node-research.md +30 -0
  6. package/agents/plastic-node-verify.md +28 -0
  7. package/agents/plastic-node-work.md +33 -0
  8. package/agents/{plastic-advisor.md → plastic-primary-advisor.md} +7 -9
  9. package/agents/{plastic-faux-advisor.md → plastic-secondary-advisor.md} +9 -12
  10. package/assets/plastic-logo.svg +1 -0
  11. package/bin/crap +4 -0
  12. package/bin/lib/context_budget.rb +43 -6
  13. package/bin/lib/skill_census.rb +839 -0
  14. package/bin/plastic +8 -0
  15. package/bin/plastic-skill-census +114 -0
  16. package/bin/test +24 -4
  17. package/bin/verify-change +345 -0
  18. package/config_asks.yml +4 -4
  19. package/deprecations.yml +1 -1
  20. package/{skills/agent-advisor/references → docs/help}/advisor-protocol.md +19 -24
  21. package/{skills/auto/references → docs/help}/agent-architecture.md +16 -14
  22. package/docs/help/completion-and-done.md +53 -0
  23. package/docs/help/human-report-contract.md +152 -0
  24. package/{skills/conventions/references → docs/help}/knowledge-graph.md +9 -0
  25. package/{skills/conventions/references → docs/help}/locks-and-worktrees.md +11 -13
  26. package/{skills/conventions/references → docs/help}/maintenance-and-revisions.md +1 -1
  27. package/{skills/conventions/references → docs/help}/roadmaps.md +5 -4
  28. package/{skills/tutorial/references → docs/help}/track-1-guided.md +28 -47
  29. package/{skills/tutorial/references → docs/help}/track-2-auto.md +8 -8
  30. package/{skills/tutorial/references → docs/help}/track-3-projects-and-roadmaps.md +24 -17
  31. package/hooks/call-budget +4 -0
  32. package/hooks/hooks.json +24 -0
  33. package/hooks/message-display +55 -2
  34. package/hooks/session-start +5 -1
  35. package/hooks/statusline +32 -27
  36. package/hooks/stop +5 -0
  37. package/package.json +5 -3
  38. package/scripts/append-ledger +2 -1
  39. package/scripts/dashboard.rb +267 -16
  40. package/scripts/day-summary +2 -1
  41. package/scripts/doctor.rb +680 -39
  42. package/scripts/end-intent +378 -56
  43. package/scripts/exec-worktree +5 -5
  44. package/scripts/file-session-intent +2 -1
  45. package/scripts/graph-measure +249 -0
  46. package/scripts/hook-call-budget +222 -0
  47. package/scripts/hook-capture +24 -123
  48. package/scripts/hook-close +2 -1
  49. package/scripts/hook-message-display +7 -0
  50. package/scripts/hook-record +24 -16
  51. package/scripts/hook-savepoint +27 -3
  52. package/scripts/hook-session-start +359 -321
  53. package/scripts/hook-stop +58 -0
  54. package/scripts/index-projection +74 -0
  55. package/scripts/insight-append +17 -4
  56. package/scripts/install.rb +9 -7
  57. package/scripts/lib/action_graph_shim.rb +279 -0
  58. package/scripts/lib/active_delivery.rb +105 -0
  59. package/scripts/lib/agent_models.rb +63 -25
  60. package/scripts/lib/arm.rb +74 -91
  61. package/scripts/lib/atomic_write.rb +31 -0
  62. package/scripts/lib/backup.rb +65 -0
  63. package/scripts/lib/cli/command.rb +92 -0
  64. package/scripts/lib/cli/commands/auto.rb +18 -0
  65. package/scripts/lib/cli/commands/auto_brief.rb +44 -0
  66. package/scripts/lib/cli/commands/auto_lock.rb +111 -0
  67. package/scripts/lib/cli/commands/auto_report.rb +50 -0
  68. package/scripts/lib/cli/commands/auto_take.rb +68 -0
  69. package/scripts/lib/cli/commands/backup.rb +43 -0
  70. package/scripts/lib/cli/commands/checkout.rb +25 -0
  71. package/scripts/lib/cli/commands/continue.rb +66 -0
  72. package/scripts/lib/cli/commands/doctor.rb +81 -0
  73. package/scripts/lib/cli/commands/feedback.rb +40 -0
  74. package/scripts/lib/cli/commands/help.rb +69 -0
  75. package/scripts/lib/cli/commands/hook.rb +32 -0
  76. package/scripts/lib/cli/commands/index.rb +23 -0
  77. package/scripts/lib/cli/commands/install.rb +21 -0
  78. package/scripts/lib/cli/commands/installer_verb.rb +37 -0
  79. package/scripts/lib/cli/commands/intent.rb +19 -0
  80. package/scripts/lib/cli/commands/intent_answer.rb +37 -0
  81. package/scripts/lib/cli/commands/intent_command.rb +58 -0
  82. package/scripts/lib/cli/commands/intent_end.rb +75 -0
  83. package/scripts/lib/cli/commands/intent_new.rb +62 -0
  84. package/scripts/lib/cli/commands/intent_note.rb +43 -0
  85. package/scripts/lib/cli/commands/intent_rule.rb +36 -0
  86. package/scripts/lib/cli/commands/intent_show.rb +32 -0
  87. package/scripts/lib/cli/commands/intent_spec.rb +44 -0
  88. package/scripts/lib/cli/commands/intent_step.rb +79 -0
  89. package/scripts/lib/cli/commands/intent_verify.rb +26 -0
  90. package/scripts/lib/cli/commands/migrate.rb +16 -0
  91. package/scripts/lib/cli/commands/migrate_stores.rb +31 -0
  92. package/scripts/lib/cli/commands/next.rb +54 -0
  93. package/scripts/lib/cli/commands/project.rb +19 -0
  94. package/scripts/lib/cli/commands/project_links.rb +46 -0
  95. package/scripts/lib/cli/commands/project_list.rb +20 -0
  96. package/scripts/lib/cli/commands/project_new.rb +95 -0
  97. package/scripts/lib/cli/commands/query.rb +31 -0
  98. package/scripts/lib/cli/commands/render.rb +35 -0
  99. package/scripts/lib/cli/commands/roadmap.rb +19 -0
  100. package/scripts/lib/cli/commands/roadmap_check.rb +54 -0
  101. package/scripts/lib/cli/commands/roadmap_log.rb +54 -0
  102. package/scripts/lib/cli/commands/roadmap_migrate.rb +53 -0
  103. package/scripts/lib/cli/commands/roadmap_next.rb +77 -0
  104. package/scripts/lib/cli/commands/roadmap_show.rb +65 -0
  105. package/scripts/lib/cli/commands/rollback.rb +20 -0
  106. package/scripts/lib/cli/commands/search.rb +60 -0
  107. package/scripts/lib/cli/commands/session.rb +18 -0
  108. package/scripts/lib/cli/commands/session_commit.rb +42 -0
  109. package/scripts/lib/cli/commands/session_handoff.rb +34 -0
  110. package/scripts/lib/cli/commands/session_summary.rb +35 -0
  111. package/scripts/lib/cli/commands/status.rb +68 -0
  112. package/scripts/lib/cli/commands/subcommand_list.rb +36 -0
  113. package/scripts/lib/cli/commands/sync.rb +55 -0
  114. package/scripts/lib/cli/commands/uninstall.rb +20 -0
  115. package/scripts/lib/cli/commands/update.rb +20 -0
  116. package/scripts/lib/cli/commands/version.rb +53 -0
  117. package/scripts/lib/cli/frontier.rb +86 -0
  118. package/scripts/lib/cli/intent_progress.rb +36 -0
  119. package/scripts/lib/cli/legacy.rb +80 -0
  120. package/scripts/lib/cli/output.rb +137 -0
  121. package/scripts/lib/cli/scope.rb +134 -0
  122. package/scripts/lib/cli/table.rb +65 -0
  123. package/scripts/lib/cli.rb +94 -0
  124. package/scripts/lib/codex_adapter.rb +198 -0
  125. package/scripts/lib/compact_instructions.rb +13 -5
  126. package/scripts/lib/core_integrity.rb +71 -0
  127. package/scripts/lib/dashboard_screen.rb +40 -0
  128. package/scripts/lib/data_boundary.rb +132 -0
  129. package/scripts/lib/day_summary.rb +23 -14
  130. package/scripts/lib/doctor_core.rb +114 -38
  131. package/scripts/lib/doctor_session_ledger.rb +5 -53
  132. package/scripts/lib/engine_permissions.rb +88 -0
  133. package/scripts/lib/exec_worktree.rb +24 -21
  134. package/scripts/lib/feedback_report.rb +1 -1
  135. package/scripts/lib/graph_edges.rb +137 -0
  136. package/scripts/lib/graph_file.rb +246 -0
  137. package/scripts/lib/graph_measure.rb +645 -0
  138. package/scripts/lib/graph_measure_budget.rb +409 -0
  139. package/scripts/lib/graph_measure_cohorts.rb +487 -0
  140. package/scripts/lib/graph_measure_models.rb +413 -0
  141. package/scripts/lib/graph_measure_report.rb +532 -0
  142. package/scripts/lib/graph_tree.rb +98 -0
  143. package/scripts/lib/guarded_append.rb +155 -0
  144. package/scripts/lib/handoff.rb +40 -13
  145. package/scripts/lib/harness_adapter.rb +184 -0
  146. package/scripts/lib/hook_registry.rb +27 -3
  147. package/scripts/lib/hook_replay.rb +235 -0
  148. package/scripts/lib/index_entry.rb +62 -0
  149. package/scripts/lib/index_projection.rb +201 -0
  150. package/scripts/lib/insights.rb +1 -1
  151. package/scripts/lib/installer_core.rb +543 -71
  152. package/scripts/lib/intent_screen.rb +4 -4
  153. package/scripts/lib/intent_screen_ansi.rb +73 -12
  154. package/scripts/lib/intent_validator.rb +2 -2
  155. package/scripts/lib/lock.rb +10 -11
  156. package/scripts/lib/message_display.rb +350 -54
  157. package/scripts/lib/meter_watch.rb +185 -0
  158. package/scripts/lib/node_file.rb +234 -0
  159. package/scripts/lib/node_ids.rb +99 -0
  160. package/scripts/lib/node_input.rb +921 -0
  161. package/scripts/lib/node_input_compatibility.rb +62 -0
  162. package/scripts/lib/node_ledger.rb +386 -0
  163. package/scripts/lib/node_progress.rb +153 -0
  164. package/scripts/lib/node_return.rb +204 -0
  165. package/scripts/lib/node_worktree.rb +337 -0
  166. package/scripts/lib/outcome_report.rb +440 -0
  167. package/scripts/lib/preflight.rb +4 -6
  168. package/scripts/lib/project_config.rb +46 -0
  169. package/scripts/lib/project_validator.rb +3 -2
  170. package/scripts/lib/qmd_sync.rb +8 -7
  171. package/scripts/lib/ready_set.rb +462 -0
  172. package/scripts/lib/reference_archive.rb +45 -0
  173. package/scripts/lib/release_guard.rb +18 -0
  174. package/scripts/lib/report_screen.rb +1371 -47
  175. package/scripts/lib/rlm/corpus.rb +13 -0
  176. package/scripts/lib/rlm/probe.rb +29 -0
  177. package/scripts/lib/rlm/query.rb +22 -0
  178. package/scripts/lib/roadmap_graph.rb +210 -0
  179. package/scripts/lib/roadmap_migration.rb +95 -0
  180. package/scripts/lib/roadmap_queue.rb +170 -12
  181. package/scripts/lib/roadmap_render.rb +150 -0
  182. package/scripts/lib/roadmap_savepoint.rb +64 -14
  183. package/scripts/lib/runner_absorb.rb +703 -0
  184. package/scripts/lib/runner_answer.rb +206 -0
  185. package/scripts/lib/runner_core.rb +194 -0
  186. package/scripts/lib/runner_dispatch.rb +526 -0
  187. package/scripts/lib/runner_policy.rb +191 -0
  188. package/scripts/lib/runner_proposals.rb +275 -0
  189. package/scripts/lib/runner_rewind.rb +201 -0
  190. package/scripts/lib/runner_sweep.rb +231 -0
  191. package/scripts/lib/runner_until_empty.rb +252 -0
  192. package/scripts/lib/runner_watch.rb +389 -0
  193. package/scripts/lib/savepoint.rb +141 -19
  194. package/scripts/lib/scaffold_intent.rb +6 -3
  195. package/scripts/lib/screen_paint.rb +365 -28
  196. package/scripts/lib/screens/dashboard.rb +20 -0
  197. package/scripts/lib/screens/plan.rb +18 -0
  198. package/scripts/lib/screens/roadmap.rb +15 -0
  199. package/scripts/lib/search_index.rb +55 -0
  200. package/scripts/lib/session_close.rb +30 -28
  201. package/scripts/lib/session_git.rb +67 -19
  202. package/scripts/lib/session_ledger.rb +48 -4
  203. package/scripts/lib/session_usage.rb +190 -0
  204. package/scripts/lib/sqlite.rb +22 -0
  205. package/scripts/lib/stop_gate.rb +95 -0
  206. package/scripts/lib/store_discovery.rb +7 -6
  207. package/scripts/lib/store_layout.rb +54 -0
  208. package/scripts/lib/store_provisioning.rb +2 -1
  209. package/scripts/lib/store_sync.rb +85 -0
  210. package/scripts/lib/stores_move.rb +93 -0
  211. package/scripts/lib/untouched_scaffold.rb +51 -0
  212. package/scripts/lib/verify_intent.rb +36 -8
  213. package/scripts/lib/version_number.rb +48 -0
  214. package/scripts/lib/work_graph.rb +59 -0
  215. package/scripts/lib/work_graph_validator.rb +201 -0
  216. package/scripts/lib/worktree.rb +27 -32
  217. package/scripts/lib/worktree_sweep.rb +6 -5
  218. package/scripts/link-suggest +2 -1
  219. package/scripts/meter-watch +57 -0
  220. package/scripts/migrate-to-global +1 -1
  221. package/scripts/new-intent +4 -13
  222. package/scripts/node-input +92 -0
  223. package/scripts/node-run +225 -0
  224. package/scripts/node-transition +291 -0
  225. package/scripts/outcome-report +74 -0
  226. package/scripts/plastic-lock +65 -60
  227. package/scripts/project-links +6 -21
  228. package/scripts/promote-session-item +3 -2
  229. package/scripts/read-config +53 -9
  230. package/scripts/ready-set +126 -0
  231. package/scripts/release-check +123 -0
  232. package/scripts/report-screen +177 -16
  233. package/scripts/roadmap-graph +125 -0
  234. package/scripts/roadmap-savepoint +7 -0
  235. package/scripts/rollback.rb +5 -1
  236. package/scripts/runner +581 -0
  237. package/scripts/savepoint-note +11 -9
  238. package/scripts/session-commit +2 -1
  239. package/scripts/session-usage +56 -0
  240. package/scripts/skill-lint +115 -6
  241. package/scripts/spawn-preamble +2 -2
  242. package/scripts/update.rb +31 -4
  243. package/scripts/validate-work-graph +39 -0
  244. package/scripts/verify-intent +3 -2
  245. package/scripts/write-handoff +2 -1
  246. package/templates/agents.md +7 -7
  247. package/templates/config.yml +16 -9
  248. package/templates/dashboard-screen.md +22 -0
  249. package/templates/display-fixture.md +21 -0
  250. package/templates/graph.md +16 -0
  251. package/templates/index.md +1 -1
  252. package/templates/intent-screen.md +1 -1
  253. package/templates/node-decision.md +11 -0
  254. package/templates/node-research.md +13 -0
  255. package/templates/node-verify.md +13 -0
  256. package/templates/node-work.md +22 -0
  257. package/templates/outcome.md +8 -3
  258. package/templates/project.yml +1 -1
  259. package/templates/render.css +10 -0
  260. package/templates/report-plan.md +15 -0
  261. package/templates/report-roadmap-delivered.md +10 -0
  262. package/templates/report-roadmap-plan.md +9 -0
  263. package/templates/report-roadmap-state.md +9 -0
  264. package/templates/report-state.md +1 -1
  265. package/templates/roadmap.md +13 -0
  266. package/bin/plastic.js +0 -70
  267. package/scripts/lib/bridge.rb +0 -116
  268. package/skills/agent-advisor/SKILL.md +0 -92
  269. package/skills/auto/SKILL.md +0 -296
  270. package/skills/auto/evals/evals.json +0 -255
  271. package/skills/auto/references/end-tail.md +0 -66
  272. package/skills/auto/references/human-report-contract.md +0 -78
  273. package/skills/conventions/SKILL.md +0 -29
  274. package/skills/conventions/references/completion-and-done.md +0 -43
  275. package/skills/dashboard/SKILL.md +0 -169
  276. package/skills/dashboard/evals/evals.json +0 -38
  277. package/skills/dashboard/references/classification.md +0 -22
  278. package/skills/dashboard/templates/dashboard-global.md +0 -20
  279. package/skills/dashboard/templates/dashboard-project.md +0 -19
  280. package/skills/direct/SKILL.md +0 -66
  281. package/skills/direct/references/request-signals.md +0 -59
  282. package/skills/doctor/SKILL.md +0 -299
  283. package/skills/doctor/report.md +0 -102
  284. package/skills/feedback/SKILL.md +0 -98
  285. package/skills/feedback/references/transport-and-privacy.md +0 -65
  286. package/skills/feedback/report.md +0 -36
  287. package/skills/install/SKILL.md +0 -217
  288. package/skills/intent-continuing/SKILL.md +0 -154
  289. package/skills/intent-continuing/references/board-fill.md +0 -43
  290. package/skills/intent-continuing/references/boarding-matrix.md +0 -34
  291. package/skills/intent-continuing/references/context-management.md +0 -28
  292. package/skills/intent-continuing/references/liveness-ranking.md +0 -57
  293. package/skills/intent-creating/SKILL.md +0 -164
  294. package/skills/intent-creating/evals/evals.json +0 -72
  295. package/skills/intent-creating/references/lifecycle.md +0 -81
  296. package/skills/intent-creating/references/wikilinks.md +0 -8
  297. package/skills/intent-ending/SKILL.md +0 -176
  298. package/skills/intent-ending/evals/evals.json +0 -74
  299. package/skills/intent-executing/SKILL.md +0 -170
  300. package/skills/intent-executing/evals/evals.json +0 -66
  301. package/skills/intent-executing/implementer-prompt.md +0 -42
  302. package/skills/intent-executing/spec-reviewer-prompt.md +0 -27
  303. package/skills/intent-speccing/SKILL.md +0 -130
  304. package/skills/intent-speccing/evals/evals.json +0 -126
  305. package/skills/intent-speccing/references/design-principles.md +0 -44
  306. package/skills/intent-speccing/references/per-section-fill-rules.md +0 -92
  307. package/skills/intent-speccing/references/self-verify-checklist.md +0 -37
  308. package/skills/project-creating/SKILL.md +0 -162
  309. package/skills/project-creating/references/hubs-projects.md +0 -55
  310. package/skills/project-creating/references/project-scaffolding.md +0 -97
  311. package/skills/releasing/SKILL.md +0 -337
  312. package/skills/releasing/references/deprecations.md +0 -60
  313. package/skills/releasing/references/promotion-and-tagging.md +0 -66
  314. package/skills/releasing/references/release-lines.md +0 -105
  315. package/skills/roadmap/SKILL.md +0 -64
  316. package/skills/roadmap/references/file-format.md +0 -124
  317. package/skills/roadmap/references/operations.md +0 -112
  318. package/skills/rollback/SKILL.md +0 -91
  319. package/skills/tutorial/SKILL.md +0 -65
  320. package/skills/tutorial/evals/evals.json +0 -186
  321. package/skills/uninstall/SKILL.md +0 -75
  322. package/skills/update/SKILL.md +0 -126
  323. /package/{skills/auto/references → docs/help}/agent-report-contract.md +0 -0
  324. /package/{skills/intent-executing → docs/help}/code-quality-reviewer-prompt.md +0 -0
  325. /package/{skills/conventions/references → docs/help}/lifecycle-and-savepoints.md +0 -0
  326. /package/{skills/intent-executing → docs/help}/plan-reviewer-prompt.md +0 -0
@@ -1,4 +1,5 @@
1
1
  # encoding: UTF-8
2
+ require_relative "store_layout"
2
3
  # frozen_string_literal: true
3
4
  # IntentScreen (intent 316) - fills templates/intent-screen.md from one intent's
4
5
  # record: the intent file, the tier's INDEX.md, savepoint.md and checklist.md.
@@ -101,9 +102,8 @@ module IntentScreen
101
102
  # --- store ---------------------------------------------------------------------
102
103
 
103
104
  def self.store_fields(store_root)
104
- parent = File.basename(File.dirname(store_root))
105
- if parent == "projects"
106
- slug = File.basename(store_root)
105
+ slug = Plastic::StoreLayout.locate(File.join(store_root, "store")).last
106
+ if slug != Plastic::StoreLayout::GLOBAL
107
107
  { "store" => "project:#{slug}", "store.note" => "the #{slug} project store" }
108
108
  else
109
109
  { "store" => "global", "store.note" => "the global store" }
@@ -287,7 +287,7 @@ module IntentScreen
287
287
  # Returns [clause_without_terminal_punctuation, remainder_or_nil]. `nil` for
288
288
  # the remainder means either no boundary exists at all, or the boundary
289
289
  # sits at the absolute end of `text` (a single trailing clause with nothing
290
- # after it) — both cases where there is no SECOND clause to fold in.
290
+ # after it) — both cases where there is no SECOND clause to merge in.
291
291
  def self.clause_and_rest(text)
292
292
  m = text.match(/\A(.+?)[.;](\s+(.*)|\z)/m)
293
293
  return [text, nil] unless m
@@ -35,10 +35,26 @@ module IntentScreenAnsi
35
35
  BAR_CELLS = 24
36
36
  EIGHTHS = [" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"].freeze
37
37
 
38
- DEFAULT_WIDTH = 100
38
+ # Intent 317a1 (D14): the approved design is a 115-column layout, measured
39
+ # from design--terminal-output.html:52-58 with its tags stripped.
40
+ DEFAULT_WIDTH = 115
39
41
 
40
42
  ELLIPSIS = "…"
41
43
 
44
+ # Intent 317a1 (D9-D11, D15): the three-column field table's geometry.
45
+ # ANSI_RE strips escapes so padding measures what the terminal actually
46
+ # draws (D10); VALUE_COL_MAX is the design's own value-column figure and
47
+ # the owner's "50 chars" (mockup--report-screen.md:74); NOTE_FLOOR is the
48
+ # minimum note length that earns the own-line fallback when the note alone
49
+ # (not the value) is what overflows the same-line budget.
50
+ ANSI_RE = /\e\[[0-9;]*m/.freeze
51
+ VALUE_COL_MAX = 50
52
+ NOTE_FLOOR = 24
53
+
54
+ def self.visible_width(text)
55
+ text.to_s.gsub(ANSI_RE, "").length
56
+ end
57
+
42
58
  def self.render(intent_dir:, store_root:, color: true, width: DEFAULT_WIDTH, markdown_safe: false)
43
59
  base = File.basename(intent_dir)
44
60
  id = base.split("--", 2).first
@@ -81,18 +97,8 @@ module IntentScreenAnsi
81
97
  ["Insight", fields["insight"], fields["insight.note"], false],
82
98
  ]
83
99
  key_width = field_rows.map { |k, _, _, _| k.length }.max
84
- prefix_width = key_width + 4 # " " + key.ljust + " "
85
-
86
- field_rows.each do |key, value, note, prebuilt|
87
- value_budget = [width - prefix_width, 0].max
88
- value_text = prebuilt ? value : fit_plain(value, value_budget)
89
- out << " #{styled(key.ljust(key_width), color, BOLD)} #{value_text}\n"
90
- next if note.to_s.empty?
91
100
 
92
- note_budget = [width - prefix_width, 0].max
93
- indent = " " * prefix_width
94
- out << "#{indent}#{fit(note, note_budget) { |t| styled(t, color, MIDGREY) }}\n"
95
- end
101
+ out << field_table_lines(field_rows, width: width, color: color, key_width: key_width)
96
102
 
97
103
  out << "\n"
98
104
  out << fit("Steps", width) { |t| styled(t, color, BOLD, NEARWHITE) }
@@ -119,6 +125,61 @@ module IntentScreenAnsi
119
125
  out
120
126
  end
121
127
 
128
+ # --- shared field-table geometry (D9-D12, D14, D15) ------------------------
129
+
130
+ # The field table's basis, cap, budget arithmetic, both fallbacks, and the
131
+ # right-strip, shared by `render` above and `ScreenPaint.paint_table`'s
132
+ # `**Key**` branch, so the two renderers can never drift apart (D12) - the
133
+ # duplication this replaced was character-for-character identical apart
134
+ # from the module prefix. `rows` is `[key, value, note]`, or `[key, value,
135
+ # note, true]` when `value` is already a finished, pre-fit string (the
136
+ # Progress bar) rather than raw text still needing `fit_plain`.
137
+ #
138
+ # Notes become a third column, padded to the widest RENDERED noted value
139
+ # (capped at VALUE_COL_MAX, D15) so every note starts at one raw-text
140
+ # position; a row whose value or note will not fit drops to the
141
+ # note-on-its-own-line form instead of squeezing anything invisibly. When
142
+ # the same-line budget has already collapsed to zero or less, the note
143
+ # falls straight to its own line rather than being fed to `fit` and
144
+ # silently returning "" - the note must be cut with a visible ellipsis or
145
+ # kept whole, never dropped outright (317a1 post-exec review, finding 4).
146
+ def self.field_table_lines(rows, width:, color:, key_width:)
147
+ prefix_width = key_width + 4 # " " + key.ljust + " "
148
+
149
+ rendered_rows = rows.map do |key, value, note, prebuilt|
150
+ value_budget = [width - prefix_width, 0].max
151
+ value_text = prebuilt ? value : fit_plain(value.to_s, value_budget)
152
+ [key.to_s, value_text, note.to_s]
153
+ end
154
+
155
+ noted_widths = rendered_rows.filter_map { |_, value_text, note| visible_width(value_text) unless note.empty? }
156
+ value_col = [noted_widths.max.to_i, VALUE_COL_MAX].min
157
+ note_budget = width - prefix_width - value_col - 2
158
+
159
+ out = +""
160
+ rendered_rows.each do |key, value_text, note|
161
+ row = " #{styled(key.ljust(key_width), color, BOLD)} #{value_text}"
162
+ if note.empty?
163
+ out << row.rstrip << "\n"
164
+ next
165
+ end
166
+
167
+ value_fits = visible_width(value_text) <= value_col
168
+ note_width = visible_width(note)
169
+ note_overflows = note_width > note_budget
170
+ note_fits = !note_overflows || (note_budget.positive? && note_width <= NOTE_FLOOR)
171
+ if value_fits && note_fits
172
+ pad = value_col - visible_width(value_text)
173
+ out << row << (" " * pad) << " " << fit(note, note_budget) { |t| styled(t, color, MIDGREY) } << "\n"
174
+ else
175
+ out << row.rstrip << "\n"
176
+ own_budget = [width - prefix_width, 0].max
177
+ out << (" " * prefix_width) << fit(note, own_budget) { |t| styled(t, color, MIDGREY) } << "\n"
178
+ end
179
+ end
180
+ out
181
+ end
182
+
122
183
  # --- markdown-noise stripping, adapter-optional (intent 316a1, D3/D5) ------
123
184
  #
124
185
  # Not every display surface passes text through a Markdown renderer, so
@@ -149,7 +149,7 @@ module IntentValidator
149
149
 
150
150
  # PURE: combine the frontmatter result with section-structure findings for a
151
151
  # content STRING. Returns the frontmatter result hash extended with
152
- # :section_missing, :section_unknown, and folded section errors; :ok is the AND
152
+ # :section_missing, :section_unknown, and merged section errors; :ok is the AND
153
153
  # of frontmatter and sections. Lets the create gate validate proposed content
154
154
  # (no file on disk) with the same definition as the CLI and doctor.
155
155
  def validate_content(content, known_stores: nil)
@@ -158,7 +158,7 @@ module IntentValidator
158
158
  merge_sections(fm_result, sections)
159
159
  end
160
160
 
161
- # Fold section findings into a frontmatter result hash (shared by validate and
161
+ # Merge section findings into a frontmatter result hash (shared by validate and
162
162
  # validate_content). Does not mutate the input.
163
163
  def merge_sections(fm_result, sections)
164
164
  errors = fm_result[:errors].dup
@@ -12,8 +12,8 @@ require "time"
12
12
  # savepoint.md (git-ignored, transient state). Ownership is session-keyed (D1):
13
13
  # the file records the owner session, never a pid. Liveness is a lease: the
14
14
  # owner's hooks touch the file mtime on tool calls (heartbeat); the lock is
15
- # stale only when that heartbeat is older than the TTL. The /tmp bridge is a
16
- # per-session CACHE of this state; on any disagreement the lock file wins (D2).
15
+ # stale only when that heartbeat is older than the TTL. This lock file is
16
+ # the sole truth of ownership (D2).
17
17
  #
18
18
  # Mutual-exclusion seam (D3): the schema carries a type ("delivery" now,
19
19
  # "maintenance" in a chained intent after 93) and acquire refuses while the
@@ -27,13 +27,12 @@ module Lock
27
27
  # Skill-invocation prefix per harness (intent 201, D2/D3). Claude Code invokes a
28
28
  # skill with a slash (/plastic-doctor); Codex CLI invokes explicitly with a
29
29
  # dollar ($plastic-doctor) and may also select one implicitly by matching the
30
- # skill's description. This table is the actual source of truth for
31
- # Bridge.skill_ref (bridge.rb requires lock.rb, never the reverse, so the
32
- # table lives here rather than pulling Bridge into this dependency-free file
33
- # just to render two characters). InstallerCore::DEFAULT_AGENTS carries the
34
- # same values per adapter as documented config (see ACTION_2); this constant
35
- # is not read from it at runtime, by the same reasoning bridge.rb/hook-*
36
- # already stay clear of installer_core.rb (spec Alternatives Considered).
30
+ # skill's description. This table is the package-wide source of truth for
31
+ # `Lock.skill_ref`; every caller reaches it directly rather than duplicating
32
+ # the prefix table. InstallerCore::DEFAULT_AGENTS carries the same values per
33
+ # adapter as documented config (see ACTION_2); this constant is not read from
34
+ # it at runtime, by the same reasoning this file and hook-* already stay
35
+ # clear of installer_core.rb (spec Alternatives Considered).
37
36
  SKILL_PREFIXES = { "claude" => "/", "codex" => "$" }.freeze
38
37
 
39
38
  # Renders a skill reference for the given harness. Unset or unrecognized
@@ -369,8 +368,8 @@ module Lock
369
368
  # file is inert: nothing reads it, it stays zero bytes, and
370
369
  # scripts/end-intent:558 keys its exit contract on Lock.path alone. This is
371
370
  # a requirement, not a guarantee the code enforces: the curator stray-file
372
- # rule (skills/conventions/references/maintenance-and-revisions.md:155)
373
- # has no *.lock carve-out today, so a wrongful delete there degrades one
371
+ # rule (docs/help/maintenance-and-revisions.md:155) has no *.lock
372
+ # carve-out today, so a wrongful delete there degrades one
374
373
  # write window to the pre-fix (unguarded) behavior, not a hard failure.
375
374
  def with_write_guard(intent_dir, type: "delivery",
376
375
  guard_timeout: WRITE_GUARD_TIMEOUT_SECONDS,