claude-dev-env 2.35.0 → 4.0.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.
Files changed (99) hide show
  1. package/.agents/skills/_shared/advisor/scripts/README.md +1 -1
  2. package/.agents/skills/autoconverge/SKILL.md +19 -15
  3. package/.agents/skills/autoconverge/reference/gotchas.md +3 -3
  4. package/.agents/skills/autoconverge/reference/multi-pr.md +6 -2
  5. package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +11 -0
  6. package/.agents/skills/autoconverge/workflow/converge.mjs +26 -33
  7. package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +26 -2
  8. package/.agents/skills/autoconverge/workflow/converge_multi.mjs +12 -28
  9. package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +16 -0
  10. package/.agents/skills/team-advisor/SKILL.md +11 -11
  11. package/_shared/advisor/advisor-protocol.md +51 -51
  12. package/_shared/advisor/reference/advisor-block.md +9 -9
  13. package/_shared/advisor/reference/astra-rung.md +39 -0
  14. package/_shared/advisor/reference/identity.md +4 -4
  15. package/_shared/advisor/reference/lifecycle.md +6 -6
  16. package/_shared/advisor/reference/spawn-walk-log.md +9 -9
  17. package/_shared/advisor/reference/third-party-bind.md +11 -11
  18. package/_shared/advisor/reference/warm-up.md +13 -13
  19. package/_shared/advisor/scripts/codex_astra_advisor.py +308 -0
  20. package/_shared/advisor/scripts/codex_astra_preflight.py +115 -0
  21. package/_shared/advisor/scripts/codex_astra_reply.py +159 -0
  22. package/_shared/advisor/scripts/config/advisor_scripts_constants/advisor_route_constants.py +3 -3
  23. package/_shared/advisor/scripts/config/advisor_scripts_constants/astra_advisor_constants.py +38 -0
  24. package/_shared/advisor/scripts/model_tier_run_validator.py +17 -18
  25. package/_shared/advisor/scripts/tests/test_codex_astra_advisor.py +271 -0
  26. package/_shared/advisor/scripts/tests/test_codex_astra_preflight.py +24 -0
  27. package/_shared/advisor/scripts/tests/test_codex_astra_reply.py +42 -0
  28. package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +55 -30
  29. package/_shared/advisor/scripts/tests/test_tier_model_ids.py +14 -4
  30. package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +14 -0
  31. package/_shared/pr-loop/scripts/terminology_sweep.py +138 -50
  32. package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +13 -1
  33. package/bin/cde.mjs +175 -0
  34. package/bin/cde.test.mjs +222 -0
  35. package/bin/install-constants.mjs +4 -0
  36. package/bin/install.cursor-rules.test.mjs +233 -2
  37. package/bin/install.mjs +49 -3
  38. package/bin/pstack-model-preferences.codex.json +23 -0
  39. package/bin/select-pstack-models.test.mjs +378 -0
  40. package/docs/references/team-advisor-skill.md +3 -3
  41. package/hooks/hooks_constants/tool_names.py +20 -0
  42. package/hooks/validators/README.md +35 -1
  43. package/hooks/validators/fast_save_validators.py +63 -89
  44. package/hooks/validators/run_all_validators.py +16 -8
  45. package/hooks/validators/test_fast_save_validators_policy_lint.py +25 -0
  46. package/hooks/validators/test_run_all_validators_policy_lint.py +52 -0
  47. package/package.json +3 -2
  48. package/rules/pstack-models.md +119 -0
  49. package/scripts/cde_lint.py +258 -0
  50. package/scripts/check.ps1 +18 -6
  51. package/scripts/policy_lint/__init__.py +41 -0
  52. package/scripts/policy_lint/adapter_configuration.py +91 -0
  53. package/scripts/policy_lint/adapter_detectors.py +368 -0
  54. package/scripts/policy_lint/adapter_pairing.py +145 -0
  55. package/scripts/policy_lint/adapter_support.py +97 -0
  56. package/scripts/policy_lint/adapters.py +376 -0
  57. package/scripts/policy_lint/config/__init__.py +1 -0
  58. package/scripts/policy_lint/config/constants.py +77 -0
  59. package/scripts/policy_lint/engine.py +224 -0
  60. package/scripts/policy_lint/model.py +388 -0
  61. package/scripts/policy_lint/registry.py +171 -0
  62. package/scripts/policy_lint/render.py +91 -0
  63. package/scripts/policy_lint/selection.py +372 -0
  64. package/scripts/policy_lint/selection_git.py +147 -0
  65. package/scripts/repository_checks/__init__.py +1 -0
  66. package/scripts/repository_checks/claude_md.py +108 -0
  67. package/scripts/repository_checks/config/__init__.py +1 -0
  68. package/scripts/repository_checks/config/constants.py +150 -0
  69. package/scripts/repository_checks/env_var_documentation.py +243 -0
  70. package/scripts/repository_checks/hook_modules.py +34 -0
  71. package/scripts/repository_checks/models.py +37 -0
  72. package/scripts/repository_checks/package_inventory.py +118 -0
  73. package/scripts/repository_checks/pytest_testpaths.py +84 -0
  74. package/scripts/repository_checks/reporting.py +39 -0
  75. package/scripts/repository_checks/runner.py +93 -0
  76. package/scripts/repository_checks/tracked_secrets.py +147 -0
  77. package/scripts/repository_checks/tracked_tree.py +28 -0
  78. package/scripts/repository_policy.py +120 -0
  79. package/scripts/select_pstack_models.mjs +304 -0
  80. package/scripts/tests/repository_policy_test_support.py +89 -0
  81. package/scripts/tests/test_cde_lint.py +398 -0
  82. package/scripts/tests/test_claude_md.py +68 -0
  83. package/scripts/tests/test_env_var_documentation.py +133 -0
  84. package/scripts/tests/test_hook_modules.py +17 -0
  85. package/scripts/tests/test_models.py +26 -0
  86. package/scripts/tests/test_package_inventory.py +96 -0
  87. package/scripts/tests/test_policy_lint_rules_engine.py +381 -0
  88. package/scripts/tests/test_policy_lint_rules_registry.py +369 -0
  89. package/scripts/tests/test_policy_lint_selection.py +373 -0
  90. package/scripts/tests/test_pytest_testpaths.py +66 -0
  91. package/scripts/tests/test_reporting.py +54 -0
  92. package/scripts/tests/test_repository_policy.py +71 -0
  93. package/scripts/tests/test_runner.py +59 -0
  94. package/scripts/tests/test_tracked_secrets.py +175 -0
  95. package/scripts/tests/test_tracked_tree.py +28 -0
  96. package/_shared/advisor/reference/sol-rung.md +0 -39
  97. package/_shared/advisor/scripts/codex_sol_advisor.py +0 -581
  98. package/_shared/advisor/scripts/config/advisor_scripts_constants/sol_advisor_constants.py +0 -38
  99. package/_shared/advisor/scripts/tests/test_codex_sol_advisor.py +0 -740
