@zalom/plastic 1.8.0 → 1.10.0
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 +94 -556
- package/README.md +18 -6
- package/agents/plastic-enforcer.md +3 -2
- package/agents/plastic-intent-curator.md +2 -2
- package/agents/plastic-intent-discovery.md +7 -0
- package/bin/plastic.js +17 -8
- package/deprecations.yml +10 -2
- package/hooks/auto-arm +2 -2
- package/hooks/bash-gate +1 -1
- package/hooks/check-update +1 -1
- package/hooks/continue +2 -2
- package/hooks/edit-gates +3 -0
- package/hooks/future-intent-check +2 -2
- package/hooks/gate-check +3 -3
- package/hooks/hooks.json +4 -44
- package/hooks/power-tools +8 -0
- package/hooks/session-start +1 -1
- package/package.json +1 -2
- package/scripts/codex-hook +57 -118
- package/scripts/doctor.rb +146 -1012
- package/scripts/exec-worktree +103 -0
- package/scripts/hash-intent +1 -1
- package/scripts/hook-bash-gate +19 -0
- package/scripts/hook-code-gate +16 -28
- package/scripts/hook-continue +2 -2
- package/scripts/hook-create-gate +13 -57
- package/scripts/hook-edit-gates +58 -0
- package/scripts/hook-gate-check +17 -0
- package/scripts/hook-links-gate +11 -31
- package/scripts/hook-lock-gate +19 -60
- package/scripts/hook-power-tools +38 -0
- package/scripts/hook-savepoint-pre +11 -11
- package/scripts/hook-session-start +21 -15
- package/scripts/lib/apply_patch_envelope.rb +46 -13
- package/scripts/lib/bridge.rb +85 -17
- package/scripts/lib/codex_edit_gates.rb +138 -0
- package/scripts/lib/doctor_core.rb +1087 -0
- package/scripts/lib/edit_gates.rb +398 -0
- package/scripts/lib/exec_worktree.rb +325 -0
- package/scripts/lib/harness_text.rb +57 -0
- package/scripts/lib/hook_registry.rb +64 -28
- package/scripts/lib/installer_core.rb +166 -24
- package/scripts/lib/lock.rb +196 -47
- package/scripts/lib/qmd_hook.rb +21 -41
- package/scripts/lib/qmd_sync.rb +0 -15
- package/scripts/lib/revisions_writer.rb +1 -1
- package/scripts/lib/ruby_probe.rb +60 -0
- package/scripts/lib/scaffold_intent.rb +392 -0
- package/scripts/lib/spec_header.rb +83 -0
- package/scripts/lib/start_intent.rb +296 -0
- package/scripts/lib/verify_intent.rb +262 -0
- package/scripts/lib/worktree.rb +15 -1
- package/scripts/link-suggest +1 -1
- package/scripts/maintenance-run +5 -5
- package/scripts/migrate-to-global +2 -2
- package/scripts/restore-intent-v1 +17 -12
- package/scripts/scaffold-intent +120 -0
- package/scripts/start-intent +89 -0
- package/scripts/verify-intent +73 -0
- package/skills/agent-advisor/SKILL.md +5 -5
- package/skills/auto/SKILL.md +52 -32
- package/skills/auto/evals/evals.json +2 -2
- package/skills/auto/references/agent-architecture.md +1 -1
- package/skills/auto/references/agent-report-contract.md +1 -1
- package/skills/auto/references/human-report-contract.md +22 -3
- package/skills/auto/references/tiers.md +24 -2
- package/skills/conventions/SKILL.md +31 -0
- package/skills/conventions/references/completion-and-done.md +43 -0
- package/skills/conventions/references/gates-and-enforcement.md +39 -0
- package/skills/conventions/references/knowledge-graph.md +47 -0
- package/skills/conventions/references/lifecycle-and-savepoints.md +11 -0
- package/skills/conventions/references/locks-and-worktrees.md +113 -0
- package/skills/conventions/references/maintenance-and-revisions.md +170 -0
- package/skills/conventions/references/roadmaps.md +44 -0
- package/skills/conventions/references/tiers-and-dispatch.md +135 -0
- package/skills/dashboard/SKILL.md +1 -1
- package/skills/doctor/SKILL.md +15 -6
- package/skills/doctor/references/gates-stuck-detection.md +13 -8
- package/skills/doctor/report.md +1 -1
- package/skills/install/SKILL.md +1 -1
- package/skills/intent-brainstorming/SKILL.md +4 -2
- package/skills/intent-continuing/SKILL.md +4 -0
- package/skills/intent-creating/SKILL.md +13 -8
- package/skills/intent-creating/references/lifecycle.md +1 -1
- package/skills/intent-discovering/SKILL.md +10 -3
- package/skills/intent-ending/SKILL.md +12 -7
- package/skills/intent-executing/SKILL.md +37 -19
- package/skills/intent-grilling/SKILL.md +5 -3
- package/skills/intent-linking/SKILL.md +4 -0
- package/skills/intent-locking/SKILL.md +4 -0
- package/skills/intent-planning/SKILL.md +14 -3
- package/skills/intent-researching/SKILL.md +0 -2
- package/skills/intent-savepoint/SKILL.md +4 -0
- package/skills/intent-speccing/SKILL.md +4 -0
- package/skills/intent-starting/SKILL.md +20 -2
- package/skills/project-creating/SKILL.md +0 -2
- package/skills/project-creating/references/project-scaffolding.md +3 -3
- package/skills/releasing/SKILL.md +1 -1
- package/skills/releasing/references/promotion-and-tagging.md +14 -8
- package/skills/releasing/references/release-lines.md +1 -1
- package/skills/roadmap/SKILL.md +4 -0
- package/skills/roadmap-continuing/SKILL.md +4 -0
- package/skills/skill-creating/SKILL.md +8 -2
- package/skills/skill-creating/references/defaults-first.md +23 -0
- package/skills/skill-creating/references/hooks.md +4 -1
- package/skills/store-curating/SKILL.md +8 -0
- package/skills/store-indexing/SKILL.md +16 -5
- package/skills/store-indexing/references/zettelkasten-linking.md +1 -1
- package/skills/tutorial/references/track-1-guided.md +2 -2
- package/skills/tutorial/references/track-2-auto.md +10 -8
- package/skills/tutorial/references/track-3-projects-and-roadmaps.md +1 -1
- package/skills/uninstall/SKILL.md +6 -9
- package/templates/agents.md +12 -12
- package/templates/config.yml +6 -7
- package/templates/index.md +6 -3
- package/templates/spec.md +1 -1
- package/PLASTIC-reference.md +0 -138
- package/hooks/code-gate +0 -27
- package/hooks/create-gate +0 -3
- package/hooks/links-gate +0 -3
- package/hooks/lock-gate +0 -21
- package/hooks/qmd-search +0 -8
- package/hooks/retrieval-gate +0 -10
- package/hooks/savepoint-pre +0 -10
- package/scripts/hook-qmd-search +0 -44
- package/scripts/hook-retrieval-gate +0 -148
- package/scripts/lib/retrieval_gate.rb +0 -211
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
# while preserving its frontmatter GRAPH (sources/chain) as a target-resolved
|
|
7
7
|
# union of the v1 snapshot and the current snapshot (intent 193). This is the
|
|
8
8
|
# ONLY sanctioned way to restore a completed intent to v1; a hand-run whole-file
|
|
9
|
-
# `git checkout`/revert is forbidden (see
|
|
10
|
-
# because it cannot tell prose from graph
|
|
11
|
-
# backlinks written after v1 (the 124/131 incident this tool
|
|
9
|
+
# `git checkout`/revert is forbidden (see plastic-conventions > references/maintenance-and-revisions.md,
|
|
10
|
+
# WORK vs MAINTENANCE and its Restore-to-v1 paragraph), because it cannot tell prose from graph
|
|
11
|
+
# metadata and silently destroys backlinks written after v1 (the 124/131 incident this tool
|
|
12
|
+
# exists to prevent).
|
|
12
13
|
#
|
|
13
14
|
# Usage:
|
|
14
15
|
# restore-intent-v1 <intent-id> --at <git-ref> [--plastic-home PATH] [--apply] \
|
|
@@ -19,12 +20,14 @@
|
|
|
19
20
|
# class of tool already destroyed live store data once. --apply is required to
|
|
20
21
|
# write.
|
|
21
22
|
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# lock
|
|
26
|
-
#
|
|
27
|
-
#
|
|
23
|
+
# There is exactly one lock in Plastic, `delivery.lock`, and MAINTENANCE (this tool included)
|
|
24
|
+
# never acquires or checks it: WORK vs MAINTENANCE (plastic-conventions >
|
|
25
|
+
# references/maintenance-and-revisions.md) holds the corrected doctrine after intent 112's
|
|
26
|
+
# proposed second "maintenance.lock" was abandoned before merge and never shipped. This tool does
|
|
27
|
+
# NOT acquire, check, or manage `delivery.lock` itself (fail-open doctrine, intent 111: lock
|
|
28
|
+
# management is the orchestrator's job, never built into a CLI as a trap); it only prints a
|
|
29
|
+
# one-line reminder on --apply that the target intent must be terminal, which the caller is
|
|
30
|
+
# responsible for confirming before running with --apply.
|
|
28
31
|
#
|
|
29
32
|
# LINKS BLAST RADIUS: an applied restore reprojects `## Links` via
|
|
30
33
|
# scripts/project-links, which is a STORE-WIDE operation with no per-intent
|
|
@@ -142,8 +145,10 @@ class RestoreIntentV1CLI
|
|
|
142
145
|
File.write(md_path, new_md) if md_changed
|
|
143
146
|
other_files.each { |f, content| File.write(File.join(dir, f), content) }
|
|
144
147
|
|
|
145
|
-
puts "Reminder: restore-to-v1
|
|
146
|
-
"
|
|
148
|
+
puts "Reminder: restore-to-v1 is MAINTENANCE, not WORK (plastic-conventions > " \
|
|
149
|
+
"references/maintenance-and-revisions.md, WORK vs MAINTENANCE). There is no " \
|
|
150
|
+
"maintenance lock to hold; confirm the target intent is terminal (Completed or " \
|
|
151
|
+
"Abandoned) with no fresh delivery.lock before this --apply."
|
|
147
152
|
|
|
148
153
|
handle_links_reprojection(base)
|
|
149
154
|
append_revision(dir, base, graph, files: prose_changes,
|
|
@@ -266,7 +271,7 @@ class RestoreIntentV1CLI
|
|
|
266
271
|
|
|
267
272
|
def reproject_links
|
|
268
273
|
project_links = File.expand_path("project-links", __dir__)
|
|
269
|
-
system(RbConfig.ruby, project_links, "--plastic-home", plastic_home)
|
|
274
|
+
system({"RUBYOPT" => nil}, RbConfig.ruby, project_links, "--plastic-home", plastic_home)
|
|
270
275
|
return if $?.success?
|
|
271
276
|
|
|
272
277
|
warn "restore-intent-v1: ## Links may now be stale (project-links reprojection failed). " \
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# scaffold-intent (intent 213) - one CLI, three subcommands, each writes one lifecycle
|
|
6
|
+
# artifact by copying or mechanically deriving it from an already-committed source. Every
|
|
7
|
+
# field it writes is a verbatim copy or a mechanical derivation (a `git diff --stat`, a
|
|
8
|
+
# supplied file's contents) of an already-committed artifact; no subcommand interprets or
|
|
9
|
+
# invents prose. A field it cannot derive mechanically is left as the template's own stub
|
|
10
|
+
# text instead of being guessed at.
|
|
11
|
+
#
|
|
12
|
+
# Usage:
|
|
13
|
+
# scaffold-intent spec|checklist|outcome --store <path> --id <intent_id> [--force]
|
|
14
|
+
# [--test-summary <path>] (outcome subcommand only)
|
|
15
|
+
#
|
|
16
|
+
# Subcommand is the first positional argument. --store and --id are required for every
|
|
17
|
+
# subcommand. --test-summary is valid only on the outcome subcommand; on spec or
|
|
18
|
+
# checklist, or naming a path that does not exist, it is a usage error (exit 1). No other
|
|
19
|
+
# flags exist: --store, --id, --force, and --test-summary (outcome only) are the whole
|
|
20
|
+
# shipped surface (D5, a one-way door).
|
|
21
|
+
#
|
|
22
|
+
# Exit codes:
|
|
23
|
+
# 0 scaffolded
|
|
24
|
+
# 1 usage or path-resolution failure
|
|
25
|
+
# 2 refused to overwrite real content without --force
|
|
26
|
+
# 3 a prerequisite committed artifact is missing or still sentinel
|
|
27
|
+
#
|
|
28
|
+
# The actions/ rule (intent 133a, D11): scaffold-intent does not scaffold actions/ in any
|
|
29
|
+
# form. Actions require judgment and stay entirely with the planner. No subcommand
|
|
30
|
+
# creates the directory, writes a .gitkeep, or writes a sentinel-only ACTION_*.md.
|
|
31
|
+
#
|
|
32
|
+
# outcome is an end-of-Exec step. Run it once the diff and the test summary exist, right
|
|
33
|
+
# before plastic-intent-ending writes the narrative. Writing outcome.md makes the intent
|
|
34
|
+
# read as Done to the statusline and to any stage-derived display (Bridge.derive_stage
|
|
35
|
+
# keys on outcome.md's presence). This does NOT purge a bridge:
|
|
36
|
+
# Bridge.purge_done_bridges keys on INDEX Active status plus lock presence, never on the
|
|
37
|
+
# derived stage.
|
|
38
|
+
|
|
39
|
+
require_relative "lib/scaffold_intent"
|
|
40
|
+
|
|
41
|
+
SUBCOMMANDS = %w[spec checklist outcome].freeze
|
|
42
|
+
|
|
43
|
+
def parse_args(argv)
|
|
44
|
+
opts = { subcommand: nil, store: nil, id: nil, force: false, test_summary: nil }
|
|
45
|
+
args = argv.dup
|
|
46
|
+
opts[:subcommand] = args.shift
|
|
47
|
+
|
|
48
|
+
i = 0
|
|
49
|
+
while i < args.length
|
|
50
|
+
arg = args[i]
|
|
51
|
+
case arg
|
|
52
|
+
when "--store" then opts[:store] = args[i += 1]
|
|
53
|
+
when "--id" then opts[:id] = args[i += 1]
|
|
54
|
+
when "--force" then opts[:force] = true
|
|
55
|
+
when "--test-summary" then opts[:test_summary] = args[i += 1]
|
|
56
|
+
else
|
|
57
|
+
usage_abort("unknown argument #{arg.inspect}")
|
|
58
|
+
end
|
|
59
|
+
i += 1
|
|
60
|
+
end
|
|
61
|
+
opts
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def usage
|
|
65
|
+
"usage: scaffold-intent spec|checklist|outcome --store <store_path> --id <intent_id> " \
|
|
66
|
+
"[--force] [--test-summary <path>]"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def usage_abort(message)
|
|
70
|
+
warn "scaffold-intent: #{message}"
|
|
71
|
+
warn usage
|
|
72
|
+
exit 1
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def main(argv)
|
|
76
|
+
opts = parse_args(argv)
|
|
77
|
+
|
|
78
|
+
usage_abort("subcommand must be one of #{SUBCOMMANDS.join('|')}") unless SUBCOMMANDS.include?(opts[:subcommand])
|
|
79
|
+
usage_abort("--store is required") if opts[:store].nil? || opts[:store].empty?
|
|
80
|
+
usage_abort("--id is required") if opts[:id].nil? || opts[:id].empty?
|
|
81
|
+
if opts[:test_summary] && opts[:subcommand] != "outcome"
|
|
82
|
+
usage_abort("--test-summary is valid only on the outcome subcommand")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
store = ScaffoldIntent.expand(opts[:store])
|
|
86
|
+
usage_abort("store dir does not exist: #{store}") unless Dir.exist?(store)
|
|
87
|
+
|
|
88
|
+
intent_dir, err = ScaffoldIntent.resolve_intent_dir(store, opts[:id])
|
|
89
|
+
usage_abort(err) if intent_dir.nil?
|
|
90
|
+
|
|
91
|
+
test_summary_path = nil
|
|
92
|
+
if opts[:test_summary]
|
|
93
|
+
test_summary_path = ScaffoldIntent.expand(opts[:test_summary])
|
|
94
|
+
usage_abort("--test-summary path does not exist: #{test_summary_path}") unless File.exist?(test_summary_path)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
result =
|
|
98
|
+
case opts[:subcommand]
|
|
99
|
+
when "spec"
|
|
100
|
+
ScaffoldIntent.scaffold_spec(intent_dir: intent_dir, force: opts[:force])
|
|
101
|
+
when "checklist"
|
|
102
|
+
ScaffoldIntent.scaffold_checklist(intent_dir: intent_dir, force: opts[:force])
|
|
103
|
+
when "outcome"
|
|
104
|
+
ScaffoldIntent.scaffold_outcome(intent_dir: intent_dir, force: opts[:force], store: store,
|
|
105
|
+
id: opts[:id], test_summary: test_summary_path)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
if result[:message]
|
|
109
|
+
if result[:code] == 0
|
|
110
|
+
puts result[:message]
|
|
111
|
+
else
|
|
112
|
+
warn "scaffold-intent: #{result[:message]}"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
puts result[:path] if result[:path]
|
|
116
|
+
|
|
117
|
+
exit result[:code]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
main(ARGV) if $PROGRAM_NAME == __FILE__
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# start-intent (intent 213, group 2) - board a session onto an intent: arm the delivery
|
|
6
|
+
# lock, then print a read-only resume-station report.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# start-intent --store <path> --id <intent_id> --mode auto|guided [--session <session_id>]
|
|
10
|
+
#
|
|
11
|
+
# --store, --id, and --mode are required. --session is optional and defaults to
|
|
12
|
+
# CLAUDE_CODE_SESSION_ID, matching end-intent's resolution order. No other flags exist.
|
|
13
|
+
#
|
|
14
|
+
# Steps performed:
|
|
15
|
+
# 0. Resolve inputs: the intent dir, the intent name from frontmatter (falling back to
|
|
16
|
+
# the dir basename), the calling session (--session, else CLAUDE_CODE_SESSION_ID,
|
|
17
|
+
# else nil; deliberately no lock-owner fallback), and harness/thread from
|
|
18
|
+
# CODEX_THREAD_ID / CLAUDE_CODE_SESSION_ID (mirroring skills/auto/SKILL.md's arming
|
|
19
|
+
# snippet).
|
|
20
|
+
# 1. Pre-flight lock read (read-only): refuse a fresh foreign lock, an unparseable
|
|
21
|
+
# lock, or a lock present with no resolvable session identity. A stale foreign lock
|
|
22
|
+
# falls through to arming, which arbitrates it itself.
|
|
23
|
+
# 2. Arm: Bridge.arm_auto (--mode auto) or Bridge.arm_guided (--mode guided). Nothing
|
|
24
|
+
# else acquires anything.
|
|
25
|
+
# 3. Print the resume-station report (read-only): which lifecycle files are real, and
|
|
26
|
+
# where the intent should resume (Why/How/Exec/Done).
|
|
27
|
+
#
|
|
28
|
+
# This script never releases and never takes over a lock: it never calls the Lock
|
|
29
|
+
# module's release or takeover operations (parked intent 254's territory). A held or
|
|
30
|
+
# corrupt lock is reported and refused, never repaired.
|
|
31
|
+
#
|
|
32
|
+
# Exit codes:
|
|
33
|
+
# 0 armed and resume-station printed
|
|
34
|
+
# 1 usage or path-resolution failure
|
|
35
|
+
# 3 lock held by another live session (deny, mirrors end-intent's pre-flight refusal)
|
|
36
|
+
# 4 unparseable lock, or no session identity with a lock present
|
|
37
|
+
#
|
|
38
|
+
# There is deliberately no exit 2 in this script's contract.
|
|
39
|
+
|
|
40
|
+
require_relative "lib/start_intent"
|
|
41
|
+
|
|
42
|
+
def parse_args(argv)
|
|
43
|
+
opts = { store: nil, id: nil, mode: nil, session: nil }
|
|
44
|
+
i = 0
|
|
45
|
+
while i < argv.length
|
|
46
|
+
arg = argv[i]
|
|
47
|
+
case arg
|
|
48
|
+
when "--store" then opts[:store] = argv[i += 1]
|
|
49
|
+
when "--id" then opts[:id] = argv[i += 1]
|
|
50
|
+
when "--mode" then opts[:mode] = argv[i += 1]
|
|
51
|
+
when "--session" then opts[:session] = argv[i += 1]
|
|
52
|
+
else
|
|
53
|
+
usage_abort("unknown argument #{arg.inspect}")
|
|
54
|
+
end
|
|
55
|
+
i += 1
|
|
56
|
+
end
|
|
57
|
+
opts
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def usage
|
|
61
|
+
"usage: start-intent --store <store_path> --id <intent_id> --mode auto|guided " \
|
|
62
|
+
"[--session <session_id>]"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def usage_abort(message)
|
|
66
|
+
warn "start-intent: #{message}"
|
|
67
|
+
warn usage
|
|
68
|
+
exit 1
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def main(argv)
|
|
72
|
+
opts = parse_args(argv)
|
|
73
|
+
|
|
74
|
+
codex_thread_id = ENV["CODEX_THREAD_ID"]
|
|
75
|
+
claude_session_id = ENV["CLAUDE_CODE_SESSION_ID"]
|
|
76
|
+
detected = StartIntent.resolve_harness(codex_thread_id, claude_session_id)
|
|
77
|
+
|
|
78
|
+
result = StartIntent.run(
|
|
79
|
+
store: opts[:store], id: opts[:id], mode: opts[:mode], session: opts[:session],
|
|
80
|
+
env_session: claude_session_id, harness: detected[:harness], thread: detected[:thread]
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
Array(result[:stderr]).each { |line| warn line }
|
|
84
|
+
warn usage if result[:exit_code] == StartIntent::EXIT_USAGE
|
|
85
|
+
Array(result[:stdout]).each { |line| puts line }
|
|
86
|
+
exit result[:exit_code]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
main(ARGV) if $PROGRAM_NAME == __FILE__
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# verify-intent (intent 213) - bundles the checks that need no project-specific knowledge
|
|
6
|
+
# into one verdict: the per-intent doctor scan, an added-line em-dash diff guard, a
|
|
7
|
+
# diffstat, and an optional caller-supplied suite command.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# verify-intent --store <path> --id <intent_id> [--base <ref>] [--suite <command>]
|
|
11
|
+
#
|
|
12
|
+
# --base overrides the auto-detected diff base (default: the merge base with the repo's
|
|
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 fold into the verdict. No
|
|
15
|
+
# other flags exist.
|
|
16
|
+
#
|
|
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
|
|
19
|
+
# 2. em-dash - added lines only of `git diff <base>...HEAD`, never the whole tree
|
|
20
|
+
# 3. diffstat - `git diff --stat <base>...HEAD`, never a failure on its own
|
|
21
|
+
# 4. suite - the supplied --suite command, run with RUBYOPT cleared
|
|
22
|
+
#
|
|
23
|
+
# Every check runs, then the run exits on the LOWEST-numbered failure that occurred, so one
|
|
24
|
+
# invocation gives the full picture on stdout even when several checks fail.
|
|
25
|
+
#
|
|
26
|
+
# Exit codes:
|
|
27
|
+
# 0 every check passed
|
|
28
|
+
# 1 usage or path-resolution failure
|
|
29
|
+
# 2 doctor reported an issue
|
|
30
|
+
# 3 the em-dash guard found a violation on an added line
|
|
31
|
+
# 4 the supplied --suite command exited non-zero
|
|
32
|
+
|
|
33
|
+
require_relative "lib/verify_intent"
|
|
34
|
+
|
|
35
|
+
def parse_args(argv)
|
|
36
|
+
opts = { store: nil, id: nil, base: nil, suite: nil }
|
|
37
|
+
i = 0
|
|
38
|
+
while i < argv.length
|
|
39
|
+
arg = argv[i]
|
|
40
|
+
case arg
|
|
41
|
+
when "--store" then opts[:store] = argv[i += 1]
|
|
42
|
+
when "--id" then opts[:id] = argv[i += 1]
|
|
43
|
+
when "--base" then opts[:base] = argv[i += 1]
|
|
44
|
+
when "--suite" then opts[:suite] = argv[i += 1]
|
|
45
|
+
else
|
|
46
|
+
usage_abort("unknown argument #{arg.inspect}")
|
|
47
|
+
end
|
|
48
|
+
i += 1
|
|
49
|
+
end
|
|
50
|
+
opts
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def usage
|
|
54
|
+
"usage: verify-intent --store <path> --id <intent_id> [--base <ref>] [--suite <command>]"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def usage_abort(message)
|
|
58
|
+
warn "verify-intent: #{message}"
|
|
59
|
+
warn usage
|
|
60
|
+
exit 1
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def main(argv)
|
|
64
|
+
opts = parse_args(argv)
|
|
65
|
+
usage_abort("--store is required") if opts[:store].nil? || opts[:store].empty?
|
|
66
|
+
usage_abort("--id is required") if opts[:id].nil? || opts[:id].empty?
|
|
67
|
+
|
|
68
|
+
verdict = VerifyIntent.run(store: opts[:store], id: opts[:id], base: opts[:base], suite: opts[:suite])
|
|
69
|
+
verdict[:lines].each { |line| puts line }
|
|
70
|
+
exit verdict[:exit_code]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
main(ARGV) if $PROGRAM_NAME == __FILE__
|
|
@@ -39,12 +39,12 @@ a session.
|
|
|
39
39
|
|
|
40
40
|
## Routing: which advisor answers
|
|
41
41
|
|
|
42
|
-
1. Read the harness-scoped config: `advisor.claude.default
|
|
43
|
-
|
|
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
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 `advisor
|
|
46
|
-
`plastic-advisor`)
|
|
47
|
-
|
|
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
48
|
3. If `advisor.enabled` reads `false`, neither advisor agent nor this skill is
|
|
49
49
|
installed; this step should not be reachable, but if it is, tell the user the
|
|
50
50
|
advisor is disabled and point at "Setting the default" below.
|
package/skills/auto/SKILL.md
CHANGED
|
@@ -27,7 +27,7 @@ Claude Code).
|
|
|
27
27
|
|
|
28
28
|
An active intent MUST exist in INDEX.md. If none exists, refuse: "No active intent found. Create one first with /plastic-intent-creating."
|
|
29
29
|
|
|
30
|
-
If multiple active intents exist, ask the user which one to deliver (
|
|
30
|
+
If multiple active intents exist, ask the user which one to deliver (the one question auto asks at boarding, before delivery starts).
|
|
31
31
|
|
|
32
32
|
**Picking work when no intent is specified.** If the user says "auto" without naming an
|
|
33
33
|
intent and none is active, consult the roadmap first (the primary planning surface), then
|
|
@@ -75,15 +75,26 @@ and artifact depth to that size. Extended walkthrough: `references/tiers.md`.
|
|
|
75
75
|
place, under the same gate.
|
|
76
76
|
3. **Per-tier topology.** S/M: one thinker agent, one boot, two stations, sonnet
|
|
77
77
|
executor; the thinker writes at least one real action file (one consolidated
|
|
78
|
-
`actions/ACTION_1.md`), never an empty `actions/`.
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
`actions/ACTION_1.md`), never an empty `actions/`. That executor runs as ONE dispatch
|
|
79
|
+
for the whole consolidated action, with no per-task two-stage review loop
|
|
80
|
+
(`plastic-intent-executing` holds that gate). S cuts two more things: it skips the QMD
|
|
81
|
+
discovery deposit when chain and sources are both empty AND a size of S is already on
|
|
82
|
+
record (a stamped `Tier: S` line in spec.md), which a first activation does not have,
|
|
83
|
+
and it sends ONE mid-flight owner briefing, at How. M and L send all four. L: today's
|
|
84
|
+
full team (`## Team Spin-Up` below), one `actions/ACTION_N.md` per task, and a per-task
|
|
85
|
+
implementer plus two-stage review.
|
|
81
86
|
4. **Never-cut list**, any tier or mode: the independent reviewer (separate agent, fresh
|
|
82
87
|
context, never the maker), `outcome.md` as truth of delivery, the delivery lock,
|
|
83
88
|
worktree isolation, intent creation via skill, INDEX as status truth, the QMD reindex
|
|
84
89
|
at End. Lightness is about ceremony, never about these guarantees.
|
|
85
90
|
5. **Tier record.** `Tier: S|M|L` at the top of spec.md. Convention-only: read by the
|
|
86
|
-
orchestrator, never validated by any gate or by doctor.
|
|
91
|
+
orchestrator, never validated by any gate or by doctor. A separate
|
|
92
|
+
`Settled: yes (<reason>)` line may sit directly beneath the `Tier:` line; an absent
|
|
93
|
+
line means not settled, and settledness is independent of scope.
|
|
94
|
+
|
|
95
|
+
Read `../plastic-conventions/references/tiers-and-dispatch.md` for tier sizing, agent-model
|
|
96
|
+
config, advisor routing, and the auto-mode human report contract behind the sizing above. This
|
|
97
|
+
path resolves relative to this skill's own installed directory.
|
|
87
98
|
|
|
88
99
|
## Arm the Lifecycle Gate (do this FIRST)
|
|
89
100
|
|
|
@@ -110,6 +121,9 @@ implies for later tool calls) read `references/end-tail.md`.
|
|
|
110
121
|
intent directory / `~/.plastic/`) until `plan.md` AND `checklist.md` exist for the intent.
|
|
111
122
|
Honor the cycle: What → Why (spec.md) → How (plan.md + actions/ + checklist.md) → Exec.
|
|
112
123
|
|
|
124
|
+
Read `../plastic-conventions/references/locks-and-worktrees.md` for delivery isolation: the
|
|
125
|
+
single-owner lock, claims, worktrees, solo mode, and the station ledger behind the arming above.
|
|
126
|
+
|
|
113
127
|
## Flags
|
|
114
128
|
|
|
115
129
|
- `--skip-permissions` - bypass hard stops on destructive actions on existing projects. Full trust mode. Default: off.
|
|
@@ -130,7 +144,7 @@ Roster (one role per cycle stage):
|
|
|
130
144
|
|
|
131
145
|
Dispatch rule: sequential, one specialist per stage on one branch (the deliverables share files). Gate each deliverable against the stage's exit criteria before handing off. The How and Exec phases below default to Plastic's native dispatch (`plastic-intent-executing`) and delegate to the superpowers skills only when they are available or the user asks; do not restate the phase mechanics here.
|
|
132
146
|
|
|
133
|
-
Spawn preamble (live-state injection): before dispatching any specialist, run `scripts/spawn-preamble <intent_dir> --role <role>` and PREPEND its output to that specialist's prompt. The preamble is a deterministic, filesystem-only snapshot of the active intent (id, intent line, current stage, and the provisioned code worktree path when one exists on disk) plus the honoring instruction, so every spawned agent boots with accurate live state instead of guessing. This is the authoritative L2 mechanism for harnesses whose sub-agents do not inherit a top-level session event (see `docs/reference/harness-adapters.md
|
|
147
|
+
Spawn preamble (live-state injection): before dispatching any specialist, run `scripts/spawn-preamble <intent_dir> --role <role>` and PREPEND its output to that specialist's prompt. The preamble is a deterministic, filesystem-only snapshot of the active intent (id, intent line, current stage, and the provisioned code worktree path when one exists on disk) plus the honoring instruction, so every spawned agent boots with accurate live state instead of guessing. This is the authoritative L2 mechanism for harnesses whose sub-agents do not inherit a top-level session event (see [`harness-adapters.md`](https://github.com/zalom/plastic/blob/main/docs/reference/harness-adapters.md)).
|
|
134
148
|
|
|
135
149
|
Dispatch-time model contract (belt-and-braces): alongside the preamble, resolve each specialist's model through the config chain (`read-config agents.models.<basename> --project <repo>`: project override, then global, then the shipped tier default) and pass it explicitly at dispatch. Never rely on the dispatched role's frontmatter alone; a resolved subagent model is never Fable,
|
|
136
150
|
unless an explicit `agents.models.<name>` config override names Fable for that role, in which
|
|
@@ -210,9 +224,9 @@ Filesystem fallback (ledger missing only):
|
|
|
210
224
|
|
|
211
225
|
Announce which stage you're entering and why.
|
|
212
226
|
|
|
213
|
-
Notify user (What briefing): brief per `references/human-report-contract.md`
|
|
227
|
+
Notify user (What briefing, M and L only): brief per `references/human-report-contract.md`
|
|
214
228
|
(State: the work picked up and why it matters now; Risk: scope uncertainty; Call: confirm
|
|
215
|
-
this is worth doing, or proceed).
|
|
229
|
+
this is worth doing, or proceed). At S this briefing does not fire; the How briefing carries it.
|
|
216
230
|
|
|
217
231
|
## Why Completion (Autonomous)
|
|
218
232
|
|
|
@@ -228,9 +242,10 @@ When entering at Why stage:
|
|
|
228
242
|
5. Make decisions - pick best option, document in `## Context > ### Decisions` with rationale
|
|
229
243
|
6. Log all autonomous decisions in `## Insights` with `(autonomous)` marker: "Decision: chose X because Y (autonomous)"
|
|
230
244
|
7. Write `spec.md` - consolidated specification
|
|
231
|
-
8. Notify user (Why briefing): brief per `references/human-report-contract.md`
|
|
245
|
+
8. Notify user (Why briefing, M and L only): brief per `references/human-report-contract.md`
|
|
232
246
|
(State: the approach chosen, one line; Risk: the main trade-off; Call: the one decision
|
|
233
|
-
needed, approve or pick an option).
|
|
247
|
+
needed, approve or pick an option). At S this briefing does not fire; the How briefing
|
|
248
|
+
carries it.
|
|
234
249
|
|
|
235
250
|
Then proceed to How.
|
|
236
251
|
|
|
@@ -246,9 +261,12 @@ one consolidated `actions/ACTION_1.md`, L writes one `actions/ACTION_N.md` per t
|
|
|
246
261
|
2. Otherwise, write `plan.md` directly - implementation plan with numbered tasks
|
|
247
262
|
3. Write at least one real `ACTION_N.md` into the existing `actions/` directory, self-contained (S/M: one consolidated `ACTION_1.md`; L: one per task)
|
|
248
263
|
4. Write `checklist.md` - execution registry with checkboxes covering all actions
|
|
249
|
-
5. Notify user (How briefing): brief per `references/human-report-contract.md`
|
|
264
|
+
5. Notify user (How briefing, every tier): brief per `references/human-report-contract.md`
|
|
250
265
|
(State: the plan shape, task count and what it builds; Risk: the riskiest task or
|
|
251
|
-
dependency; Call: approve the plan to build).
|
|
266
|
+
dependency; Call: approve the plan to build). At S this is the ONE mid-flight briefing:
|
|
267
|
+
fold into the same three lines what the What and Why briefings would have said (the work
|
|
268
|
+
picked up, the approach chosen), and send it here, with the plan ready and before any
|
|
269
|
+
code is written.
|
|
252
270
|
|
|
253
271
|
Then proceed to Exec.
|
|
254
272
|
|
|
@@ -257,7 +275,7 @@ Then proceed to Exec.
|
|
|
257
275
|
If the plan calls for creating a new project (the intent is an implementation intent that needs a new codebase):
|
|
258
276
|
|
|
259
277
|
1. Determine project path from `~/.plastic/config.yml` `project_roots` or from intent context
|
|
260
|
-
2. **Confirm path with user** -
|
|
278
|
+
2. **Confirm path with user** - the one human interaction added mid-delivery, and only when this gate fires:
|
|
261
279
|
> "Creating project `<slug>` at `<path>`. Confirm path, or provide alternative."
|
|
262
280
|
3. Invoke `plastic-project-creating` skill
|
|
263
281
|
4. The global intent is now Completed (creating-project handles this)
|
|
@@ -272,9 +290,10 @@ If the plan calls for creating a new project (the intent is an implementation in
|
|
|
272
290
|
4. Check off items in `checklist.md` as completed
|
|
273
291
|
5. Append observations to `## Insights` with `(autonomous)` marker
|
|
274
292
|
6. Sub-agents can be spawned for parallel actions (one agent per action)
|
|
275
|
-
7. Notify user (Exec briefing): brief per `references/human-report-contract.md`
|
|
293
|
+
7. Notify user (Exec briefing, M and L only): brief per `references/human-report-contract.md`
|
|
276
294
|
(State: what got built and the test result; Risk: residual failures or deviations;
|
|
277
|
-
Call: go to review, or done).
|
|
295
|
+
Call: go to review, or done). At S this briefing does not fire; the final owner report at
|
|
296
|
+
End carries what it would have said.
|
|
278
297
|
|
|
279
298
|
## Permission Model - Safe-by-Default
|
|
280
299
|
|
|
@@ -303,17 +322,19 @@ During initial project creation, all decisions are non-destructive by definition
|
|
|
303
322
|
|
|
304
323
|
## Completion
|
|
305
324
|
|
|
325
|
+
Read `../plastic-conventions/references/completion-and-done.md` for what "intent done" means and
|
|
326
|
+
the End-stage tail the steps below walk through.
|
|
327
|
+
|
|
306
328
|
1. Verify all checklist items are checked
|
|
307
|
-
2. Write `outcome.md` with detailed results, from
|
|
329
|
+
2. Write `outcome.md` with detailed results, from `~/.plastic/templates/outcome.md`.
|
|
308
330
|
Set the frontmatter `disposition: delivered` (this is the delivered terminal). `outcome.md`
|
|
309
331
|
is mandatory at every terminal and self-declares its disposition (see the canonical done-marker
|
|
310
332
|
and End tail in PLASTIC.md `## Delivery Isolation and the Single-Owner Lock`).
|
|
311
|
-
3.
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
2. Read `~/.plastic/projects/{slug}/project.yml`. If the file doesn't exist or has no `release` key, skip to step 5.
|
|
333
|
+
3. **Release (if configured)**
|
|
334
|
+
1. Detect project - match CWD against paths in `~/.plastic/projects.yml` to find the project slug. If no match, skip to step 4 (default commit-only behavior).
|
|
335
|
+
2. Read `~/.plastic/projects/{slug}/project.yml`. If the file doesn't exist or has no `release` key, skip to step 4.
|
|
315
336
|
3. Based on `release.on_complete`:
|
|
316
|
-
- `commit` - git add + commit (same as default, proceed to step
|
|
337
|
+
- `commit` - git add + commit (same as default, proceed to step 4)
|
|
317
338
|
- `commit_and_push` - git add + commit + push
|
|
318
339
|
- `manual` - skip auto-commit, notify user: "Release configured as manual - commit when ready."
|
|
319
340
|
4. If `release.verify` is set, run the verify command (e.g. `bundle exec rake test`):
|
|
@@ -323,14 +344,15 @@ During initial project creation, all decisions are non-destructive by definition
|
|
|
323
344
|
- `stop` - write `savepoint.md` with current state, notify user: "Verify failed - savepoint written.", **STOP**
|
|
324
345
|
- `manual` - notify user: "Verify failed: [summary]. Resolve manually."
|
|
325
346
|
5. If `release.on_green` has items, invoke `plastic-releasing` to handle them (tag, changelog, publish, etc.). Do NOT duplicate release logic - delegate entirely.
|
|
326
|
-
|
|
347
|
+
4. Review `## Insights` for observations that should spawn future intents. If any:
|
|
327
348
|
- Create them (using `plastic-intent-creating` conventions)
|
|
328
349
|
- Update `chain` in the current intent's frontmatter
|
|
329
|
-
|
|
330
|
-
procedure (outcome/INDEX/savepoint/commit, disarm,
|
|
331
|
-
delegation, not
|
|
332
|
-
steps 1-5 itself, INCLUDING disarm (worktree
|
|
333
|
-
single call closes the intent AND clears its
|
|
350
|
+
5. Run the mechanical close through `plastic-intent-ending`: it owns steps 1-7 of the Done
|
|
351
|
+
procedure (outcome/INDEX/savepoint/commit, disarm, the QMD reindex last, and the single
|
|
352
|
+
EM-to-CTO owner report) as ONE delegation, not a series of separate one-liners restated
|
|
353
|
+
here. `scripts/end-intent` now performs steps 1-5 itself, INCLUDING disarm (worktree
|
|
354
|
+
release plus clearing `delivery.lock`): a single call closes the intent AND clears its
|
|
355
|
+
lock, so exit 0 means both are done. Pass
|
|
334
356
|
`--session` (this session's id, or rely on the `CLAUDE_CODE_SESSION_ID` fallback) so
|
|
335
357
|
disarm resolves the right bridge, and `--index-note` with a rich Completed/Abandoned entry
|
|
336
358
|
description (mode/tier, what shipped or why abandoned, suite result):
|
|
@@ -344,13 +366,11 @@ During initial project creation, all decisions are non-destructive by definition
|
|
|
344
366
|
lock (back off), 5 means the code worktree is dirty (commit/stash first, or pass
|
|
345
367
|
`--discard-worktree-changes` deliberately), 3 means disarm ran but the lock is still
|
|
346
368
|
present (run `/plastic-doctor check the lock status`), 6 means the structure gate refused
|
|
347
|
-
(see the named reason on stderr; fix via the owning tool named above, then re-run).
|
|
348
|
-
|
|
369
|
+
(see the named reason on stderr; fix via the owning tool named above, then re-run). Two
|
|
370
|
+
steps remain as separate actions after this call succeeds: Step 6 (QMD reindex, async,
|
|
371
|
+
last) and Step 7 (the EM-to-CTO owner report, the single report the owner reads).
|
|
349
372
|
Never leave an orphaned worktree; run `git worktree prune` on a stale reference. If any of
|
|
350
373
|
this ever needs to change, change `plastic-intent-ending`, not this skill.
|
|
351
|
-
7. Notify user (Done briefing): brief per `references/human-report-contract.md`
|
|
352
|
-
(State: the delivered impact; Risk: residual risk; Call: the decision left to you, merge,
|
|
353
|
-
release, or accept). See `outcome.md` for details.
|
|
354
374
|
|
|
355
375
|
## Error Handling
|
|
356
376
|
|
|
@@ -208,13 +208,13 @@
|
|
|
208
208
|
"scope": "behavior",
|
|
209
209
|
"set": "validation",
|
|
210
210
|
"prompt": "A power-tool is present (qmd on PATH, or a .serena marker / serena on PATH). A substantive prompt arrives in auto mode.",
|
|
211
|
-
"expected_output": "The UserPromptSubmit power-tools hook appends a MANDATORY obligation per present tool: a MUST-use-QMD line when qmd is present (to check for an existing or related intent before treating work as new), and a MUST-use-Serena line when serena is present (symbolic tools before grep/Read).
|
|
211
|
+
"expected_output": "The UserPromptSubmit power-tools hook appends a MANDATORY obligation per present tool: a MUST-use-QMD line when qmd is present (to check for an existing or related intent before treating work as new), and a MUST-use-Serena line when serena is present (symbolic tools before grep/Read). No search hits are injected: intent 246 removed the per-prompt qmd hit search, so the hook emits the mandate and nothing else.",
|
|
212
212
|
"files": [],
|
|
213
213
|
"assertions": [
|
|
214
214
|
{
|
|
215
215
|
"type": "code",
|
|
216
216
|
"check": "PowerTools.mandate returns MUST/MANDATORY lines for each present tool; QmdHook.run appends the mandate",
|
|
217
|
-
"observed": "power_tools_test.rb + qmd_hook_test.rb assert MUST wording; serena line gated on the serena detector",
|
|
217
|
+
"observed": "power_tools_test.rb + qmd_hook_test.rb assert MUST wording; serena line gated on the serena detector; qmd_hook_test.rb test_no_retrieval_hits_are_ever_injected asserts no hit header for any tool combination",
|
|
218
218
|
"result": "pass"
|
|
219
219
|
}
|
|
220
220
|
]
|
|
@@ -59,7 +59,7 @@ savepoint line, else stage derived from which lifecycle files exist), the cycle
|
|
|
59
59
|
role, and the honoring instruction that the agent must emit valid lifecycle artifacts
|
|
60
60
|
and not hallucinate intents or stages. This is the standard L2 live-state mechanism
|
|
61
61
|
for harnesses whose spawned sub-agents do not inherit the top-level session event. See
|
|
62
|
-
`docs/reference/harness-adapters.md
|
|
62
|
+
[`harness-adapters.md`](https://github.com/zalom/plastic/blob/main/docs/reference/harness-adapters.md) for how it slots into the per-harness contract.
|
|
63
63
|
|
|
64
64
|
### Completion Reports
|
|
65
65
|
|
|
@@ -90,7 +90,7 @@ argument is sound before any code is written.
|
|
|
90
90
|
## Fallback: always a report
|
|
91
91
|
|
|
92
92
|
Decision-shaping (the preamble plus these prompts) makes the report mandatory, but child-agent
|
|
93
|
-
honor is best-effort across harnesses (Tier B/C in `docs/reference/harness-adapters.md
|
|
93
|
+
honor is best-effort across harnesses (Tier B/C in [`harness-adapters.md`](https://github.com/zalom/plastic/blob/main/docs/reference/harness-adapters.md)), so the
|
|
94
94
|
contract is never a hard block (decision D3). When a dispatched agent returns no usable report
|
|
95
95
|
(it went idle, emitted only a bare ping, or its message was lost to a mid-run interjection), the
|
|
96
96
|
enforcer synthesizes one:
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Human Report Contract (per-stage EM-to-CTO briefing)
|
|
2
2
|
|
|
3
3
|
This doc defines how the orchestrator briefs the human at each of the five stage boundaries
|
|
4
|
-
(What, Why, How, Exec, Done) in auto mode
|
|
4
|
+
(What, Why, How, Exec, Done) in auto mode, at M and L; at S only the How boundary fires (see
|
|
5
|
+
`## Depth at Tier S`). It is the outward, human-facing counterpart to the
|
|
5
6
|
internal report contract in `references/agent-report-contract.md`. Voice: an engineering
|
|
6
7
|
manager briefing a CTO. Lead with impact, name the risk, leave the decision.
|
|
7
8
|
|
|
@@ -29,6 +30,23 @@ short. The words can flex to fit the stage.
|
|
|
29
30
|
- **Done**: State = the delivered impact. Risk = residual risk. Call = the decision left to you
|
|
30
31
|
(merge, release, accept).
|
|
31
32
|
|
|
33
|
+
## Depth at Tier S
|
|
34
|
+
|
|
35
|
+
At Tier S in auto mode the mid-flight briefings collapse to one. Only the How briefing fires, and
|
|
36
|
+
it folds in what the What and Why briefings would have said: the work picked up and the approach
|
|
37
|
+
chosen go into its State line. The Exec briefing folds into the final owner report at End. M and L
|
|
38
|
+
send all four. The shape does not change: still State, then Risk, then Call, and the per-stage
|
|
39
|
+
content above still says what each line covers. This is a depth cut, not a new report. A delivery
|
|
40
|
+
still ends with `outcome.md` plus one owner report.
|
|
41
|
+
|
|
42
|
+
## One report per audience
|
|
43
|
+
|
|
44
|
+
A delivery produces exactly two artifacts: `outcome.md` (authored by `plastic-intent-ending`)
|
|
45
|
+
and one EM-to-CTO owner report at the End stage. No stage or skill restates a delivery
|
|
46
|
+
already written to `outcome.md`; point at it instead. Skills do not open with a banner that
|
|
47
|
+
names the skill or restates the intent id and name the owner just typed. Announce only what
|
|
48
|
+
the reader cannot already know: an error, a result, a choice with its reason, or a handoff.
|
|
49
|
+
|
|
32
50
|
## Boundary vs intent 74
|
|
33
51
|
|
|
34
52
|
Intent 74's report contract (`references/agent-report-contract.md`) is the INTERNAL,
|
|
@@ -50,6 +68,7 @@ always-on layer for everything else.
|
|
|
50
68
|
In guided mode, the briefing lands at each stage boundary and the human acts on the Call line
|
|
51
69
|
before the next stage starts.
|
|
52
70
|
|
|
53
|
-
In auto mode, the orchestrator still emits the briefing at each boundary, as a running
|
|
54
|
-
account.
|
|
71
|
+
In auto mode, at M and L the orchestrator still emits the briefing at each boundary, as a running
|
|
72
|
+
EM-to-CTO account. At S only the How briefing fires; see `## Depth at Tier S` above for what it
|
|
73
|
+
folds in. The Call line becomes the go-ahead the orchestrator takes itself and moves on, except at
|
|
55
74
|
the existing hard stops (destructive action without a safe alternative, project-path confirm).
|