@zalom/plastic 2.0.0-alpha.26 → 2.0.0-alpha.28

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 (224) hide show
  1. package/PLASTIC.md +13 -139
  2. package/README.md +337 -133
  3. package/agents/plastic-enforcer.md +12 -12
  4. package/agents/plastic-executor.md +2 -1
  5. package/agents/plastic-node-research.md +4 -2
  6. package/agents/plastic-node-verify.md +1 -0
  7. package/agents/plastic-node-work.md +1 -0
  8. package/agents/{plastic-advisor.md → plastic-primary-advisor.md} +6 -8
  9. package/agents/{plastic-faux-advisor.md → plastic-secondary-advisor.md} +9 -12
  10. package/bin/crap +4 -0
  11. package/bin/lib/context_budget.rb +35 -1
  12. package/bin/lib/skill_census.rb +839 -0
  13. package/bin/plastic +6 -0
  14. package/bin/plastic-skill-census +114 -0
  15. package/bin/verify-change +345 -0
  16. package/config_asks.yml +4 -4
  17. package/deprecations.yml +1 -1
  18. package/{skills/agent-advisor/references → docs/help}/advisor-protocol.md +19 -24
  19. package/{skills/auto/references → docs/help}/agent-architecture.md +7 -7
  20. package/{skills/conventions/references → docs/help}/completion-and-done.md +1 -1
  21. package/{skills/auto/references → docs/help}/human-report-contract.md +17 -19
  22. package/{skills/conventions/references → docs/help}/roadmaps.md +2 -2
  23. package/{skills/tutorial/references → docs/help}/track-1-guided.md +8 -8
  24. package/{skills/tutorial/references → docs/help}/track-2-auto.md +5 -5
  25. package/{skills/tutorial/references → docs/help}/track-3-projects-and-roadmaps.md +24 -17
  26. package/package.json +3 -2
  27. package/scripts/append-ledger +2 -1
  28. package/scripts/dashboard.rb +10 -9
  29. package/scripts/day-summary +2 -1
  30. package/scripts/doctor.rb +57 -49
  31. package/scripts/end-intent +2 -8
  32. package/scripts/file-session-intent +2 -1
  33. package/scripts/hook-capture +4 -3
  34. package/scripts/hook-close +2 -1
  35. package/scripts/hook-record +3 -2
  36. package/scripts/hook-savepoint +3 -2
  37. package/scripts/hook-session-start +5 -4
  38. package/scripts/hook-stop +2 -1
  39. package/scripts/insight-append +1 -2
  40. package/scripts/install.rb +7 -5
  41. package/scripts/lib/action_graph_shim.rb +3 -1
  42. package/scripts/lib/active_delivery.rb +1 -1
  43. package/scripts/lib/agent_models.rb +44 -26
  44. package/scripts/lib/arm.rb +2 -1
  45. package/scripts/lib/backup.rb +63 -0
  46. package/scripts/lib/cli/command.rb +85 -0
  47. package/scripts/lib/cli/commands/auto.rb +18 -0
  48. package/scripts/lib/cli/commands/auto_brief.rb +44 -0
  49. package/scripts/lib/cli/commands/auto_lock.rb +60 -0
  50. package/scripts/lib/cli/commands/auto_report.rb +50 -0
  51. package/scripts/lib/cli/commands/auto_take.rb +25 -0
  52. package/scripts/lib/cli/commands/backup.rb +43 -0
  53. package/scripts/lib/cli/commands/checkout.rb +25 -0
  54. package/scripts/lib/cli/commands/continue.rb +66 -0
  55. package/scripts/lib/cli/commands/doctor.rb +20 -0
  56. package/scripts/lib/cli/commands/feedback.rb +40 -0
  57. package/scripts/lib/cli/commands/help.rb +69 -0
  58. package/scripts/lib/cli/commands/hook.rb +32 -0
  59. package/scripts/lib/cli/commands/index.rb +23 -0
  60. package/scripts/lib/cli/commands/install.rb +21 -0
  61. package/scripts/lib/cli/commands/installer_verb.rb +37 -0
  62. package/scripts/lib/cli/commands/intent.rb +19 -0
  63. package/scripts/lib/cli/commands/intent_answer.rb +37 -0
  64. package/scripts/lib/cli/commands/intent_command.rb +53 -0
  65. package/scripts/lib/cli/commands/intent_end.rb +61 -0
  66. package/scripts/lib/cli/commands/intent_new.rb +62 -0
  67. package/scripts/lib/cli/commands/intent_note.rb +43 -0
  68. package/scripts/lib/cli/commands/intent_rule.rb +36 -0
  69. package/scripts/lib/cli/commands/intent_show.rb +25 -0
  70. package/scripts/lib/cli/commands/intent_spec.rb +44 -0
  71. package/scripts/lib/cli/commands/intent_step.rb +43 -0
  72. package/scripts/lib/cli/commands/intent_verify.rb +26 -0
  73. package/scripts/lib/cli/commands/migrate.rb +16 -0
  74. package/scripts/lib/cli/commands/migrate_stores.rb +31 -0
  75. package/scripts/lib/cli/commands/next.rb +49 -0
  76. package/scripts/lib/cli/commands/project.rb +19 -0
  77. package/scripts/lib/cli/commands/project_links.rb +42 -0
  78. package/scripts/lib/cli/commands/project_list.rb +20 -0
  79. package/scripts/lib/cli/commands/project_new.rb +72 -0
  80. package/scripts/lib/cli/commands/query.rb +31 -0
  81. package/scripts/lib/cli/commands/render.rb +25 -0
  82. package/scripts/lib/cli/commands/roadmap.rb +19 -0
  83. package/scripts/lib/cli/commands/roadmap_check.rb +44 -0
  84. package/scripts/lib/cli/commands/roadmap_log.rb +54 -0
  85. package/scripts/lib/cli/commands/roadmap_next.rb +34 -0
  86. package/scripts/lib/cli/commands/roadmap_show.rb +45 -0
  87. package/scripts/lib/cli/commands/rollback.rb +20 -0
  88. package/scripts/lib/cli/commands/search.rb +60 -0
  89. package/scripts/lib/cli/commands/session.rb +18 -0
  90. package/scripts/lib/cli/commands/session_commit.rb +42 -0
  91. package/scripts/lib/cli/commands/session_handoff.rb +34 -0
  92. package/scripts/lib/cli/commands/session_summary.rb +35 -0
  93. package/scripts/lib/cli/commands/status.rb +68 -0
  94. package/scripts/lib/cli/commands/subcommand_list.rb +36 -0
  95. package/scripts/lib/cli/commands/sync.rb +46 -0
  96. package/scripts/lib/cli/commands/uninstall.rb +20 -0
  97. package/scripts/lib/cli/commands/update.rb +20 -0
  98. package/scripts/lib/cli/commands/version.rb +53 -0
  99. package/scripts/lib/cli/frontier.rb +84 -0
  100. package/scripts/lib/cli/legacy.rb +50 -0
  101. package/scripts/lib/cli/output.rb +102 -0
  102. package/scripts/lib/cli/scope.rb +127 -0
  103. package/scripts/lib/cli/table.rb +64 -0
  104. package/scripts/lib/cli.rb +94 -0
  105. package/scripts/lib/codex_adapter.rb +5 -4
  106. package/scripts/lib/compact_instructions.rb +8 -0
  107. package/scripts/lib/day_summary.rb +4 -3
  108. package/scripts/lib/doctor_core.rb +7 -32
  109. package/scripts/lib/doctor_session_ledger.rb +2 -1
  110. package/scripts/lib/feedback_report.rb +1 -1
  111. package/scripts/lib/graph_measure_models.rb +4 -2
  112. package/scripts/lib/index_entry.rb +9 -0
  113. package/scripts/lib/installer_core.rb +175 -56
  114. package/scripts/lib/intent_screen.rb +3 -3
  115. package/scripts/lib/lock.rb +2 -2
  116. package/scripts/lib/node_file.rb +22 -2
  117. package/scripts/lib/node_input.rb +11 -6
  118. package/scripts/lib/node_return.rb +8 -3
  119. package/scripts/lib/preflight.rb +2 -4
  120. package/scripts/lib/project_config.rb +2 -1
  121. package/scripts/lib/project_validator.rb +3 -2
  122. package/scripts/lib/qmd_sync.rb +8 -7
  123. package/scripts/lib/reference_archive.rb +45 -0
  124. package/scripts/lib/release_guard.rb +2 -0
  125. package/scripts/lib/report_screen.rb +4 -3
  126. package/scripts/lib/rlm/corpus.rb +13 -0
  127. package/scripts/lib/rlm/probe.rb +29 -0
  128. package/scripts/lib/rlm/query.rb +22 -0
  129. package/scripts/lib/roadmap_queue.rb +2 -2
  130. package/scripts/lib/roadmap_savepoint.rb +1 -1
  131. package/scripts/lib/runner_absorb.rb +59 -2
  132. package/scripts/lib/runner_dispatch.rb +12 -8
  133. package/scripts/lib/runner_policy.rb +28 -10
  134. package/scripts/lib/search_index.rb +55 -0
  135. package/scripts/lib/session_git.rb +4 -3
  136. package/scripts/lib/sqlite.rb +22 -0
  137. package/scripts/lib/store_discovery.rb +7 -6
  138. package/scripts/lib/store_layout.rb +54 -0
  139. package/scripts/lib/store_provisioning.rb +2 -1
  140. package/scripts/lib/store_sync.rb +85 -0
  141. package/scripts/lib/stores_move.rb +93 -0
  142. package/scripts/lib/verify_intent.rb +2 -7
  143. package/scripts/lib/version_number.rb +48 -0
  144. package/scripts/lib/work_graph.rb +59 -0
  145. package/scripts/lib/worktree.rb +3 -8
  146. package/scripts/lib/worktree_sweep.rb +3 -2
  147. package/scripts/link-suggest +2 -1
  148. package/scripts/migrate-to-global +1 -1
  149. package/scripts/new-intent +3 -12
  150. package/scripts/node-run +2 -1
  151. package/scripts/plastic-lock +3 -2
  152. package/scripts/promote-session-item +3 -2
  153. package/scripts/read-config +44 -6
  154. package/scripts/release-check +10 -5
  155. package/scripts/report-screen +1 -1
  156. package/scripts/session-commit +2 -1
  157. package/scripts/spawn-preamble +2 -2
  158. package/scripts/update.rb +25 -4
  159. package/scripts/write-handoff +2 -1
  160. package/templates/agents.md +6 -6
  161. package/templates/config.yml +13 -6
  162. package/templates/node-research.md +4 -2
  163. package/templates/render.css +10 -0
  164. package/bin/plastic.js +0 -70
  165. package/skills/agent-advisor/SKILL.md +0 -92
  166. package/skills/auto/SKILL.md +0 -297
  167. package/skills/auto/evals/evals.json +0 -255
  168. package/skills/auto/references/end-tail.md +0 -64
  169. package/skills/conventions/SKILL.md +0 -29
  170. package/skills/dashboard/SKILL.md +0 -180
  171. package/skills/dashboard/evals/evals.json +0 -38
  172. package/skills/dashboard/references/classification.md +0 -22
  173. package/skills/dashboard/templates/dashboard-global.md +0 -20
  174. package/skills/dashboard/templates/dashboard-project.md +0 -19
  175. package/skills/direct/SKILL.md +0 -66
  176. package/skills/direct/references/request-signals.md +0 -59
  177. package/skills/doctor/SKILL.md +0 -305
  178. package/skills/doctor/report.md +0 -102
  179. package/skills/feedback/SKILL.md +0 -98
  180. package/skills/feedback/references/transport-and-privacy.md +0 -65
  181. package/skills/feedback/report.md +0 -36
  182. package/skills/install/SKILL.md +0 -217
  183. package/skills/intent-continuing/SKILL.md +0 -156
  184. package/skills/intent-continuing/references/board-fill.md +0 -52
  185. package/skills/intent-continuing/references/boarding-matrix.md +0 -35
  186. package/skills/intent-continuing/references/context-management.md +0 -28
  187. package/skills/intent-continuing/references/liveness-ranking.md +0 -57
  188. package/skills/intent-creating/SKILL.md +0 -89
  189. package/skills/intent-creating/evals/evals.json +0 -72
  190. package/skills/intent-creating/references/lifecycle.md +0 -81
  191. package/skills/intent-creating/references/wikilinks.md +0 -8
  192. package/skills/intent-ending/SKILL.md +0 -182
  193. package/skills/intent-ending/evals/evals.json +0 -74
  194. package/skills/intent-executing/SKILL.md +0 -87
  195. package/skills/intent-executing/evals/evals.json +0 -66
  196. package/skills/intent-executing/implementer-prompt.md +0 -47
  197. package/skills/intent-executing/spec-reviewer-prompt.md +0 -27
  198. package/skills/intent-speccing/SKILL.md +0 -136
  199. package/skills/intent-speccing/evals/evals.json +0 -126
  200. package/skills/intent-speccing/references/design-principles.md +0 -44
  201. package/skills/intent-speccing/references/per-section-fill-rules.md +0 -92
  202. package/skills/intent-speccing/references/self-verify-checklist.md +0 -37
  203. package/skills/project-creating/SKILL.md +0 -162
  204. package/skills/project-creating/references/hubs-projects.md +0 -55
  205. package/skills/project-creating/references/project-scaffolding.md +0 -97
  206. package/skills/releasing/SKILL.md +0 -376
  207. package/skills/releasing/references/deprecations.md +0 -60
  208. package/skills/releasing/references/promotion-and-tagging.md +0 -70
  209. package/skills/releasing/references/release-lines.md +0 -105
  210. package/skills/roadmap/SKILL.md +0 -90
  211. package/skills/roadmap/references/file-format.md +0 -134
  212. package/skills/roadmap/references/operations.md +0 -112
  213. package/skills/rollback/SKILL.md +0 -91
  214. package/skills/tutorial/SKILL.md +0 -66
  215. package/skills/tutorial/evals/evals.json +0 -186
  216. package/skills/uninstall/SKILL.md +0 -75
  217. package/skills/update/SKILL.md +0 -126
  218. /package/{skills/auto/references → docs/help}/agent-report-contract.md +0 -0
  219. /package/{skills/intent-executing → docs/help}/code-quality-reviewer-prompt.md +0 -0
  220. /package/{skills/conventions/references → docs/help}/knowledge-graph.md +0 -0
  221. /package/{skills/conventions/references → docs/help}/lifecycle-and-savepoints.md +0 -0
  222. /package/{skills/conventions/references → docs/help}/locks-and-worktrees.md +0 -0
  223. /package/{skills/conventions/references → docs/help}/maintenance-and-revisions.md +0 -0
  224. /package/{skills/intent-executing → docs/help}/plan-reviewer-prompt.md +0 -0
@@ -13,7 +13,7 @@
13
13
  # suite.
14
14
  #
15
15
  # Usage:
16
- # release-check --tag <tag> --npm-version <version>
16
+ # release-check (--tag <tag> | --branch <branch>) --npm-version <version>
17
17
  # [--github-output <path>] [--root <dir>]
18
18
  #
19
19
  # Exit codes: 0 (clean), 1 (violations; reported on stderr, one per line,
@@ -24,10 +24,10 @@ require "json"
24
24
  require_relative "lib/release_guard"
25
25
 
26
26
  NPM_FLOOR = [11, 5, 1].freeze
27
- KNOWN_FLAGS = %w[--tag --npm-version --github-output --root].freeze
27
+ KNOWN_FLAGS = %w[--tag --branch --npm-version --github-output --root].freeze
28
28
 
29
29
  def usage
30
- warn "usage: release-check --tag <tag> --npm-version <version> [--github-output <path>] [--root <dir>]"
30
+ warn "usage: release-check (--tag <tag> | --branch <branch>) --npm-version <version> [--github-output <path>] [--root <dir>]"
31
31
  exit 2
32
32
  end
33
33
 
@@ -54,7 +54,7 @@ rescue Errno::ENOENT, JSON::ParserError
54
54
  end
55
55
 
