claude-dev-env 2.10.0 → 2.12.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/CLAUDE.md +1 -1
- package/_shared/advisor/CLAUDE.md +3 -2
- package/_shared/advisor/advisor-protocol.md +74 -108
- package/_shared/advisor/reference/advisor-block.md +37 -0
- package/_shared/advisor/reference/cli-chain.md +45 -0
- package/_shared/advisor/reference/consult-format.md +41 -0
- package/_shared/advisor/reference/lifecycle.md +21 -0
- package/_shared/advisor/reference/sol-rung.md +34 -0
- package/_shared/advisor/reference/spawn-walk-log.md +31 -0
- package/_shared/advisor/reference/third-party-bind.md +30 -0
- package/_shared/advisor/reference/warm-up.md +34 -0
- package/_shared/advisor/scripts/codex_sol_advisor.py +514 -0
- package/_shared/advisor/scripts/config/advisor_scripts_constants/advisor_route_constants.py +21 -0
- package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +19 -17
- package/_shared/advisor/scripts/config/advisor_scripts_constants/sol_advisor_constants.py +33 -0
- package/_shared/advisor/scripts/model_tier_run_validator.py +32 -9
- package/_shared/advisor/scripts/tests/test_codex_sol_advisor.py +636 -0
- package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +79 -0
- package/_shared/advisor/scripts/tests/test_tier_model_ids.py +39 -17
- package/_shared/advisor/scripts/tier_model_ids.py +24 -0
- package/commands/CLAUDE.md +1 -0
- package/commands/sr-loop.md +48 -0
- package/docs/references/CLAUDE.md +2 -1
- package/docs/references/advisor-tool.md +26 -8
- package/docs/references/team-advisor-skill.md +3 -3
- package/docs/references/weak-executor-advisor.md +91 -0
- package/hooks/blocking/test_fable_spawn_gate.py +18 -11
- package/package.json +1 -1
- package/skills/_shared/advisor/CLAUDE.md +1 -1
- package/skills/_shared/advisor/scripts/README.md +2 -0
- package/skills/grokify/SKILL.md +1 -1
- package/skills/grokify/templates/handoff-template.md +2 -2
- package/skills/orchestrator/SKILL.md +5 -4
- package/skills/team-advisor/SKILL.md +7 -4
- package/skills/team-advisor/reference/advisor-docs-review.md +207 -0
- package/skills/usage-pause/SKILL.md +1 -1
- package/skills/usage-pause/scripts/resolve_usage_window.py +32 -4
- package/skills/usage-pause/scripts/test_resolve_usage_window.py +26 -0
- package/skills/usage-pause/scripts/usage_pause_constants/resolve_usage_window_constants.py +3 -1
|
@@ -33,6 +33,8 @@ main = model_tier_run_validator.main
|
|
|
33
33
|
load_model_tier_run_from_json_path = (
|
|
34
34
|
model_tier_run_validator.load_model_tier_run_from_json_path
|
|
35
35
|
)
|
|
36
|
+
ADVISOR_MODEL_TIER = model_tier_run_validator.ADVISOR_MODEL_TIER
|
|
37
|
+
CODEX_BIND_SUCCESS_TOKEN = model_tier_run_validator.CODEX_BIND_SUCCESS_TOKEN
|
|
36
38
|
|
|
37
39
|
|
|
38
40
|
def test_clean_single_spawn_at_top_of_slice_passes() -> None:
|
|
@@ -45,6 +47,66 @@ def test_clean_single_spawn_at_top_of_slice_passes() -> None:
|
|
|
45
47
|
assert validate_model_tier_run(run) is None
|
|
46
48
|
|
|
47
49
|
|
|
50
|
+
def test_sol_codex_bind_is_first_success_when_enabled() -> None:
|
|
51
|
+
run = ModelTierRun(
|
|
52
|
+
own_tier="Opus",
|
|
53
|
+
candidate_tiers=[ADVISOR_MODEL_TIER, "Fable", "Opus"],
|
|
54
|
+
attempts=[{"tier": ADVISOR_MODEL_TIER, "result": CODEX_BIND_SUCCESS_TOKEN}],
|
|
55
|
+
selected_tier=ADVISOR_MODEL_TIER,
|
|
56
|
+
is_sol_enabled=True,
|
|
57
|
+
)
|
|
58
|
+
assert validate_model_tier_run(run) is None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_sol_failure_falls_through_to_fable_when_enabled() -> None:
|
|
62
|
+
run = ModelTierRun(
|
|
63
|
+
own_tier="Opus",
|
|
64
|
+
candidate_tiers=[ADVISOR_MODEL_TIER, "Fable", "Opus"],
|
|
65
|
+
attempts=[
|
|
66
|
+
{"tier": ADVISOR_MODEL_TIER, "result": "unavailable"},
|
|
67
|
+
{"tier": "Fable", "result": "spawned"},
|
|
68
|
+
],
|
|
69
|
+
selected_tier="Fable",
|
|
70
|
+
is_sol_enabled=True,
|
|
71
|
+
)
|
|
72
|
+
assert validate_model_tier_run(run) is None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_sol_rung_precedes_third_party_cli_floor_when_enabled() -> None:
|
|
76
|
+
run = ModelTierRun(
|
|
77
|
+
own_tier="ThirdParty",
|
|
78
|
+
candidate_tiers=[ADVISOR_MODEL_TIER, "Fable", "Opus"],
|
|
79
|
+
attempts=[{"tier": ADVISOR_MODEL_TIER, "result": CODEX_BIND_SUCCESS_TOKEN}],
|
|
80
|
+
selected_tier=ADVISOR_MODEL_TIER,
|
|
81
|
+
is_sol_enabled=True,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
assert validate_model_tier_run(run) is None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_sol_codex_result_requires_sol_candidate() -> None:
|
|
88
|
+
run = ModelTierRun(
|
|
89
|
+
own_tier="Opus",
|
|
90
|
+
candidate_tiers=["Fable", "Opus"],
|
|
91
|
+
attempts=[{"tier": "Fable", "result": CODEX_BIND_SUCCESS_TOKEN}],
|
|
92
|
+
selected_tier="Fable",
|
|
93
|
+
)
|
|
94
|
+
with pytest.raises(ModelTierRunError):
|
|
95
|
+
validate_model_tier_run(run)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_sol_spawned_result_does_not_count_as_codex_success() -> None:
|
|
99
|
+
run = ModelTierRun(
|
|
100
|
+
own_tier="Opus",
|
|
101
|
+
candidate_tiers=[ADVISOR_MODEL_TIER, "Fable", "Opus"],
|
|
102
|
+
attempts=[{"tier": ADVISOR_MODEL_TIER, "result": "spawned"}],
|
|
103
|
+
selected_tier=ADVISOR_MODEL_TIER,
|
|
104
|
+
is_sol_enabled=True,
|
|
105
|
+
)
|
|
106
|
+
with pytest.raises(ModelTierRunError):
|
|
107
|
+
validate_model_tier_run(run)
|
|
108
|
+
|
|
109
|
+
|
|
48
110
|
def test_fallthrough_to_floor_tier_passes() -> None:
|
|
49
111
|
run = ModelTierRun(
|
|
50
112
|
own_tier="Opus",
|
|
@@ -223,6 +285,23 @@ def test_cli_validates_json_log_file(tmp_path: Path) -> None:
|
|
|
223
285
|
assert loaded_run.selected_tier == "Fable"
|
|
224
286
|
|
|
225
287
|
|
|
288
|
+
def test_cli_rejects_non_boolean_sol_enabled(tmp_path: Path) -> None:
|
|
289
|
+
log_path = tmp_path / "invalid-sol-enabled.json"
|
|
290
|
+
log_path.write_text(
|
|
291
|
+
json.dumps(
|
|
292
|
+
{
|
|
293
|
+
"own_tier": "Opus",
|
|
294
|
+
"candidate_tiers": ["Fable", "Opus"],
|
|
295
|
+
"attempts": [{"tier": "Fable", "result": "spawned"}],
|
|
296
|
+
"selected_tier": "Fable",
|
|
297
|
+
"sol_enabled": "false",
|
|
298
|
+
}
|
|
299
|
+
),
|
|
300
|
+
encoding="utf-8",
|
|
301
|
+
)
|
|
302
|
+
assert main([str(log_path)]) == 2
|
|
303
|
+
|
|
304
|
+
|
|
226
305
|
def test_cli_rejects_incomplete_fallback_log(tmp_path: Path) -> None:
|
|
227
306
|
log_path = tmp_path / "incomplete-walk.json"
|
|
228
307
|
log_path.write_text(
|
|
@@ -10,6 +10,26 @@ from types import ModuleType
|
|
|
10
10
|
import pytest
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
constants_root = Path(__file__).parent.parent / "config"
|
|
14
|
+
if str(constants_root) not in sys.path:
|
|
15
|
+
sys.path.insert(0, str(constants_root))
|
|
16
|
+
|
|
17
|
+
from advisor_scripts_constants.model_tier_run_validator_constants import ( # noqa: E402
|
|
18
|
+
ADVISOR_SENDMESSAGE_REPLY_WAIT_SECONDS,
|
|
19
|
+
ALL_CLI_MODEL_ID_BY_TIER,
|
|
20
|
+
ALL_KNOWN_TIER_NAMES,
|
|
21
|
+
ALL_MODEL_TIERS,
|
|
22
|
+
HOST_PROFILE_CLAUDE,
|
|
23
|
+
HOST_PROFILE_THIRD_PARTY,
|
|
24
|
+
THIRD_PARTY_MODEL_TIER,
|
|
25
|
+
)
|
|
26
|
+
from advisor_scripts_constants.advisor_route_constants import ( # noqa: E402
|
|
27
|
+
ADVISOR_CODEX_MODEL_ID,
|
|
28
|
+
ADVISOR_MODEL_TIER,
|
|
29
|
+
ALL_CODEX_MODEL_ID_BY_TIER,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
13
33
|
def _load_tier_model_ids_module() -> ModuleType:
|
|
14
34
|
scripts_root = Path(__file__).parent.parent
|
|
15
35
|
module_path = scripts_root / "tier_model_ids.py"
|
|
@@ -26,21 +46,9 @@ def _load_tier_model_ids_module() -> ModuleType:
|
|
|
26
46
|
|
|
27
47
|
tier_model_ids = _load_tier_model_ids_module()
|
|
28
48
|
resolve_cli_model_id = tier_model_ids.resolve_cli_model_id
|
|
49
|
+
resolve_codex_model_id = tier_model_ids.resolve_codex_model_id
|
|
29
50
|
canonical_tier_name = tier_model_ids.canonical_tier_name
|
|
30
51
|
detect_host_profile = tier_model_ids.detect_host_profile
|
|
31
|
-
constants_root = Path(__file__).parent.parent / "config"
|
|
32
|
-
if str(constants_root) not in sys.path:
|
|
33
|
-
sys.path.insert(0, str(constants_root))
|
|
34
|
-
|
|
35
|
-
from advisor_scripts_constants.model_tier_run_validator_constants import ( # noqa: E402
|
|
36
|
-
ADVISOR_SENDMESSAGE_REPLY_WAIT_SECONDS,
|
|
37
|
-
ALL_CLI_MODEL_ID_BY_TIER,
|
|
38
|
-
ALL_KNOWN_TIER_NAMES,
|
|
39
|
-
ALL_MODEL_TIERS,
|
|
40
|
-
HOST_PROFILE_CLAUDE,
|
|
41
|
-
HOST_PROFILE_THIRD_PARTY,
|
|
42
|
-
THIRD_PARTY_MODEL_TIER,
|
|
43
|
-
)
|
|
44
52
|
|
|
45
53
|
SCRIPTS_ROOT = Path(__file__).parent.parent
|
|
46
54
|
DOCUMENTED_RESOLVE_ONE_LINER = (
|
|
@@ -94,14 +102,28 @@ def test_sendmessage_reply_wait_is_positive_bound() -> None:
|
|
|
94
102
|
assert ADVISOR_SENDMESSAGE_REPLY_WAIT_SECONDS == 120
|
|
95
103
|
|
|
96
104
|
|
|
105
|
+
def test_resolve_codex_model_id_maps_sol() -> None:
|
|
106
|
+
assert resolve_codex_model_id(f" {ADVISOR_MODEL_TIER.lower()} ") == (
|
|
107
|
+
ADVISOR_CODEX_MODEL_ID
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_resolve_codex_model_id_rejects_claude_tier() -> None:
|
|
112
|
+
with pytest.raises(ValueError, match="not a known model tier"):
|
|
113
|
+
resolve_codex_model_id("Opus")
|
|
114
|
+
|
|
115
|
+
|
|
97
116
|
def test_cli_model_alias_map_keys_match_known_tiers() -> None:
|
|
98
|
-
|
|
117
|
+
all_cli_tiers = (*ALL_MODEL_TIERS, THIRD_PARTY_MODEL_TIER)
|
|
118
|
+
assert set(ALL_CLI_MODEL_ID_BY_TIER) == set(all_cli_tiers)
|
|
99
119
|
assert set(ALL_MODEL_TIERS).issubset(set(ALL_KNOWN_TIER_NAMES))
|
|
120
|
+
assert ADVISOR_MODEL_TIER in ALL_KNOWN_TIER_NAMES
|
|
100
121
|
assert THIRD_PARTY_MODEL_TIER in ALL_KNOWN_TIER_NAMES
|
|
101
122
|
assert THIRD_PARTY_MODEL_TIER not in ALL_MODEL_TIERS
|
|
102
|
-
assert all(
|
|
103
|
-
|
|
104
|
-
|
|
123
|
+
assert all(ALL_CLI_MODEL_ID_BY_TIER[each_tier] for each_tier in all_cli_tiers)
|
|
124
|
+
assert ALL_CODEX_MODEL_ID_BY_TIER == {
|
|
125
|
+
ADVISOR_MODEL_TIER: ADVISOR_CODEX_MODEL_ID,
|
|
126
|
+
}
|
|
105
127
|
|
|
106
128
|
|
|
107
129
|
def test_canonical_tier_name_strips_and_normalizes() -> None:
|
|
@@ -45,6 +45,9 @@ from advisor_scripts_constants.model_tier_run_validator_constants import ( # no
|
|
|
45
45
|
UNKNOWN_HOST_PROFILE_ERROR,
|
|
46
46
|
UNKNOWN_LADDER_NAME_ERROR,
|
|
47
47
|
)
|
|
48
|
+
from advisor_scripts_constants.advisor_route_constants import ( # noqa: E402
|
|
49
|
+
ALL_CODEX_MODEL_ID_BY_TIER,
|
|
50
|
+
)
|
|
48
51
|
|
|
49
52
|
|
|
50
53
|
def canonical_tier_name(tier_name: str) -> str | None:
|
|
@@ -111,6 +114,27 @@ def resolve_cli_model_id(tier: str) -> str:
|
|
|
111
114
|
return maybe_model_alias
|
|
112
115
|
|
|
113
116
|
|
|
117
|
+
def resolve_codex_model_id(tier: str) -> str:
|
|
118
|
+
"""Return the dated Codex model id for a Codex-backed advisor tier.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
tier: Ladder tier name whose Codex model id should be resolved.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
The configured Codex model id.
|
|
125
|
+
|
|
126
|
+
Raises:
|
|
127
|
+
ValueError: When ``tier`` is not a known Codex-backed tier.
|
|
128
|
+
"""
|
|
129
|
+
maybe_canonical_tier = canonical_tier_name(tier)
|
|
130
|
+
if maybe_canonical_tier is None:
|
|
131
|
+
raise ValueError(UNKNOWN_LADDER_NAME_ERROR.format(tier))
|
|
132
|
+
maybe_model_id = ALL_CODEX_MODEL_ID_BY_TIER.get(maybe_canonical_tier)
|
|
133
|
+
if maybe_model_id is None:
|
|
134
|
+
raise ValueError(UNKNOWN_LADDER_NAME_ERROR.format(tier))
|
|
135
|
+
return maybe_model_id
|
|
136
|
+
|
|
137
|
+
|
|
114
138
|
def detect_host_profile(
|
|
115
139
|
setting_by_name: Mapping[str, str] | None = None,
|
|
116
140
|
) -> str:
|
package/commands/CLAUDE.md
CHANGED
|
@@ -15,6 +15,7 @@ Slash-command definitions installed into `~/.claude/commands/` by `bin/install.m
|
|
|
15
15
|
| `pr-comments.md` | `/pr-comments` | Fetches and formats PR review comments for response |
|
|
16
16
|
| `review-plan.md` | `/review-plan` | Reviews the current plan packet against code standards |
|
|
17
17
|
| `right-size.md` | `/right-size` | Checks an implementation against the Right-Sized Engineering rules |
|
|
18
|
+
| `sr-loop.md` | `/sr-loop` | Runs the converging cleanup loop: /simplify passes until clean, then a code-review fix pass |
|
|
18
19
|
| `sum.md` | `/sum` | Generates a formatted session summary for quick pickup in a new session |
|
|
19
20
|
|
|
20
21
|
## Format
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Converging cleanup loop - repeat /simplify until clean, then repeat /code-review --fix until clean
|
|
3
|
+
argument-hint: [PR URL, branch, or blank for the current diff]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Run the converging cleanup loop on the target: `$ARGUMENTS` (blank means the
|
|
7
|
+
current branch's diff). Each phase invokes an existing skill with the Skill
|
|
8
|
+
tool and repeats it until a pass returns zero new findings.
|
|
9
|
+
|
|
10
|
+
## Phase A — loop /simplify
|
|
11
|
+
|
|
12
|
+
1. Invoke the `simplify` skill on the target (the same review the user gets
|
|
13
|
+
from `/simplify <target>`). Let it run its 4-lens fan-out and apply its
|
|
14
|
+
fixes.
|
|
15
|
+
2. After each pass: run the scoped test suite (test files beside the touched
|
|
16
|
+
code, not the full repo suite), commit once (`git commit -F <file>`, body
|
|
17
|
+
written with the Write tool, Co-Authored-By line, 10-minute timeout — the
|
|
18
|
+
pre-commit gate runs its own tests), and push to the PR head branch. The PR
|
|
19
|
+
stays draft.
|
|
20
|
+
3. Repeat the invocation. **Skips are sticky:** carry every adjudicated skip
|
|
21
|
+
forward into the next pass as "already adjudicated — do not re-report: ..."
|
|
22
|
+
context, or the loop never converges.
|
|
23
|
+
4. Phase A converges when a full pass returns zero new findings. When the
|
|
24
|
+
previous pass changed only a line or two, a single combined-lens
|
|
25
|
+
confirmation agent may serve as the final pass.
|
|
26
|
+
|
|
27
|
+
## Phase B — loop /code-review low --fix
|
|
28
|
+
|
|
29
|
+
1. Invoke the `code-review` skill with arguments `low --fix` on the same
|
|
30
|
+
target. Let it report findings and apply its fixes.
|
|
31
|
+
2. After any pass that changed files: test, commit, push as in Phase A.
|
|
32
|
+
3. Repeat until a pass reports zero findings. Phase B usually converges in one
|
|
33
|
+
pass when Phase A ran first.
|
|
34
|
+
|
|
35
|
+
## Finish
|
|
36
|
+
|
|
37
|
+
Report: passes run per phase, commits pushed with hashes, fixes applied, and
|
|
38
|
+
the standing skip list with reasons.
|
|
39
|
+
|
|
40
|
+
## Constraints (observed under headless runs)
|
|
41
|
+
|
|
42
|
+
- Run this loop in the main session. A wrapper subagent cannot see the
|
|
43
|
+
`code-review` skill, and a nested agent's own subagent reports route to the
|
|
44
|
+
main session instead of back to it.
|
|
45
|
+
- Scope test runs to the touched files; a full-suite run can outlive one
|
|
46
|
+
foreground tool call.
|
|
47
|
+
- A hung or newly slow test suite is a finding to investigate, not an
|
|
48
|
+
inconvenience.
|
|
@@ -10,7 +10,8 @@ Pointer documents to external sources, standard terminology, and internal tool o
|
|
|
10
10
|
| `code-review-enforcement.md` | How the code-review gates work: the two required efforts (push at low, PR creation at xhigh), the stamp bound to the branch-surface hash, the single sanctioned minter, the two-layer stamp-directory guard, and the bypass surfaces the gates leave open |
|
|
11
11
|
| `prose-style-enforcement.md` | How `CLAUDE_PROSE_STYLE_ENFORCEMENT` arms opinionated prose gates (default off) while AskUserQuestion lean-block stays always on |
|
|
12
12
|
| `advisor-tool.md` | Canonical consult bones for any stronger reviewer: when to call, hard rule before first write, how to treat advice; maps to the Anthropic advisor tool |
|
|
13
|
-
| `team-advisor-skill.md` | `/team-advisor` map: sole-consumer warm bind, ref index, and
|
|
13
|
+
| `team-advisor-skill.md` | `/team-advisor` map: sole-consumer warm bind, ref index, and advisor selection |
|
|
14
|
+
| `weak-executor-advisor.md` | Consult profile a below-advisor-tier executor (Sonnet, Haiku) follows on top of `advisor-tool.md`: spawn-prompt steering, context packaging, two-timing rule, consult budget, failure branches |
|
|
14
15
|
|
|
15
16
|
## Role
|
|
16
17
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Advisor Tool
|
|
2
2
|
|
|
3
|
-
Canonical consult timing and weight for
|
|
3
|
+
Canonical consult timing and weight for the repository advisor path: `/team-advisor` and the shared warm advisor. Anthropic's advisor documentation supplies the source guidance for packet shape and review timing.
|
|
4
4
|
|
|
5
5
|
Source bones: [Anthropic Advisor tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool) (Suggested system prompt for coding tasks). API shape, model pairs, cost, and caching live there. This file carries only the call rules a session needs every time.
|
|
6
6
|
|
|
7
7
|
## What it is
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
`/team-advisor` is the repository's advisor implementation. It carries the full first packet explicitly, sends later deltas, and owns the warm Agent/SendMessage or read-only Sol CLI lifecycle.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
See `team-advisor-skill.md` for the bind and lifecycle map.
|
|
12
12
|
|
|
13
13
|
## When to call
|
|
14
14
|
|
|
@@ -18,11 +18,11 @@ If the task needs orientation first (find files, fetch a source, see what exists
|
|
|
18
18
|
|
|
19
19
|
Also call:
|
|
20
20
|
|
|
21
|
-
- **When you believe the task is complete.** Before this call, make the deliverable durable: write the file, save the result, commit the change. The call takes time; if the session ends during it, a durable result survives and an unwritten one does not.
|
|
21
|
+
- **When you believe the task is complete.** Before this call, make the deliverable durable: write the file, save the result, commit the change. The call takes time; if the session ends during it, a durable result survives and an unwritten one does not. Ask the advisor to hunt for missing requirements, untested behavior, wrong assumptions, unhandled edge cases, evidence gaps, and early completion claims.
|
|
22
22
|
- **When stuck** — errors recur, approach does not converge, results do not fit.
|
|
23
23
|
- **When considering a change of approach.**
|
|
24
24
|
|
|
25
|
-
On tasks longer than a few steps,
|
|
25
|
+
On tasks longer than a few steps, aim for an early approach consult and a completion review. Reserve a third consult for recovery or reconciliation, and add consults when material new evidence or forks arise. This cadence guides planning and leaves the task free to follow its evidence. Short reactive tasks may use the single consult that best fits the live decision.
|
|
26
26
|
|
|
27
27
|
Call for design, architecture, and risk questions where you will not touch a file. If the response would be analysis or a recommendation with no other tool calls, call first. That judgment is where a second opinion is highest value. Simple factual lookups and arithmetic do not need a call.
|
|
28
28
|
|
|
@@ -34,7 +34,22 @@ Your first write, edit, or state-changing shell call on a task must be preceded
|
|
|
34
34
|
|
|
35
35
|
Give the advice serious weight. If a step fails empirically, or primary-source evidence contradicts a claim (the file says X, the paper states Y), adapt. A passing self-test is not evidence the advice is wrong — it is evidence the test does not check what the advice is checking.
|
|
36
36
|
|
|
37
|
-
If your data points one way and the advisor points another: do not silently switch. Surface the conflict in one more call — "I found X, you suggest Y, which constraint breaks the tie?"
|
|
37
|
+
If your data points one way and the advisor points another: do not silently switch. Surface the conflict in one more call — "I found X, you suggest Y, which constraint breaks the tie?" A reconcile call is cheaper than the wrong branch.
|
|
38
|
+
|
|
39
|
+
Work a disagreement in this order: keep the observed evidence in the record, name the conflict plainly, ask the advisor which constraint breaks the tie, then act on the reconciled plan.
|
|
40
|
+
|
|
41
|
+
## Escalation shapes
|
|
42
|
+
|
|
43
|
+
Four shapes cover how a harder task gets more strength behind it. Route to the one that matches the work, not by default to the advisor.
|
|
44
|
+
|
|
45
|
+
| Shape | Fits when |
|
|
46
|
+
|---|---|
|
|
47
|
+
| Advisor | The task needs intermittent strategy and review, and one executor keeps the task from start to finish. |
|
|
48
|
+
| Subagent | A piece of the task is a bounded subtask that benefits from its own context and its own loop. |
|
|
49
|
+
| Stronger-model planning phase | The plan needs the strong model's judgment; the fast model can carry it out once written. |
|
|
50
|
+
| Full model switch | Every step of the task needs the stronger tier, not just the hard decisions. |
|
|
51
|
+
|
|
52
|
+
Spawn a subagent when the work is a delegable bounded subtask. Switch the whole task to the stronger model when every turn needs that tier.
|
|
38
53
|
|
|
39
54
|
## Brevity cue
|
|
40
55
|
|
|
@@ -42,10 +57,13 @@ When the consult path supports a free-text brief, append:
|
|
|
42
57
|
|
|
43
58
|
`(Advisor: please keep your guidance under 80 words — I need a focused starting point, not a comprehensive plan.)`
|
|
44
59
|
|
|
60
|
+
Size the ask at roughly 80 percent of the true ceiling; direct address to the advisor lands more reliably than a third-person description.
|
|
61
|
+
|
|
45
62
|
## Related
|
|
46
63
|
|
|
47
64
|
| Doc | Holds |
|
|
48
65
|
|---|---|
|
|
49
66
|
| [Anthropic Advisor tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool) | API shape, model pairs, cost, caching, full best practices |
|
|
50
|
-
| `team-advisor-skill.md` | Standing warm advisor
|
|
51
|
-
| `~/.claude/_shared/advisor/advisor-protocol.md` | Host bind, floor walk, lifecycle
|
|
67
|
+
| `team-advisor-skill.md` | Standing warm advisor for this repository |
|
|
68
|
+
| `~/.claude/_shared/advisor/advisor-protocol.md` | Host bind, floor walk, lifecycle — a read map routes each bind or consult moment to its `reference/` detail file |
|
|
69
|
+
| `weak-executor-advisor.md` | Consult deltas for an executor spawned below the advisor's own tier |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Team-Advisor Skill
|
|
2
2
|
|
|
3
|
-
`/team-advisor` binds one standing warm advisor for this session at the strongest reachable tier.
|
|
3
|
+
`/team-advisor` binds one standing warm advisor for this session at the strongest reachable tier. This skill is the selected custom reproduction path for advisor behavior: it forwards explicit packets to a warm Agent/SendMessage advisor or the read-only `codex_sol_advisor.py` path across many decision points.
|
|
4
4
|
|
|
5
5
|
## Refs
|
|
6
6
|
|
|
@@ -15,6 +15,6 @@
|
|
|
15
15
|
|
|
16
16
|
Follow the call rules in `advisor-tool.md` (orientation first, then consult before substantive work; durable deliverable before the completion consult; stuck or reapproach; long tasks twice).
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## Selected path
|
|
19
19
|
|
|
20
|
-
`/team-advisor`
|
|
20
|
+
`/team-advisor` is the repository's advisor implementation. It provides explicit first-consult packets, delta consults, a standing warm reviewer, and a read-only Sol CLI option.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Weak-Executor Advisor Profile
|
|
2
|
+
|
|
3
|
+
Consult profile for an executor spawned below the advisor's own tier — a
|
|
4
|
+
Sonnet or Haiku model carrying an advisor bind. `advisor-tool.md` sets the
|
|
5
|
+
canonical cadence for every consumer; this file adds the deltas a below-tier
|
|
6
|
+
executor needs on top of it.
|
|
7
|
+
|
|
8
|
+
Source: [Anthropic Advisor tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool)
|
|
9
|
+
(Suggested system prompt for coding tasks). The distilled facts behind each
|
|
10
|
+
section live in
|
|
11
|
+
`skills/team-advisor/reference/advisor-docs-review.md`.
|
|
12
|
+
|
|
13
|
+
## Scope
|
|
14
|
+
|
|
15
|
+
Applies to any executor running below the advisor's tier. A same-tier or
|
|
16
|
+
stronger executor follows `advisor-tool.md` alone. The paste-ready form of
|
|
17
|
+
this profile is the **Weak-executor add-on** block in
|
|
18
|
+
`~/.claude/_shared/advisor/reference/advisor-block.md`.
|
|
19
|
+
|
|
20
|
+
## Steering lives in the spawn prompt
|
|
21
|
+
|
|
22
|
+
The advisor rules sit at the top of the spawn prompt, ahead of every other
|
|
23
|
+
sentence that mentions the advisor — the spawn prompt is the one steering
|
|
24
|
+
surface with measured effect on Sonnet.
|
|
25
|
+
|
|
26
|
+
## Context packaging
|
|
27
|
+
|
|
28
|
+
Everything the advisor learns arrives inside the consult. Each consult
|
|
29
|
+
carries its own packet:
|
|
30
|
+
|
|
31
|
+
- **First consult** — use the complete packet in
|
|
32
|
+
`~/.claude/_shared/advisor/reference/consult-format.md`: assignment,
|
|
33
|
+
desired outcome, constraints and exclusions, actions taken in order, real
|
|
34
|
+
output and current state, decision or blocker, validation evidence,
|
|
35
|
+
unresolved risks, and load-bearing paths or excerpts.
|
|
36
|
+
- **Later consults** — the delta since the last consult.
|
|
37
|
+
- **Ordering** — stable role and charter text first, volatile detail last.
|
|
38
|
+
|
|
39
|
+
## Two-timing rule
|
|
40
|
+
|
|
41
|
+
Two consult moments carry the measured gain:
|
|
42
|
+
|
|
43
|
+
1. **Early** — after a few exploratory reads land in the transcript, before
|
|
44
|
+
the first write. This is the hard rule `advisor-tool.md` §Hard rule
|
|
45
|
+
states for every consumer.
|
|
46
|
+
2. **Final** — after file writes and test output exist to forward. Make the
|
|
47
|
+
deliverable durable first (write the file, save the result, commit the
|
|
48
|
+
change), then consult.
|
|
49
|
+
|
|
50
|
+
## Planner funnel
|
|
51
|
+
|
|
52
|
+
Consult the advisor before any task-list or planner tool. The advisor's plan
|
|
53
|
+
becomes the task list.
|
|
54
|
+
|
|
55
|
+
## Consult budget
|
|
56
|
+
|
|
57
|
+
Aim for two consults per task: early orientation and completion review. Reserve a third for advisory recovery or reconciliation guidance, and add a consult when a material fork produces new evidence. This is a planning target that leaves the task free to follow its evidence.
|
|
58
|
+
|
|
59
|
+
## Advice weight
|
|
60
|
+
|
|
61
|
+
Advice is binding absent empirical contradiction. A conflict between the
|
|
62
|
+
executor's own evidence and the advisor's guidance goes back to the advisor
|
|
63
|
+
as a reconcile consult. See `advisor-tool.md` §How to treat advice for the
|
|
64
|
+
full weighing rule.
|
|
65
|
+
|
|
66
|
+
## Long-run reminder
|
|
67
|
+
|
|
68
|
+
On a run past roughly 20 advisor-free turns, the executor re-reads its
|
|
69
|
+
advisor rules before the next substantive step — the re-read keeps the
|
|
70
|
+
advisor visible across a long horizon.
|
|
71
|
+
|
|
72
|
+
## Failure branches
|
|
73
|
+
|
|
74
|
+
- **Transient advisor failure** — retry once, then carry on with the
|
|
75
|
+
evidence in hand and record the gap in the result.
|
|
76
|
+
- **Advisor unreachable** — report upward and hold the decision for the
|
|
77
|
+
owning session; re-binding belongs to that session alone.
|
|
78
|
+
|
|
79
|
+
## Pairing invariant
|
|
80
|
+
|
|
81
|
+
The advisor binds at or above the strongest consumer's tier. The floor
|
|
82
|
+
holds at that tier whichever executor joins the pairing.
|
|
83
|
+
|
|
84
|
+
## Related
|
|
85
|
+
|
|
86
|
+
| Doc | Holds |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `advisor-tool.md` | Canonical consult cadence, hard rule, brevity cue |
|
|
89
|
+
| `~/.claude/_shared/advisor/advisor-protocol.md` | Host bind, model floor, and the Advisor-block assembly rule |
|
|
90
|
+
| `~/.claude/_shared/advisor/reference/advisor-block.md` | The paste parts — transport preambles, shared core, weak-executor add-on |
|
|
91
|
+
| `skills/team-advisor/reference/advisor-docs-review.md` | Distilled source facts behind each section above |
|
|
@@ -11,8 +11,9 @@ field, pass whether or not the marker is present. One test reads
|
|
|
11
11
|
spawn tool names.
|
|
12
12
|
|
|
13
13
|
Token pins read the warm-up section and each consuming skill. Two doc-gate
|
|
14
|
-
agreement tests assemble a spawn prompt out of the advisor
|
|
15
|
-
warm-up bind and a drift re-spawn
|
|
14
|
+
agreement tests assemble a spawn prompt out of the advisor reference wording a
|
|
15
|
+
warm-up bind (``reference/warm-up.md``) and a drift re-spawn
|
|
16
|
+
(``reference/lifecycle.md``) follow, and run each through the gate, so
|
|
16
17
|
wording that stops naming the marker fails here. Two deny-path tests read the
|
|
17
18
|
preview the gate hands the block logger and hold it bounded and scoped to the
|
|
18
19
|
model field.
|
|
@@ -64,6 +65,13 @@ _FULL_SONNET_MODEL_ID = "claude-sonnet-4-5"
|
|
|
64
65
|
_PACKAGE_ROOT = _HOOKS_TREE.parent
|
|
65
66
|
_ADVISOR_PROTOCOL_PATH = _PACKAGE_ROOT / "_shared" / "advisor" / "advisor-protocol.md"
|
|
66
67
|
_ADVISOR_PROTOCOL_TEXT = _ADVISOR_PROTOCOL_PATH.read_text(encoding="utf-8")
|
|
68
|
+
_ADVISOR_REFERENCE_DIR = _PACKAGE_ROOT / "_shared" / "advisor" / "reference"
|
|
69
|
+
_ADVISOR_LIFECYCLE_TEXT = (_ADVISOR_REFERENCE_DIR / "lifecycle.md").read_text(
|
|
70
|
+
encoding="utf-8"
|
|
71
|
+
)
|
|
72
|
+
_ADVISOR_WARM_UP_TEXT = (_ADVISOR_REFERENCE_DIR / "warm-up.md").read_text(
|
|
73
|
+
encoding="utf-8"
|
|
74
|
+
)
|
|
67
75
|
_ALL_CONSUMING_SKILL_NAMES = ("team-advisor", "orchestrator", "orchestrator-refresh")
|
|
68
76
|
_ALL_CONSUMING_SKILL_PATHS = tuple(
|
|
69
77
|
_PACKAGE_ROOT / "skills" / each_skill_name / "SKILL.md"
|
|
@@ -321,19 +329,18 @@ def test_consuming_skill_names_the_marker_token(skill_path: pathlib.Path) -> Non
|
|
|
321
329
|
assert FABLE_SPAWN_AUTHORIZATION_MARKER in skill_path.read_text(encoding="utf-8")
|
|
322
330
|
|
|
323
331
|
|
|
324
|
-
def _paragraph_starting_at(paragraph_marker: str) -> str:
|
|
325
|
-
"""Return the advisor-
|
|
332
|
+
def _paragraph_starting_at(source_text: str, paragraph_marker: str) -> str:
|
|
333
|
+
"""Return the advisor-doc paragraph that opens with a marker.
|
|
326
334
|
|
|
327
335
|
Args:
|
|
336
|
+
source_text: The advisor document text holding the paragraph.
|
|
328
337
|
paragraph_marker: The literal text opening the paragraph.
|
|
329
338
|
|
|
330
339
|
Returns:
|
|
331
340
|
The paragraph text, running from that marker to the blank line that
|
|
332
341
|
closes it.
|
|
333
342
|
"""
|
|
334
|
-
paragraph_body =
|
|
335
|
-
_ADVISOR_PROTOCOL_TEXT.index(paragraph_marker) :
|
|
336
|
-
]
|
|
343
|
+
paragraph_body = source_text[source_text.index(paragraph_marker) :]
|
|
337
344
|
paragraph_end = paragraph_body.find(_PARAGRAPH_SEPARATOR)
|
|
338
345
|
if paragraph_end < 0:
|
|
339
346
|
return paragraph_body
|
|
@@ -341,7 +348,7 @@ def _paragraph_starting_at(paragraph_marker: str) -> str:
|
|
|
341
348
|
|
|
342
349
|
|
|
343
350
|
def _respawn_spawn_prompt() -> str:
|
|
344
|
-
"""Assemble the spawn prompt a drift re-spawn writes from the
|
|
351
|
+
"""Assemble the spawn prompt a drift re-spawn writes from the lifecycle doc.
|
|
345
352
|
|
|
346
353
|
The prompt comes from the re-spawn paragraph alone, so the gate reads
|
|
347
354
|
what that one paragraph tells a session to send.
|
|
@@ -349,7 +356,7 @@ def _respawn_spawn_prompt() -> str:
|
|
|
349
356
|
Returns:
|
|
350
357
|
The spawn prompt text a session following that paragraph sends.
|
|
351
358
|
"""
|
|
352
|
-
return _paragraph_starting_at(_RESPAWN_PARAGRAPH_MARKER)
|
|
359
|
+
return _paragraph_starting_at(_ADVISOR_LIFECYCLE_TEXT, _RESPAWN_PARAGRAPH_MARKER)
|
|
353
360
|
|
|
354
361
|
|
|
355
362
|
def test_respawn_paragraph_prompt_passes_the_gate_at_the_fable_tier() -> None:
|
|
@@ -358,7 +365,7 @@ def test_respawn_paragraph_prompt_passes_the_gate_at_the_fable_tier() -> None:
|
|
|
358
365
|
|
|
359
366
|
|
|
360
367
|
def _warm_up_spawn_prompt() -> str:
|
|
361
|
-
"""Assemble the spawn prompt a warm-up bind writes from the
|
|
368
|
+
"""Assemble the spawn prompt a warm-up bind writes from the warm-up doc.
|
|
362
369
|
|
|
363
370
|
The prompt comes from the spawn-field prompt bullet alone, so the gate
|
|
364
371
|
reads what that one bullet tells a session to send.
|
|
@@ -366,7 +373,7 @@ def _warm_up_spawn_prompt() -> str:
|
|
|
366
373
|
Returns:
|
|
367
374
|
The spawn prompt text a session following that bullet sends.
|
|
368
375
|
"""
|
|
369
|
-
return _paragraph_starting_at(_WARM_UP_PROMPT_BULLET_MARKER)
|
|
376
|
+
return _paragraph_starting_at(_ADVISOR_WARM_UP_TEXT, _WARM_UP_PROMPT_BULLET_MARKER)
|
|
370
377
|
|
|
371
378
|
|
|
372
379
|
def test_warm_up_prompt_bullet_passes_the_gate_at_the_fable_tier() -> None:
|
package/package.json
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
|
|
7
7
|
@~/.claude/_shared/advisor/advisor-protocol.md
|
|
8
8
|
|
|
9
|
-
Scripts: `~/.claude/_shared/advisor/scripts/` (`model_tier_run_validator.py`, `tier_model_ids.py`, constants under `scripts/config/`).
|
|
9
|
+
Scripts: `~/.claude/_shared/advisor/scripts/` (`model_tier_run_validator.py`, `codex_sol_advisor.py`, `tier_model_ids.py`, constants under `scripts/config/`).
|
package/skills/grokify/SKILL.md
CHANGED
|
@@ -43,7 +43,7 @@ The user types `/grokify`, alone or with guidance.
|
|
|
43
43
|
|
|
44
44
|
- **Bind once, first:** charter + findings + constraints + plan piped from a temp file into `claude -p --model fable --effort high --output-format json`; parse and save `session_id` from the JSON reply.
|
|
45
45
|
- **Consult:** brief piped into `claude -p --resume <session_id> --model fable --effort high --output-format json`.
|
|
46
|
-
- **ConsultB** If fable is unavailable, use opus with
|
|
46
|
+
- **ConsultB** If fable is unavailable, use opus with xhigh effort: `claude -p --resume <session_id> --model opus --effort xhigh --output-format json`.
|
|
47
47
|
- **Signals:** every advisor reply opens with exactly one of ENDORSE, CORRECTION, PLAN, or STOP. CORRECTION and PLAN are actions to take, with a report-back in the next consult on that topic. STOP halts that line of work and surfaces it to the user. When the CLI is unreachable, Grok stops and says so — it never self-endorses in the advisor's place.
|
|
48
48
|
- **Cadence, mandatory:** after planning and before any edit; per phase before implementation (TDD red + approach) and after (diff, tests, acceptance evidence); before every `git commit` and `git push`; on every user-facing fork before asking; on any twice-repeated failure or stall.
|
|
49
49
|
|
|
@@ -43,7 +43,7 @@ CONFIRM THESE WITH THE USER FIRST, VIA ASKUSERQUESTION, BEFORE EMBEDDING]
|
|
|
43
43
|
append the full Established findings, Hard constraints, and Plan sections of this
|
|
44
44
|
document to the same file.
|
|
45
45
|
2. Bind: `claude -p --model fable --effort high --output-format json < <charter-file>`
|
|
46
|
-
2a. If 2 fails, replace fable with opus, effort high to
|
|
46
|
+
2a. If 2 fails, replace fable with opus, effort high to xhigh.
|
|
47
47
|
3. The JSON output is an array of events, not one object. Take `session_id` from any
|
|
48
48
|
event; the reply text is the `type == "result"` event's `.result` field. Persist
|
|
49
49
|
`session_id`, the repo root, and the cwd to a state file at once.
|
|
@@ -56,7 +56,7 @@ CONFIRM THESE WITH THE USER FIRST, VIA ASKUSERQUESTION, BEFORE EMBEDDING]
|
|
|
56
56
|
session, not a model failure.
|
|
57
57
|
|
|
58
58
|
**Consult (every time):** write the brief to a temp file, then
|
|
59
|
-
`claude -p --resume <session_id> --model fable (or opus) --effort high (
|
|
59
|
+
`claude -p --resume <session_id> --model fable (or opus) --effort high (xhigh for opus) --output-format json < <brief-file>`.
|
|
60
60
|
Act on the reply's opening signal: ENDORSE — proceed. CORRECTION — apply it first;
|
|
61
61
|
your next consult on that topic opens with what happened. PLAN — adopt it; same
|
|
62
62
|
report-back rule. STOP — halt that line of work and surface it to the user. Never
|
|
@@ -193,7 +193,7 @@ Touch only: <files or globs>
|
|
|
193
193
|
Done when: <one mechanical check — a command, a test, a diff scope>
|
|
194
194
|
Return: status, artifact paths, blockers — nothing else.
|
|
195
195
|
|
|
196
|
-
<
|
|
196
|
+
<Advisor block assembled per _shared/advisor/reference/advisor-block.md — advisor name filled in>
|
|
197
197
|
```
|
|
198
198
|
|
|
199
199
|
- **Size the task by its done-check.** The right task is the largest
|
|
@@ -218,9 +218,10 @@ Return: status, artifact paths, blockers — nothing else.
|
|
|
218
218
|
table picks the definition, and `clean-coder` already holds the code
|
|
219
219
|
discipline. The ticket adds the task, the pointers, and the Advisor
|
|
220
220
|
block only.
|
|
221
|
-
- **The Advisor block is
|
|
222
|
-
|
|
223
|
-
block
|
|
221
|
+
- **The Advisor block is pasted, assembled text.** Assemble it at bind
|
|
222
|
+
time from the parts in
|
|
223
|
+
[`_shared/advisor/reference/advisor-block.md`](../../_shared/advisor/reference/advisor-block.md)
|
|
224
|
+
and paste the assembled text itself into the ticket.
|
|
224
225
|
|
|
225
226
|
## Workflow Agent Routing
|
|
226
227
|
|