okstra 0.185.1 → 0.186.1

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 (34) hide show
  1. package/dist/commands/chat/chat.mjs +60 -14
  2. package/dist/commands/chat/chat.mjs.map +1 -1
  3. package/docs/cli.md +1 -1
  4. package/docs/for-ai/skills/okstra-chat.md +4 -4
  5. package/package.json +1 -1
  6. package/runtime/BUILD.json +2 -2
  7. package/runtime/prompts/lead/okstra-lead-contract.md +1 -1
  8. package/runtime/prompts/profiles/implementation-planning.md +1 -1
  9. package/runtime/python/okstra_ctl/cmux.py +63 -35
  10. package/runtime/python/okstra_ctl/report_html/common.py +86 -11
  11. package/runtime/python/okstra_ctl/report_html/filters.py +27 -10
  12. package/runtime/python/okstra_ctl/report_html/render.py +1 -0
  13. package/runtime/python/okstra_ctl/report_html/report_index.py +5 -1
  14. package/runtime/python/okstra_ctl/report_html/view_models/implementation_planning.py +1 -1
  15. package/runtime/skills/okstra-chat/SKILL.md +10 -2
  16. package/runtime/templates/reports/html/assets/base.css +48 -3
  17. package/runtime/templates/reports/html/base.template.html +7 -4
  18. package/runtime/templates/reports/html/i18n/en.json +86 -8
  19. package/runtime/templates/reports/html/i18n/ko.json +86 -8
  20. package/runtime/templates/reports/html/macros/forms.html +74 -55
  21. package/runtime/templates/reports/html/macros/layout.html +2 -2
  22. package/runtime/templates/reports/html/macros/visualizations.html +1 -1
  23. package/runtime/templates/reports/html/tasks/change-impact-analysis.template.html +2 -2
  24. package/runtime/templates/reports/html/tasks/error-analysis.template.html +3 -3
  25. package/runtime/templates/reports/html/tasks/feature-analysis.template.html +4 -4
  26. package/runtime/templates/reports/html/tasks/final-verification.template.html +3 -3
  27. package/runtime/templates/reports/html/tasks/implementation-option-selection.template.html +9 -9
  28. package/runtime/templates/reports/html/tasks/implementation-planning.template.html +20 -18
  29. package/runtime/templates/reports/html/tasks/implementation.template.html +3 -3
  30. package/runtime/templates/reports/html/tasks/improvement-discovery.template.html +3 -3
  31. package/runtime/templates/reports/html/tasks/project-analysis.template.html +10 -10
  32. package/runtime/templates/reports/html/tasks/release-handoff.template.html +2 -2
  33. package/runtime/templates/reports/html/tasks/requirements-discovery.template.html +4 -4
  34. package/runtime/validators/validate-run.py +2 -8
@@ -11,7 +11,7 @@ Usage:
11
11
  okstra chat create --room <name>
12
12
  okstra chat join --room <name> --name <display>
13
13
  okstra chat members --room <name>
14
- okstra chat send --room <name> --as <display> --to <all|name> --body <text>
14
+ okstra chat send --room <name> --as <display> (--to <all|name> | --reply-to <id>) (--body <text> | --body-file <path>)
15
15
  okstra chat unread --room <name> --as <display>
16
16
  okstra chat inbox --room <name> --as <display>
17
17
  okstra chat log --room <name> --as <display> [--to <all|name>]
@@ -80,8 +80,10 @@ function cleanDisplayName(raw) {
80
80
  return value;
81
81
  }
82
82
  function formatLine(message) {
83
- const to = message.to === BROADCAST ? BROADCAST : `@${message.to}`;
84
- return `${message.id}:${message.at}:@${message.from}:${to}:${message.body}`;
83
+ // 이하는 버리고 반올림하지 않는다.
84
+ const time = `${message.at.slice(0, 10)} ${message.at.slice(11, 16)}`;
85
+ const mark = message.replyTo === undefined ? "" : ` ↑${message.replyTo}`;
86
+ return `${message.id} @${message.from} ${time}${mark} ${message.body}`;
85
87
  }