56
56
  opts = parse_args(ARGV)
57
- usage unless opts["--tag"] && opts["--npm-version"]
57
+ usage unless (opts["--tag"] || opts["--branch"]) && opts["--npm-version"]
58
58
 
59
59
  root = opts["--root"] ? File.expand_path(opts["--root"]) : File.expand_path("..", __dir__)
60
60
  package_json_path = File.join(root, "package.json")
@@ -66,16 +66,20 @@ violations = []
66
66
  canonical_version = read_version(package_json_path)
67
67
  violations << "could not read a version from #{package_json_path}" if canonical_version.nil?
68
68
 
69
- tag = opts["--tag"].sub(%r{\Arefs/tags/}, "")
69
+ branch = opts["--branch"]
70
70
  dist_tag = nil
71
71
 
72
72
  if canonical_version
73
73
  expected_tag = "v#{canonical_version}"
74
+ tag = opts.fetch("--tag", expected_tag).sub(%r{\Arefs/tags/}, "")
74
75
  if tag != expected_tag
75
76
  violations << "tag #{tag} does not match package.json version #{canonical_version} (expected #{expected_tag})"
76
77
  end
77
78
 
78
79
  dist_tag = ReleaseGuard.dist_tag(canonical_version)
80
+ if branch && ReleaseGuard::CHANNELS[branch] != dist_tag
81
+ violations << "branch #{branch} publishes #{ReleaseGuard::CHANNELS[branch] || "nothing"}, and version #{canonical_version} is #{dist_tag}"
82
+ end
79
83
  stable = dist_tag == "latest"
