@zalom/plastic 2.0.0-alpha.9 → 2.0.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.
- package/PLASTIC.md +13 -136
- package/README.md +357 -133
- package/agents/plastic-enforcer.md +20 -15
- package/agents/plastic-executor.md +15 -4
- package/agents/plastic-node-research.md +30 -0
- package/agents/plastic-node-verify.md +28 -0
- package/agents/plastic-node-work.md +33 -0
- package/agents/{plastic-advisor.md → plastic-primary-advisor.md} +7 -9
- package/agents/{plastic-faux-advisor.md → plastic-secondary-advisor.md} +9 -12
- package/assets/plastic-logo.svg +1 -0
- package/bin/crap +4 -0
- package/bin/lib/context_budget.rb +43 -6
- package/bin/lib/skill_census.rb +839 -0
- package/bin/plastic +6 -0
- package/bin/plastic-skill-census +114 -0
- package/bin/test +24 -4
- package/bin/verify-change +345 -0
- package/config_asks.yml +4 -4
- package/deprecations.yml +1 -1
- package/{skills/agent-advisor/references → docs/help}/advisor-protocol.md +19 -24
- package/{skills/auto/references → docs/help}/agent-architecture.md +16 -14
- package/{skills/conventions/references → docs/help}/completion-and-done.md +15 -16
- package/docs/help/human-report-contract.md +152 -0
- package/{skills/conventions/references → docs/help}/knowledge-graph.md +9 -0
- package/{skills/conventions/references → docs/help}/locks-and-worktrees.md +11 -13
- package/{skills/conventions/references → docs/help}/maintenance-and-revisions.md +1 -1
- package/{skills/conventions/references → docs/help}/roadmaps.md +2 -2
- package/{skills/tutorial/references → docs/help}/track-1-guided.md +28 -47
- package/{skills/tutorial/references → docs/help}/track-2-auto.md +8 -8
- package/{skills/tutorial/references → docs/help}/track-3-projects-and-roadmaps.md +24 -17
- package/hooks/call-budget +4 -0
- package/hooks/hooks.json +24 -0
- package/hooks/message-display +55 -2
- package/hooks/session-start +5 -1
- package/hooks/statusline +32 -27
- package/hooks/stop +5 -0
- package/package.json +5 -3
- package/scripts/append-ledger +2 -1
- package/scripts/dashboard.rb +267 -16
- package/scripts/day-summary +2 -1
- package/scripts/doctor.rb +680 -39
- package/scripts/end-intent +153 -30
- package/scripts/exec-worktree +5 -5
- package/scripts/file-session-intent +2 -1
- package/scripts/graph-measure +249 -0
- package/scripts/hook-call-budget +222 -0
- package/scripts/hook-capture +24 -123
- package/scripts/hook-close +2 -1
- package/scripts/hook-message-display +7 -0
- package/scripts/hook-record +24 -16
- package/scripts/hook-savepoint +27 -3
- package/scripts/hook-session-start +359 -321
- package/scripts/hook-stop +58 -0
- package/scripts/index-projection +74 -0
- package/scripts/insight-append +17 -4
- package/scripts/install.rb +9 -7
- package/scripts/lib/action_graph_shim.rb +279 -0
- package/scripts/lib/active_delivery.rb +105 -0
- package/scripts/lib/agent_models.rb +63 -25
- package/scripts/lib/arm.rb +48 -83
- package/scripts/lib/atomic_write.rb +31 -0
- package/scripts/lib/backup.rb +65 -0
- package/scripts/lib/cli/command.rb +92 -0
- package/scripts/lib/cli/commands/auto.rb +18 -0
- package/scripts/lib/cli/commands/auto_brief.rb +44 -0
- package/scripts/lib/cli/commands/auto_lock.rb +99 -0
- package/scripts/lib/cli/commands/auto_report.rb +50 -0
- package/scripts/lib/cli/commands/auto_take.rb +31 -0
- package/scripts/lib/cli/commands/backup.rb +43 -0
- package/scripts/lib/cli/commands/checkout.rb +25 -0
- package/scripts/lib/cli/commands/continue.rb +66 -0
- package/scripts/lib/cli/commands/doctor.rb +81 -0
- package/scripts/lib/cli/commands/feedback.rb +40 -0
- package/scripts/lib/cli/commands/help.rb +69 -0
- package/scripts/lib/cli/commands/hook.rb +32 -0
- package/scripts/lib/cli/commands/index.rb +23 -0
- package/scripts/lib/cli/commands/install.rb +21 -0
- package/scripts/lib/cli/commands/installer_verb.rb +37 -0
- package/scripts/lib/cli/commands/intent.rb +19 -0
- package/scripts/lib/cli/commands/intent_answer.rb +37 -0
- package/scripts/lib/cli/commands/intent_command.rb +53 -0
- package/scripts/lib/cli/commands/intent_end.rb +62 -0
- package/scripts/lib/cli/commands/intent_new.rb +62 -0
- package/scripts/lib/cli/commands/intent_note.rb +43 -0
- package/scripts/lib/cli/commands/intent_rule.rb +36 -0
- package/scripts/lib/cli/commands/intent_show.rb +32 -0
- package/scripts/lib/cli/commands/intent_spec.rb +44 -0
- package/scripts/lib/cli/commands/intent_step.rb +71 -0
- package/scripts/lib/cli/commands/intent_verify.rb +26 -0
- package/scripts/lib/cli/commands/migrate.rb +16 -0
- package/scripts/lib/cli/commands/migrate_stores.rb +31 -0
- package/scripts/lib/cli/commands/next.rb +54 -0
- package/scripts/lib/cli/commands/project.rb +19 -0
- package/scripts/lib/cli/commands/project_links.rb +42 -0
- package/scripts/lib/cli/commands/project_list.rb +20 -0
- package/scripts/lib/cli/commands/project_new.rb +72 -0
- package/scripts/lib/cli/commands/query.rb +31 -0
- package/scripts/lib/cli/commands/render.rb +33 -0
- package/scripts/lib/cli/commands/roadmap.rb +19 -0
- package/scripts/lib/cli/commands/roadmap_check.rb +54 -0
- package/scripts/lib/cli/commands/roadmap_log.rb +54 -0
- package/scripts/lib/cli/commands/roadmap_migrate.rb +53 -0
- package/scripts/lib/cli/commands/roadmap_next.rb +70 -0
- package/scripts/lib/cli/commands/roadmap_show.rb +45 -0
- package/scripts/lib/cli/commands/rollback.rb +20 -0
- package/scripts/lib/cli/commands/search.rb +60 -0
- package/scripts/lib/cli/commands/session.rb +18 -0
- package/scripts/lib/cli/commands/session_commit.rb +42 -0
- package/scripts/lib/cli/commands/session_handoff.rb +34 -0
- package/scripts/lib/cli/commands/session_summary.rb +35 -0
- package/scripts/lib/cli/commands/status.rb +68 -0
- package/scripts/lib/cli/commands/subcommand_list.rb +36 -0
- package/scripts/lib/cli/commands/sync.rb +46 -0
- package/scripts/lib/cli/commands/uninstall.rb +20 -0
- package/scripts/lib/cli/commands/update.rb +20 -0
- package/scripts/lib/cli/commands/version.rb +53 -0
- package/scripts/lib/cli/frontier.rb +86 -0
- package/scripts/lib/cli/intent_progress.rb +36 -0
- package/scripts/lib/cli/legacy.rb +80 -0
- package/scripts/lib/cli/output.rb +137 -0
- package/scripts/lib/cli/scope.rb +134 -0
- package/scripts/lib/cli/table.rb +65 -0
- package/scripts/lib/cli.rb +94 -0
- package/scripts/lib/codex_adapter.rb +198 -0
- package/scripts/lib/compact_instructions.rb +13 -5
- package/scripts/lib/core_integrity.rb +71 -0
- package/scripts/lib/dashboard_screen.rb +40 -0
- package/scripts/lib/data_boundary.rb +132 -0
- package/scripts/lib/day_summary.rb +23 -14
- package/scripts/lib/doctor_core.rb +114 -38
- package/scripts/lib/doctor_session_ledger.rb +5 -53
- package/scripts/lib/engine_permissions.rb +88 -0
- package/scripts/lib/exec_worktree.rb +24 -21
- package/scripts/lib/feedback_report.rb +1 -1
- package/scripts/lib/graph_edges.rb +137 -0
- package/scripts/lib/graph_file.rb +246 -0
- package/scripts/lib/graph_measure.rb +645 -0
- package/scripts/lib/graph_measure_budget.rb +409 -0
- package/scripts/lib/graph_measure_cohorts.rb +487 -0
- package/scripts/lib/graph_measure_models.rb +413 -0
- package/scripts/lib/graph_measure_report.rb +532 -0
- package/scripts/lib/graph_tree.rb +98 -0
- package/scripts/lib/guarded_append.rb +155 -0
- package/scripts/lib/handoff.rb +40 -13
- package/scripts/lib/harness_adapter.rb +184 -0
- package/scripts/lib/hook_registry.rb +27 -3
- package/scripts/lib/hook_replay.rb +229 -0
- package/scripts/lib/index_entry.rb +62 -0
- package/scripts/lib/index_projection.rb +201 -0
- package/scripts/lib/insights.rb +1 -1
- package/scripts/lib/installer_core.rb +531 -71
- package/scripts/lib/intent_screen.rb +4 -4
- package/scripts/lib/intent_screen_ansi.rb +73 -12
- package/scripts/lib/intent_validator.rb +2 -2
- package/scripts/lib/lock.rb +10 -11
- package/scripts/lib/message_display.rb +350 -54
- package/scripts/lib/meter_watch.rb +185 -0
- package/scripts/lib/node_file.rb +234 -0
- package/scripts/lib/node_ids.rb +99 -0
- package/scripts/lib/node_input.rb +913 -0
- package/scripts/lib/node_input_compatibility.rb +62 -0
- package/scripts/lib/node_ledger.rb +386 -0
- package/scripts/lib/node_progress.rb +153 -0
- package/scripts/lib/node_return.rb +204 -0
- package/scripts/lib/node_worktree.rb +337 -0
- package/scripts/lib/outcome_report.rb +440 -0
- package/scripts/lib/preflight.rb +4 -6
- package/scripts/lib/project_config.rb +46 -0
- package/scripts/lib/project_validator.rb +3 -2
- package/scripts/lib/qmd_sync.rb +8 -7
- package/scripts/lib/ready_set.rb +462 -0
- package/scripts/lib/reference_archive.rb +45 -0
- package/scripts/lib/release_guard.rb +18 -0
- package/scripts/lib/report_screen.rb +1371 -47
- package/scripts/lib/rlm/corpus.rb +13 -0
- package/scripts/lib/rlm/probe.rb +29 -0
- package/scripts/lib/rlm/query.rb +22 -0
- package/scripts/lib/roadmap_graph.rb +210 -0
- package/scripts/lib/roadmap_migration.rb +95 -0
- package/scripts/lib/roadmap_queue.rb +158 -8
- package/scripts/lib/roadmap_render.rb +150 -0
- package/scripts/lib/roadmap_savepoint.rb +64 -14
- package/scripts/lib/runner_absorb.rb +703 -0
- package/scripts/lib/runner_answer.rb +206 -0
- package/scripts/lib/runner_core.rb +194 -0
- package/scripts/lib/runner_dispatch.rb +525 -0
- package/scripts/lib/runner_policy.rb +191 -0
- package/scripts/lib/runner_proposals.rb +275 -0
- package/scripts/lib/runner_rewind.rb +201 -0
- package/scripts/lib/runner_sweep.rb +231 -0
- package/scripts/lib/runner_until_empty.rb +252 -0
- package/scripts/lib/runner_watch.rb +389 -0
- package/scripts/lib/savepoint.rb +141 -19
- package/scripts/lib/scaffold_intent.rb +6 -3
- package/scripts/lib/screen_paint.rb +365 -28
- package/scripts/lib/screens/dashboard.rb +20 -0
- package/scripts/lib/screens/plan.rb +18 -0
- package/scripts/lib/screens/roadmap.rb +15 -0
- package/scripts/lib/search_index.rb +55 -0
- package/scripts/lib/session_close.rb +30 -28
- package/scripts/lib/session_git.rb +25 -18
- package/scripts/lib/session_ledger.rb +48 -4
- package/scripts/lib/session_usage.rb +190 -0
- package/scripts/lib/sqlite.rb +22 -0
- package/scripts/lib/stop_gate.rb +95 -0
- package/scripts/lib/store_discovery.rb +7 -6
- package/scripts/lib/store_layout.rb +54 -0
- package/scripts/lib/store_provisioning.rb +2 -1
- package/scripts/lib/store_sync.rb +85 -0
- package/scripts/lib/stores_move.rb +93 -0
- package/scripts/lib/verify_intent.rb +36 -8
- package/scripts/lib/version_number.rb +48 -0
- package/scripts/lib/work_graph.rb +59 -0
- package/scripts/lib/work_graph_validator.rb +201 -0
- package/scripts/lib/worktree.rb +27 -32
- package/scripts/lib/worktree_sweep.rb +6 -5
- package/scripts/link-suggest +2 -1
- package/scripts/meter-watch +57 -0
- package/scripts/migrate-to-global +1 -1
- package/scripts/new-intent +4 -13
- package/scripts/node-input +92 -0
- package/scripts/node-run +225 -0
- package/scripts/node-transition +291 -0
- package/scripts/outcome-report +74 -0
- package/scripts/plastic-lock +42 -33
- package/scripts/promote-session-item +3 -2
- package/scripts/read-config +53 -9
- package/scripts/ready-set +126 -0
- package/scripts/release-check +123 -0
- package/scripts/report-screen +177 -16
- package/scripts/roadmap-graph +119 -0
- package/scripts/roadmap-savepoint +7 -0
- package/scripts/runner +581 -0
- package/scripts/savepoint-note +11 -9
- package/scripts/session-commit +2 -1
- package/scripts/session-usage +56 -0
- package/scripts/skill-lint +115 -6
- package/scripts/spawn-preamble +2 -2
- package/scripts/update.rb +25 -4
- package/scripts/validate-work-graph +39 -0
- package/scripts/verify-intent +3 -2
- package/scripts/write-handoff +2 -1
- package/templates/agents.md +7 -7
- package/templates/config.yml +16 -9
- package/templates/dashboard-screen.md +22 -0
- package/templates/display-fixture.md +21 -0
- package/templates/graph.md +16 -0
- package/templates/index.md +1 -1
- package/templates/intent-screen.md +1 -1
- package/templates/node-decision.md +11 -0
- package/templates/node-research.md +13 -0
- package/templates/node-verify.md +13 -0
- package/templates/node-work.md +22 -0
- package/templates/outcome.md +8 -3
- package/templates/project.yml +1 -1
- package/templates/render.css +10 -0
- package/templates/report-plan.md +15 -0
- package/templates/report-roadmap-delivered.md +10 -0
- package/templates/report-roadmap-plan.md +9 -0
- package/templates/report-roadmap-state.md +9 -0
- package/templates/report-state.md +1 -1
- package/templates/roadmap.md +13 -0
- package/bin/plastic.js +0 -70
- package/scripts/lib/bridge.rb +0 -116
- package/skills/agent-advisor/SKILL.md +0 -92
- package/skills/auto/SKILL.md +0 -296
- package/skills/auto/evals/evals.json +0 -255
- package/skills/auto/references/end-tail.md +0 -66
- package/skills/auto/references/human-report-contract.md +0 -78
- package/skills/conventions/SKILL.md +0 -29
- package/skills/dashboard/SKILL.md +0 -169
- package/skills/dashboard/evals/evals.json +0 -38
- package/skills/dashboard/references/classification.md +0 -22
- package/skills/dashboard/templates/dashboard-global.md +0 -20
- package/skills/dashboard/templates/dashboard-project.md +0 -19
- package/skills/direct/SKILL.md +0 -66
- package/skills/direct/references/request-signals.md +0 -59
- package/skills/doctor/SKILL.md +0 -299
- package/skills/doctor/report.md +0 -102
- package/skills/feedback/SKILL.md +0 -98
- package/skills/feedback/references/transport-and-privacy.md +0 -65
- package/skills/feedback/report.md +0 -36
- package/skills/install/SKILL.md +0 -217
- package/skills/intent-continuing/SKILL.md +0 -154
- package/skills/intent-continuing/references/board-fill.md +0 -43
- package/skills/intent-continuing/references/boarding-matrix.md +0 -34
- package/skills/intent-continuing/references/context-management.md +0 -28
- package/skills/intent-continuing/references/liveness-ranking.md +0 -57
- package/skills/intent-creating/SKILL.md +0 -164
- package/skills/intent-creating/evals/evals.json +0 -72
- package/skills/intent-creating/references/lifecycle.md +0 -81
- package/skills/intent-creating/references/wikilinks.md +0 -8
- package/skills/intent-ending/SKILL.md +0 -176
- package/skills/intent-ending/evals/evals.json +0 -74
- package/skills/intent-executing/SKILL.md +0 -170
- package/skills/intent-executing/evals/evals.json +0 -66
- package/skills/intent-executing/implementer-prompt.md +0 -42
- package/skills/intent-executing/spec-reviewer-prompt.md +0 -27
- package/skills/intent-speccing/SKILL.md +0 -130
- package/skills/intent-speccing/evals/evals.json +0 -126
- package/skills/intent-speccing/references/design-principles.md +0 -44
- package/skills/intent-speccing/references/per-section-fill-rules.md +0 -92
- package/skills/intent-speccing/references/self-verify-checklist.md +0 -37
- package/skills/project-creating/SKILL.md +0 -162
- package/skills/project-creating/references/hubs-projects.md +0 -55
- package/skills/project-creating/references/project-scaffolding.md +0 -97
- package/skills/releasing/SKILL.md +0 -337
- package/skills/releasing/references/deprecations.md +0 -60
- package/skills/releasing/references/promotion-and-tagging.md +0 -66
- package/skills/releasing/references/release-lines.md +0 -105
- package/skills/roadmap/SKILL.md +0 -64
- package/skills/roadmap/references/file-format.md +0 -124
- package/skills/roadmap/references/operations.md +0 -112
- package/skills/rollback/SKILL.md +0 -91
- package/skills/tutorial/SKILL.md +0 -65
- package/skills/tutorial/evals/evals.json +0 -186
- package/skills/uninstall/SKILL.md +0 -75
- package/skills/update/SKILL.md +0 -126
- /package/{skills/auto/references → docs/help}/agent-report-contract.md +0 -0
- /package/{skills/intent-executing → docs/help}/code-quality-reviewer-prompt.md +0 -0
- /package/{skills/conventions/references → docs/help}/lifecycle-and-savepoints.md +0 -0
- /package/{skills/intent-executing → docs/help}/plan-reviewer-prompt.md +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# session-usage (intent 355, D10): read the harness transcripts since a cutoff
|
|
6
|
+
# and report per session the model, calls, boot context, last context, median
|
|
7
|
+
# step, steps over 5k, and cache read. Broken records are counted and named.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# session-usage [--since <iso8601>] [--format text|json] [--root <dir>] [--rate-limits <file>]
|
|
11
|
+
#
|
|
12
|
+
# Defaults: the root is ~/.claude/projects, the rate-limit cache is
|
|
13
|
+
# ~/.plastic/.cache/rate-limits.json, and the cutoff is that cache's reset
|
|
14
|
+
# time minus five hours, else the last five hours.
|
|
15
|
+
#
|
|
16
|
+
# Exit codes: 0 reported (unavailable included); 2 usage error.
|
|
17
|
+
|
|
18
|
+
require "json"
|
|
19
|
+
require "time"
|
|
20
|
+
require_relative "lib/session_usage"
|
|
21
|
+
|
|
22
|
+
FLAGS = %w[--since --format --root --rate-limits].freeze
|
|
23
|
+
FORMATS = %w[text json].freeze
|
|
24
|
+
|
|
25
|
+
def usage_abort(message)
|
|
26
|
+
warn "session-usage: #{message}"
|
|
27
|
+
warn "Usage: session-usage [--since <iso8601>] [--format text|json] [--root <dir>] [--rate-limits <file>]"
|
|
28
|
+
exit 2
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def parse_args(argv)
|
|
32
|
+
usage_abort("every flag takes a value") if argv.length.odd?
|
|
33
|
+
opts = argv.each_slice(2).to_h
|
|
34
|
+
unknown = opts.keys - FLAGS
|
|
35
|
+
usage_abort("unknown flag #{unknown.first.inspect}") unless unknown.empty?
|
|
36
|
+
usage_abort("unknown format #{opts['--format'].inspect}") if opts["--format"] && !FORMATS.include?(opts["--format"])
|
|
37
|
+
opts
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def parse_since(value)
|
|
41
|
+
value && Time.iso8601(value)
|
|
42
|
+
rescue ArgumentError
|
|
43
|
+
usage_abort("--since #{value.inspect} is not an ISO 8601 time")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
opts = parse_args(ARGV)
|
|
47
|
+
usage = SessionUsage.new(
|
|
48
|
+
transcripts_root: File.expand_path(opts.fetch("--root", File.join(Dir.home, ".claude", "projects"))),
|
|
49
|
+
rate_limits_path: File.expand_path(opts.fetch("--rate-limits", File.join(Dir.home, ".plastic", ".cache", "rate-limits.json")))
|
|
50
|
+
)
|
|
51
|
+
report = usage.report(since: parse_since(opts["--since"]))
|
|
52
|
+
if opts["--format"] == "json"
|
|
53
|
+
puts JSON.pretty_generate(report)
|
|
54
|
+
else
|
|
55
|
+
print SessionUsage.render_text(report)
|
|
56
|
+
end
|
package/scripts/skill-lint
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
# encoding: UTF-8
|
|
3
3
|
# frozen_string_literal: true
|
|
4
4
|
|
|
5
|
-
# skill-lint: deterministic CLI over SkillLint (intent 85b)
|
|
5
|
+
# skill-lint: deterministic CLI over SkillLint (intent 85b), plus one CLI-local
|
|
6
|
+
# check (intent 341, G8, n1, C35).
|
|
6
7
|
#
|
|
7
|
-
# Runs the five structural
|
|
8
|
-
# bare-pointer, orphan-files, references-depth)
|
|
9
|
-
#
|
|
8
|
+
# Runs the five structural checks (body-budget, frontmatter-validity,
|
|
9
|
+
# bare-pointer, orphan-files, references-depth) via SkillLint, then this
|
|
10
|
+
# script's own refusal-restatement check, over a directory of Agent Skills,
|
|
11
|
+
# and reports every violation. Mirrors `scripts/validate-intent`'s
|
|
10
12
|
# CLI-over-lib shape and exit-code contract.
|
|
11
13
|
#
|
|
12
14
|
# Usage:
|
|
@@ -17,6 +19,112 @@
|
|
|
17
19
|
|
|
18
20
|
require_relative "lib/skill_lint"
|
|
19
21
|
|
|
22
|
+
# RefusalRestatementCheck (C35): a skill body must not restate, past a short
|
|
23
|
+
# run of words, a refusal rule the conventions chapter already carries; it
|
|
24
|
+
# must link that chapter instead. No-op when <skills_dir>/conventions/references
|
|
25
|
+
# does not exist, so an older tree or a fixture dir with no conventions chapter
|
|
26
|
+
# is unaffected.
|
|
27
|
+
#
|
|
28
|
+
# Deliberately lives in this CLI, not in scripts/lib/skill_lint.rb: C35 is a
|
|
29
|
+
# doctrine-duplication check, one level removed from SkillLint's five
|
|
30
|
+
# structural checks, and keeping it here means adding it touches only the
|
|
31
|
+
# files this change is scoped to.
|
|
32
|
+
class RefusalRestatementCheck
|
|
33
|
+
REFUSAL_KEYWORD_RE = /\brefus(e|es|ed|ing|al)\b/i
|
|
34
|
+
CONVENTIONS_LINK_RE = %r{conventions/references/|plastic-conventions}i
|
|
35
|
+
|
|
36
|
+
# How many consecutive normalized words must match, verbatim, between a
|
|
37
|
+
# skill's refusal paragraph and the doctrine text before it counts as a
|
|
38
|
+
# restatement rather than a coincidental shared phrase.
|
|
39
|
+
NGRAM = 6
|
|
40
|
+
|
|
41
|
+
def initialize(skills_dir)
|
|
42
|
+
@skills_dir = skills_dir
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def run
|
|
46
|
+
doctrine = doctrine_blob
|
|
47
|
+
return [] unless doctrine
|
|
48
|
+
|
|
49
|
+
skill_md_paths.flat_map do |skill_md|
|
|
50
|
+
skill_dir = File.dirname(skill_md)
|
|
51
|
+
next [] if File.basename(skill_dir) == "conventions" # the source never restates itself
|
|
52
|
+
|
|
53
|
+
check_skill(skill_dir, skill_md, File.read(skill_md), doctrine)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def skill_md_paths
|
|
60
|
+
Dir.glob(File.join(@skills_dir, "*", "SKILL.md")).sort
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def doctrine_blob
|
|
64
|
+
chapters = Dir.glob(File.join(@skills_dir, "conventions", "references", "*.md")).sort
|
|
65
|
+
return nil if chapters.empty?
|
|
66
|
+
|
|
67
|
+
text = chapters.map { |f| File.read(f) }.join(" ")
|
|
68
|
+
" #{normalize_words(text).join(" ")} "
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def normalize_words(text)
|
|
72
|
+
text.downcase.gsub("`", "").gsub(/[^a-z0-9\s-]/, " ").split(/\s+/).reject(&:empty?)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Same split as SkillLint's own frontmatter/body divide: `content.split("---", 3)`.
|
|
76
|
+
def body_and_offset(content)
|
|
77
|
+
parts = content.split("---", 3)
|
|
78
|
+
return [content, 0] if parts.length < 3
|
|
79
|
+
|
|
80
|
+
prefix_len = parts[0].length + 3 + parts[1].length + 3
|
|
81
|
+
[parts[2], content[0...prefix_len].count("\n")]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Blank-line-delimited paragraph blocks, so a refusal keyword and its
|
|
85
|
+
# doctrine echo are compared across the whole paragraph, not one line.
|
|
86
|
+
def paragraph_blocks(lines)
|
|
87
|
+
blocks = []
|
|
88
|
+
start = nil
|
|
89
|
+
lines.each_with_index do |line, i|
|
|
90
|
+
if line.strip.empty?
|
|
91
|
+
blocks << { start: start, text: lines[start..(i - 1)].join } if start
|
|
92
|
+
start = nil
|
|
93
|
+
else
|
|
94
|
+
start ||= i
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
blocks << { start: start, text: lines[start..].join } if start
|
|
98
|
+
blocks
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def restated?(block_text, doctrine)
|
|
102
|
+
words = normalize_words(block_text)
|
|
103
|
+
return false if words.length < NGRAM
|
|
104
|
+
|
|
105
|
+
(0..(words.length - NGRAM)).any? do |i|
|
|
106
|
+
doctrine.include?(" #{words[i, NGRAM].join(" ")} ")
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def check_skill(skill_dir, skill_md, content, doctrine)
|
|
111
|
+
name = File.basename(skill_dir)
|
|
112
|
+
body, offset = body_and_offset(content)
|
|
113
|
+
|
|
114
|
+
paragraph_blocks(body.lines).filter_map do |block|
|
|
115
|
+
next unless block[:text].match?(REFUSAL_KEYWORD_RE)
|
|
116
|
+
next if block[:text].match?(CONVENTIONS_LINK_RE) # links the chapter instead of restating
|
|
117
|
+
next unless restated?(block[:text], doctrine)
|
|
118
|
+
|
|
119
|
+
{
|
|
120
|
+
check: "refusal-restatement", skill: name, file: skill_md, line: offset + block[:start] + 1,
|
|
121
|
+
message: "this paragraph restates a refusal rule word-for-word from " \
|
|
122
|
+
"skills/conventions/references/; link the chapter instead of repeating its text",
|
|
123
|
+
}
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
20
128
|
def resolve_skills_dir(args)
|
|
21
129
|
if (i = args.index("--skills-dir"))
|
|
22
130
|
args[i + 1]
|
|
@@ -37,14 +145,15 @@ end
|
|
|
37
145
|
|
|
38
146
|
dir = File.expand_path(resolve_skills_dir(ARGV))
|
|
39
147
|
result = SkillLint.new(skills_dir: dir).run
|
|
148
|
+
violations = result.violations + RefusalRestatementCheck.new(dir).run
|
|
40
149
|
|
|
41
|
-
if
|
|
150
|
+
if violations.empty?
|
|
42
151
|
puts "OK: #{dir}"
|
|
43
152
|
exit 0
|
|
44
153
|
end
|
|
45
154
|
|
|
46
155
|
warn "VIOLATIONS: #{dir}"
|
|
47
|
-
|
|
156
|
+
violations.each do |v|
|
|
48
157
|
warn "#{v[:check]} #{v[:skill]} #{v[:file]}:#{v[:line].nil? ? "-" : v[:line]} #{v[:message]}"
|
|
49
158
|
end
|
|
50
159
|
exit 1
|
package/scripts/spawn-preamble
CHANGED
|
@@ -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 (
|
|
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
|
|
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 (
|
|
235
|
-
# the target version's install verb, recording the ledger action as `update`.
|
|
236
|
-
|
|
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
|
-
|
|
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
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# validate-work-graph - deterministic CLI over WorkGraphValidator (intent 334, n4).
|
|
6
|
+
#
|
|
7
|
+
# Checks whether one intent directory's graph.md and nodes/ form a valid work
|
|
8
|
+
# graph: needs targets resolve, node files reconcile with the declared graph,
|
|
9
|
+
# per-kind body sections are present, and (above the trivial bar) a verify
|
|
10
|
+
# node gates two or more work nodes with a failure-mode matrix per work node.
|
|
11
|
+
# Modelled on scripts/validate-intent: errors to stderr, same exit-code shape.
|
|
12
|
+
#
|
|
13
|
+
# Usage:
|
|
14
|
+
# validate-work-graph <intent_dir>
|
|
15
|
+
#
|
|
16
|
+
# Exit codes: 0 (valid), 1 (invalid or unreadable; report on stderr),
|
|
17
|
+
# 2 (usage - no argument given).
|
|
18
|
+
|
|
19
|
+
require_relative "lib/work_graph_validator"
|
|
20
|
+
|
|
21
|
+
intent_dir = ARGV.find { |a| !a.start_with?("--") }
|
|
22
|
+
|
|
23
|
+
if intent_dir.nil?
|
|
24
|
+
warn "usage: validate-work-graph <intent_dir>"
|
|
25
|
+
exit 2
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
dir = File.expand_path(intent_dir)
|
|
29
|
+
result = WorkGraphValidator.validate(dir)
|
|
30
|
+
|
|
31
|
+
if result[:ok]
|
|
32
|
+
puts "OK: #{dir}"
|
|
33
|
+
exit 0
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
warn "INVALID: #{dir}"
|
|
37
|
+
result[:missing].each { |m| warn "missing: #{m}" }
|
|
38
|
+
result[:errors].each { |e| warn e }
|
|
39
|
+
exit 1
|
package/scripts/verify-intent
CHANGED
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
#
|
|
12
12
|
# --base overrides the auto-detected diff base (default: the merge base with the repo's
|
|
13
13
|
# detected default branch) for repos where detection is ambiguous. --suite is an optional
|
|
14
|
-
# caller-supplied command to run (in the repo directory) and
|
|
14
|
+
# caller-supplied command to run (in the repo directory) and merge into the verdict. No
|
|
15
15
|
# other flags exist.
|
|
16
16
|
#
|
|
17
17
|
# Checks, all run every invocation (the fourth only when --suite is given):
|
|
18
|
-
# 1. doctor - Doctor#run_intent_check(id, store: scope), fail-open on a crash
|
|
18
|
+
# 1. doctor - Doctor#run_intent_check(id, store: scope), fail-open on a crash; the doctor
|
|
19
|
+
# scan includes the intent_ticks_lag warning (intent 329)
|
|
19
20
|
# 2. em-dash - added lines only of `git diff <base>...HEAD`, never the whole tree
|
|
20
21
|
# 3. diffstat - `git diff --stat <base>...HEAD`, never a failure on its own
|
|
21
22
|
# 4. suite - the supplied --suite command, run with RUBYOPT cleared
|
package/scripts/write-handoff
CHANGED
|
@@ -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]) :
|
|
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
|
|
package/templates/agents.md
CHANGED
|
@@ -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
|
|
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,14 +54,14 @@ 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
|
|
58
|
-
| Why | `plastic
|
|
59
|
-
| How | `plastic
|
|
60
|
-
| Exec | `plastic
|
|
61
|
-
|
|
|
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
|
|
|
65
|
-
## When
|
|
65
|
+
## When the Project Wraps
|
|
66
66
|
|
|
67
67
|
When this project satisfies the governing intent's goal, report back. The orchestrator will complete the strategic intent.
|
package/templates/config.yml
CHANGED
|
@@ -2,11 +2,11 @@ version: 3
|
|
|
2
2
|
project_roots:
|
|
3
3
|
- ~/.plastic/projects
|
|
4
4
|
stale_threshold_days: 3
|
|
5
|
-
# When to compact. Absolute token counts for a 1M window (
|
|
5
|
+
# When to compact. Absolute token counts for a 1M window (15 and 25 percent), not
|
|
6
6
|
# percentages: models are reliable only to roughly 50 to 65 percent of advertised
|
|
7
7
|
# context, so a percentage that is right at 200k floats to an untested size at 1M.
|
|
8
|
-
context_offer_tokens:
|
|
9
|
-
context_insist_tokens:
|
|
8
|
+
context_offer_tokens: 150000
|
|
9
|
+
context_insist_tokens: 250000
|
|
10
10
|
execution_mode: subagent-driven
|
|
11
11
|
hash_length: 6
|
|
12
12
|
hash_algorithm: sha256-base36
|
|
@@ -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
|
|
39
|
-
#
|
|
40
|
-
#
|
|
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
|
|
58
|
+
# default: plastic-primary-advisor # which agent the advisor skill routes to
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## ▶ {{scope}} · dashboard
|
|
2
|
+
|
|
3
|
+
| | | |
|
|
4
|
+
| --- | --- | --- |
|
|
5
|
+
| **Active** | {{active}} | intents |
|
|
6
|
+
| **In delivery** | {{in_delivery}} | with a fresh lock |
|
|
7
|
+
| **Delivered** | {{delivered}} | in the last 7 days |
|
|
8
|
+
| **Roadmap** | {{roadmap}} | frontier batch |
|
|
9
|
+
| **Sessions** | {{sessions}} | alive |
|
|
10
|
+
| **Changed** | {{changed}} | newest savepoint |
|
|
11
|
+
|
|
12
|
+
**Where we are**
|
|
13
|
+
|
|
14
|
+
| Graph ID | Intent | Stage | Progress | Lead |
|
|
15
|
+
| --- | --- | --- | --- | --- |
|
|
16
|
+
{{where_we_are.rows}}
|
|
17
|
+
|
|
18
|
+
**Where we go next**
|
|
19
|
+
|
|
20
|
+
| Rank | Graph ID | Intent | Reason |
|
|
21
|
+
| --- | --- | --- | --- |
|
|
22
|
+
{{where_we_go_next.rows}}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!-- Doctor's display self-test fixture (intent 331e). Replayed through the
|
|
2
|
+
installed MessageDisplay hook by `display_hook_paints` to prove painting
|
|
3
|
+
still works; this is NOT a report-screen scaffold (no {{...}} mustache
|
|
4
|
+
placeholders) and ships no data of its own. -->
|
|
5
|
+
|
|
6
|
+
## ▶ 331e · Doctor display check
|
|
7
|
+
|
|
8
|
+
| | | |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| **Store** | project:plastic | the plastic project store |
|
|
11
|
+
| **Status** | Active | listed under ## Active in INDEX.md |
|
|
12
|
+
| **Stage** | Exec | What, Why, How, Exec delivered; the work is open |
|
|
13
|
+
| **Progress** | ██████████░░░░░░░░░░ 3 / 6 | 3 steps open |
|
|
14
|
+
|
|
15
|
+
**Steps**
|
|
16
|
+
|
|
17
|
+
| Step | Status | What |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| S1 | done | Tests red |
|
|
20
|
+
| S2 | done | check_display_registration in doctor_core.rb |
|
|
21
|
+
| S3 | open | The three full-run checks in doctor.rb |
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Graph: <intent name>
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
<What this intent's graph delivers once every node reaches done.>
|
|
5
|
+
|
|
6
|
+
## Decisions
|
|
7
|
+
- D1 <first ruling made while building this graph>
|
|
8
|
+
|
|
9
|
+
## Graph
|
|
10
|
+
Edges, `needs` only; the head needs the tail done. The literal target `nothing` declares a root.
|
|
11
|
+
- n1 needs nothing
|
|
12
|
+
|
|
13
|
+
## Status
|
|
14
|
+
| Node | State | Detail |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| n1 | planned | |
|
package/templates/index.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Active
|
|
4
4
|
<!-- Line shape: `- [ID — Title](path)`. Writes emit the em-dash (U+2014) between
|
|
5
|
-
id and title; readers (
|
|
5
|
+
id and title; readers (IndexEntry.match) accept the em-dash or a plain
|
|
6
6
|
hyphen, so either form parses (see https://github.com/zalom/plastic/blob/main/docs/internals.md). -->
|
|
7
7
|
(no active intents)
|
|
8
8
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
node: r1
|
|
3
|
+
kind: research
|
|
4
|
+
files: []
|
|
5
|
+
budget: 60000
|
|
6
|
+
# Optional. When present, use one relative Markdown path under resources/.
|
|
7
|
+
# report: resources/report--topic.md
|
|
8
|
+
---
|
|
9
|
+
# r1 - <what to find out>
|
|
10
|
+
|
|
11
|
+
## Deposit
|
|
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,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
node: n1
|
|
3
|
+
kind: work
|
|
4
|
+
files: [path/to/file.rb, test/path_to_file_test.rb]
|
|
5
|
+
budget: 100000
|
|
6
|
+
---
|
|
7
|
+
# n1 - <one-line description of what this node builds>
|
|
8
|
+
|
|
9
|
+
<Why this node exists and what it changes, in a sentence or two.>
|
|
10
|
+
|
|
11
|
+
## n1 failure-mode matrix
|
|
12
|
+
| Operation | Failure mode | Test |
|
|
13
|
+
| --- | --- | --- |
|
|
14
|
+
| <operation> | <what goes wrong without this code, and its consequence> | `some_test#test_name` |
|
|
15
|
+
|
|
16
|
+
## Steps
|
|
17
|
+
1. Red: the matrix's tests above, committed before any code.
|
|
18
|
+
2. Write the code that makes them pass.
|
|
19
|
+
3. Green, then the whole suite at its baseline.
|
|
20
|
+
|
|
21
|
+
## Proven by
|
|
22
|
+
(filled at close from the ledger: commit, suite counts, review verdict)
|
package/templates/outcome.md
CHANGED
|
@@ -9,9 +9,14 @@ disposition: delivered|abandoned
|
|
|
9
9
|
## Delivered
|
|
10
10
|
<!-- One row per thing delivered, in plain wording a reader recognizes, not
|
|
11
11
|
an implementation summary; the technical detail belongs in ## Summary. Each
|
|
12
|
-
row's label must appear as a standalone token in an actions/*.md
|
|
13
|
-
(for example "### S1 - ..."
|
|
14
|
-
|
|
12
|
+
row's label must appear as a standalone token in an actions/*.md OR
|
|
13
|
+
nodes/*.md heading that owns the matrix table (for example "### S1 - ..."
|
|
14
|
+
with a table beneath it proves row S1, or "## n1 failure-mode matrix" proves
|
|
15
|
+
row n1); that heading's matrix rows become the row's Proven-by cell on the
|
|
16
|
+
delivered screen (intent 317 D19, 317a, 322 D1r, 334 D10r). Readers resolve
|
|
17
|
+
actions/ first, then nodes/ (334 D15r). A label with no owning heading falls
|
|
18
|
+
back to a matrix row cell that carries it, when one under a heading named
|
|
19
|
+
"matrix" exists (322 D3r). -->
|
|
15
20
|
| Row | What |
|
|
16
21
|
| --- | --- |
|
|
17
22
|
| S1 | ... |
|
package/templates/project.yml
CHANGED
|
@@ -8,5 +8,5 @@ release:
|
|
|
8
8
|
# mode: direct # direct | pull_request
|
|
9
9
|
# base: main # defaults to origin/HEAD, then main, then master
|
|
10
10
|
# branch_template: "session/{{day}}" # {{day}}, {{ticket}}, {{slug}} tokens
|
|
11
|
-
# ticket_source: intent_id # intent_id (the
|
|
11
|
+
# ticket_source: intent_id # intent_id (the delivering intent's id from its delivery lock, else the day id)
|
|
12
12
|
# workspace: checkout # checkout | worktree (worktree applies to direct mode only)
|
|
@@ -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
|
+
}
|