opensquid 0.5.412 → 0.5.432
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/dist/channels/env-token.js +2 -2
- package/dist/channels/env-token.js.map +1 -1
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/functions/event.d.ts.map +1 -1
- package/dist/functions/event.js +30 -0
- package/dist/functions/event.js.map +1 -1
- package/dist/functions/index.d.ts +2 -0
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +2 -0
- package/dist/functions/index.js.map +1 -1
- package/dist/functions/read_rubric.d.ts +27 -0
- package/dist/functions/read_rubric.d.ts.map +1 -0
- package/dist/functions/read_rubric.js +53 -0
- package/dist/functions/read_rubric.js.map +1 -0
- package/dist/functions/rubric_pre_inject.d.ts +22 -0
- package/dist/functions/rubric_pre_inject.d.ts.map +1 -0
- package/dist/functions/rubric_pre_inject.js +58 -0
- package/dist/functions/rubric_pre_inject.js.map +1 -0
- package/dist/functions/session_status_manifest.d.ts.map +1 -1
- package/dist/functions/session_status_manifest.js +15 -0
- package/dist/functions/session_status_manifest.js.map +1 -1
- package/dist/functions/shell_parse.d.ts +41 -0
- package/dist/functions/shell_parse.d.ts.map +1 -0
- package/dist/functions/shell_parse.js +185 -0
- package/dist/functions/shell_parse.js.map +1 -0
- package/dist/mcp/server.js +14 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/memorize.d.ts +3 -0
- package/dist/mcp/tools/memorize.d.ts.map +1 -1
- package/dist/mcp/tools/memorize.js +8 -0
- package/dist/mcp/tools/memorize.js.map +1 -1
- package/dist/mcp/tools/ralph.d.ts +21 -0
- package/dist/mcp/tools/ralph.d.ts.map +1 -0
- package/dist/mcp/tools/ralph.js +18 -0
- package/dist/mcp/tools/ralph.js.map +1 -0
- package/dist/mcp/tools/workgraph.d.ts +11 -0
- package/dist/mcp/tools/workgraph.d.ts.map +1 -1
- package/dist/mcp/tools/workgraph.js +7 -0
- package/dist/mcp/tools/workgraph.js.map +1 -1
- package/dist/rag/backends/libsql_store.d.ts.map +1 -1
- package/dist/rag/backends/libsql_store.js +13 -5
- package/dist/rag/backends/libsql_store.js.map +1 -1
- package/dist/rag/backends/perfile_source.d.ts.map +1 -1
- package/dist/rag/backends/perfile_source.js +6 -0
- package/dist/rag/backends/perfile_source.js.map +1 -1
- package/dist/rag/durability.d.ts +26 -0
- package/dist/rag/durability.d.ts.map +1 -0
- package/dist/rag/durability.js +34 -0
- package/dist/rag/durability.js.map +1 -0
- package/dist/rag/memory/store.d.ts.map +1 -1
- package/dist/rag/memory/store.js +11 -3
- package/dist/rag/memory/store.js.map +1 -1
- package/dist/rag/types.d.ts +3 -0
- package/dist/rag/types.d.ts.map +1 -1
- package/dist/rag/types.js.map +1 -1
- package/dist/runtime/agent_bridge/daemon.d.ts.map +1 -1
- package/dist/runtime/agent_bridge/daemon.js +9 -6
- package/dist/runtime/agent_bridge/daemon.js.map +1 -1
- package/dist/runtime/bootstrap.d.ts.map +1 -1
- package/dist/runtime/bootstrap.js +4 -0
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/runtime/ralph/decision_classifier.d.ts +18 -0
- package/dist/runtime/ralph/decision_classifier.d.ts.map +1 -0
- package/dist/runtime/ralph/decision_classifier.js +72 -0
- package/dist/runtime/ralph/decision_classifier.js.map +1 -0
- package/dist/runtime/ralph/escalate_lap.d.ts +31 -0
- package/dist/runtime/ralph/escalate_lap.d.ts.map +1 -0
- package/dist/runtime/ralph/escalate_lap.js +22 -0
- package/dist/runtime/ralph/escalate_lap.js.map +1 -0
- package/dist/runtime/ralph/escalator.d.ts +34 -0
- package/dist/runtime/ralph/escalator.d.ts.map +1 -0
- package/dist/runtime/ralph/escalator.js +19 -0
- package/dist/runtime/ralph/escalator.js.map +1 -0
- package/dist/runtime/ralph/lap_outcome.d.ts +43 -0
- package/dist/runtime/ralph/lap_outcome.d.ts.map +1 -0
- package/dist/runtime/ralph/lap_outcome.js +119 -0
- package/dist/runtime/ralph/lap_outcome.js.map +1 -0
- package/dist/runtime/ralph/orchestrator.d.ts +71 -0
- package/dist/runtime/ralph/orchestrator.d.ts.map +1 -0
- package/dist/runtime/ralph/orchestrator.js +74 -0
- package/dist/runtime/ralph/orchestrator.js.map +1 -0
- package/dist/runtime/ralph/ralph_template.d.ts +18 -0
- package/dist/runtime/ralph/ralph_template.d.ts.map +1 -0
- package/dist/runtime/ralph/ralph_template.js +61 -0
- package/dist/runtime/ralph/ralph_template.js.map +1 -0
- package/dist/runtime/ralph/supervisor.d.ts +30 -0
- package/dist/runtime/ralph/supervisor.d.ts.map +1 -0
- package/dist/runtime/ralph/supervisor.js +24 -0
- package/dist/runtime/ralph/supervisor.js.map +1 -0
- package/dist/setup/cli/chat_actions.js +1 -1
- package/dist/setup/cli/chat_actions.js.map +1 -1
- package/dist/setup/cli/chat_actions_prompts_alias.js +4 -1
- package/dist/setup/cli/chat_actions_prompts_alias.js.map +1 -1
- package/dist/setup/cli/chat_actions_test_step.js +2 -2
- package/dist/setup/cli/chat_actions_test_step.js.map +1 -1
- package/dist/setup/cli/chat_state.d.ts.map +1 -1
- package/dist/setup/cli/chat_state.js +3 -2
- package/dist/setup/cli/chat_state.js.map +1 -1
- package/dist/setup/cli/mcp.d.ts +1 -1
- package/dist/setup/cli/mcp.d.ts.map +1 -1
- package/dist/setup/cli/mcp.js +7 -8
- package/dist/setup/cli/mcp.js.map +1 -1
- package/dist/setup/cli/ralph.d.ts +20 -0
- package/dist/setup/cli/ralph.d.ts.map +1 -0
- package/dist/setup/cli/ralph.js +180 -0
- package/dist/setup/cli/ralph.js.map +1 -0
- package/dist/setup/wizard/mcp-writer.d.ts +3 -3
- package/dist/setup/wizard/mcp-writer.d.ts.map +1 -1
- package/dist/setup/wizard/mcp-writer.js +17 -0
- package/dist/setup/wizard/mcp-writer.js.map +1 -1
- package/dist/setup/wizard/ralph_writer.d.ts +98 -0
- package/dist/setup/wizard/ralph_writer.d.ts.map +1 -0
- package/dist/setup/wizard/ralph_writer.js +114 -0
- package/dist/setup/wizard/ralph_writer.js.map +1 -0
- package/dist/workgraph/audience.d.ts +12 -0
- package/dist/workgraph/audience.d.ts.map +1 -0
- package/dist/workgraph/audience.js +10 -0
- package/dist/workgraph/audience.js.map +1 -0
- package/dist/workgraph/events.d.ts.map +1 -1
- package/dist/workgraph/events.js +34 -0
- package/dist/workgraph/events.js.map +1 -1
- package/dist/workgraph/store.d.ts.map +1 -1
- package/dist/workgraph/store.js +86 -12
- package/dist/workgraph/store.js.map +1 -1
- package/dist/workgraph/types.d.ts +33 -2
- package/dist/workgraph/types.d.ts.map +1 -1
- package/docs/rubric/author.md +17 -0
- package/docs/rubric/scope.md +16 -0
- package/package.json +4 -3
- package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +9 -0
- package/packs/builtin/coding-flow/skills/execute-gate/skill.yaml +19 -12
- package/packs/builtin/coding-flow/skills/scope-lifecycle/skill.yaml +67 -50
- package/packs/builtin/default-discipline/manifest.yaml +6 -3
- package/packs/builtin/default-discipline/skills/workflow/skill.yaml +7 -3
- package/packs/builtin/pack-architect/SKILL.md +10 -0
- package/packs/builtin/pack-architect/skills/skill-yaml-author-walkthrough/skill.yaml +7 -0
- package/packs/builtin/scope-architect/team.yaml +5 -2
- package/schemas/manifest.schema.json +45 -203
- package/schemas/models.schema.json +3 -13
- package/schemas/notifications.schema.json +6 -24
- package/schemas/skill.schema.json +33 -120
- package/schemas/team.schema.json +46 -0
|
@@ -89,6 +89,15 @@ rules:
|
|
|
89
89
|
args:
|
|
90
90
|
key: coding-flow-track
|
|
91
91
|
value: trivial
|
|
92
|
+
# TR.B (wg-2d1d8698f563): deliver the coding-flow quality rubric to the agent BEFORE it authors — the
|
|
93
|
+
# fix for the blind-first-draft root cause. Placed AFTER enter-scoping so the cold kickoff turn's
|
|
94
|
+
# just-armed `scoping` is visible (rules walk file-order; handoff-rescope-nudge below relies on the same
|
|
95
|
+
# ordering). rubric_pre_inject reads the coding-flow FSM and, when in an active SCOPE/AUTHOR phase, returns
|
|
96
|
+
# an inject_context payload carrying the FULL rubric (scope + author — prompt_submit can't track mid-turn
|
|
97
|
+
# phase advances, so one injection must cover the whole uninterrupted turn). Inject-only; never blocks.
|
|
98
|
+
- id: inject-rubric
|
|
99
|
+
process:
|
|
100
|
+
- call: rubric_pre_inject
|
|
92
101
|
# GF.1 (F9) — the re-scope NUDGE, surfaced on prompt_submit (where directives are
|
|
93
102
|
# delivered) for the `scoping` state. Fires after `enter-scoping` advanced idle→scoping
|
|
94
103
|
# (or after task-start's task_unscoped reset, or GF.7's phases_complete re-arm landed
|
|
@@ -15,18 +15,25 @@ triggers:
|
|
|
15
15
|
rules:
|
|
16
16
|
- id: phase-logged-before-commit
|
|
17
17
|
process:
|
|
18
|
-
-
|
|
18
|
+
# T-GATE-MATCHER-SUBSTRING (GM.3, wg-52e57e2ed252): was a raw-string `match_command`
|
|
19
|
+
# regex `\bgit…commit\b` over the whole command — it false-fired on `git commit` inside a
|
|
20
|
+
# grep pattern, an echo arg, or a quoted subprocess prompt (`claude -p "…git commit…"`).
|
|
21
|
+
# `command_invokes` parses the command into real shell segments and matches only a genuine
|
|
22
|
+
# `git commit` INVOCATION (compounds like `cd x && git commit` still match; the owned git
|
|
23
|
+
# pre-commit hook stays the hard boundary). Recall-over-precision band-aid retired.
|
|
24
|
+
- call: command_invokes
|
|
19
25
|
args:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
# actually made, since the Bash tool resets cwd) starts with `cd` and EVADED the
|
|
23
|
-
# gate entirely. The gate was dead for real commits. Match `git … commit` ANYWHERE
|
|
24
|
-
# (`\b`, like the sibling no-verify matcher) so compounds can't slip past. A false
|
|
25
|
-
# match on a string that merely mentions `git commit` is the safe direction (recall
|
|
26
|
-
# over precision, same as no-verify-block).
|
|
27
|
-
pattern: '\bgit\s+(?:-[cC]\s+\S+\s+)*commit\b'
|
|
28
|
-
target: tool_args.command
|
|
26
|
+
program: git
|
|
27
|
+
subcommand: commit
|
|
29
28
|
as: committing
|
|
29
|
+
# T-commit-nudge-docsonly-parity (wg-3dcca3b29ed1): a docs-only commit the git-owned
|
|
30
|
+
# HARD gate ALLOWS (gate.ts isDocsOnly) must not be over-blocked by this in-session gate
|
|
31
|
+
# either — predicate parity, the SAME `staged_docs_only` primitive the default-discipline
|
|
32
|
+
# nudge uses. Reads the staged diff (fixed-argv git); fails toward `false` (= not docs-only
|
|
33
|
+
# = the gate still fires) on any error, so it can never falsely SUPPRESS a real code block.
|
|
34
|
+
- call: staged_docs_only
|
|
35
|
+
if: 'committing'
|
|
36
|
+
as: docs_only
|
|
30
37
|
# T-FLOW-UNSKIPPABLE FU.1 (D1): the gates must COMPOSE. The "no active task ⇒
|
|
31
38
|
# ad-hoc ⇒ allow" branch below was a SEAM — a blocked TaskCreate (AUTHOR gate)
|
|
32
39
|
# leaves NO active task, so its code leaked out as an "ad-hoc" commit. Close it:
|
|
@@ -39,7 +46,7 @@ rules:
|
|
|
39
46
|
if: 'committing'
|
|
40
47
|
as: st
|
|
41
48
|
- call: verdict
|
|
42
|
-
if: 'committing && (st == "scoping" || st == "researching" || st == "researched" || st == "spec_authored")'
|
|
49
|
+
if: 'committing && !docs_only && (st == "scoping" || st == "researching" || st == "researched" || st == "spec_authored")'
|
|
43
50
|
args:
|
|
44
51
|
level: block
|
|
45
52
|
message: >-
|
|
@@ -54,7 +61,7 @@ rules:
|
|
|
54
61
|
if: 'committing && active.present == true'
|
|
55
62
|
as: phases
|
|
56
63
|
- call: verdict
|
|
57
|
-
if: 'committing && active.present == true && phases.complete == false'
|
|
64
|
+
if: 'committing && active.present == true && phases.complete == false && !docs_only'
|
|
58
65
|
args:
|
|
59
66
|
level: block
|
|
60
67
|
message: >-
|
|
@@ -43,7 +43,9 @@ rules:
|
|
|
43
43
|
# checks run BEFORE the advance, and research_done is COUPLED to them — no
|
|
44
44
|
# advisory pass. The advance fires ONLY when SCOPE content is complete:
|
|
45
45
|
# GUESS_FREE (every claim cited-or-flagged + the BEST/simplest solution justified)
|
|
46
|
-
# AND zero unresolved
|
|
46
|
+
# AND zero unresolved open-question markers (an unchecked `- [ ] OPEN QUESTION:` task-list
|
|
47
|
+
# item — GM.3 made this a STRUCTURED marker so prose that merely mentions the phrase no
|
|
48
|
+
# longer false-blocks) AND research depth >= 3 this turn.
|
|
47
49
|
- id: scope-advance
|
|
48
50
|
process:
|
|
49
51
|
- call: tool_name
|
|
@@ -94,8 +96,23 @@ rules:
|
|
|
94
96
|
# latency (268s worst observed under subscription contention, 2026-06-10)
|
|
95
97
|
# and 20s under the 360s outer hook cap the setup wizard writes — the
|
|
96
98
|
# inner timer must die first so the gate fails with a readable error.
|
|
97
|
-
-
|
|
99
|
+
# TR.A (wg-2d1d8698f563): the rubric is single-sourced to docs/rubric/scope.md and interpolated as
|
|
100
|
+
# {{rubric}} below — NOT hardcoded here. read_rubric returns null on a missing/unreadable fragment.
|
|
101
|
+
- call: read_rubric
|
|
98
102
|
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-")'
|
|
103
|
+
args: { name: scope }
|
|
104
|
+
as: rubric
|
|
105
|
+
# FAIL-LOUD: never run the audit rubric-less (a rubric-less verdict would be a silent fallback worse
|
|
106
|
+
# than fail-open). docs/rubric/scope.md MUST ship (package.json files[]).
|
|
107
|
+
- call: verdict
|
|
108
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && rubric == null'
|
|
109
|
+
args:
|
|
110
|
+
level: block
|
|
111
|
+
message: >-
|
|
112
|
+
SCOPE audit cannot run: the canonical rubric (docs/rubric/scope.md) is unreadable — a
|
|
113
|
+
packaging/install fault, NOT a content failure. Verify the opensquid package ships docs/rubric/.
|
|
114
|
+
- call: cached_audit
|
|
115
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && rubric != null'
|
|
99
116
|
on_error: continue
|
|
100
117
|
args:
|
|
101
118
|
cache_key: coding-flow-guess-audit-cache
|
|
@@ -103,16 +120,8 @@ rules:
|
|
|
103
120
|
timeout_ms: 340000
|
|
104
121
|
prompt: >-
|
|
105
122
|
You are an adversarial reviewer enforcing the lexicon's Research/Audit flow
|
|
106
|
-
principles
|
|
107
|
-
|
|
108
|
-
evidence (a file:line, a memory, or the user's own words) OR explicitly flagged
|
|
109
|
-
as an OPEN QUESTION to ask the user. (2) BEST-SOLUTION: the artifact must show
|
|
110
|
-
the best solution was found — alternatives weighed against the criteria and the
|
|
111
|
-
SIMPLEST correct one chosen per docs/lexicon.md (no proliferating special-cases).
|
|
112
|
-
(3) FULL-FIX: the chosen solution must be the FULL fix — when the existing shape
|
|
113
|
-
is the cause, it is re-architected, NOT a local patch that bolts on a special-case
|
|
114
|
-
to dodge the rework (that patch is itself the proliferating-special-case
|
|
115
|
-
overcomplication the Full-fix-over-patch guideline forbids).
|
|
123
|
+
principles on a pre-research / scope artifact. Apply EXACTLY this rubric (the single
|
|
124
|
+
canonical source, docs/rubric/scope.md):\n\n{{rubric}}\n\n
|
|
116
125
|
Begin your response with EXACTLY one line — `VERDICT: GUESS_FREE` ONLY if every
|
|
117
126
|
claim is cited-or-flagged-open AND the simplest-correct solution is justified
|
|
118
127
|
against alternatives AND is a full fix, not a patch around a design that should be
|
|
@@ -124,18 +133,20 @@ rules:
|
|
|
124
133
|
# audit-string trichotomy below is a clean partition over its own subspace.
|
|
125
134
|
# BLOCK: unresolved open questions — answer them in SCOPE (this is the interactive phase).
|
|
126
135
|
- call: verdict
|
|
127
|
-
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") &&
|
|
136
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && match(effective, "(?im)^\\s*-\\s*\\[ \\]\\s*open[ _-]?question")'
|
|
128
137
|
args:
|
|
129
138
|
level: block
|
|
130
139
|
message: >-
|
|
131
|
-
SCOPE incomplete: the pre-research still has unresolved
|
|
132
|
-
|
|
133
|
-
the
|
|
134
|
-
|
|
140
|
+
SCOPE incomplete: the pre-research still has an unresolved open-question marker
|
|
141
|
+
(an unchecked `- [ ] OPEN QUESTION: …` task-list item). SCOPE is the interactive
|
|
142
|
+
phase — ASK the user (AskUserQuestion), record + cite the answer, then CHECK THE BOX
|
|
143
|
+
(`- [x]`) or remove the item BEFORE authoring. Everything after scope is automated;
|
|
144
|
+
a question must not survive into it. (Merely MENTIONING the phrase in prose is fine —
|
|
145
|
+
only an unchecked checkbox marker blocks.)
|
|
135
146
|
# BLOCK: shallow research (folded DPC.5 depth). Ordered after open-question; its
|
|
136
|
-
# !
|
|
147
|
+
# !match(OQ-marker) guard keeps the two preconditions mutually exclusive.
|
|
137
148
|
- call: verdict
|
|
138
|
-
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && !
|
|
149
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && !match(effective, "(?im)^\\s*-\\s*\\[ \\]\\s*open[ _-]?question") && depth.count < 3'
|
|
139
150
|
args:
|
|
140
151
|
level: block
|
|
141
152
|
message: >-
|
|
@@ -145,17 +156,17 @@ rules:
|
|
|
145
156
|
# {GUESS_FREE, UNRESOLVED, no-VERDICT} is a total partition of the audit string.
|
|
146
157
|
# PASS → advance.
|
|
147
158
|
- call: advance_fsm
|
|
148
|
-
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && depth.count >= 3 && !
|
|
159
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && depth.count >= 3 && !match(effective, "(?im)^\\s*-\\s*\\[ \\]\\s*open[ _-]?question") && contains(audit, "VERDICT: GUESS_FREE")'
|
|
149
160
|
args:
|
|
150
161
|
event: research_done
|
|
151
162
|
# CONTENT-FAIL → loop-back + warn (keyed POSITIVELY on UNRESOLVED, not !GUESS_FREE — so an
|
|
152
163
|
# audit that could not run no longer masquerades as "guesses found").
|
|
153
164
|
- call: advance_fsm
|
|
154
|
-
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && depth.count >= 3 && !
|
|
165
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && depth.count >= 3 && !match(effective, "(?im)^\\s*-\\s*\\[ \\]\\s*open[ _-]?question") && contains(audit, "VERDICT: UNRESOLVED")'
|
|
155
166
|
args:
|
|
156
167
|
event: guess_found
|
|
157
168
|
- call: verdict
|
|
158
|
-
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && depth.count >= 3 && !
|
|
169
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && depth.count >= 3 && !match(effective, "(?im)^\\s*-\\s*\\[ \\]\\s*open[ _-]?question") && contains(audit, "VERDICT: UNRESOLVED")'
|
|
159
170
|
args:
|
|
160
171
|
level: warn
|
|
161
172
|
message: >-
|
|
@@ -166,7 +177,7 @@ rules:
|
|
|
166
177
|
# AUDIT-UNAVAILABLE → terminal BLOCK, NO advance (stays scoping, re-armable). F0c fix:
|
|
167
178
|
# the audit subagent could not spawn (a no-VERDICT response, incl. the bound err message).
|
|
168
179
|
- call: verdict
|
|
169
|
-
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && depth.count >= 3 && !
|
|
180
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/research/") && contains(targs.file_path, "-pre-research-") && depth.count >= 3 && !match(effective, "(?im)^\\s*-\\s*\\[ \\]\\s*open[ _-]?question") && rubric != null && !contains(audit, "VERDICT:")'
|
|
170
181
|
args:
|
|
171
182
|
level: block
|
|
172
183
|
message: >-
|
|
@@ -214,25 +225,29 @@ rules:
|
|
|
214
225
|
# SCOPE audit — a re-fire on an UNCHANGED spec reuses the verdict, no spawn.
|
|
215
226
|
# timeout_ms (T-AUDIT-SPAWN-FIX): 340s, same measured sizing as the SCOPE
|
|
216
227
|
# audit above (268s worst observed; 20s under the 360s outer hook cap).
|
|
217
|
-
-
|
|
228
|
+
# TR.A (wg-2d1d8698f563): the AUTHOR rubric is single-sourced to docs/rubric/author.md,
|
|
229
|
+
# interpolated as {{rubric}} below — NOT hardcoded. Fail-loud on a missing fragment (below).
|
|
230
|
+
- call: read_rubric
|
|
218
231
|
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/tasks/T-") && endsWith(targs.file_path, ".md")'
|
|
232
|
+
args: { name: author }
|
|
233
|
+
as: rubric
|
|
234
|
+
- call: verdict
|
|
235
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/tasks/T-") && endsWith(targs.file_path, ".md") && rubric == null'
|
|
236
|
+
args:
|
|
237
|
+
level: block
|
|
238
|
+
message: >-
|
|
239
|
+
AUTHOR audit cannot run: the canonical rubric (docs/rubric/author.md) is unreadable — a
|
|
240
|
+
packaging/install fault, NOT a content failure. Verify the opensquid package ships docs/rubric/.
|
|
241
|
+
- call: cached_audit
|
|
242
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/tasks/T-") && endsWith(targs.file_path, ".md") && rubric != null'
|
|
219
243
|
on_error: continue
|
|
220
244
|
args:
|
|
221
245
|
cache_key: coding-flow-spec-audit-cache
|
|
222
246
|
model: reasoning
|
|
223
247
|
timeout_ms: 340000
|
|
224
248
|
prompt: >-
|
|
225
|
-
You are an adversarial reviewer enforcing THREE author-completeness rules.
|
|
226
|
-
|
|
227
|
-
skills, Deliverable, Depends on, Files affected, Key code shapes, Test
|
|
228
|
-
fixtures, Acceptance criteria, Risk callouts, References, Verification
|
|
229
|
-
commands, 7-phase steps), every Key-code-shapes block is REAL code (not
|
|
230
|
-
pseudocode), every 7-phase step names concrete files/decisions. (2) 100%
|
|
231
|
-
DESIGN COVERAGE: the task set covers EVERY element of the SCOPE design below —
|
|
232
|
-
no design item is left without a task. (3) SIMPLICITY (per docs/lexicon.md):
|
|
233
|
-
the design is the SIMPLEST correct solution — no proliferating special-cases
|
|
234
|
-
(that signals a missed decomposition), every lifecycle an explicit
|
|
235
|
-
total-transition FSM, every transform a pure function, no implicit state.
|
|
249
|
+
You are an adversarial reviewer enforcing THREE author-completeness rules. Apply EXACTLY
|
|
250
|
+
this rubric (the single canonical source, docs/rubric/author.md):\n\n{{rubric}}\n\n
|
|
236
251
|
Begin your response with EXACTLY one line — `VERDICT: SPEC_COMPLETE` ONLY if
|
|
237
252
|
ALL THREE hold; otherwise `VERDICT: INCOMPLETE` + one bullet per offending
|
|
238
253
|
block, uncovered design element, OR over-complected smell. Never say
|
|
@@ -260,7 +275,7 @@ rules:
|
|
|
260
275
|
Audit:\n\n{{spec_audit}}
|
|
261
276
|
# AUDIT-UNAVAILABLE → BLOCK, no advance (stays spec_authored, re-armable). F0c fix.
|
|
262
277
|
- call: verdict
|
|
263
|
-
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/tasks/T-") && endsWith(targs.file_path, ".md") && !contains(spec_audit, "VERDICT:")'
|
|
278
|
+
if: '(tool == "Write" || tool == "Edit") && contains(targs.file_path, "docs/tasks/T-") && endsWith(targs.file_path, ".md") && rubric != null && !contains(spec_audit, "VERDICT:")'
|
|
264
279
|
args:
|
|
265
280
|
level: block
|
|
266
281
|
message: >-
|
|
@@ -303,25 +318,27 @@ rules:
|
|
|
303
318
|
code commit/push that has not completed the flow.)
|
|
304
319
|
# ── verify-skip detector: the ONE closed opt-out token (GF.3) ────────────────
|
|
305
320
|
# The git gate (GF.2) is bypassable only by passing the verify-skipping flag to `git
|
|
306
|
-
# commit/push`
|
|
307
|
-
#
|
|
308
|
-
#
|
|
309
|
-
#
|
|
310
|
-
#
|
|
311
|
-
#
|
|
312
|
-
#
|
|
313
|
-
#
|
|
321
|
+
# commit/push` — a single explicit opt-out (not a denylist over an open set), so it is a
|
|
322
|
+
# hard BLOCK. `git push -n` is --dry-run, NOT a verify-skip, so `-n` is matched for `commit`
|
|
323
|
+
# ONLY (git-commit(1) `-n,--no-verify`; git-push(1) `-n,--dry-run`).
|
|
324
|
+
# T-GATE-MATCHER-SUBSTRING (GM.3, wg-52e57e2ed252): was a raw-string `match_command` that
|
|
325
|
+
# false-fired on a read-only `grep -n "…git commit…"` (the prose `git commit` + grep's `-n`).
|
|
326
|
+
# `command_invokes` parses real shell segments and detects the flag only WITHIN a genuine git
|
|
327
|
+
# invocation — so a real `git commit --no-verify`/`-n` still blocks (recall preserved within the
|
|
328
|
+
# invocation), but prose/grep/echo no longer trip it. The old "over-block is intentional"
|
|
329
|
+
# band-aid is retired: blocking read-only work gave zero bypass-protection value.
|
|
314
330
|
- id: no-verify-block
|
|
315
331
|
process:
|
|
316
332
|
- call: tool_name
|
|
317
333
|
as: tool
|
|
318
|
-
- call:
|
|
319
|
-
args:
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
334
|
+
- call: command_invokes
|
|
335
|
+
args: { program: git, subcommand: commit, flag_any: ['--no-verify', '-n'] }
|
|
336
|
+
as: skip_commit
|
|
337
|
+
- call: command_invokes
|
|
338
|
+
args: { program: git, subcommand: push, flag_any: ['--no-verify'] }
|
|
339
|
+
as: skip_push
|
|
323
340
|
- call: verdict
|
|
324
|
-
if: '(tool == "Bash") &&
|
|
341
|
+
if: '(tool == "Bash") && (skip_commit || skip_push)'
|
|
325
342
|
args:
|
|
326
343
|
level: block
|
|
327
344
|
message: >-
|
|
@@ -34,13 +34,16 @@ evolves: true
|
|
|
34
34
|
# command-boundary prefixes survive).
|
|
35
35
|
guards:
|
|
36
36
|
# git hygiene (block_tool)
|
|
37
|
+
# T-GATE-MATCHER-SUBSTRING (GM.3, wg-52e57e2ed252): structural — matches a real
|
|
38
|
+
# `git commit --amend` invocation, not the substring inside a grep/echo/prompt.
|
|
37
39
|
- name: never-amend
|
|
38
40
|
on: tool_call
|
|
39
41
|
detect:
|
|
40
|
-
call:
|
|
42
|
+
call: command_invokes
|
|
41
43
|
args:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
program: git
|
|
45
|
+
subcommand: commit
|
|
46
|
+
flag_any: ['--amend']
|
|
44
47
|
when: hit
|
|
45
48
|
level: block
|
|
46
49
|
message: >-
|
|
@@ -34,10 +34,14 @@ rules:
|
|
|
34
34
|
|
|
35
35
|
- id: phase-logged-before-commit
|
|
36
36
|
process:
|
|
37
|
-
-
|
|
37
|
+
# T-GATE-MATCHER-SUBSTRING (GM.3, wg-52e57e2ed252): was a raw-string regex over the whole
|
|
38
|
+
# command (boundary-anchored, but still matched `; git commit` inside a quoted echo/prompt).
|
|
39
|
+
# `command_invokes` parses real shell segments → matches only a genuine `git commit`
|
|
40
|
+
# invocation (compounds like `cd … && git commit` still match).
|
|
41
|
+
- call: command_invokes
|
|
38
42
|
args:
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
program: git
|
|
44
|
+
subcommand: commit
|
|
41
45
|
as: committing
|
|
42
46
|
- call: read_state
|
|
43
47
|
if: committing
|
|
@@ -35,6 +35,16 @@ but the chain-handoff stalls.
|
|
|
35
35
|
| `skill-yaml-author-walkthrough` | PreToolUse Edit/Write of `packs/*/skills/*/skill.yaml` | Surface verdict with skill-field checklist (cites pack-runtime.md §2 + skill-grammar-guide.md) |
|
|
36
36
|
| `fsm-author-walkthrough` | PreToolUse Edit/Write of `packs/*/fsm.yaml` | Surface verdict with FSM checklist (cites pack-fsm-architecture.md; coding-flow example) |
|
|
37
37
|
|
|
38
|
+
### Discipline: gates teach their rubric (TR.C, wg-2d1d8698f563)
|
|
39
|
+
|
|
40
|
+
A gate is not just a blocker — it must TEACH its bar. If a skill emits a block/audit verdict with a content
|
|
41
|
+
rubric (like coding-flow's guess/spec audits), it must ship a companion that DELIVERS that rubric to the
|
|
42
|
+
agent BEFORE the gated action, sourced from the gate's single canonical rubric (e.g. `read_rubric` →
|
|
43
|
+
`inject_context` at `prompt_submit`). Otherwise the agent authors content-blind and learns the bar only by
|
|
44
|
+
tripping the gate. Light block/warn gates (no heavy content rubric) teach via a remedy-naming message
|
|
45
|
+
instead. The `skill-yaml-author-walkthrough` checklist enforces this; the coding-flow pairing is the
|
|
46
|
+
reference implementation.
|
|
47
|
+
|
|
38
48
|
## The 4-phase pack-authoring workflow (when spawned as profession)
|
|
39
49
|
|
|
40
50
|
1. **Identify scope + persona** — kind/usage decisions, detected_by
|
|
@@ -45,6 +45,13 @@ rules:
|
|
|
45
45
|
functions per skill-grammar-guide.md
|
|
46
46
|
[ ] Final step emits a verdict
|
|
47
47
|
(pass / block / warn / surface / directive)
|
|
48
|
+
[ ] GATES TEACH (TR.C, wg-2d1d8698f563): if a rule emits a
|
|
49
|
+
block/audit verdict (a GATE with a content rubric), ship a
|
|
50
|
+
companion that DELIVERS that gate's rubric to the agent BEFORE
|
|
51
|
+
the gated action, sourced from the gate's canonical rubric
|
|
52
|
+
(e.g. read_rubric → inject_context at prompt_submit). A gate
|
|
53
|
+
teaches its bar; it does not only block. (Light block/warn
|
|
54
|
+
gates teach via a remedy-naming message instead.)
|
|
48
55
|
[ ] For directive verdict: next_action is skill XOR tool
|
|
49
56
|
XOR profession (exactly one)
|
|
50
57
|
[ ] No vendor model names anywhere (use model_alias)
|
|
@@ -61,5 +61,8 @@ roles:
|
|
|
61
61
|
weighed against the criteria with the SIMPLEST-correct chosen;
|
|
62
62
|
failure-modes / inversion; an empirical-spike note; a scope boundary;
|
|
63
63
|
and EVERY claim cited (file:line / memory / the user's words) or
|
|
64
|
-
flagged
|
|
65
|
-
|
|
64
|
+
flagged as an unchecked `- [ ] OPEN QUESTION: …` task-list marker — and
|
|
65
|
+
such a marker must be resolved with the user IN SCOPE before the write
|
|
66
|
+
(check the box `- [x]` once answered), never carried unresolved into the
|
|
67
|
+
artifact. (Merely discussing an open question in prose is fine; only an
|
|
68
|
+
unchecked checkbox marker blocks the advance.)
|