80
84
 
81
85
  result = ReleaseGuard.check(
@@ -107,6 +111,7 @@ if violations.empty?
107
111
  File.open(opts["--github-output"], "a") do |f|
108
112
  f.puts "version=#{canonical_version}"
109
113
  f.puts "dist_tag=#{dist_tag}"
114
+ f.puts "tag=#{tag}"
110
115
  end
111
116
  end
112
117
  puts "OK: tag #{tag}, version #{canonical_version}, dist-tag #{dist_tag}"
@@ -63,7 +63,7 @@ end
63
63
  def resolve_repo(intent_dir, explicit_repo, script_dir, include_self: true)
64
64
  candidates = []
65
65
  candidates << File.expand_path(explicit_repo) if explicit_repo
66
- if (m = intent_dir.match(%r{\A(.*)/projects/([^/]+)/store/[^/]+\z}))
66
+ if (m = intent_dir.match(%r{\A(.*)/(?:projects|stores)/([^/]+)/store/[^/]+\z}))
67
67
  home, slug = m[1], m[2]
68
68
  projects_yml = File.join(home, "projects.yml")
69
69
  if File.exist?(projects_yml)
@@ -18,6 +18,7 @@
18
18
  # 0 - always, except a usage error
19
19
  # 2 - usage error (missing --cwd or --summary); nothing is written
20
20
 
21
+ require_relative "lib/store_layout"
21
22
  require "fileutils"
22
23
  require_relative "lib/session_git"
23
24
  require_relative "lib/session_ledger"
@@ -78,7 +79,7 @@ def main(argv)
78
79
  usage_abort("--summary is required") if opts[:summary].nil?
79
80
 
80
81
  plastic_home = expand(opts[:plastic_home] || ENV.fetch("PLASTIC_HOME", "~/.plastic"))
81
- store = opts[:store] ? expand(opts[:store]) : File.join(plastic_home, "store")
82
+ store = opts[:store] ? expand(opts[:store]) : Plastic::StoreLayout.global_store(plastic_home)
82
83
  cwd = expand(opts[:cwd])
83
84
 
84
85
  day = opts[:day] || SessionLedger.day_id
@@ -44,7 +44,7 @@ WORKTREE_FALLBACK_INSTRUCTION =
44
44
  "directory, cd directly to the code worktree path above before editing project code."
45
45
 
46
46
  # Verbatim completion-report contract (intent 74). Kept as one constant so the
47
- # contract doc (skills/auto/references/agent-report-contract.md), the role prompts,
47
+ # contract doc (docs/help/agent-report-contract.md), the role prompts,
48
48
  # and the test assert against the exact same string. SINGLE SOURCE OF TRUTH for the
49
49
  # report wording: the work output is lifecycle artifacts, the final message is a
50
50
  # structured report about them. Both are required and they do not contradict.
@@ -64,7 +64,7 @@ REPORT_CONTRACT =
64
64
  "depends on the discovering session's file-write access. Keep the report " \
65
65
  "prose-stripped: the envelope and payload only, no greeting, no preamble, " \
66
66
  "no end-recap, no restating of the task; reasoning stays in the thinking channel. " \
67
- "See skills/auto/references/agent-report-contract.md for the per-role format."
67
+ "See docs/help/agent-report-contract.md for the per-role format."
68
68
 
69
69
  def parse_args(argv)
70
70
  role = nil
package/scripts/update.rb CHANGED
@@ -231,12 +231,33 @@ class Update < InstallerCore
231
231
  ($stdin.gets&.strip || "").downcase.start_with?("y")
232
232
  end
233
233
 
234
- # Thin npx-exec glue (not unit-tested; the decision above is). Delegates the file-sync to
235
- # the target version's install verb, recording the ledger action as `update`.
236
- def perform_switch(target, agent_flags)
234
+ # Thin npx-exec glue (the decision above is unit-tested). Delegates the file-sync to
235
+ # the target version's install verb, recording the ledger action as `update`. On
236
+ # success, commits the re-synced core files and clears the update-check cache
237
+ # (former update skill, lines 124-125).
238
+ def perform_switch(target, agent_flags, switch_runner: ->(cmd) { system(*cmd) })
237
239
  cmd = ["npx", "#{PKG}@#{target}", "install", "--reinstall", "--ledger-action", "update", *agent_flags]
238
240
  puts " $ #{cmd.join(" ")}"
239
- system(*cmd) ? 0 : 1
241
+ return 1 unless switch_runner.call(cmd)
242
+
243
+ commit_core_files(target)
244
+ clear_update_check_cache
245
+ 0
246
+ end
247
+
248
+ # Intent 372 (former update skill, lines 124-125): `~/.plastic` is its own git
249
+ # repository (install.rb's git_init_if_absent), so a successful update commits the
250
+ # core files it just re-synced. Empty commits are allowed: a same-version repair
251
+ # re-syncs nothing new, and that is still worth a ledger-adjacent commit.
252
+ def commit_core_files(target, runner: ->(cmd) { system(*cmd) })
253
+ runner.call(["git", "-C", plastic_home, "add", "PLASTIC.md", "scripts", "AGENTS.md", "VERSION",
254
+ "versions.json", "deprecations.yml", "config_asks.yml"])
255
+ runner.call(["git", "-C", plastic_home, "commit", "-m", "chore: update Plastic to #{target}",
256
+ "--allow-empty"])
257
+ end
258
+
259
+ def clear_update_check_cache
260
+ FileUtils.rm_f(File.join(plastic_home, ".cache", "update-check.json"))
240
261
  end
241
262
 
242
263
  def show_help
@@ -16,6 +16,7 @@
16
16
  #
17
17
  # Exit codes: 0 done; 2 usage error.
18
18
 
19
+ require_relative "lib/store_layout"
19
20
  require_relative "lib/session_ledger"
20
21
  require_relative "lib/handoff"
21
22
 
@@ -48,7 +49,7 @@ usage_abort("--trigger is required (#{Handoff::TRIGGERS.join(', ')})") unless op
48
49
  usage_abort("--trigger must be one of #{Handoff::TRIGGERS.join(', ')}") unless Handoff::TRIGGERS.include?(opts[:trigger])
49
50
 
50
51
  plastic_home = expand(ENV.fetch("PLASTIC_HOME", "~/.plastic"))
51
- store = opts[:store] ? expand(opts[:store]) : File.join(plastic_home, "store")
52
+ store = opts[:store] ? expand(opts[:store]) : Plastic::StoreLayout.global_store(plastic_home)
52
53
  templates = opts[:templates] ? expand(opts[:templates]) : File.expand_path("../templates", __dir__)
53
54
  usage_abort("templates dir not found: #{templates}") unless Dir.exist?(templates)
54
55
 
@@ -42,7 +42,7 @@ Active/Future/Completed placement is managed in INDEX.md, not in frontmatter.
42
42
 
43
43
  ## Creating Tactical Intents
44
44
 
45
- Create through the `plastic-intent-creating` skill, which scaffolds with one call:
45
+ Create through the `plastic intent new` command, which scaffolds with one call:
46
46
  `ruby ~/.plastic/scripts/new-intent --store .plastic/store --intent "<one-line>" --slug <slug> [--sources <governing-id>]`.
47
47
  It allocates the Folgezettel ID, creates `.plastic/store/ID--slug/ID--slug.md` born
48
48
  complete, and wires the links. Never hand-author the files: `new-intent` validates the
@@ -54,11 +54,11 @@ Plastic has its own lifecycle skills. When a Plastic skill exists for the curren
54
54
 
55
55
  | Phase | Skill | Produces |
56
56
  |-------|-------|----------|
57
- | What | `plastic-intent-creating` | Intent file |
58
- | Why | `plastic-intent-speccing` | Rulings as insights, `resources/*.md`, `spec.md` |
59
- | How | `plastic-intent-speccing` | `actions/`, `plan.md`, `checklist.md` |
60
- | Exec | `plastic-intent-executing` | Code + `outcome.md` |
61
- | End | `plastic-intent-ending` | Lifecycle transition |
57
+ | What | `plastic intent new` | Intent file |
58
+ | Why | `plastic intent spec` | Rulings as insights, `resources/*.md`, `spec.md` |
59
+ | How | `plastic intent spec` | `actions/`, `plan.md`, `checklist.md` |
60
+ | Exec | `plastic intent step` | Code + `outcome.md` |
61
+ | End | `plastic intent end` | Lifecycle transition |
62
62
 
63
63
  **Artifact convention:** ALL lifecycle artifacts go to the active intent directory (`store/{id}--{slug}/`). Never write specs to `docs/superpowers/specs/` or plans to `docs/superpowers/plans/`.
64
64
 
@@ -34,18 +34,25 @@ architect:
34
34
  # plastic-enforcer: opus
35
35
  # codex:
36
36
  # plastic-executor: gpt-5.6-terra
37
+ # efforts:
38
+ # claude:
39
+ # plastic-executor: medium
40
+ # codex:
41
+ # plastic-executor: medium
42
+ # Every shipped agent defaults to medium reasoning effort on both harnesses.
43
+ # An agents.efforts.<harness>.<agent> entry is an explicit per-agent override.
37
44
 
38
- # The advisor (intent 185): two consultation agents, plastic-advisor (the real
39
- # advisor, expensive, model fable by default) and plastic-faux-advisor (the
40
- # cheaper imitation, model opus by default, carrying the same reasoning
41
- # discipline inline). advisor.enabled defaults to enabled; missing or
45
+ # The advisors: Primary Advisor and Secondary Advisor. Both use Fable on Claude
46
+ # Code and gpt-6-astra on Codex. Primary uses medium effort; Secondary uses high.
47
+ # advisor.enabled defaults to enabled; missing or
42
48
  # unreadable counts as enabled (fail-open). The claude.default value is an
43
49
  # AGENT NAME, never a model name, so it can point at
44
50
  # a locally registered agent instead. Set at install time via --no-advisor /
45
51
  # --advisor, or uncomment here directly. Each agent's actual model is a plain
46
- # agents.models.claude.<name> override, same mechanism as any other agent.
52
+ # agents.models.claude.<name> override, same mechanism as any other agent. Codex
53
+ # generates both advisors with their role-specific effort.
47
54
  # advisor:
48
55
  # enabled: false # skip installing both advisor agents and the
49
56
  # # agent-advisor skill entirely
50
57
  # claude:
51
- # default: plastic-advisor # which agent the advisor skill routes to
58
+ # default: plastic-primary-advisor # which agent the advisor skill routes to
@@ -3,9 +3,11 @@ node: r1
3
3
  kind: research
4
4
  files: []
5
5
  budget: 60000
6
+ # Optional. When present, use one relative Markdown path under resources/.
7
+ # report: resources/report--topic.md
6
8
  ---
7
9
  # r1 - <what to find out>
8
10
 
9
11
  ## Deposit
10
- <Where the finding lands: a resources/ file, an artifact URL, or a ruling
11
- recorded in the intent's ## Decisions.>
12
+ <Where the finding lands: declare report: above for a resources/ Markdown file,
13
+ or name an artifact URL or a ruling recorded in the intent's ## Decisions.>
@@ -0,0 +1,10 @@
1
+ body { max-width: 46rem; margin: 2rem auto; padding: 0 1rem; font: 16px/1.6 system-ui, sans-serif; color: #1f2933; background: #f4f5f7; }
2
+ h1, h2, h3 { line-height: 1.25; }
3
+ table { border-collapse: collapse; display: block; overflow-x: auto; }
4
+ th, td { border: 1px solid #9aa5b1; padding: 0.3rem 0.6rem; text-align: left; }
5
+ pre { background: #e4e7eb; padding: 0.8rem; overflow-x: auto; }
6
+ code { font-family: ui-monospace, monospace; }
7
+ @media (prefers-color-scheme: dark) {
8
+ body { color: #e4e7eb; background: #1f2933; }
9
+ pre { background: #323f4b; }
10
+ }
package/bin/plastic.js DELETED
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // Thin shim — npx entry point that dispatches a subcommand to the matching Ruby verb script.
4
- // All logic lives in scripts/<verb>.rb. JS is only the distribution + dispatch mechanism.
5
- //
6
- // npx @zalom/plastic install [flags]
7
- // npx @zalom/plastic update [flags]
8
- // npx @zalom/plastic uninstall [flags]
9
- // npx @zalom/plastic rollback [flags]
10
- //
11
- // Back-compat: a bare `--uninstall` (no subcommand) routes to uninstall with a deprecation
12
- // warning; no subcommand at all defaults to install (legacy behaviour, one release).
13
-
14
- import { execFileSync } from 'node:child_process'
15
- import { resolve } from 'node:path'
16
- import { existsSync } from 'node:fs'
17
-
18
- const VERBS = ['install', 'update', 'uninstall', 'rollback']
19
- const packageRoot = new URL('..', import.meta.url).pathname
20
- const argv = process.argv.slice(2)
21
-
22
- let verb
23
- let rest
24
-
25
- if (VERBS.includes(argv[0])) {
26
- verb = argv[0]
27
- rest = argv.slice(1)
28
- } else if (argv.includes('--uninstall')) {
29
- // Deprecated: `--uninstall` as a flag instead of the `uninstall` subcommand.
30
- console.error('! plastic: `--uninstall` is deprecated — use `npx @zalom/plastic uninstall`. (works for now)')
31
- verb = 'uninstall'
32
- rest = argv.filter((a) => a !== '--uninstall')
33
- } else {
34
- // No subcommand: legacy default to install (one release of grace).
35
- verb = 'install'
36
- rest = argv
37
- }
38
-
39
- const script = resolve(packageRoot, 'scripts', `${verb}.rb`)
40
-
41
- if (!existsSync(script)) {
42
- console.error(`Error: scripts/${verb}.rb not found in package.`)
43
- process.exit(1)
44
- }
45
-
46
- try {
47
- execFileSync('ruby', [script, ...rest], {
48
- stdio: 'inherit',
49
- // Clear RUBYOPT last, after the spread, so a global setting (for example --yjit)
50
- // cannot reach a ruby that does not know the flag. A machine with an old ruby
51
- // must get preflight's real message, not a crash.
52
- env: { ...process.env, PLASTIC_PACKAGE_ROOT: packageRoot, RUBYOPT: '' },
53
- })
54
- } catch (err) {
55
- if (err.status) process.exit(err.status)
56
- // We only get here when ruby could not be executed at all. A ruby that runs but is
57
- // too old exits with a status, handled on the line above, and prints its own real
58
- // message from scripts/lib/preflight.rb naming the version actually found.
59
- if (err.code === 'ENOENT') {
60
- console.error('Plastic needs Ruby 3.0.0 or newer to run its scripts (ruby was not found on PATH).')
61
- console.error('Install a pinned Ruby with mise:')
62
- console.error(' curl https://mise.run | sh # only if mise is not installed yet')
63
- console.error(' mise use --global ruby@3.3')
64
- console.error('Then re-run the Plastic installer.')
65
- } else {
66
- console.error(`Plastic could not run ruby: ${err.message}`)
67
- console.error('Check that `ruby -v` works in this shell, then re-run the Plastic installer.')
68
- }
69
- process.exit(1)
70
- }
@@ -1,92 +0,0 @@
1
- ---
2
- name: plastic-agent-advisor
3
- description: >-
4
- Consult the advisor for expensive reasoning: one-way doors, plans, adversarial
5
- review of a plan or conclusion before an irreversible step, a deadlock after two
6
- failed attempts, or ranking several plausible options. Use when the user asks for
7
- a second opinion, a hard design decision, an architecture review, help breaking a
8
- deadlock, or says "ask the advisor". Also sets which advisor is the default when
9
- asked ("make Fable my advisor", "switch my advisor", "use the real advisor").
10
- user-invocable: true
11
- ---
12
-
13
- # Agent Advisor
14
-
15
- Plastic ships two consultation agents, never dispatched by the auto pipeline, summoned
16
- only when you decide the reasoning is worth buying:
17
-
18
- - **`plastic-advisor`** ("the real advisor"): the frontier model itself, expensive,
19
- billed through usage credits. Spawn it for a few rounds on the hardest problem, then
20
- close the session.
21
- - **`plastic-faux-advisor`** ("the imitation advisor"): an ordinary model carrying the
22
- same reasoning discipline inline in its own body, so it reasons the same disciplined
23
- way at a fraction of the cost. The cheaper default.
24
-
25
- ## When to consult (and when not to)
26
-
27
- Buy a consultation for: decisions with one-way doors (architecture, migration order,
28
- public contracts); turning a goal plus evidence into a step plan with checks;
29
- adversarial review of your plan or conclusion before an irreversible step; a deadlock
30
- after two failed attempts where you cannot say why; ranking several plausible options
31
- when the ordering decides where you spend the next day.
32
-
33
- Never buy a consultation for: anything a tool can answer (search, reading code, running
34
- tests, documentation), writing code at volume, confirming a decision you already made,
35
- style or naming a linter would settle, or anything reversible and cheap you have not
36
- tried first. The full buy/never-buy list, the effort table, and the entry test live in
37
- `references/advisor-protocol.md`; read it before writing a brief for the first time in
38
- a session.
39
-
40
- ## Routing: which advisor answers
41
-
42
- 1. Read the harness-scoped config: `advisor.claude.default`, the only advisor routing key
43
- the installer writes. If unset, use `plastic-advisor`, the shipped default.
44
- 2. If the user names which advisor they want ("ask the real one", "use Fable", "ask the
45
- cheap one"), honor that directly and dispatch `plastic-advisor` (the real advisor) or
46
- `plastic-faux-advisor` (the cheaper imitation) accordingly, overriding step 1 for this
47
- consultation only.
48
- 3. If `advisor.enabled` reads `false`, neither advisor agent nor this skill is
49
- installed; this step should not be reachable, but if it is, tell the user the
50
- advisor is disabled and point at "Setting the default" below.
51
- 4. Dispatch the resolved agent with a brief built per `references/advisor-protocol.md`
52
- section 4 (natural prose, the block is a completeness check, not a form to fill).
53
- State EFFORT and the answer shape explicitly; classify low and prove your way up,
54
- never open high "to be safe".
55
- 5. Consume the answer per the protocol's section 5: run the Operating Manual's
56
- five-question self-test on the advisor's plan before executing it. Advice is input,
57
- not authority; the plan is the advisor's, the outcome is yours.
58
-
59
- Read the resolved config value with:
60
-
61
- ```bash
62
- ruby ~/.plastic/scripts/read-config advisor.claude.default --project <repo>
63
- ```
64
-
65
- (Omit `--project` outside a registered project; falls back to the global value.)
66
-
67
- ## Setting the default advisor
68
-
69
- When asked to change the default ("make Fable my advisor", "switch my advisor", "use
70
- the cheaper one by default"), present the two options in plain language and write the
71
- choice:
72
-
73
- - **Faux Fable** (`plastic-faux-advisor`, recommended): an ordinary model carrying the
74
- frontier reasoning instructions. Much cheaper, available on any plan, reasons in the
75
- same disciplined way.
76
- - **Fable 5** (`plastic-advisor`): the frontier model itself. The strongest reasoning
77
- available, billed through usage credits, so summon it for a few rounds and close it.
78
-
79
- These are the same two options the installer offers at install and update time. Write
80
- the choice to `advisor.claude.default` in the global `~/.plastic/config.yml` (or the
81
- project's `.plastic_store/config.yml` when the user scopes the change to one project):
82
- read the file as YAML, set `advisor.claude.default` to the agent name (`plastic-advisor`
83
- or `plastic-faux-advisor`, never a model name or nickname), and write it back. Confirm
84
- the new default back to the user in one line.
85
-
86
- ## References
87
-
88
- - `references/advisor-protocol.md`: the full shipped Advisor Protocol (what to buy,
89
- effort and answer shape, the entry test, how to write a brief that earns its cost, the
90
- answer contract, session economics, anti-patterns). Read it before the first
91
- consultation in a session; the second consultation in the same advisor thread costs a
92
- fraction of the first, so keep follow-ups on one thread rather than opening a new one.