@@ -4,7 +4,7 @@
4
4
 
5
5
  @~/.claude/_shared/advisor/scripts/model_tier_run_validator.py
6
6
 
7
- @~/.claude/_shared/advisor/scripts/codex_sol_advisor.py
7
+ @~/.claude/_shared/advisor/scripts/codex_astra_advisor.py
8
8
 
9
9
  @~/.claude/_shared/advisor/scripts/tier_model_ids.py
10
10
 
@@ -59,8 +59,10 @@ python "$HOME/.claude/skills/_shared/pr-loop/scripts/select_converge_pacer.py" \
59
59
  [`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md).
60
60
  **Do not abort** because the Workflow tool is missing.
61
61
 
62
- Transport still needs authenticated GitHub access for the PR's owner (`gh` or
63
- `pr-loop-cloud-transport`).
62
+ Set the GitHub transport directive before any GitHub step. Use `transport: "cloud"` in a
63
+ Cloud session. Use `transport: "local"` in a local session. Cloud uses the
64
+ connected GitHub MCP tools and never starts a local GitHub CLI authentication
65
+ flow.
64
66
 
65
67
  ## Review-lens boundary
66
68
 
@@ -68,18 +70,19 @@ The code-review lens boundary (workflow agent versus the built-in `/code-review`
68
70
  command) is defined on the **Code-review lens** bullet in
69
71
  [`reference/convergence.md`](reference/convergence.md).
70
72
 
71
- ## Transport check (before any GitHub step)
73
+ ## Select the GitHub transport directive before any GitHub step
72
74
 
73
- Run `command -v gh`; when it succeeds, run `gh auth status`; once the PR
74
- scope is resolved, run `gh api repos/<owner>/<repo> --jq .permissions.push`
75
- and take `true` as the pass. When any check fails, run the
76
- `pr-loop-cloud-transport` skill first and route every `gh` operation in this
77
- skill through its substitution matrix. The workflow script
78
- (`workflow/converge.mjs`) embeds `gh` commands and gh-backed helper scripts in
79
- its agent prompts, so a cloud run also applies the same substitution to those
80
- agent prompts when it authors the launch — the transport skill covers the
81
- orchestrating session's own steps, and the script's agent-prompt text carries
82
- `gh` calls the spawned agents cannot run in a cloud session.
75
+ In a Cloud session, set `transport: "cloud"` and load the GitHub MCP schemas
76
+ before the first GitHub tool call. Do not run any local GitHub CLI
77
+ authentication, account-switch, or token command. Use the operation in
78
+ [`cloud-pr-loop-compatibility.md`](../../../docs/references/cloud-pr-loop-compatibility.md)
79
+ for each GitHub read or write. Use the Cloud session's credentialed push path
80
+ for local commits. If that path rejects a push, report the exact error instead
81
+ of trying to log in through the local CLI.
82
+
83
+ In a local session, set `transport: "local"` and use the authenticated local
84
+ GitHub CLI. The workflow defaults to this value when older callers omit the
85
+ field.
83
86
 
84
87
  ## Pre-flight (main session)
85
88
 
@@ -161,7 +164,7 @@ orchestrating session's own steps, and the script's agent-prompt text carries
161
164
  ```
162
165
  Workflow({
163
166
  scriptPath: "<this skill dir>/workflow/converge.mjs",
164
- args: { owner: "<O>", repo: "<R>", prNumber: <N>, bugbotDisabled: false, copilotDisabled: false, homeDirectory: "<HOME>" }
167
+ args: { owner: "<O>", repo: "<R>", prNumber: <N>, bugbotDisabled: false, copilotDisabled: false, homeDirectory: "<HOME>", transport: "<cloud|local>" }
165
168
  })
166
169
  ```
167
170
 
@@ -173,7 +176,8 @@ the absolute path to the directory that holds `.claude` (resolve it once from
173
176
  runs in a sandbox with no access to environment variables, so the run reads the
174
177
  home directory from this arg to build the path to the codex-review scripts the
175
178
  Codex gate calls; leave it out and the Codex gate cannot find those scripts. Set
176
- `bugbotDisabled: true` only when the user has opted Cursor Bugbot out for the
179
+ `transport: "cloud"` for Cloud and `transport: "local"` for local execution.
180
+ Set `bugbotDisabled: true` only when the user has opted Cursor Bugbot out for the
177
181
  run; otherwise the workflow detects an opt-out or an unreachable Bugbot on its
178
182
  own. Set `copilotDisabled: true` when the step 5 quota pre-check exits non-zero,
179
183
  and `false` when it exits 0; on `true` the workflow skips the Copilot gate with
@@ -46,9 +46,9 @@ fails in a new way.
46
46
  not `~/.claude/...`; a tilde resolves to the wrong home and gives a
47
47
  file-not-found error that looks like a script failure.
48
48
 
49
- - **`gh` token drift across accounts.** When a run touches more than one GitHub
50
- account, pin the token with `--user <login>`; `gh auth token` alone can return
51
- another account's token after a switch.
49
+ - **Local identity drift across accounts.** A local run that touches more than
50
+ one GitHub account must use the selected local account. Cloud runs use the
51
+ connected GitHub MCP identity and never use local CLI identity commands.
52
52
 
53
53
  - **Commit or push fails after a repair.** Read the hook or command output,
54
54
  repair the named issue, and record the rerun. Apply the
@@ -73,6 +73,7 @@ Workflow({
73
73
  args: {
74
74
  convergeScriptPath: "<this skill dir>/workflow/converge.mjs",
75
75
  homeDirectory: "<HOME>",
76
+ transport: "<cloud|local>",
76
77
  prs: [
77
78
  { owner: "<O>", repo: "<R>", prNumber: <N1>, repoPath: "<abs worktree 1>", bugbotDisabled: false, copilotDisabled: false },
78
79
  { owner: "<O>", repo: "<R>", prNumber: <N2>, repoPath: "<abs worktree 2>", bugbotDisabled: false, copilotDisabled: false }
@@ -87,8 +88,11 @@ checked out in. `homeDirectory` is the absolute path to the directory that holds
87
88
  `.claude` (resolve it once from `$HOME`, or `$env:USERPROFILE` on Windows, with
88
89
  forward slashes); the fan-out forwards it to every child run, which needs it to
89
90
  build the codex-review scripts path because the workflow sandbox has no access to
90
- environment variables. The workflow runs in the background and notifies the session on
91
- completion; watch live progress with `/workflows`, where each PR's child run
91
+ environment variables. Set `transport: "cloud"` in a Cloud session and
92
+ `transport: "local"` in a local session. Cloud uses the connected GitHub MCP
93
+ tools and skips local CLI authentication. The workflow runs in the background
94
+ and notifies the session on completion; watch live progress with `/workflows`,
95
+ where each PR's child run
92
96
  appears under its own group.
93
97
 
94
98
  The workflow returns
@@ -32,6 +32,17 @@ test('review tasks use code-quality-agent and keep the working tree read-only',
32
32
  assert.match(reviewTaskSource, /Make no edit to the tree under verification/)
33
33
  })
34
34
 
35
+ test('workflow agents receive the selected GitHub transport before role instructions', () => {
36
+ assert.match(
37
+ workflowSource,
38
+ /HEADLESS_EDIT_PREAMBLE\}\$\{githubTransportDirective\(activeGithubTransport\)\}\$\{worktreeDirective/,
39
+ )
40
+ assert.match(
41
+ workflowSource,
42
+ /HEADLESS_READONLY_PREAMBLE\}\$\{githubTransportDirective\(activeGithubTransport\)\}\$\{worktreeDirective/,
43
+ )
44
+ })
45
+
35
46
  test('review result parser accepts one standalone terminal disposition only', () => {
36
47
  const parseReviewResult = loadReviewResultParser()
37
48
 
@@ -91,6 +91,7 @@ const HEADLESS_READONLY_PREAMBLE = HEADLESS_EDIT_PREAMBLE.replace(
91
91
  )
92
92
 
93
93
  let activeRepoPath = null
94
+ let activeGithubTransport = 'local'
94
95
 
95
96
  /**
96
97
  * Build the per-agent worktree directive for a path-scoped run.
@@ -111,33 +112,11 @@ const worktreeDirective = (repoPath) =>
111
112
  ? `WORKTREE — this PR is checked out at ${repoPath}. Unless a step explicitly names a different repository directory (for example an environment-hardening repo checkout, which you cd into exactly as that step directs), run every git, gh, diff, edit, commit, push, and test command for this PR in that worktree: cd "${repoPath}" before any such command, and resolve repository roots from there.\n\n`
112
113
  : ''
113
114
 
114
- /**
115
- * Spawn a workflow agent that edits code, with the full edit preamble prepended
116
- * to its prompt. An edit agent may run rm during cleanup, so it inherits the
117
- * rm-shape rules alongside the no-confirmation-prompt guidance. On a path-scoped
118
- * run the worktree directive is prepended too, so the agent runs in the PR's own
119
- * worktree (activeRepoPath); on a single-PR run that directive is empty and the
120
- * agent keeps its own working directory. A read-only agent (a review, verify, or
121
- * utility spawn) routes through convergeReadOnlyAgent for the trimmed preamble.
122
- * @param {string} prompt the agent's role-specific instruction body
123
- * @param {object} options the agent() options (label, phase, schema, agentType, model)
124
- * @returns {Promise<*>} the agent() result
125
- */
126
115
  const convergeAgent = (prompt, options) =>
127
- agent(`${HEADLESS_EDIT_PREAMBLE}${worktreeDirective(activeRepoPath)}${prompt}`, options)
116
+ agent(`${HEADLESS_EDIT_PREAMBLE}${githubTransportDirective(activeGithubTransport)}${worktreeDirective(activeRepoPath)}${prompt}`, options)
128
117
 
129
- /**
130
- * Spawn a read-only workflow agent with the trimmed read-only preamble prepended
131
- * to its prompt. A review, verify, or utility agent edits nothing and never runs
132
- * rm, so it receives the read-only preamble that drops the rm-shape-rules bullet.
133
- * The worktree directive is prepended on a path-scoped run exactly as for
134
- * convergeAgent, so a read-only agent still runs in the PR's own worktree.
135
- * @param {string} prompt the agent's role-specific instruction body
136
- * @param {object} options the agent() options (label, phase, schema, agentType, model)
137
- * @returns {Promise<*>} the agent() result
138
- */
139
118
  const convergeReadOnlyAgent = (prompt, options) =>
140
- agent(`${HEADLESS_READONLY_PREAMBLE}${worktreeDirective(activeRepoPath)}${prompt}`, options)
119
+ agent(`${HEADLESS_READONLY_PREAMBLE}${githubTransportDirective(activeGithubTransport)}${worktreeDirective(activeRepoPath)}${prompt}`, options)
141
120
 
142
121
  /**
143
122
  * Spawn a fresh git-utility Explore agent for a specific task. The one task,
@@ -1627,19 +1606,32 @@ function normalizeRunInput(rawArgs) {
1627
1606
  }
1628
1607
  }
1629
1608
 
1630
- /**
1631
- * Validate the normalized run input into either usable coordinates or a
1632
- * structured blocker. The run cannot build a single GitHub call without owner,
1633
- * repo, and prNumber, so a null payload (failed parse or missing args) or a
1634
- * payload missing any coordinate yields a blocker the top-level run reports as
1635
- * {converged:false, blocker} rather than throwing on input.owner at startup.
1636
- * @param {string|object} rawArgs the workflow args global (JSON string or object)
1637
- * @returns {{input: object|null, blocker: string|null}} usable coordinates or a blocker
1638
- */
1609
+ const DEFAULT_GITHUB_TRANSPORT = 'local'
1610
+ const GITHUB_TRANSPORT_DIRECTIVES = {
1611
+ local:
1612
+ 'LOCAL GITHUB TRANSPORT DIRECTIVE. Use the authenticated local GitHub CLI for GitHub operations. Report local authentication or permission failures directly.\n\n',
1613
+ cloud:
1614
+ 'CLOUD GITHUB TRANSPORT DIRECTIVE. Use the connected GitHub MCP tools for every GitHub API read and write. Load the GitHub MCP schemas before the first MCP call and resolve the connected identity with mcp__github__get_me. Do not invoke a local GitHub CLI for authentication, account switching, token lookup, pull-request operations, review operations, or push setup. Replace local CLI steps in this prompt with the matching operation in docs/references/cloud-pr-loop-compatibility.md. For a local commit push, use only the credentialed push path supplied by the Cloud session. If no credentialed path is available, return a named blocker instead of attempting a login.\n\n',
1615
+ }
1616
+ const VALID_GITHUB_TRANSPORTS = new Set(Object.keys(GITHUB_TRANSPORT_DIRECTIVES))
1617
+
1618
+ function githubTransportDirective(transport) {
1619
+ return GITHUB_TRANSPORT_DIRECTIVES[transport] || GITHUB_TRANSPORT_DIRECTIVES[DEFAULT_GITHUB_TRANSPORT]
1620
+ }
1621
+
1639
1622
  function classifyRunInput(rawArgs) {
1640
1623
  const candidate = normalizeRunInput(rawArgs)
1641
1624
  const hasUsableCoordinates =
1642
1625
  candidate != null && candidate.owner && candidate.repo && candidate.prNumber
1626
+ const hasValidTransport =
1627
+ candidate != null &&
1628
+ (candidate.transport === undefined || VALID_GITHUB_TRANSPORTS.has(candidate.transport))
1629
+ if (hasUsableCoordinates && !hasValidTransport) {
1630
+ return {
1631
+ input: null,
1632
+ blocker: 'invalid run transport: expected "local" or "cloud"',
1633
+ }
1634
+ }
1643
1635
  if (hasUsableCoordinates) return { input: candidate, blocker: null }
1644
1636
  return {
1645
1637
  input: null,
@@ -1654,6 +1646,7 @@ if (runInput.blocker) {
1654
1646
  }
1655
1647
  const input = runInput.input
1656
1648
  activeRepoPath = typeof input.repoPath === 'string' && input.repoPath ? input.repoPath : null
1649
+ activeGithubTransport = input.transport === undefined ? DEFAULT_GITHUB_TRANSPORT : input.transport
1657
1650
  const prCoordinates = `owner=${input.owner} repo=${input.repo} PR #${input.prNumber} (https://github.com/${input.owner}/${input.repo}/pull/${input.prNumber})`
1658
1651
 
1659
1652
  /**
@@ -17,10 +17,10 @@ function sourceSliceBetween(startNeedle, endNeedle) {
17
17
 
18
18
  const productionModule = new Function(
19
19
  `${sourceSliceBetween('function normalizeRunInput(', '\nconst runInput =')}\n` +
20
- 'return { normalizeRunInput, classifyRunInput };',
20
+ 'return { normalizeRunInput, classifyRunInput, githubTransportDirective };',
21
21
  )();
22
22
 
23
- const { normalizeRunInput, classifyRunInput } = productionModule;
23
+ const { normalizeRunInput, classifyRunInput, githubTransportDirective } = productionModule;
24
24
 
25
25
  const VALID_COORDINATES = { owner: 'jl-cmd', repo: 'claude-dev-env', prNumber: 543 };
26
26
 
@@ -46,6 +46,19 @@ test('classifyRunInput accepts coordinates carrying owner, repo, and prNumber',
46
46
  assert.equal(classified.blocker, null);
47
47
  });
48
48
 
49
+ test('classifyRunInput accepts the cloud transport without changing the input shape', () => {
50
+ const cloudInput = { ...VALID_COORDINATES, transport: 'cloud' };
51
+ const classified = classifyRunInput(cloudInput);
52
+ assert.deepEqual(classified.input, cloudInput);
53
+ assert.equal(classified.blocker, null);
54
+ });
55
+
56
+ test('classifyRunInput blocks an unknown transport before any GitHub work starts', () => {
57
+ const classified = classifyRunInput({ ...VALID_COORDINATES, transport: 'proxy' });
58
+ assert.equal(classified.input, null);
59
+ assert.match(classified.blocker, /transport/i);
60
+ });
61
+
49
62
  test('classifyRunInput blocks a failed parse with a structured blocker and no input', () => {
50
63
  const classified = classifyRunInput('not json at all');
51
64
  assert.equal(classified.input, null);
@@ -90,3 +103,14 @@ test('classifyRunInput leaves copilotDisabled undefined when the input omits it'
90
103
  const classified = classifyRunInput(VALID_COORDINATES);
91
104
  assert.equal(classified.input.copilotDisabled, undefined);
92
105
  });
106
+
107
+ test('the cloud transport directive selects MCP and contains no local CLI auth command', () => {
108
+ const cloudDirective = githubTransportDirective('cloud');
109
+ assert.match(cloudDirective, /mcp__github__/);
110
+ assert.match(cloudDirective, /credentialed push path/);
111
+ assert.doesNotMatch(cloudDirective, /gh auth/);
112
+ });
113
+
114
+ test('the local transport directive keeps the local CLI path', () => {
115
+ assert.match(githubTransportDirective('local'), /authenticated local GitHub CLI/);
116
+ });
@@ -57,18 +57,9 @@ function isUsablePrEntry(prEntry) {
57
57
  )
58
58
  }
59
59
 
60
- /**
61
- * Validate the normalized multi-PR input into usable coordinates or a blocker.
62
- *
63
- * A fan-out run needs the absolute converge.mjs script path and a non-empty list
64
- * of PR entries that each carry owner, repo, prNumber, and the absolute worktree
65
- * path the PR is checked out in. A payload that fails to parse, a non-string
66
- * convergeScriptPath, a missing or empty prs list, or any entry missing a
67
- * coordinate yields a blocker the top-level run reports as
68
- * {converged:false, blocker} rather than throwing on a missing field.
69
- * @param {string|object} rawArgs the workflow args global (JSON string or object)
70
- * @returns {{input: object|null, blocker: string|null}} usable coordinates or a blocker
71
- */
60
+ const DEFAULT_GITHUB_TRANSPORT = 'local'
61
+ const VALID_GITHUB_TRANSPORTS = new Set(['local', 'cloud'])
62
+
72
63
  function classifyMultiInput(rawArgs) {
73
64
  const candidate = normalizeMultiInput(rawArgs)
74
65
  if (candidate == null) {
@@ -84,6 +75,12 @@ function classifyMultiInput(rawArgs) {
84
75
  'invalid run coordinates: convergeScriptPath (absolute path to converge.mjs) is required',
85
76
  }
86
77
  }
78
+ if (candidate.transport !== undefined && !VALID_GITHUB_TRANSPORTS.has(candidate.transport)) {
79
+ return {
80
+ input: null,
81
+ blocker: 'invalid run transport: expected "local" or "cloud"',
82
+ }
83
+ }
87
84
  if (!Array.isArray(candidate.prs) || candidate.prs.length === 0) {
88
85
  return {
89
86
  input: null,
@@ -102,21 +99,7 @@ function classifyMultiInput(rawArgs) {
102
99
  return { input: candidate, blocker: null }
103
100
  }
104
101
 
105
- /**
106
- * Build the converge.mjs child-run args for one validated PR entry.
107
- *
108
- * Every per-run opt-out the child converge.mjs reads is forwarded here so the
109
- * fan-out honors it: bugbotDisabled skips the Bugbot phase, and copilotDisabled
110
- * short-circuits the Copilot quota gate when the account is out of premium
111
- * requests. An entry that omits an opt-out defaults it to false so the child
112
- * runs that phase. homeDirectory is a run-level value forwarded to every child
113
- * so the child can build its codex-review scripts path: the workflow sandbox
114
- * exposes no process global, so the child reads home from its args, not env.
115
- * @param {object} prEntry one validated element of the args.prs array
116
- * @param {string} homeDirectory the run-level home directory for every child
117
- * @returns {object} the args object passed to the converge.mjs child run
118
- */
119
- function childRunInput(prEntry, homeDirectory) {
102
+ function childRunInput(prEntry, homeDirectory, transport = DEFAULT_GITHUB_TRANSPORT) {
120
103
  return {
121
104
  owner: prEntry.owner,
122
105
  repo: prEntry.repo,
@@ -125,6 +108,7 @@ function childRunInput(prEntry, homeDirectory) {
125
108
  bugbotDisabled: Boolean(prEntry.bugbotDisabled),
126
109
  copilotDisabled: Boolean(prEntry.copilotDisabled),
127
110
  homeDirectory,
111
+ transport,
128
112
  }
129
113
  }
130
114
 
@@ -141,7 +125,7 @@ const childResults = await parallel(
141
125
  input.prs.map((eachPr) => async () => {
142
126
  const childOutcome = await workflow(
143
127
  { scriptPath: input.convergeScriptPath },
144
- childRunInput(eachPr, input.homeDirectory),
128
+ childRunInput(eachPr, input.homeDirectory, input.transport),
145
129
  )
146
130
  return {
147
131
  owner: eachPr.owner,
@@ -68,6 +68,18 @@ test('valid coordinates classify with no blocker and keep every PR entry', () =>
68
68
  assert.equal(classified.input.prs.length, 2);
69
69
  });
70
70
 
71
+ test('a cloud transport classifies with no blocker', () => {
72
+ const classified = classifyMultiInput({ ...validArgs(), transport: 'cloud' });
73
+ assert.equal(classified.blocker, null);
74
+ assert.equal(classified.input.transport, 'cloud');
75
+ });
76
+
77
+ test('an unknown transport is blocked before child workflows start', () => {
78
+ const classified = classifyMultiInput({ ...validArgs(), transport: 'proxy' });
79
+ assert.equal(classified.input, null);
80
+ assert.match(classified.blocker, /transport/i);
81
+ });
82
+
71
83
  test('a missing convergeScriptPath is blocked', () => {
72
84
  const classified = classifyMultiInput({ prs: [validEntry(101)] });
73
85
  assert.equal(classified.input, null);
@@ -138,6 +150,10 @@ test('childRunInput defaults bugbotDisabled to false when the entry omits it', (
138
150
  assert.equal(childRunInput(validEntry(101)).bugbotDisabled, false);
139
151
  });
140
152
 
153
+ test('childRunInput forwards the selected cloud transport', () => {
154
+ assert.equal(childRunInput(validEntry(101), '/home/dev', 'cloud').transport, 'cloud');
155
+ });
156
+
141
157
  test('childRunInput forwards the run-level home directory to the child run', () => {
142
158
  const childArgs = childRunInput(validEntry(101), '/home/dev');
143
159
  assert.equal(childArgs.homeDirectory, '/home/dev');
@@ -16,23 +16,23 @@ One warm advisor at the strongest tier this session can reach. This session is t
16
16
 
17
17
  | Doc | Holds |
18
18
  |---|---|
19
- | [`docs/references/advisor-tool.md`](../../docs/references/advisor-tool.md) | **Consult cadence and weight** — when to call, hard rule before first write, how to treat advice. Read this for every consult. |
20
- | [`~/.claude/_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md) | **Bind and lifecycle** — session identity, host detect, model floor, warm-up, CLI fallback; its read map routes each moment to a `reference/` detail file. |
21
- | [`agents/session-advisor.md`](../../agents/session-advisor.md) | **Reply contract** — ENDORSE / CORRECTION / PLAN / STOP; SendMessage only. |
22
- | [`reference/advisor-docs-review.md`](reference/advisor-docs-review.md) | Anthropic advisor-tool source facts: measured effects, Sonnet steering, cost levers, failure modes. Background — read it when tuning the bind, not on every consult. |
19
+ | [`docs/references/advisor-tool.md`](../../docs/references/advisor-tool.md) | **Consult cadence and weight.** When to call, the hard rule before first write, and how to treat advice. Read this for every consult. |
20
+ | [`~/.claude/_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md) | **Bind and lifecycle.** Session identity, host detect, model floor, warm-up, CLI fallback. Its read map routes each moment to a `reference/` detail file. |
21
+ | [`agents/session-advisor.md`](../../agents/session-advisor.md) | **Reply contract.** ENDORSE / CORRECTION / PLAN / STOP. SendMessage only. |
22
+ | [`reference/advisor-docs-review.md`](reference/advisor-docs-review.md) | Anthropic advisor-tool source facts: measured effects, Sonnet steering, cost levers, failure modes. Background. Read it when tuning the bind, not on every consult. |
23
23
 
24
24
  ## Bind
25
25
 
26
26
  1. Name the session identity first (protocol **Host profiles**), then walk the model floor.
27
- 2. Claude: Fable first in-session at `ADVISOR_EFFORT` (default low). When Fable is out of usage, bind Sol at the same effort. Codex: Sol in-session. Third-party: headless Fable then Sol. When the host's walk fails, fail closed.
28
- 3. Name: `team-advisor-agent` on Claude (Agent spawn of `session-advisor`); a native Sol subagent on Codex; one CLI `session_id` on a third-party host via the protocol Claude-chain.
27
+ 2. Claude: Fable first in-session at `ADVISOR_EFFORT` (default low). When Fable is out of usage, bind Astra at the same effort. Codex: Astra in-session. Third-party: headless Fable then Astra. When the host's walk fails, fail closed.
28
+ 3. Name: `team-advisor-agent` on Claude (Agent spawn of `session-advisor`); a native Astra subagent on Codex; one CLI `session_id` on a third-party host via the protocol Claude-chain or Astra helper.
29
29
  4. A Fable-tier spawn or re-spawn carries the exact token `FABLE-SPAWN-AUTHORIZED` in its prompt (protocol warm-up; `fable_spawn_gate` requires it).
30
- 5. Skip the multi-consumer "who you are" opener — sole consumer.
31
- 6. When the bind or reply path fails, fail closed and report to the user. On a third-party host, only the bound Claude advisor issues ENDORSE / CORRECTION / PLAN / STOP.
30
+ 5. Skip the multi-consumer "who you are" opener. This session is the sole consumer.
31
+ 6. When the bind or reply path fails, fail closed and report to the user. On a third-party host, only the bound advisor issues ENDORSE / CORRECTION / PLAN / STOP.
32
32
 
33
- **GOTCHA (Cursor / ThirdParty + Sol):** when the walk reaches Sol or the user asks for Sol, first tool call is `python ~/.claude/_shared/advisor/scripts/codex_sol_advisor.py --bind --enable-sol --cwd <repo-root>` with the charter on stdin — not Agent/Task, not a probe-path search. Details: [`third-party-bind.md`](../../_shared/advisor/reference/third-party-bind.md) GOTCHA and [`sol-rung.md`](../../_shared/advisor/reference/sol-rung.md).
33
+ **GOTCHA (Cursor / ThirdParty + Astra):** when the walk reaches Astra or the user asks for Astra, first tool call is `python ~/.claude/_shared/advisor/scripts/codex_astra_advisor.py --bind --enable-astra --cwd <repo-root>` with the charter on stdin. Do not use Agent or Task. Do not search for a probe path. Details: [`third-party-bind.md`](../../_shared/advisor/reference/third-party-bind.md) GOTCHA and [`astra-rung.md`](../../_shared/advisor/reference/astra-rung.md).
34
34
 
35
- Full walk, charter, consult packet, Sol routing, and drift re-bind live in the protocol read map and its authoritative `reference/` leaves.
35
+ Full walk, charter, consult packet, Astra routing, and drift re-bind live in the protocol read map and its `reference/` files.
36
36
 
37
37
  ## Consult
38
38
 
@@ -44,6 +44,6 @@ Aim for two consults on a normal task: one after orientation and one after write
44
44
 
45
45
  ## Constraints
46
46
 
47
- - One bind per session; this session owns spawn, in-session Sol spawn, or CLI bind, drift re-bind, and shutdown.
47
+ - One bind per session; this session owns spawn, in-session Astra spawn, or CLI bind, drift re-bind, and shutdown.
48
48
  - Bind at or above the protocol floor for this host.
49
49
  - The advisor only answers (messaging); the session runs tools and posts.
@@ -13,20 +13,20 @@ On Claude, continue with **Model floor** and the rest of this document.
13
13
 
14
14
  ## Read map
15
15
 
16
- The sections below hold the standing rules; open a reference file at the moment its row names.
16
+ The sections below hold the standing rules. Open a reference file at the moment its row names.
17
17
 
18
18
  | Moment | Open |
19
19
  |---|---|
20
- | Naming the session identity | [`reference/identity.md`](reference/identity.md) — Claude, Codex, or neither |
21
- | Binding on a Claude host | [`reference/warm-up.md`](reference/warm-up.md) — spawn fields, Fable token, charter |
22
- | Binding on a Codex host | [`reference/identity.md`](reference/identity.md) — in-session Sol spawn |
23
- | Binding from a third-party host | [`reference/third-party-bind.md`](reference/third-party-bind.md) — CLI bind steps, fail-closed rule |
24
- | Fable is out of usage | [`reference/sol-rung.md`](reference/sol-rung.md) — Sol fallback at shared effort |
25
- | Composing a consult | [`reference/consult-format.md`](reference/consult-format.md) — packet, new-evidence and report-back rules |
26
- | Assembling an executor spawn prompt | [`reference/advisor-block.md`](reference/advisor-block.md) — the paste parts |
27
- | Advisor drifts, dies, or the task pivots | [`reference/lifecycle.md`](reference/lifecycle.md) — re-spawn and re-bind steps |
28
- | Logging or checking a bind walk | [`reference/spawn-walk-log.md`](reference/spawn-walk-log.md) — record shape, validator |
29
- | Any CLI call to a Claude advisor | [`reference/cli-chain.md`](reference/cli-chain.md) — runner modes, alias table, resume |
20
+ | Naming the session identity | [`reference/identity.md`](reference/identity.md): Claude, Codex, or neither |
21
+ | Binding on a Claude host | [`reference/warm-up.md`](reference/warm-up.md): spawn fields, Fable token, charter |
22
+ | Binding on a Codex host | [`reference/identity.md`](reference/identity.md): in-session Astra spawn |
23
+ | Binding from a third-party host | [`reference/third-party-bind.md`](reference/third-party-bind.md): CLI bind steps, fail-closed rule |
24
+ | Fable is out of usage | [`reference/astra-rung.md`](reference/astra-rung.md): Astra fallback at shared effort |
25
+ | Composing a consult | [`reference/consult-format.md`](reference/consult-format.md): packet, new-evidence and report-back rules |
26
+ | Assembling an executor spawn prompt | [`reference/advisor-block.md`](reference/advisor-block.md): the paste parts |
27
+ | Advisor drifts, dies, or the task pivots | [`reference/lifecycle.md`](reference/lifecycle.md): re-spawn and re-bind steps |
28
+ | Logging or checking a bind walk | [`reference/spawn-walk-log.md`](reference/spawn-walk-log.md): record shape, validator |
29
+ | Any CLI call to a Claude advisor | [`reference/cli-chain.md`](reference/cli-chain.md): runner modes, alias table, resume |
30
30
 
31
31
  ## Host profiles
32
32
 
@@ -42,95 +42,95 @@ Session identity:
42
42
  Mechanical override for scripts:
43
43
 
44
44
  1. `ADVISOR_HOST_PROFILE=ThirdParty` or `=Claude` or `=Codex` (explicit override; any letter case).
45
- 2. `THIRD_PARTY=1` (or `true` / `yes` / `on`) — a third-party (non-Claude) harness.
45
+ 2. `THIRD_PARTY=1` (or `true` / `yes` / `on`) selects a third-party (non-Claude) harness.
46
46
  3. Default: Claude.
47
47
 
48
- ### Shared effort — any host
48
+ ### Shared effort, any host
49
49
 
50
- Fable and Sol both read `ADVISOR_EFFORT` (`low`, `medium`, `high`, `xhigh`, `max`). The default is `low`.
51
- Pass `--effort <level>` on the Sol helper to set effort for that Sol run.
50
+ Fable and Astra both read `ADVISOR_EFFORT` (`low`, `medium`, `high`, `xhigh`, `max`). The default is `low`.
51
+ Pass `--effort <level>` on the Astra helper to set effort for that Astra run.
52
52
  Pass `--effort <level>` on the Claude CLI bind for Fable. An unset or unrecognized value uses `low`.
53
53
 
54
- ### Sol rung
54
+ ### Astra rung
55
55
 
56
- On Claude and ThirdParty: when Fable is out of usage, bind Sol through the Codex helper.
57
- Open that attempt with `ADVISOR_SOL=1` (or `true` / `yes` / `on`) in the environment, or pass `--enable-sol` on the helper invocation.
56
+ On Claude and ThirdParty: when Fable is out of usage, bind Astra through the Codex helper.
57
+ Open that attempt with `ADVISOR_ASTRA=1` (or `true` / `yes` / `on`) in the environment, or pass `--enable-astra` on the helper invocation.
58
58
  Flag off both ways: fail closed when Fable did not bind.
59
- Flag on: run the Codex preflight and bind per [`reference/sol-rung.md`](reference/sol-rung.md); a failed preflight fails closed when Fable did not bind.
59
+ Flag on: run the Codex preflight and bind per [`reference/astra-rung.md`](reference/astra-rung.md); a failed preflight fails closed when Fable did not bind.
60
60
 
61
- On Codex: Sol is the in-session default. The `ADVISOR_SOL` flag is not required. Fail closed when that spawn does not bind.
61
+ On Codex: Astra is the in-session default. The `ADVISOR_ASTRA` flag is not required. Fail closed when that spawn does not bind.
62
62
 
63
63
  ### Claude host
64
64
 
65
- Use the **Model floor** ladder below (Fable first, then Sol when Fable is out of usage).
66
- Warm-up spawns `subagent_type: session-advisor` via the Agent tool; consults go through `SendMessage` to that warm agent.
65
+ Use the **Model floor** ladder below (Fable first, then Astra when Fable is out of usage).
66
+ Warm-up spawns `subagent_type: session-advisor` via the Agent tool for Fable; consults go through `SendMessage` to that warm agent. Astra uses the Codex helper.
67
67
  Assemble and paste each executor's Advisor block per the **Advisor block** section.
68
68
 
69
69
  ### Codex host
70
70
 
71
- Spawn a native in-session Sol subagent at `resolve_codex_model_id("Sol")`.
72
- Walk `candidate_tiers = ["Sol"]`. Record `{tier: "Sol", result: "spawned"}` on success.
73
- **Fail closed:** when Sol does not bind, set `selected_tier = null` and a `fallback_reason`, report that the advisor is unreachable, and **stop**.
74
- Do not walk Fable on a Codex host. Consults stay in-session with that Sol subagent.
71
+ Spawn a native in-session Astra subagent at `resolve_codex_model_id("Astra")`.
72
+ Walk `candidate_tiers = ["Astra"]`. Record `{tier: "Astra", result: "spawned"}` on success.
73
+ **Fail closed:** when Astra does not bind, set `selected_tier = null` and a `fallback_reason`, report that the advisor is unreachable, and **stop**.
74
+ Do not walk Fable on a Codex host. Consults stay in-session with that Astra subagent.
75
75
  Assemble and paste each executor's Advisor block per the **Advisor block** section.
76
76
 
77
77
  ### Third-party host
78
78
 
79
79
  On a third-party (non-Claude, non-Codex) harness, the shared CLI Claude-chain is the one path to a Claude advisor: bind Fable through it, per [`reference/third-party-bind.md`](reference/third-party-bind.md).
80
80
  The bound Claude session is the advisor; this third-party session stays the executor.
81
- Walk `candidate_tiers = ["Fable"]`. When Fable is out of usage, the sol rung binds after Fable (`candidate_tiers = ["Fable", "Sol"]`).
82
- **Cursor Sol first shot:** when the walk reaches Sol (or the user asks for Sol), bind through `codex_sol_advisor.py --bind --enable-sol` on the first tool call (see the GOTCHA in [`reference/third-party-bind.md`](reference/third-party-bind.md)) — not the Agent tool, and not a probe-path hunt.
83
- **Fail closed:** when every candidate fails, set `selected_tier = null` and a `fallback_reason`, report that the advisor is unreachable, and **stop** — ENDORSE / CORRECTION / PLAN / STOP come only from a bound advisor.
81
+ Walk `candidate_tiers = ["Fable"]`. When Fable is out of usage, the Astra rung binds after Fable (`candidate_tiers = ["Fable", "Astra"]`).
82
+ **Cursor Astra first shot:** when the walk reaches Astra (or the user asks for Astra), bind through `codex_astra_advisor.py --bind --enable-astra` on the first tool call (see the GOTCHA in [`reference/third-party-bind.md`](reference/third-party-bind.md)). Do not use the Agent tool, and do not hunt a probe path.
83
+ **Fail closed:** when every candidate fails, set `selected_tier = null` and a `fallback_reason`, report that the advisor is unreachable, and **stop**. ENDORSE / CORRECTION / PLAN / STOP come only from a bound advisor.
84
84
  Executors report to the orchestrating session; that session consults the bound advisor and relays the four-signal reply.
85
85
 
86
86
  ## Model floor
87
87
 
88
- On Claude and ThirdParty the advisor ladder is `Fable` first, then sol (flag-gated, Codex CLI) when Fable is out of usage.
89
- On Codex the walk is Sol only, in-session.
88
+ On Claude and ThirdParty the advisor ladder is `Fable` first, then Astra (flag-gated, Codex CLI) when Fable is out of usage.
89
+ On Codex the walk is Astra only, in-session.
90
90
  Opus is not an advisor candidate. `Sonnet` and `Haiku` are executor tiers only.
91
91
  Consumer `own_tier` is recorded on the spawn-walk log; it does not add Opus to the advisor walk.
92
92
  Tier names are canonical Title Case; the validator accepts any letter case and normalizes to Title Case.
93
- Try binds top-down. Each try resolves its candidate tier to the short model alias via the tier-to-alias map in [`reference/cli-chain.md`](reference/cli-chain.md).
94
- The advisor is created at `selected_tier` — the first ladder tier that binds.
95
- When Fable fails on a Claude host, try Sol if the flag is on, else fail closed. The CLI chain is the Fable bind path on a third-party host and the Claude-host fallback for Fable; it does not bind Opus as advisor.
96
- On a Codex host a failed Sol spawn fails closed per **Host profiles → Codex host**.
97
- On a third-party host the CLI chain is already the primary path, so a failed Fable (and Sol, when enabled) walk fails closed per **Host profiles → Third-party host**.
93
+ Try binds top-down. Fable resolves to the short model alias in [`reference/cli-chain.md`](reference/cli-chain.md); Astra resolves through `resolve_codex_model_id("Astra")` to `gpt-6-astra`.
94
+ The advisor is created at `selected_tier`, the first ladder tier that binds.
95
+ When Fable fails on a Claude host, try Astra if the flag is on, else fail closed. The CLI chain is the Fable bind path on a third-party host and the Claude-host fallback for Fable; it does not bind Opus as advisor.
96
+ On a Codex host a failed Astra spawn fails closed per **Host profiles → Codex host**.
97
+ On a third-party host the CLI chain is already the primary path, so a failed Fable (and Astra, when enabled) walk fails closed per **Host profiles → Third-party host**.
98
98
 
99
99
  Emit a structured spawn-walk log so the walk can be checked mechanically: [`reference/spawn-walk-log.md`](reference/spawn-walk-log.md).
100
100
  The validator checks ladder shape only; host policy sits on top.
101
101
 
102
- **Equal-tier pairings.** Bind Fable for an independent second pass on irreversible or security-sensitive work. The advisor is Fable or Sol.
102
+ **Equal-tier pairings.** Bind Fable for an independent second pass on irreversible or security-sensitive work. The advisor is Fable or Astra.
103
103
 
104
104
  ## Warm-up (once per session)
105
105
 
106
- On a **Claude host**, walk the candidate tiers top-down, spawning `session-advisor` in the background at each candidate's alias with the charter as its prompt, stopping at the first successful spawn.
107
- A **Fable**-tier try carries the exact token `FABLE-SPAWN-AUTHORIZED` in its prompt — `hooks/blocking/fable_spawn_gate.py` denies a Fable-tier spawn without it.
106
+ On a **Claude host**, spawn `session-advisor` at the Fable alias with the charter as its prompt. When Fable is out of usage and the Astra rung is open, bind Astra through the Codex helper instead.
107
+ A **Fable**-tier try carries the exact token `FABLE-SPAWN-AUTHORIZED` in its prompt. `hooks/blocking/fable_spawn_gate.py` denies a Fable-tier spawn without it.
108
108
  Full spawn fields and the charter template: [`reference/warm-up.md`](reference/warm-up.md).
109
109
 
110
- On a **Codex host**, spawn a native in-session Sol subagent with the same charter. Bind fields: [`reference/identity.md`](reference/identity.md) and [`reference/warm-up.md`](reference/warm-up.md).
110
+ On a **Codex host**, spawn a native in-session Astra subagent with the same charter. Bind fields: [`reference/identity.md`](reference/identity.md) and [`reference/warm-up.md`](reference/warm-up.md).
111
111
 
112
- On a **third-party host**, bind per [`reference/third-party-bind.md`](reference/third-party-bind.md) and charter the CLI session with the same charter — the reply contract is the same, and consults travel through the CLI runner.
112
+ On a **third-party host**, bind per [`reference/third-party-bind.md`](reference/third-party-bind.md) and charter the CLI session with the same charter. The reply contract is the same, and consults travel through the CLI runner.
113
113
 
114
114
  ## Consulting the warm agent
115
115
 
116
- Send a consult at the trigger points `docs/references/advisor-tool.md` **When to call** defines — plan lock-in, believed completion, hard-to-reverse actions, repeated failure or stalled progress, and reconsidered approach.
116
+ Send a consult at the trigger points `docs/references/advisor-tool.md` **When to call** defines: plan lock-in, believed completion, hard-to-reverse actions, repeated failure or stalled progress, and reconsidered approach.
117
117
  The paste parts in [`reference/advisor-block.md`](reference/advisor-block.md) restate them for executors.
118
118
 
119
- Each consult carries the sender's identity and assignment, the delta since the last consult, the live decision or blocker, and the paths or excerpts needed to answer well — full packet shape plus the new-evidence and report-back rules: [`reference/consult-format.md`](reference/consult-format.md).
119
+ Each consult carries the sender's identity and assignment, the delta since the last consult, the live decision or blocker, and the paths or excerpts needed to answer well. Full packet shape plus the new-evidence and report-back rules: [`reference/consult-format.md`](reference/consult-format.md).
120
120
  Consult briefs embed the `docs/references/advisor-tool.md` **Brevity cue** line, sized per that section.
121
121
 
122
- Treat the reply as a serious second opinion: a CORRECTION — whether it names a wrong step or a risk worth closing — is something to address before treating the plan or the work as done.
122
+ A CORRECTION names a wrong step or a risk worth closing. Address it before treating the plan or the work as done.
123
123
  Route a STOP, or an unreachable advisor, upward per [`reference/consult-format.md`](reference/consult-format.md).
124
124
 
125
- ## Advisor block — assemble and paste into every executor spawn prompt
125
+ ## Advisor block
126
126
 
127
- Assemble each executor's block from the parts in [`reference/advisor-block.md`](reference/advisor-block.md), in order: one transport preamble picked by host profile, then the shared core, then — for an executor at Sonnet or below — the weak-executor add-on.
127
+ Assemble each executor's block from the parts in [`reference/advisor-block.md`](reference/advisor-block.md), in order: one transport preamble picked by host profile, then the shared core, then the weak-executor add-on for an executor at Sonnet or below.
128
128
  Paste the assembled block at the **top** of the spawn prompt, ahead of any other sentence that mentions the advisor.
129
- The assembled block is self-contained — the executor receives this text alone.
129
+ The assembled block is self-contained. The executor receives this text alone.
130
130
 
131
131
  ## Lifecycle ownership
132
132
 
133
- The session that binds the advisor owns its whole lifecycle — first bind, drift re-spawn or re-bind, and shutdown; every other consumer reaches the advisor by message alone.
133
+ The session that binds the advisor owns its whole lifecycle: first bind, drift re-spawn or re-bind, and shutdown. Every other consumer reaches the advisor by message alone.
134
134
  Drift signals and the per-host re-spawn / re-bind steps: [`reference/lifecycle.md`](reference/lifecycle.md).
135
135
 
136
136
  ## CLI chain
@@ -140,14 +140,14 @@ Modes and failover, the tier-to-alias table, brief piping, and `--resume` sessio
140
140
 
141
141
  **Third-party host:** the primary bind and consult path; the walk order and fail-closed rule live in [`reference/third-party-bind.md`](reference/third-party-bind.md).
142
142
 
143
- **Codex host:** do not use this runner as the primary path. Sol binds in-session.
143
+ **Codex host:** do not use this runner as the primary path. Astra binds in-session.
144
144
 
145
145
  **Claude host:** fall back to this runner exactly when one of these holds:
146
- - The Agent-tool spawn errors at every candidate tier down to the floor — the tool itself is unavailable.
146
+ - The Agent-tool spawn errors at every candidate tier down to the floor. The tool itself is unavailable.
147
147
  - `SendMessage` to the shared advisor errors, or draws no reply within the bound in `ADVISOR_SENDMESSAGE_REPLY_WAIT_SECONDS` (120) in `$HOME/.claude/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py`, and a re-spawn also fails.
148
148
  - The running session is itself a subagent barred from spawning further agents.
149
149
 
150
150
  ## State the mechanism
151
151
 
152
- One warm agent, addressed by name, whose transcript accumulates across consults — each consult sends only the delta since the last one.
152
+ One warm agent, addressed by name, whose transcript accumulates across consults. Each consult sends only the delta since the last one.
153
153
  A consuming skill's own text states this mechanism; a token or cost saving becomes a claim only after a measured comparison against cold spawns.