86
88
  function emptyIndex() {
87
89
  return { rooms: [] };
@@ -256,28 +258,72 @@ function resolveRecipient(state, raw) {
256
258
  throw new ChatError("recipient is not a member");
257
259
  return name;
258
260
  }
259
- async function opSend(args) {
260
- const flags = parseFlags(args, new Set(["--room", "--as", "--to", "--body"]));
261
- if (flags.to === undefined)
262
- throw new ChatError("send requires --to");
263
- if (flags.body === undefined)
264
- throw new ChatError("send requires --body");
265
- const room = cleanToken(requireFlag(flags, "room"), "room name");
266
- const from = cleanDisplayName(requireFlag(flags, "as"));
267
- const body = flags.body;
261
+ function requireXor(flags, left, right) {
262
+ if ((flags[left] === undefined) === (flags[right] === undefined)) {
263
+ throw new ChatError(`send requires exactly one of --${left} or --${right}`);
264
+ }
265
+ }
266
+ function parseMessageId(raw, flag) {
267
+ const trimmed = raw.trim();
268
+ const id = Number.parseInt(trimmed, 10);
269
+ if (!Number.isInteger(id) || id < 1 || String(id) !== trimmed) {
270
+ throw new ChatError(`${flag} must be a positive message id`);
271
+ }
272
+ return id;
273
+ }
274
+ async function resolveBody(flags) {
275
+ requireXor(flags, "body", "body-file");
276
+ let body = flags.body;
277
+ if (body === undefined) {
278
+ try {
279
+ body = await fs.readFile(flags["body-file"] ?? "", "utf8");
280
+ }
281
+ catch (err) {
282
+ if (err.code === "ENOENT") {
283
+ throw new ChatError("body file not found");
284
+ }
285
+ throw err;
286
+ }
287
+ if (body.endsWith("\r\n"))
288
+ body = body.slice(0, -2);
289
+ else if (body.endsWith("\n"))
290
+ body = body.slice(0, -1);
291
+ }
268
292
  if (body.trim() === "" || /[\n\r]/.test(body)) {
269
293
  throw new ChatError("body must be a single non-empty line");
270
294
  }
295
+ return body;
296
+ }
297
+ async function resolveSendAddress(state, room, flags) {
298
+ requireXor(flags, "to", "reply-to");
299
+ if (flags.to !== undefined)
300
+ return { to: resolveRecipient(state, flags.to) };
301
+ const replyTo = parseMessageId(flags["reply-to"] ?? "", "--reply-to");
302
+ const parent = (await loadMessages(room)).find((row) => row.id === replyTo);
303
+ if (parent === undefined)
304
+ throw new ChatError("message id not found");
305
+ // 부모는 준 아이디 그대로다. 스레드 루트로 올리지 않는다.
306
+ return {
307
+ to: parent.to === BROADCAST ? BROADCAST : parent.from,
308
+ reply: { replyTo },
309
+ };
310
+ }
311
+ async function opSend(args) {
312
+ const flags = parseFlags(args, new Set(["--room", "--as", "--to", "--reply-to", "--body", "--body-file"]));
313
+ const room = cleanToken(requireFlag(flags, "room"), "room name");
314
+ const from = cleanDisplayName(requireFlag(flags, "as"));
315
+ const body = await resolveBody(flags);
271
316
  const id = await withLock(roomDir(room), async () => {
272
317
  const state = await loadRoom(room);
273
318
  requireMember(state, from);
274
- const to = resolveRecipient(state, flags.to ?? "");
319
+ const addressed = await resolveSendAddress(state, room, flags);
275
320
  const message = {
276
321
  id: state.nextId,
277
322
  at: new Date().toISOString(),
278
323
  from,
279
- to,
324
+ to: addressed.to,
280
325
  body,
326
+ ...addressed.reply,
281
327
  };
282
328
  await appendMessage(room, message);
283
329
  await writeJson(statePath(room), { ...state, nextId: state.nextId + 1 });
@@ -1 +1 @@
1
- {"version":3,"file":"chat.mjs","sourceRoot":"","sources":["../../../src/commands/chat/chat.mts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat.mjs","sourceRoot":"","sources":["../../../src/commands/chat/chat.mts"],"names":[],"mappings":"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"}
package/docs/cli.md CHANGED
@@ -825,7 +825,7 @@ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and
825
825
  | `okstra error-log append-observed --out <errors.jsonl> --task-key <key> --phase <phase> --agent <assigned-worker-id> --agent-role worker --model <model> --error-type tool-failure --command-file <markdown-file> --command-kind <kind> --message-file <markdown-file> [--cause <cause> --evidence-file <kind=file>]…` | Worker-facing typed error recording surface. Python validates and serializes the JSONL record; a worker supplies scalar identity fields plus Markdown files for free-form command, message, and probe content, never a JSON sidecar or JSON argument. `sandbox-denied` requires both `targetProbe` and `controlProbe` evidence files. |
826
826
  | `okstra config <get\|set\|unset\|show> [key] [value] [--scope project\|global\|all]` | Manage persistent settings such as `pr-template-path` with atomic JSON writes |
827
827
  | `okstra memory <add\|list\|search\|show\|archive>` | Manage global conversation memory in `~/.okstra/memory-book`, a user-home store separate from project `.okstra/` and the CLI basis of the `save this in okstra` natural-language skill |
828
- | `okstra chat <rooms\|create\|join\|members\|send\|unread\|inbox\|log\|ack>` | Global rooms under `~/.okstra/chat`. Join takes an explicit `--name`. Send requires `--to` (`all` or a member); `--to` may equal `--as`. Unread is the inbox after the read cursor minus messages the participant sent; it does not move the cursor. `inbox` and `log` keep those arrivals, including after ack. Rows are `id:time:@from:to:body`. CLI basis of the `okstra-chat` skill. |
828
+ | `okstra chat <rooms\|create\|join\|members\|send\|unread\|inbox\|log\|ack>` | Global rooms under `~/.okstra/chat`. Join takes an explicit `--name`. Send takes exactly one of `--to` (`all` or a member; may equal `--as`) or `--reply-to` (an id in that room), and exactly one of `--body` or `--body-file`. A reply inherits `to` from the parent (`all` stays `all`, otherwise the parent's `from`). Unread is the inbox after the read cursor minus messages the participant sent; it does not move the cursor. `inbox` and `log` keep those arrivals, including after ack. Rows are `id @from YYYY-MM-DD HH:MM body`; a reply inserts `↑parentId` after the time. CLI basis of the `okstra-chat` skill. |
829
829
  | `okstra model-io active-context-input --project-root <dir> --run-manifest <path>` | Resolve the prior implementation-planning active context only through the current project and run authority, then emit fixed fields such as the executor base ref. Caller-supplied active-context paths are not accepted. |
830
830
  | `okstra report-translate <source\|write\|check-data> --run-manifest <path> …` | Resolve the report data and translation sidecar from the run manifest. `source` emits a source digest with the fixed translation queue; `write` requires that digest and rejects a stale report; `check-data` verifies the derived sidecar. Models never choose the data or sidecar path. |
831
831
  | `okstra convergence prepare-groups --run-manifest <path> --input <grouping.md>` | Parse fixed grouping Markdown, validate distinct per-worker evidence and group semantics against the run authority, then publish the schema-valid groups artifact at the run-owned path. |
@@ -16,7 +16,7 @@ okstra chat rooms
16
16
  okstra chat create --room <name>
17
17
  okstra chat join --room <name> --name <display>
18
18
  okstra chat members --room <name>
19
- okstra chat send --room <name> --as <display> --to <all|name> --body <text>
19
+ okstra chat send --room <name> --as <display> (--to <all|name> | --reply-to <id>) (--body <text> | --body-file <path>)
20
20
  okstra chat unread --room <name> --as <display>
21
21
  okstra chat inbox --room <name> --as <display>
22
22
  okstra chat log --room <name> --as <display>
@@ -25,10 +25,10 @@ okstra chat ack --room <name> --as <display> --through <id>
25
25
 
26
26
  Display names are typed. The CLI does not generate them.
27
27
 
28
- Unread is the inbox after the read cursor minus messages whose `from` equals `--as`. It does not move the cursor. `inbox` and `log` keep those messages. Rows are `id:time:@from:to:body`; recipient `all` stays `all`.
28
+ Unread is the inbox after the read cursor minus messages whose `from` equals `--as`. It does not move the cursor. `inbox` and `log` keep those messages. Rows are `id @from YYYY-MM-DD HH:MM body`. A reply inserts `↑parentId` after the time. Recipient is not on the line.
29
29
 
30
- `send --to` may equal `--as`. `members` is the full roster.
30
+ `send --to` may equal `--as`. `--to` and `--reply-to` are exactly one. `--body` and `--body-file` are exactly one. A reply inherits `to` from the parent. `members` is the full roster.
31
31
 
32
- The skill picker is `all` plus `members` minus the current display name. After showing unread rows, the skill runs `ack --through` with the last unread id unless the output is `no unread`.
32
+ The skill picker is `all` plus `members` minus the current display name. Skill send and reply use `--body`, not `--body-file`. After showing unread rows, the skill runs `ack --through` with the last unread id unless the output is `no unread`. The Step 3 menu is send, unread, inbox, log, reply, done. Reply takes a free-input id and body; there is no recipient picker and no `okstra chat reply` subcommand.
33
33
 
34
34
  Read the fixed text rows. Do not parse JSON.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okstra",
3
- "version": "0.185.1",
3
+ "version": "0.186.1",
4
4
  "description": "Host-aware multi-provider cross-verification orchestrator runtime and agent skills.",
5
5
  "license": "MIT",
6
6
  "author": "devonshin",
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.185.1",
3
- "builtAt": "2026-08-23T14:31:57.118Z",
2
+ "package": "0.186.1",
3
+ "builtAt": "2026-08-23T17:23:36.757Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -396,7 +396,7 @@ For a new `implementation-planning` run, the fixed order is initial verification
396
396
  2. Dispatch a single plan-body reverify round to every analyser worker in the roster (`claude`, `codex`, and `antigravity` when opted in). `Report writer worker` is NOT a participant in this round.
397
397
  3. Record each verifier Markdown result through `okstra plan-items apply-verdicts --state <plan-body-verification.json> --result <worker-id>=<result.md> --round <N>`. Python validates every submitted `P-*` identifier against the current convergence state and overwrites only that round's verdicts. Then resolve the gate result to one of `passed` / `passed-with-dissent` / `blocked-by-disagreement` / `aborted-non-result`.
398
398
  4. After `okstra plan-verify` succeeds, run `okstra plan-items complete-round --state <plan-body-verification.json> --run-manifest <current-run-manifest.json> --round <N>`. Python reads the current worker assignments, atomically appends the convergence-owned history, and updates its nested final projection. This state is the only plan-verification input report assembly reads.
399
- 5. Record every surviving `majority-disagree` decision through `okstra approval-decision`; record its plan and clarification links only on activities. Do not append `clarificationItems[]` directly.
399
+ 5. Record every *in-scope execution* `majority-disagree` decision through `okstra approval-decision`; record its plan and clarification links only on activities. Do not promote `observed` / `deferred` / `record` items, and do not append `clarificationItems[]` directly.
400
400
  6. Run report assembly after the final plan-body state, approval ledger, design snapshot, activity ledger, and team state are complete. Assembly writes `implementationPlanning.planBodyVerification` and derived clarification rows while publishing `data.json` once.
401
401
  7. Publish the report record `frontmatter.approved` field as `false`. There is no in-body `- [ ] Approved` marker line — approval lives only in the record (see [plan-body-verification](./plan-body-verification.md) §"Round protocol" step 9). The user may set it to `true` (via `--approve` or the in-session wizard) only when the gate is `passed` or `passed-with-dissent`. **Enforced:** `validators/validate-run.py` `validate_phase_boundary` fails a report shipping `approved: true` under `blocked-by-disagreement` / `aborted-non-result`, and run-prep (`scripts/okstra_ctl/run.py` `_validate_approved_plan`) fail-closes the same case. Manually flipping a blocked gate to passing is a contract violation.
402
402
 
@@ -256,7 +256,7 @@ roles:
256
256
  4. **Ambiguity check** — any requirement that could be read two ways must be made explicit or moved to the `## 1. Clarification Items` table as a `Blocks=approval` row.
257
257
  5. **Scope check** — if the plan now spans multiple independent subsystems, split it into separate planning runs rather than shipping an oversized plan. Then walk the plan in the expansion direction: for every stage, name the Requirement Coverage row that demanded it, and for every requirement row, read its `Source` cell as a skeptic — does the cited brief heading actually exist, and does a `derived:` rationale state a real technical consequence rather than a preference? Move anything that fails to a `Blocks=approval` clarification row.
258
258
  6. **Review-rule preflight check** — when a project review rule pack applies (cited by the brief, or listed by `okstra model-io project-context --project-root <PROJECT_ROOT> --task-ref <task-ref>`), map each relevant rule to the chosen realization. Reject the draft if it knowingly creates a violation that the later PR reviewer would flag, unless the plan records a specific rationale and follow-up. In particular, scan for repeated helper stacks across planned files, tests that assert delegation to the same calculator/helper they exercise, public names that hide side effects, domain rules placed in repositories/adapters, and APIs made dead by this change.
259
- 7. **Plan-body verification reconciliation (BLOCKING for implementation-planning).** For every §5.5.9 `planItems[]` entry whose verdicts make it `majority-disagree`, set that item's `clarificationId` to a `C-<N>` row that MUST exist in `## 1. Clarification Items` with `Kind` chosen per the standard policy and `Blocks=approval`. **Enforced:** `validators/validate-run.py` `_validate_plan_body_clarification_matching` recomputes each item's class and fails when a majority-disagree item has no `clarificationId`, or its `clarificationId` is dangling / points at a non-`approval` row. For `partial-consensus` and `dissent-isolated` plan-items, the dissenting opinion lives in §5.5.9 `Dissent log` and is NOT promoted to §5.
259
+ 7. **Plan-body verification reconciliation (BLOCKING for implementation-planning).** For every §5.5.9 `planItems[]` entry whose *gate class after stage scope* is `majority-disagree` (in-scope execution only), set that item's `clarificationId` to a `C-<N>` row that MUST exist in `## 1. Clarification Items` with `Kind` chosen per the standard policy and `Blocks=approval`. Do **not** promote `observed` / `deferred` / `record` items — those belong in `setAside`. Raw vote `majority-disagree` is not enough; promoting it is how a frozen or unreached stage kept opening new `C-NNN` rows. **Enforced:** `validators/validate-run.py` `_validate_plan_body_clarification_matching` uses `_plan_item_gate_class` and fails when an in-scope execution majority-disagree item has no `clarificationId`, or its `clarificationId` is dangling / points at a non-`approval` row. For `partial-consensus` and `dissent-isolated` plan-items, the dissenting opinion lives in §5.5.9 `Dissent log` and is NOT promoted to §5.
260
260
  8. **Stage Map self-check** — for every stage, count the effective rows of its `Stepwise Execution Order` table by hand; reject the draft if any stage exceeds 8. Confirm each stage declares a non-empty `Slice value:` and `Acceptance:` line, the three `Test case (success|boundary|failure):` lines (or carries a `TDD exemption:` line), and that its first step `action` starts with `RED:` with a later `GREEN:` — this is what validator S10 enforces, including S10d on the test-case lines. Read each stage's three test-case lines as a reviewer: reject any that restates the happy path in all three slots, leaves `boundary` blank, or writes `N/A` where a real edge input exists. Walk the `depends-on` graph and confirm it is a DAG (no cycle, no self-reference). For each `depends-on` link, confirm it encodes a real data/contract dependency — do NOT add links to serialise unrelated work, and do NOT split a stage merely to create more parallel stages. **Parallel-safety:** for every pair of `depends-on (none)` stages, confirm their `Stage Exit Contract` predicted file sets are disjoint; if they share a file, merge them or add a `depends-on` link (validator S9 rejects overlap). **Project-boundary:** confirm no stage mixes edits from two projects (different repo/`PROJECT_ROOT` or different top-level deployable module); if any stage does, split it per project. For multi-project plans, confirm each stage's `title` carries its `[<project>]` tag and the `Cross-project parallelism:` line under the table records the parallel-vs-sequenced determination (with the forcing dependency) for every project pair; for cross-repo work, confirm it is split into separate per-repo runs (required — one run structurally cannot touch another repo) rather than crammed into one task's stages.
261
261
  9. **Cross-project dependency check** — confirm you have not missed a dependency on another repo / another top-level deployable module / a published package. If `dependencyMigrationRisk` has a `kind: cross-project` row, confirm a matching `direction: upstream-precondition` `XP-NNN` row exists in `crossProjectDependencies`, and re-read as a reviewer whether its `requiredWork` is the concrete work the other side must actually build rather than an abstract phrase ("other side's work done") — validator S only checks existence, so concreteness is the self-review's responsibility. Confirm cross-repo work is split into a separate run + XP row instead of being crammed into one task's stages, and that the cross-project substance is not duplicated in `§3 Recommended Next Steps` but lives only in `§5.4 Cross-Project Dependencies`.
262
262
  10. **Decision-draft materialization check** — when `decisionDrafts` is non-empty, confirm as a reviewer which stage's stepwise order contains the matching materialization step (creating `.okstra/decisions/<NNNN>-<slug>.md`) and that the number of drafts corresponds 1:1 with the materialization steps. The validator only checks the *existence* of the step, so the `<NNNN>-<slug>` correctness and count correspondence are the self-review's responsibility.
@@ -30,12 +30,13 @@ LOGIN_SHELL_TIMEOUT_SECONDS = 15
30
30
  # re-enters cmux's own agent wrapper instead of the real CLI.
31
31
  SHIM_DIR_MARKER = "cmux-cli-shims"
32
32
 
33
- # The workspace is split in fifths: two for the lead, three for the workers.
34
- # Every worker lands in that one column and the column divides downward, so all
35
- # workers hold the same width. Splitting sideways instead would make each
36
- # worker's width a function of how many rounds preceded it. The split itself
37
- # halves the pane it lands on; worker heights are evened out afterwards.
33
+ # The first three workers share one column, so the lead keeps two fifths. A
34
+ # fourth worker opens a second column; the lead drops to two sixths so that
35
+ # extra column has room. Splitting the first column sideways before it is full
36
+ # would make the second worker narrower than the first.
37
+ WORKERS_PER_COLUMN = 3
38
38
  LEAD_SHARE_WITH_WORKERS = 2 / 5
39
+ LEAD_SHARE_WITH_MULTIPLE_COLUMNS = 2 / 6
39
40
 
40
41
  # Three fifths is what a worker needs to be worth watching: measured against a
41
42
  # Claude Code worker, 67 columns renders losslessly and 33 drops content off the
@@ -46,8 +47,8 @@ LEAD_SHARE_WITH_WORKERS = 2 / 5
46
47
  # whole workspace back rather than sitting at its working width.
47
48
  LEAD_SHARE_ALONE = 1.0
48
49
 
49
- # Two passes per pane above the bottom. A roster of four analysers is four
50
- # workers in the column; eight moves is that bound with one extra pass.
50
+ # Two passes per pane above the bottom. The first column holds at most three
51
+ # workers; eight moves is that bound with room to spare.
51
52
  MAX_WORKER_HEIGHT_MOVES = 8
52
53
 
53
54
  # Sidebar entries are keyed by source so tools do not overwrite each other's.
@@ -195,11 +196,11 @@ def plan_worker_placement(
195
196
  ) -> Placement:
196
197
  """Pick the next worker slot from the workspace's current geometry.
197
198
 
198
- One column for every worker: the first split takes it off the lead, and each
199
- one after that divides the worker next to the lead downward. Width is
200
- therefore decided once, by where the lead's border sits, and every worker
201
- inherits it nothing here computes a width, and no worker's width depends
202
- on how many rounds ran before it.
199
+ The first worker splits off the lead to the right. The next two fill that
200
+ column downward from the bottom, so three workers share one width. From the
201
+ fourth onward the new pane splits worker n-3 to the right — the matching
202
+ row of the previous column which is column-major order of the current
203
+ panes sorted by (x, y).
203
204
 
204
205
  Stateless by design: okstra records surface UUIDs, never a layout, so a
205
206
  resumed or crashed run cannot carry a layout model that no longer matches
@@ -220,7 +221,9 @@ def plan_worker_placement(
220
221
  ]
221
222
  if not workers:
222
223
  return Placement(pane_id=lead_pane_id, direction="right")
223
- return _extend_the_worker_column(workers)
224
+ if len(workers) < WORKERS_PER_COLUMN:
225
+ return _extend_the_worker_column(workers)
226
+ return _extend_the_worker_grid(workers)
224
227
 
225
228
 
226
229
  def lead_target_width(
@@ -232,9 +235,10 @@ def lead_target_width(
232
235
  ) -> float:
233
236
  """How wide the lead should be, in the points `pixel_frame` reports.
234
237
 
235
- Two fifths while workers are on screen, all of it when they are gone. The
236
- share is taken of what okstra may actually place into, not of the window:
237
- a workspace can hold panes okstra never opened, and handing the lead the
238
+ Two fifths while the first worker column is filling, two sixths once a
239
+ fourth worker is on screen, all of it when they are gone. The share is
240
+ taken of what okstra may actually place into, not of the window: a
241
+ workspace can hold panes okstra never opened, and handing the lead the
238
242
  whole container would shove those off their own width. Their width is
239
243
  subtracted first and the share applies to the remainder.
240
244
 
@@ -252,12 +256,18 @@ def lead_target_width(
252
256
  usable = container_width_points - strangers
253
257
  if usable <= 0:
254
258
  return 0.0
255
- workers_on_screen = any(
256
- pane.pane_id != lead_pane_id
257
- and _holds_an_okstra_surface(pane, owned_surface_ids)
259
+ worker_count = sum(
260
+ 1
258
261
  for pane in panes
262
+ if pane.pane_id != lead_pane_id
263
+ and _holds_an_okstra_surface(pane, owned_surface_ids)
259
264
  )
260
- share = LEAD_SHARE_WITH_WORKERS if workers_on_screen else LEAD_SHARE_ALONE
265
+ if worker_count == 0:
266
+ share = LEAD_SHARE_ALONE
267
+ elif worker_count <= WORKERS_PER_COLUMN:
268
+ share = LEAD_SHARE_WITH_WORKERS
269
+ else:
270
+ share = LEAD_SHARE_WITH_MULTIPLE_COLUMNS
261
271
  return usable * share
262
272
 
263
273
 
@@ -292,15 +302,25 @@ def _holds_an_okstra_surface(
292
302
 
293
303
 
294
304
  def _extend_the_worker_column(workers: Sequence[PaneGeometry]) -> Placement:
295
- """Divide the worker next to the lead downward. A tab would hide the new worker.
305
+ """Split the bottom of the first column downward. A tab would hide the new worker.
296
306
 
297
- The first worker is split off the lead, so it stays at the lead's y. Later
298
- workers stack below it. Splitting the bottom one parks each new pane at the
299
- far end of the column; splitting the neighbour keeps the new pane next to
300
- the lead.
307
+ The first worker is split off the lead, so it stays at the lead's y. The
308
+ second and third stack below it. Splitting the bottom parks the new pane at
309
+ the next row rather than inserting it beside the lead.
301
310
  """
302
- neighbour = min(workers, key=lambda pane: pane.y)
303
- return Placement(pane_id=neighbour.pane_id, direction="down")
311
+ bottom = max(workers, key=lambda pane: pane.y)
312
+ return Placement(pane_id=bottom.pane_id, direction="down")
313
+
314
+
315
+ def _extend_the_worker_grid(workers: Sequence[PaneGeometry]) -> Placement:
316
+ """Split worker n-3 to the right, filling the next 3-row column.
317
+
318
+ Column-major (x, y) matches creation order while this placement is the only
319
+ one writing the grid: worker 4 is to the right of 1, 5 of 2, 6 of 3, 7 of 4.
320
+ """
321
+ ordered = sorted(workers, key=lambda pane: (pane.x, pane.y))
322
+ source = ordered[len(ordered) - WORKERS_PER_COLUMN]
323
+ return Placement(pane_id=source.pane_id, direction="right")
304
324
 
305
325
 
306
326
  def plan_worker_height_resize(
@@ -313,11 +333,17 @@ def plan_worker_height_resize(
313
333
  again. The bottom pane is never the one named: it absorbs the remainder.
314
334
 
315
335
  `new-split` halves the pane it lands on and does not take a ratio, so a
316
- third worker split off the top would otherwise stay at a quarter while
317
- the bottom one keeps a half.
336
+ third worker split off the bottom would otherwise stay at a quarter while
337
+ the top one keeps a half.
338
+
339
+ A second column inherits row height from the pane it split. Equalizing
340
+ every worker as one stack would move the first column independently of the
341
+ pane sitting in the same row to the right.
318
342
  """
319
343
  if len(workers) < 2:
320
344
  return None
345
+ if len({pane.x for pane in workers}) > 1:
346
+ return None
321
347
  ordered = sorted(workers, key=lambda pane: pane.y)
322
348
  total = sum(pane.height_points for pane in ordered)
323
349
  if total <= 0:
@@ -649,9 +675,10 @@ def _exec_worker(surface_uuid: str, *, cwd: Path, command: Sequence[str]) -> Non
649
675
  def _size_lead_pane(workspace: str, owned_surface_ids: Collection[str]) -> None:
650
676
  """Move the lead's border to its share of the workspace.
651
677
 
652
- This is the horizontal border okstra places. Workers divide their column
653
- downward and inherit the remaining width, so this one move sizes the lead
654
- and every worker's width. Worker heights are equalized separately after
678
+ This is the horizontal border okstra places. The first worker column
679
+ inherits whatever the lead leaves. A fourth worker also drops the lead
680
+ from two fifths to two sixths, and that extra sixth goes to the neighbour
681
+ that pulls the border in. Worker heights are equalized separately after
655
682
  the split that just halved one of them.
656
683
 
657
684
  Which pane carries the request follows from what `pane.resize` does: it
@@ -706,12 +733,13 @@ def _size_lead_pane(workspace: str, owned_surface_ids: Collection[str]) -> None:
706
733
  def _equalize_worker_heights(
707
734
  workspace: str, owned_surface_ids: Collection[str]
708
735
  ) -> None:
709
- """Give every owned worker the same height in the column.
736
+ """Give every owned worker the same height in the first column.
710
737
 
711
738
  `new-split` halves whichever pane it lands on, so the third worker of a
712
- round would otherwise sit at a quarter with the bottom one still at a half.
739
+ round would otherwise sit at a quarter with the top one still at a half.
713
740
  Each call moves one border and re-reads: growing the top pane steals from
714
- the one below, and that is what the next plan has to see.
741
+ the one below, and that is what the next plan has to see. A second column
742
+ is left alone — its row heights came from the pane it split.
715
743
  """
716
744
  for _ in range(MAX_WORKER_HEIGHT_MOVES):
717
745
  panes = list_panes(workspace)
@@ -1,8 +1,6 @@
1
1
  """Common data transformations that carry no task-specific section order."""
2
2
  from __future__ import annotations
3
3
 
4
- import re
5
-
6
4
 
7
5
  # Every block whose rows prose cites but no section of its own renders, with
8
6
  # the keys each one names its content, its provenance, and its confidence by. A
@@ -97,14 +95,69 @@ def _own_section_ids(data: dict, omitted_fields: tuple[str, ...] = ()) -> set[st
97
95
  return found
98
96
 
99
97
 
100
- def evidence_index(data: dict) -> dict[str, object]:
98
+ _OMITTED_TEXT_KEYS = (
99
+ "subject",
100
+ "check",
101
+ "item",
102
+ "action",
103
+ "requiredWork",
104
+ "statement",
105
+ "summary",
106
+ "need",
107
+ "title",
108
+ )
109
+
110
+
111
+ def _omitted_row_text(row: dict) -> str:
112
+ """생략된 행에서 독자가 읽을 한 줄을 고른다."""
113
+ for key in _OMITTED_TEXT_KEYS:
114
+ value = row.get(key)
115
+ if isinstance(value, str) and value.strip():
116
+ return value.strip()
117
+ return ""
118
+
119
+
120
+ def _collect_row_dicts(value: object, rows: dict[str, dict]) -> None:
121
+ if isinstance(value, dict):
122
+ row_id = value.get("id") or value.get("activityId") or value.get("clarificationId")
123
+ if isinstance(row_id, str) and row_id:
124
+ rows.setdefault(row_id, value)
125
+ for nested in value.values():
126
+ _collect_row_dicts(nested, rows)
127
+ elif isinstance(value, list):
128
+ for nested in value:
129
+ _collect_row_dicts(nested, rows)
130
+
131
+
132
+ def _omitted_rows(data: dict, omitted_fields: tuple[str, ...]) -> dict[str, dict]:
133
+ from ..report_contract import TASK_TYPE_DATA_PROPERTY
134
+
135
+ property_name = TASK_TYPE_DATA_PROPERTY.get(
136
+ (data.get("header") or {}).get("taskType", "")
137
+ )
138
+ block = data.get(property_name) if property_name else None
139
+ if not isinstance(block, dict):
140
+ return {}
141
+ rows: dict[str, dict] = {}
142
+ for field in omitted_fields:
143
+ _collect_row_dicts(block.get(field), rows)
144
+ return rows
145
+
146
+
147
+ def evidence_index(
148
+ data: dict, omitted_fields: tuple[str, ...] = ()
149
+ ) -> dict[str, object]:
101
150
  """The rows the ledger carries, keyed by id.
102
151
 
103
152
  A row whose statement came out empty is dropped rather than listed: the
104
153
  ledger exists so a cited id resolves to something the reader can read, and
105
154
  an id above a blank line resolves to nothing.
155
+
156
+ `omitted_fields` are task-block arrays the HTML template does not render
157
+ as their own section. Their rows still have to land somewhere, because
158
+ prose cites them — without a ledger entry the id in the body is dead text.
106
159
  """
107
- owned = _own_section_ids(data)
160
+ owned = _own_section_ids(data, omitted_fields)
108
161
  rows: dict[str, object] = {}
109
162
  for path, text_key, source_key, confidence_key, kind in _LEDGER_BLOCKS:
110
163
  for row in _dig(data, path):
@@ -116,12 +169,26 @@ def evidence_index(data: dict) -> dict[str, object]:
116
169
  entry = _ledger_row(row, text_key, source_key, confidence_key, kind)
117
170
  if entry["text"]:
118
171
  rows[row_id] = entry
172
+ for row_id, row in _omitted_rows(data, omitted_fields).items():
173
+ if row_id in owned or row_id in rows:
174
+ continue
175
+ text = _omitted_row_text(row)
176
+ if not text:
177
+ continue
178
+ rows[row_id] = {
179
+ "id": row_id,
180
+ "kind": "plan-item",
181
+ "text": text,
182
+ "codeEvidence": [],
183
+ "source": "",
184
+ "confidence": "",
185
+ }
119
186
  return rows
120
187
 
121
188
 
122
189
  def _collect_ids(value: object, found: set[str]) -> None:
123
190
  if isinstance(value, dict):
124
- for key in ("id", "activityId"):
191
+ for key in ("id", "activityId", "clarificationId"):
125
192
  row_id = value.get(key)
126
193
  if isinstance(row_id, str) and row_id:
127
194
  found.add(row_id)
@@ -132,7 +199,9 @@ def _collect_ids(value: object, found: set[str]) -> None:
132
199
  _collect_ids(nested, found)
133
200
 
134
201
 
135
- _ROW_ID = re.compile(r"[A-Z]{1,3}-\d+")
202
+ def _anchorable(row_id: str) -> bool:
203
+ """공백이나 경로 구분자가 있는 값은 HTML id 로 쓰지 않는다."""
204
+ return bool(row_id) and " " not in row_id and "/" not in row_id
136
205
 
137
206
 
138
207
  def anchor_index(data: dict, omitted_fields: tuple[str, ...] = ()) -> dict[str, str]:
@@ -141,15 +210,21 @@ def anchor_index(data: dict, omitted_fields: tuple[str, ...] = ()) -> dict[str,
141
210
  Prose cites ids across section boundaries — a hotspot names a
142
211
  cross-verification finding, a quality row names a difference — so the
143
212
  target set spans the whole reader-facing report: the task's own sections,
144
- the clarifications, and every block the ledger takes in.
213
+ the clarifications, and every block the ledger takes in, including rows
214
+ whose section the template left out.
145
215
 
146
216
  It stops there. `summary` is the AI-facing digest and
147
217
  `analysisCommon.scope` describes the analysis target rather than listing
148
- rows; neither renders, so a link to one would land nowhere. Same for the
149
- blocks a template declares in `omitted_fields`.
218
+ rows; neither renders, so a link to one would land nowhere.
150
219
  """
151
- found = _own_section_ids(data, omitted_fields) | set(evidence_index(data))
152
- return {row_id: f"id-{row_id}" for row_id in sorted(found) if _ROW_ID.fullmatch(row_id)}
220
+ found = _own_section_ids(data, omitted_fields) | set(
221
+ evidence_index(data, omitted_fields)
222
+ )
223
+ return {
224
+ row_id: f"id-{row_id}"
225
+ for row_id in sorted(found)
226
+ if isinstance(row_id, str) and _anchorable(row_id)
227
+ }
153
228
 
154
229
 
155
230
  def analysis_review_ids(data: dict) -> tuple[str, ...]: