@akagilnc/pi-workflow-roles 0.1.4259 → 0.1.4276

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.
@@ -19,62 +19,6 @@ function seatModelOnly(seat) {
19
19
  if (seat?.provider === void 0 || seat.model === void 0) return void 0;
20
20
  return seat.thinking === void 0 ? { provider: seat.provider, model: seat.model } : { provider: seat.provider, model: seat.model, thinking: seat.thinking };
21
21
  }
22
- const STARTUP_CANDIDATES = {
23
- judge: [
24
- { provider: "openai-codex", model: "gpt-5.6-sol", thinking: "high" },
25
- { provider: "xai", model: "grok-4.5", thinking: "high" }
26
- ],
27
- countersign: [
28
- { provider: "openai-codex", model: "gpt-5.6-sol", thinking: "high" },
29
- { provider: "xai", model: "grok-4.5", thinking: "high" }
30
- ],
31
- "gleaner-left": [
32
- { provider: "openai-codex", model: "gpt-5.6-sol", thinking: "medium" },
33
- { provider: "xai", model: "grok-4.5", thinking: "high" }
34
- ],
35
- reviewer: [
36
- { provider: "openai-codex", model: "gpt-5.6-sol", thinking: "medium" },
37
- { provider: "xai", model: "grok-4.5", thinking: "high" }
38
- ],
39
- coder: [
40
- { provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
41
- { provider: "xai", model: "grok-4.5", thinking: "high" }
42
- ],
43
- fixer: [
44
- { provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
45
- { provider: "xai", model: "grok-4.5", thinking: "high" }
46
- ],
47
- collector: [
48
- { provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
49
- { provider: "xai", model: "grok-4.5", thinking: "high" }
50
- ],
51
- doctor: [
52
- { provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
53
- { provider: "xai", model: "grok-4.5", thinking: "high" }
54
- ],
55
- merger: [
56
- { provider: "openai-codex", model: "gpt-5.6-luna", thinking: "high" },
57
- { provider: "xai", model: "grok-4.5", thinking: "high" }
58
- ],
59
- // #620: subordinate officers inherit gatekeeper; no package startup model.
60
- notary: [],
61
- // #453/#620/#639: gatekeeper callable but no package startup model — caller
62
- // configures it or inherits on the province path.
63
- gatekeeper: [],
64
- inspector: [],
65
- navigator: [
66
- { provider: "openai-codex", model: "gpt-5.6-luna", thinking: "medium" },
67
- { provider: "xai", model: "grok-4.5", thinking: "high" }
68
- ],
69
- // #675: auditor public seat — no package startup; caller configures.
70
- auditor: [],
71
- // #708 `diarist-seat-default`: owner-set initial value; changed in the seat
72
- // table like any other seat. No engine axis, package-default host.
73
- diarist: [{ provider: "xai", model: "grok-4.5", thinking: "medium" }]
74
- };
75
- function publicStartupCandidates(seat) {
76
- return STARTUP_CANDIDATES[seat];
77
- }
78
22
  const PUBLIC_DETERMINISTIC_COMMANDS = ["analyst"];
79
23
  function listHelpCapabilities() {
80
24
  const support = PUBLIC_CLI_SUPPORT_COMMANDS.map((name) => ({
@@ -118,6 +62,5 @@ export {
118
62
  isPublicCliSupportCommand,
119
63
  isPublicConfigurableSeat,
120
64
  listHelpCapabilities,
121
- publicStartupCandidates,
122
65
  seatModelOnly
123
66
  };
@@ -77,11 +77,17 @@ function hostSelectionFailureFromUnknown(error) {
77
77
  const failure = error.failure;
78
78
  return failure;
79
79
  }
80
- async function createSummonEnv(options) {
81
- const [{ piDurablePrincipalAuthority }, { appendPiSessionCustomEntry }, { resolveRoleTurnHost }] = await Promise.all([
80
+ async function createSummonEnv(options, afterHost) {
81
+ const [
82
+ { piDurablePrincipalAuthority },
83
+ { appendPiSessionCustomEntry },
84
+ { resolveRoleTurnHost },
85
+ { missingResolvedSeatModelMessage, resolvedSeatWithModel }
86
+ ] = await Promise.all([
82
87
  import("./pi/durable-principal.js"),
83
88
  import("./pi/role-turn-host.js"),
84
- import("./public-cli/role-turn-host-resolution.js")
89
+ import("./public-cli/role-turn-host-resolution.js"),
90
+ import("./public-cli/config.js")
85
91
  ]);
86
92
  const principalAuthority = piDurablePrincipalAuthority;
87
93
  const roleTurnHost = resolveRoleTurnHost(
@@ -93,26 +99,37 @@ async function createSummonEnv(options) {
93
99
  },
94
100
  { role: options.role, seat: options.seat, principalAuthority }
95
101
  );
96
- const hostName = options.seat.host ?? "pi";
102
+ afterHost?.();
103
+ const seatWithModel = resolvedSeatWithModel(options.seat);
104
+ if (seatWithModel === void 0) {
105
+ return {
106
+ ok: false,
107
+ missingModelMessage: missingResolvedSeatModelMessage(options.role)
108
+ };
109
+ }
110
+ const hostName = seatWithModel.host ?? "pi";
97
111
  const { loadHostProvidersTable, projectHostFacingProvider } = await import("./public-cli/host-providers.js");
98
- const hostFacingSelection = options.seat.selection === void 0 ? void 0 : projectHostFacingProvider(
99
- options.seat.selection,
112
+ const hostFacingSelection = projectHostFacingProvider(
113
+ seatWithModel.selection,
100
114
  hostName,
101
115
  loadHostProvidersTable(options.home),
102
116
  options.home
103
117
  );
104
118
  return {
105
- home: options.home,
106
- principalAuthority,
107
- agentDir: options.agentDir,
108
- sessionAppender: appendPiSessionCustomEntry,
109
- packageRoot: options.packageRoot,
110
- roleTurnHost,
111
- cwd: options.cwd,
112
- credentials: options.credentials,
113
- ...hostFacingSelection === void 0 ? {} : { model: hostFacingSelection },
114
- ...projectSeatEngine(options.seat),
115
- ...projectSeatHost(options.seat)
119
+ ok: true,
120
+ env: {
121
+ home: options.home,
122
+ principalAuthority,
123
+ agentDir: options.agentDir,
124
+ sessionAppender: appendPiSessionCustomEntry,
125
+ packageRoot: options.packageRoot,
126
+ roleTurnHost,
127
+ cwd: options.cwd,
128
+ credentials: options.credentials,
129
+ ...hostFacingSelection === void 0 ? {} : { model: hostFacingSelection },
130
+ ...projectSeatEngine(seatWithModel),
131
+ ...projectSeatHost(seatWithModel)
132
+ }
116
133
  };
117
134
  }
118
135
  async function summonPublicRole(options) {
@@ -127,46 +144,72 @@ async function summonPublicRole(options) {
127
144
  const credentials = options.credentials ?? await loadCredentialProviders(agentDir);
128
145
  const config = await loadPublicCliConfig(home);
129
146
  const seat = resolveEffectiveSeat(config, options.role, credentials);
130
- let summonEnv;
131
- try {
132
- summonEnv = await createSummonEnv({
133
- role: options.role,
134
- home,
135
- agentDir,
136
- cwd: options.cwd,
137
- packageRoot,
138
- credentials,
139
- seat,
140
- ...options.extraPiArgs === void 0 ? {} : { extraPiArgs: options.extraPiArgs },
141
- ...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
142
- ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters }
143
- });
144
- } catch (error) {
145
- const failure = hostSelectionFailureFromUnknown(error);
146
- if (failure !== void 0) {
147
- const { formatHostSelectionFailure } = await import("./public-cli/role-turn-host-resolution.js");
148
- return { exitCode: 1, stderr: formatHostSelectionFailure(failure) };
149
- }
150
- throw error;
151
- }
152
- const env = {
153
- ...summonEnv,
154
- // Station child role run (#840): omit automatic navigator attendance.
155
- stationChild: true,
156
- // Host config passthrough only — same face as public CLI (#422 / #675).
157
- ...config.autoResumeLimit === void 0 ? {} : { autoResumeLimit: config.autoResumeLimit },
158
- // Parent cancellation reaches the nested activation's own turn dispatch.
159
- ...options.signal === void 0 ? {} : { signal: options.signal },
160
- // #753: reask rides the existing notary same-ticket resume summons.instruction.
161
- ...options.reviewReask === void 0 ? {} : { reviewReask: options.reviewReask },
162
- // #879: verbatim submission body on officer dialogue content channel.
163
- ...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction },
164
- ...options.boundTicketNumber === void 0 ? {} : { boundTicketNumber: options.boundTicketNumber },
165
- // createRunId is the only remaining env overlay — host is seat-selected above.
166
- ...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
167
- };
168
147
  const captured = options.io === void 0 ? createCapturingIo() : void 0;
169
148
  const io = options.io ?? captured.io;
149
+ const summonEnvInput = {
150
+ role: options.role,
151
+ home,
152
+ agentDir,
153
+ cwd: options.cwd,
154
+ packageRoot,
155
+ credentials,
156
+ seat,
157
+ ...options.extraPiArgs === void 0 ? {} : { extraPiArgs: options.extraPiArgs },
158
+ ...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
159
+ ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters }
160
+ };
161
+ async function prepareSummonEnv(afterHost) {
162
+ try {
163
+ const built = await createSummonEnv(summonEnvInput, afterHost);
164
+ if (!built.ok) {
165
+ return { ok: false, exitCode: 1, stderr: built.missingModelMessage };
166
+ }
167
+ return {
168
+ ok: true,
169
+ env: {
170
+ ...built.env,
171
+ stationChild: true,
172
+ ...config.autoResumeLimit === void 0 ? {} : { autoResumeLimit: config.autoResumeLimit },
173
+ ...options.signal === void 0 ? {} : { signal: options.signal },
174
+ ...options.reviewReask === void 0 ? {} : { reviewReask: options.reviewReask },
175
+ ...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction },
176
+ ...options.boundTicketNumber === void 0 ? {} : { boundTicketNumber: options.boundTicketNumber },
177
+ ...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
178
+ }
179
+ };
180
+ } catch (error) {
181
+ const failure = hostSelectionFailureFromUnknown(error);
182
+ if (failure !== void 0) {
183
+ const { formatHostSelectionFailure } = await import("./public-cli/role-turn-host-resolution.js");
184
+ return { ok: false, exitCode: 1, stderr: formatHostSelectionFailure(failure) };
185
+ }
186
+ const { CliUsageError } = await import("./public-cli/cli-errors.js");
187
+ if (error instanceof CliUsageError) {
188
+ const { presentStructuralRejection } = await import("./public-cli/settlement.js");
189
+ presentStructuralRejection(error, io);
190
+ return { ok: false, exitCode: 2 };
191
+ }
192
+ throw error;
193
+ }
194
+ }
195
+ function projectPrepareFailure(prepared) {
196
+ const parts = [prepared.stderr, captured?.stderrText()].filter(
197
+ (s) => typeof s === "string" && s !== ""
198
+ );
199
+ const stderr2 = parts.length === 0 ? void 0 : parts.join("");
200
+ return {
201
+ exitCode: prepared.exitCode,
202
+ ...stderr2 === void 0 ? {} : { stderr: stderr2 }
203
+ };
204
+ }
205
+ async function runPrepared(parse, run) {
206
+ let parsedArgv;
207
+ const prepared = await prepareSummonEnv(() => {
208
+ parsedArgv = parse(options.argv);
209
+ });
210
+ if (!prepared.ok) return { fail: projectPrepareFailure(prepared) };
211
+ return { ok: await run(prepared.env, () => parsedArgv) };
212
+ }
170
213
  let result;
171
214
  switch (options.role) {
172
215
  case "notary": {
@@ -174,7 +217,9 @@ async function summonPublicRole(options) {
174
217
  import("./public-cli/notary-run.js"),
175
218
  import("./public-cli/invocation.js")
176
219
  ]);
177
- result = await runPublicNotary(options.argv, env, io, parseNotaryArgv);
220
+ const stepped = await runPrepared(parseNotaryArgv, (env, once) => runPublicNotary(options.argv, env, io, once));
221
+ if ("fail" in stepped) return stepped.fail;
222
+ result = stepped.ok;
178
223
  break;
179
224
  }
180
225
  case "inspector": {
@@ -182,49 +227,23 @@ async function summonPublicRole(options) {
182
227
  import("./public-cli/inspector-run.js"),
183
228
  import("./public-cli/invocation.js")
184
229
  ]);
185
- result = await runPublicInspector(options.argv, env, io, parseInspectorArgv);
186
- break;
187
- }
188
- case "auditor": {
189
- const [{ runPublicInstructionSeat }, { parseAuditorArgv }] = await Promise.all([
190
- import("./public-cli/instruction-seat-run.js"),
191
- import("./public-cli/invocation.js")
192
- ]);
193
- result = await runPublicInstructionSeat(
194
- options.argv,
195
- env,
196
- io,
197
- "auditor",
198
- parseAuditorArgv
199
- );
200
- break;
201
- }
202
- case "navigator": {
203
- const [{ runPublicInstructionSeat }, { parseNavigatorArgv }] = await Promise.all([
204
- import("./public-cli/instruction-seat-run.js"),
205
- import("./public-cli/invocation.js")
206
- ]);
207
- result = await runPublicInstructionSeat(
208
- options.argv,
209
- env,
210
- io,
211
- "navigator",
212
- parseNavigatorArgv
213
- );
230
+ const stepped = await runPrepared(parseInspectorArgv, (env, once) => runPublicInspector(options.argv, env, io, once));
231
+ if ("fail" in stepped) return stepped.fail;
232
+ result = stepped.ok;
214
233
  break;
215
234
  }
235
+ case "auditor":
236
+ case "navigator":
216
237
  case "gatekeeper": {
217
- const [{ runPublicInstructionSeat }, { parseGatekeeperArgv }] = await Promise.all([
238
+ const seat2 = options.role;
239
+ const [{ runPublicInstructionSeat }, invocation] = await Promise.all([
218
240
  import("./public-cli/instruction-seat-run.js"),
219
241
  import("./public-cli/invocation.js")
220
242
  ]);
221
- result = await runPublicInstructionSeat(
222
- options.argv,
223
- env,
224
- io,
225
- "gatekeeper",
226
- parseGatekeeperArgv
227
- );
243
+ const parse = seat2 === "auditor" ? invocation.parseAuditorArgv : seat2 === "navigator" ? invocation.parseNavigatorArgv : invocation.parseGatekeeperArgv;
244
+ const stepped = await runPrepared(parse, (env, once) => runPublicInstructionSeat(options.argv, env, io, seat2, once));
245
+ if ("fail" in stepped) return stepped.fail;
246
+ result = stepped.ok;
228
247
  break;
229
248
  }
230
249
  case "judge": {
@@ -232,7 +251,9 @@ async function summonPublicRole(options) {
232
251
  import("./public-cli/judge-run.js"),
233
252
  import("./public-cli/invocation.js")
234
253
  ]);
235
- result = await runPublicJudge(options.argv, env, io, parseJudgeArgv);
254
+ const stepped = await runPrepared(parseJudgeArgv, (env, once) => runPublicJudge(options.argv, env, io, once));
255
+ if ("fail" in stepped) return stepped.fail;
256
+ result = stepped.ok;
236
257
  break;
237
258
  }
238
259
  case "doctor": {
@@ -240,7 +261,9 @@ async function summonPublicRole(options) {
240
261
  import("./public-cli/doctor-run.js"),
241
262
  import("./public-cli/invocation.js")
242
263
  ]);
243
- result = await runPublicDoctor(options.argv, env, io, parseDoctorArgv);
264
+ const stepped = await runPrepared(parseDoctorArgv, (env, once) => runPublicDoctor(options.argv, env, io, once));
265
+ if ("fail" in stepped) return stepped.fail;
266
+ result = stepped.ok;
244
267
  break;
245
268
  }
246
269
  case "diarist": {
@@ -248,7 +271,9 @@ async function summonPublicRole(options) {
248
271
  import("./public-cli/diarist-run.js"),
249
272
  import("./public-cli/invocation.js")
250
273
  ]);
251
- result = await runPublicDiarist(options.argv, env, io, parseDiaristArgv);
274
+ const stepped = await runPrepared(parseDiaristArgv, (env, once) => runPublicDiarist(options.argv, env, io, once));
275
+ if ("fail" in stepped) return stepped.fail;
276
+ result = stepped.ok;
252
277
  break;
253
278
  }
254
279
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.4259",
3
+ "version": "0.1.4276",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/souls/notary.md CHANGED
@@ -20,6 +20,7 @@
20
20
  报「参与人物不存在」的那个人其实存在——他叫练国事,LLM 按奏疏称他「陕西巡抚」,引擎只认本名、连自己名册里存着的别名都不认;而符宝郎三轮放行,是因为闸只核「有没有编陛下的话」,票面确实一个字没编,于是一张根因就错的票完全合法地过了庭。
21
21
  意图曲解:大理寺 r2 要求「最终 head 上先真跑一次审核往返才收敛」,起居录当时已有陛下「645等我在的时候试。你不跑。做完以后告诉我就行了。我会拿真的东西跑」(#645 大理寺 r2,2026-09-09 02:52,符宝郎 run 01a0821b)。符宝郎两轮放行,判词写「仍与票面『交付后实际跑』一致」——对了六个字,没对陛下明说的意思。
22
22
  只查行为不查内容:大理寺查「每轮新增回执为空」,就断定起居录里没有记录,判票庭伪引;实际权威账本里那 24 条一直都在,引证属实。而符宝郎自己也没找到起居录,就信了大理寺引用的起居录。符宝郎要的是「权威起居录」,判官给的是「每轮新增回执」,把后者当成了前者的充分证明,然后第三轮 pass 时还把这个推断写进了署词。。认得出票、本该有录却找不到,应上呈,不是通过;真无票对象(true-unbound)本就无录,按 ADR 0075 改以 source-run 核旨,不得因缺录打回给事中。
23
+ 驳回被读成授权:一条腿怎么知道自己在哪张票上,陛下两次驳回——「? 起居录是吃干饭的吗?还要问这个?」「票号不是 读起居录吗?又是什么道?」——意思是 LLM 自己去读那份记录;票面却把「读」读成「机械层读」,据此写出「缺来源的九席在 turn 之前读起居录取得本票号」与验收「经新增前置读取接缝」,授权栏挂的正是那两句驳回(#858 seal 5,2026-09-14 23:35,符宝郎 run 01a0a0aa)。符宝郎九轮全 pass,因为闸只核「有没有编陛下的话」,那两句确实一个字没编——于是一段没人批准的机制完全合法地过了庭,施工席照它跑了一整局、零 commit 收工,直到陛下第四次开口才拦下。原话为真只答了一半,另一半是:这条机制是从这句话的哪个意思推出来的?推不出即加戏。驳回句是关闭分叉,不是开工授权。
23
24
  等等。。。
24
25
  任一病成立,点名该条驳回;拿不准陛下本意的,上呈。
25
26
 
@@ -18,7 +18,6 @@ import {
18
18
  import type { HostContext } from "./host-contracts.ts";
19
19
  import { createNativeNavigatorSessionFactory } from "./navigator-public-session.ts";
20
20
  import {
21
- NAVIGATOR_DEFAULT_MODEL,
22
21
  NAVIGATOR_PREPARE_TOOL_NAME,
23
22
  NavigatorUnavailableError,
24
23
  navigatorModelSettingPath,
@@ -40,7 +39,6 @@ import {
40
39
  import { sitianReport } from "./sitian-facade.ts";
41
40
 
42
41
  export {
43
- NAVIGATOR_DEFAULT_MODEL,
44
42
  NAVIGATOR_PREPARE_TOOL_NAME,
45
43
  NavigatorUnavailableError,
46
44
  navigatorModelSettingPath,
@@ -12,7 +12,6 @@ import {
12
12
  navigatorProviderFailureFromError,
13
13
  navigatorUnavailableError,
14
14
  parseNavigatorModelSetting,
15
- resolveNavigatorSeatSelection,
16
15
  type NavigatorProviderFailureFact,
17
16
  type NavigatorSessionFactory,
18
17
  } from "./navigator-session-contracts.ts";
@@ -43,8 +42,9 @@ async function resolveNavigatorLedgerHome(context: HostContext): Promise<string
43
42
 
44
43
  export function createNativeNavigatorSessionFactory(): NavigatorSessionFactory {
45
44
  return async ({ context, subject, tool }) => {
46
- const resolved = await resolveNavigatorSeatSelection(context);
47
- let thinkingLevel = resolved.thinkingLevel;
45
+ // Model is enforced at prepare (attendance seat resolve) and at prompt (summon).
46
+ // Factory open only books the archivist nest — no package default, no eager seat read.
47
+ let thinkingLevel: string | undefined;
48
48
 
49
49
  // Archivist nest for attendance route memory only (ADR 0018 / 0065) — not a session open.
50
50
  // #852: navigator/<work-subject> is the sole book-top exception; always pass subject so
@@ -15,7 +15,6 @@ import type { NoReceiptLifecycleFacts } from "./receipt-delivery-policy.ts";
15
15
 
16
16
 
17
17
  export const NAVIGATOR_PREPARE_TOOL_NAME = "ak_navigator_prepare" as const;
18
- export const NAVIGATOR_DEFAULT_MODEL = "openai-codex/gpt-5.6-luna:max" as const;
19
18
 
20
19
  export type NavigatorUnavailableKey =
21
20
  | "context" | "session" | "model" | "thinking" | "auth" | "quota" | "transport" | "unknown";
@@ -229,8 +228,9 @@ export async function readNavigatorModelSetting(path = navigatorModelSettingPath
229
228
  }
230
229
  return raw.model;
231
230
  } catch (error) {
231
+ // #178: missing file is absence (no package default).
232
232
  if (error instanceof Error && "code" in error && (error as NodeJS.ErrnoException).code === "ENOENT") {
233
- return NAVIGATOR_DEFAULT_MODEL;
233
+ throw new Error("Navigator model setting is missing");
234
234
  }
235
235
  throw error;
236
236
  }
@@ -294,19 +294,13 @@ export async function resolveNavigatorSeatSelection(
294
294
  : packageMachineHome();
295
295
  const config = await loadPublicCliConfig(home);
296
296
  const modelOnly = seatModelOnly(config.seats.navigator);
297
- // Seat table is the only model authority — no legacy navigator-model.json.
298
- // Bare missing seat uses the package default constant (not a file path).
297
+ // Seat table only — missing navigator seat → typed model-unavailable (#178).
299
298
  if (modelOnly === undefined) {
300
- const parsed = parseNavigatorModelSetting(NAVIGATOR_DEFAULT_MODEL);
301
- return {
302
- selection: {
303
- provider: parsed.provider,
304
- model: parsed.model,
305
- ...(parsed.thinkingLevel === undefined ? {} : { thinking: parsed.thinkingLevel }),
306
- },
307
- configuredLabel: NAVIGATOR_DEFAULT_MODEL,
308
- ...(parsed.thinkingLevel === undefined ? {} : { thinkingLevel: parsed.thinkingLevel }),
309
- };
299
+ const { missingResolvedSeatModelMessage } = await import("./public-cli/config.ts");
300
+ throw navigatorUnavailableError(
301
+ "model",
302
+ new Error(missingResolvedSeatModelMessage("navigator")),
303
+ );
310
304
  }
311
305
  // Host params passthrough only — no map/validate/default (#675 ⑥).
312
306
  const thinkingRaw = modelOnly.thinking;