@specset/cli 2.0.0 → 2.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specset/cli",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Command-line interface for Specset — authenticate, run GraphQL queries, and chat with Specset project agents.",
5
5
  "license": "Elastic-2.0",
6
6
  "homepage": "https://specset.com",
@@ -24,7 +24,7 @@
24
24
  "specset": "./dist/main.js"
25
25
  },
26
26
  "dependencies": {
27
- "@anthropic-ai/claude-agent-sdk": "0.3.257",
27
+ "@anthropic-ai/claude-agent-sdk": "0.3.296",
28
28
  "@anthropic-ai/sdk": "0.93.0",
29
29
  "@modelcontextprotocol/sdk": "^1.31.0",
30
30
  "open": "^11.0.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specset",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Search and manage Specset construction project data with shared skills and MCP tools.",
5
5
  "author": {
6
6
  "name": "Specset"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specset",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Search and manage Specset construction project data with shared skills and MCP tools.",
5
5
  "author": {
6
6
  "name": "Specset",
@@ -21,6 +21,7 @@ This is the core skill — setup and mechanics only. Domain workflows live in si
21
21
  | `specset-projects` | Creating projects, uploading spec/drawing PDFs, publishing spec and drawing sets |
22
22
  | `specset-submittals` | Submittal lifecycle, attachments, approvers, and AI compliance reviews |
23
23
  | `specset-rfis` | RFI logging, tracking, and responses |
24
+ | `specset-issues` | Listing a project's design-review issues and their verification verdicts |
24
25
  | `specset-closeout` | Assets, locations, products, companies, warranties, and maintenance |
25
26
  | `specset-agent` | Delegating deep project questions to Specset's in-app AI agent |
26
27
  | `specset-admin` | Org members, invites, and whitelabel branding |
@@ -38,8 +39,6 @@ Run this when the user installs or updates the skill/plugin, asks to get started
38
39
 
39
40
  Credentials persist across sessions in `~/.config/specset/config.yml` (mode 0600) — setup only needs to happen once per machine.
40
41
 
41
- If `specset auth status` reports an invalid session, run `specset logout`, then sign in again. Pin the same `--host` on both commands when using a development or non-default host; `login` does not replace an existing stored session.
42
-
43
42
  ## Running GraphQL
44
43
 
45
44
  Use the `api` subcommand. It accepts the operation via `--query` or stdin, and string variables via `-F key=value` (repeatable). Output preserves the raw JSON GraphQL envelope (`{ data, errors }`) — non-zero exit on HTTP errors or `errors[]`.
@@ -118,7 +117,7 @@ specset api --query 'query($id: ID!) {
118
117
  }' -F id=<bulk-action-id>
119
118
  ```
120
119
 
121
- Processing large PDF sets takes minutes; poll every 15–30 seconds and tell the user what's in flight rather than blocking silently.
120
+ Processing large PDF sets takes minutes; poll every 15–30 seconds and tell the user what's in flight rather than blocking silently. A workflow `status` of `Queued` (documents from an integration sync, an upload of more than 10 files, a portal or a reprocess) means it is waiting its turn for background processing: count it as in progress, like `NotStarted` and `Running`.
122
121
 
123
122
  ## Safety
124
123
 
@@ -40,11 +40,9 @@ specset agent show <threadId>
40
40
  specset agent export <artifactId> --format docx --out ./filled-rfi.docx
41
41
  specset agent export <artifactId> --format pdf --out ./filled-rfi.pdf
42
42
 
43
- # Pin the host and organization when inspecting a local test run
44
- specset agent show <threadId-or-link> --host https://app2.specset.dev --org <slug-or-id> --json
43
+ # Pin the host and organization when inspecting a run on another deployment
44
+ specset agent show <threadId-or-link> --host <host> --org <slug-or-id> --json
45
45
 
46
- # Super-admin: inspect the current system prompt, tools, and model-input messages
47
- specset agent inspect <threadId-or-link> --host https://app2.specset.dev --org <slug-or-id> --json
48
46
  ```
49
47
 
50
48
  Use `--json` for machine-readable output (all commands accept it). Long-running questions may need `--timeout <seconds>` — document analysis can take a few minutes.
@@ -119,22 +117,16 @@ specset agent start --type DrawingReview --project <projectId> \
119
117
 
120
118
  - `--type` accepts any top-level agent type (`DesignReview`, `DrawingReview`, `DesignQualityReview`, `StructuredReview`, `SubmittalLog`, …). The kickoff message is the review's scope: name the building areas, disciplines, sections or sheets, what to exclude, and any special coordination checks — the same text a user would type when launching the review in the app.
121
119
  - `--type DrawingReview` also needs `--coordinationTaskTypes` (`all`, or a comma-separated subset of the 16 families: `CeilingOverhead`, `EquipmentPowerControls`, `LifeSafetyEgress`, `ArchitectureStructureOpenings`, `ArchitectureMepPenetrations`, `StructuralMepInterfaces`, `EnvelopeWaterproofing`, `FireLifeSafetyProtection`, `CivilSiteUtilities`, `ElectricalDistribution`, `MechanicalSystemsContinuity`, `PlumbingSystemsContinuity`, `StructuralSystemsContinuity`, `FireSuppressionSystemsContinuity`, `FireAlarmEmergencyCommunications`, `TechnologySecurityCommunications`). The server refuses a Drawing Review whose first message carries no scope, and the scope cannot change afterwards, so these flags apply only to new threads. `--drawingArea` limits the review to one building-scoped drawing area, and `--noDrawingArea` limits it to the sheets that belong to no drawing area (the site-wide set; exclusive with `--drawingArea`); `--coordinationTaskIds` narrows it to exact graph task ids for a bounded pilot or rerun (ids must belong to the selected families and area). `--executionIntent` decides how earlier reviews' runs of the same tasks are treated: `Reuse` (the default) answers a task from another review's completed run while the drawings it read are unchanged and leaves Blocked or Failed tasks alone (reported as incomplete), `RetryIncomplete` also re-runs those, and `Fresh` ignores earlier runs. The project needs a current drawing graph (`drawingCoordinationReviewAvailability.graphState` is `Ready`); otherwise the review cannot start.
122
- - `--debugTrace` writes the thread's agent transcript and drawing-coordination trace to the development server's `.local/debug` for an investigation. `--noDebugTrace` turns it off for a continued thread; omitting the flag preserves its setting. Both flags also work with `agent chat`.
123
120
  - Local Drawing Review kickoff uses the same required `--coordinationTaskTypes` and optional `--coordinationTaskIds` / `--drawingArea` flags as `agent start`. Pass them with the first message to `agent serve`; an existing thread keeps its original scope.
124
- - `--autoApprovePlan` skips plan sign-off. To inspect a plan before execution, pass `--noAutoApprovePlan`: this also disables the CLI's default blanket tool approval, so the session parks at `finalizePlan`. Approve it with `agent approve <threadId> --tool finalizePlan`. Omitting the flag preserves the existing plan setting, but blanket approval defaults on. `--isolateIssues` hides the project's pre-existing issues; `--noIsolateIssues` explicitly restores ordinary issue reads. `--reviewEffort Quick|Standard|Deep` sets a Project Review's effort: Quick investigates the strongest few leads on the root; Standard covers the brief within an approved worker budget; Deep covers the whole surveyed inventory. The plan states the expected worker count and estimated worker cost for approval. Omitting it keeps the thread's setting (Quick for a new thread).
125
- - `--scanParallelism <n>` sets a positive integer thread override for concurrent scan/coordination tasks (superadmin only). It uses the server's protected settings mutation, preserves other settings, and persists when later messages omit the flag. Each scan reads it at startup; changing it does not resize an already-running scan. For a scoped drawing-review benchmark, add `--scanParallelism 8` to the `agent start` command above or to `agent chat --type DrawingReview --timeout 2400`; select at least eight tasks to exercise that limit. It does not change the shared default or the review's internal visual/admission limits.
121
+ - `--autoApprovePlan` skips plan sign-off. To inspect a plan before execution, pass `--noAutoApprovePlan`: this also disables the CLI's default blanket tool approval, so the session parks at `finalizePlan`. Approve it with `agent approve <threadId> --tool finalizePlan`. Omitting the flag preserves the existing plan setting, but blanket approval defaults on. `--isolateIssues` hides the project's pre-existing issues; `--noIsolateIssues` explicitly restores ordinary issue reads. `--reviewEffort Quick|Standard|Deep` sets a Project Review's effort: Quick investigates the strongest few leads on the root; Standard covers the brief within an approved worker budget; Deep covers the whole surveyed inventory. The plan states the expected worker count and estimated worker cost for approval. Omitting it keeps the thread's setting (Quick for a new thread). For a quick test of a Standard or Deep review, `--reviewMaxWorkers 3` caps the workers it starts (the server refuses more; the root records the rest as not examined). Native tools let a local run's harness use its own tools in the run's workspace and run sandboxed code over document and drawing reads, cropping and enlarging a detail. A thread that starts running locally has them on unless it already chose; `--noNativeTools` (both commands) or the conversation's Settings toggle turns them off.
126
122
  - `--title` names the session in Agent Sessions. `agent start` is `agent chat --detach` for a new thread; use `chat --type … --timeout …` instead when you want to wait for a short run to finish.
127
123
 
128
124
  ## Notes
129
125
 
130
126
  - Keep one thread per topic: follow-ups via `--thread` give the agent the prior context and produce better answers than fresh threads.
131
- - The agent may propose changes (creating submittals, updating records) but those are applied through the Specset UI thread where the user approves them — CLI chat is best treated as read/analysis oriented. To make changes headlessly, use the mutations documented in the domain skills instead.
127
+ - `agent chat` approves every tool by default, so changes the agent makes (creating submittals, updating records) are applied without a confirmation step. Confirm with the user before asking it to change data, or pass `--noAutoApprove` so its proposals wait for approval in the Specset UI or `agent approve`. To make changes headlessly yourself, use the mutations documented in the domain skills.
132
128
  - The agent answers from the project you scope it to; double-check the `--project` id when results look unrelated.
133
129
 
134
- For local drawing evaluations, add `--freshVisualReads` to `agent chat` or `agent start` to make every drawing examination a fresh response. It bypasses application response caching only in development; provider prefix discounts remain enabled. Use `--noFreshVisualReads` to restore normal behavior on that task.
135
-
136
- For the local comparison-reader arm, add `--drawingComparisonModel OpenAI6Astra` alongside `--freshVisualReads`. Only multi-view, region, or subject-window drawing examinations use Astra medium; single-view overviews keep normal routing. `--drawingComparisonModel Auto` clears that override on an existing task. This switch is ignored in production and does not change planner or worker reasoning models.
137
-
138
130
  ## Run agent threads locally with your own Claude Code / Codex
139
131
 
140
132
  `specset agent serve` connects this machine to Specset. A conversation switched to **Execute locally** (conversation Settings) runs its model calls through the user's own coding harness (Claude Code or Codex) instead of a cloud model, while Specset keeps the agent loop, its tools, approvals and the transcript. Nothing else changes for the user: the thread stays the record.
@@ -151,7 +143,7 @@ Codex uses `CODEX_PATH` when set, then `codex` on PATH, then the managed runtime
151
143
  **When the user asks to run a thread locally**, start the runner in the background so your own tool timeout does not cut it off, then check the thread:
152
144
 
153
145
  ```bash
154
- specset agent serve --host <deployment> --org <slug> --harness codex & # or --harness claude
146
+ specset agent serve --host <deployment> --org <slug> & # --account claude2,codex limits it to those accounts
155
147
  specset agent show <thread link> # the transcript so far
156
148
  ```
157
149
 
@@ -159,17 +151,19 @@ What the harness spends is recorded on the thread as unbilled local usage (per m
159
151
 
160
152
  ### Native tools and the run workspace
161
153
 
162
- Native tools are off by default: the harness only calls Specset functions, which the server authorizes and executes (approvals stay in the web app). Turn on **Native tools** in the conversation's Settings to let it also run shell commands and read, search or edit files. Each action is mirrored into the conversation as a local action card, and the thread's **Permissions** setting bounds what happens without asking: Read only, Accept edits, Auto (edits accepted, escalations reviewed) or Full access; for Codex these map to its sandbox (read-only, workspace-write, full access). Native sub-agents stay off; Specset's own sub-agent and fan-out tools run through the same machine.
154
+ Native tools are on for a thread that starts running locally, unless the thread already chose (an earlier on or off stands): the harness can then run shell commands and read, search or edit files in the run workspace. Turn them off with **Native tools** in the conversation's Settings or `--noNativeTools`; with them off, the harness only calls Specset functions, which the server authorizes and executes (approvals stay in the web app). Each action is mirrored into the conversation as a local action card, and the thread's **Permissions** setting bounds what happens without asking: Read only, Accept edits, Auto (edits accepted, escalations reviewed) or Full access; for Codex these map to its sandbox (read-only, workspace-write, full access). Native sub-agents stay off; Specset's own sub-agent and fan-out tools run through the same machine.
163
155
 
164
156
  Each run (a root thread and its children) works in one private directory under `--directory` (`~/.specset/personal-runs/<runner>/runs/<thread>/` by default) with `specs/`, `drawings/`, `docs/`, `inputs/` and `out/`. It starts empty. The `specset` CLI is logged in inside the session as the user for that host and organization, so the harness downloads what it needs: `specset specs download <ref> --out specs/`, `specset drawings download <ref> --format pdf --out drawings/`, `specset docs download <ref> --out docs/`, `specset files download <ref> --out inputs/`, or `specset projects hydrate <project> --out . --include specs,drawings,docs` for a whole project. `.specset/manifest.json` records each file's Specset link, version id and checksum; repeating a download is idempotent and replaces a stale version. Findings cite the Specset link, never the local path.
165
157
 
158
+ With Native tools on and Permissions Auto or Full, the vision tier's document and drawing reads (`examineDrawingSheets`, `examineDocument`, `examineFile` and the like) may also run code to look closer at their attachments: crop a dense detail from the full-resolution file and view it enlarged. Such a read runs in its own scratch directory holding only its attachments (`inputs/attachment-N.png|pdf`), never the run workspace. Its commands are sandboxed: no network, no credentials in their environment, and nothing readable but the system, developer tools, Homebrew (for Python and Pillow) and that directory. Your own temp directory, where other applications keep files, stays closed except, under Claude Code, for the scratch files macOS's `sips` saves there; the shared `/tmp` stays closed. Claude Code's command sandbox denies reading by default, a hook holds its Read tool to the directory, and zsh skips your startup files; Codex runs under a permissions profile that adds only Homebrew and its own binary, with the core environment, so it crops with Pillow and `sips` fails; the runner first checks once that the binary enforces the profile (Codex before 0.157.1 ignores its deny entries), and otherwise runs these reads without code. Code execution needs macOS: on Linux, Claude Code's bubblewrap sandbox leaves the credentials it removes readable to commands through its own process, so these reads run without code there. Its actions are printed in the `agent serve` terminal, because a helper read's actions never reach the conversation. These reads were evaluated on the cloud models without code execution, so treat code-execution results as unevaluated.
159
+
166
160
  Files the harness writes under `out/` are the run's deliverables: after each turn that used native tools, and when the run ends, the runner uploads new or changed ones and attaches them to the root thread at their `out/…` path (a re-synced path replaces the earlier attachment). The workspace is removed once its run has ended (checked when the runner starts and stops and every ten minutes) or after seven untouched days; outputs that could not be attached keep the directory for a retry.
167
161
 
168
162
  Sessions are ephemeral (`persistSession: false` for Claude, `ephemeral: true` for Codex): a restarted runner needs a new machine assignment and starts fresh sessions seeded from Specset's transcript. A lost native continuation fails visibly rather than replaying writes or switching to a cloud model. This is a personal runner executing project content as the local OS user, not an OS sandbox: use a separate account or host for untrusted content.
169
163
 
170
164
  ### Serve multiple local threads
171
165
 
172
- Connect to an organization with `specset agent serve --host <host> --org <slug|id>`; no project or thread is required. Enable **Execute locally** in conversation Settings. A sole eligible connected runner automatically receives your queued local request; with multiple connected runners, choose **Machine** in Settings. The connection command disappears once a machine is connected. Completed, stopped, or expired runs offer **Start a new local run** above the composer; viewing them does not restart them. `--thread <id>` immediately assigns an existing root; `--message "Review electrical coordination" --type DrawingReview --coordinationTaskTypes ElectricalDistribution` creates a local root in the selected project. `--org <slug|id>` pins the org; otherwise the selected org or sole membership on that host is used. Omit `--project` for organization scope, or supply a comma-separated project allowlist. A new message-created thread requires exactly one project. Omit `--harness` to use that host’s saved default or its sole available native runtime; ambiguity requires an explicit choice. Claude uses the CLI’s bundled SDK runtime, then native `claude` on PATH. Codex uses `CODEX_PATH`, native `codex` on PATH, then the managed native runtime from `specset harness install codex`. Startup checks that runtime before registering. Run a separate `serve --host <deployment>` process for each dev worktree. Each process prints and pins its host/org/harness at startup; later CLI host/org changes cannot redirect it. Login, selected org, and harness defaults are stored per host; execution limits apply per runner. For a bounded smoke test, add `--stopAfterIssues 2`; the root counts issues across its children and stops that tree when the threshold is reached (an in-flight batch can exceed it). Only this signed-in user can assign work, and children inherit the same machine, project scope, deadline and thread budget.
166
+ Connect to an organization with `specset agent serve --host <host> --org <slug|id>`; no project or thread is required. Enable **Execute locally** in conversation Settings. A sole eligible connected runner automatically receives your queued local request; with multiple connected runners, choose **Machine** in Settings. The connection command disappears once a machine is connected. Completed, stopped, or expired runs offer **Start a new local run** above the composer; viewing them does not restart them. `--thread <id>` immediately assigns an existing root; `--message "Review electrical coordination" --type DrawingReview --coordinationTaskTypes ElectricalDistribution` creates a local root in the selected project. `--org <slug|id>` pins the org; otherwise the selected org or sole membership on that host is used. Omit `--project` for organization scope, or supply a comma-separated project allowlist. A new message-created thread requires exactly one project. It serves from the accounts `specset harness list` shows (config.yml's `runner:` block, or the logins this shell would use when none are listed); `specset harness add claude2 --harness claude --home ~/.claude2 --preferred` adds another login, and `--account` limits one run. Claude uses the CLI’s bundled SDK runtime, then native `claude` on PATH. Codex uses `CODEX_PATH`, native `codex` on PATH, then the managed native runtime from `specset harness install codex`. Startup checks each account's runtime before registering. Run a separate `serve --host <deployment>` process for each dev worktree. Each process prints and pins its host/org/accounts at startup; later CLI host/org changes cannot redirect it. Login and selected org are stored per host; execution limits apply per runner. For a bounded smoke test, add `--stopAfterIssues 2`; the root counts issues across its children and stops that tree when the threshold is reached (an in-flight batch can exceed it). Only this signed-in user can assign work, and children inherit the same machine, project scope, deadline and thread budget.
173
167
 
174
168
  `agent serve` uses server-owned orchestration: Temporal executes the agent and its tools, while model requests run through the connected machine. This includes generic drawing-coordination assessments, image inputs and structured output. The runner keeps a native session alive across each complete parallel tool batch and sends back the server's authorized results. All Specset approvals remain in the web app; native tools follow the thread's **Native tools** setting (see above) and native delegation stays off. Independent model requests use independent sessions. Claude uses `persistSession: false`; Codex uses `ephemeral: true`.
175
169
 
@@ -177,9 +171,9 @@ For an unattended kickoff, `--autoApprovePlan` skips the plan sign-off and `--au
177
171
 
178
172
  Pin both `--host <deployment>` and `--org <slug>` when using `agent chat`, `agent start`, `agent show`, `agent inspect`, `agent approve` or `agent stop`; these overrides do not change the CLI’s saved selection.
179
173
 
180
- The conversation's Settings lists the models the connected machine reported (Codex's catalog, Claude's supported models) and pins one per harness for the thread, plus a reasoning effort from that model's reported levels (agent steps only; helper calls keep the harness default); `--model` on the machine pins one for every job and shows as fixed there. `--concurrency` defaults to 5 and limits active model calls; tool and approval waits release their slot so even 1 can complete nested fan-out. `--maxThreads` defaults to 100 and `--maxRunSeconds` to 3600 per root authorization. `--model` is fixed on the machine. Specset’s `--autoApprove` message setting controls tool approval; the thread's Permissions setting bounds native tools when they are on. Ctrl-C revokes the registration and stops queued/running descendants. A restart needs a new assignment. A lost native continuation fails visibly rather than replaying writes or switching to a cloud model.
174
+ Every model call carries its routing tier (conversation, orchestrator, planner, analyst, worker, lite, balanced, query, vision), and each tier names a model that any account whose harness offers it serves. The defaults match the app; `specset harness list` prints each tier's current model and the class it runs as. Antigravity is opt-in: it serves those tiers only after you add an account for it (`specset harness add agy --harness antigravity`); until then they run their model's class on Claude Code or Codex, or in the cloud with `harness fallback`. A model no account offers runs as its class (frontier, standard, fast) on a harness the machine has. Change a tier with `specset harness tier <tier> <model[:effort]>`, a class's model with `specset harness model <harness> <class> <model> [--effort e]`, or one run's with `agent serve --tier conversation=opus`. The conversation's Settings pins a class or one of the reported models per harness for that thread's own steps, plus a reasoning effort; children and helper calls keep the tiers. When the preferred accounts for a model are at their limits, `specset harness failover sameModel|any|off` decides where its calls go (default sameModel: other accounts with the same model; any: also the same class elsewhere); a call that already streamed fails instead and the next one goes elsewhere. A provider rate limit (HTTP 429) is waited out rather than failing the run: the server retries the call once the account's short wait passes (on another account if one has room), unless it already ran a native command or edit, which a retry could repeat; only every account being at its usage limit stops the run. `specset harness fallback <tier|all> cloud` (or `agent serve --fallback analyst=cloud`) sends a tier's calls to Specset's cloud model, billed to the organization, instead of another provider's whenever no account here can serve its model (none offers it, or its accounts are at their limits); `local` is the default. `--concurrency` defaults to 5 (at most 16) and limits active model calls; tool and approval waits release their slot so even 1 can complete nested fan-out. `--maxThreads` defaults to 100 and `--maxRunSeconds` to 3600 per root authorization. `specset harness limits --concurrency 16 --maxThreads 300 --maxRunSeconds 43200` saves them in config.yml for every `agent serve` (a flag still wins for one run; `default` clears one; no flags prints them). Specset’s `--autoApprove` message setting controls tool approval; the thread's Permissions setting bounds native tools when they are on. Ctrl-C revokes the registration and stops queued/running descendants. A restart needs a new assignment. A lost native continuation fails visibly rather than replaying writes or switching to a cloud model.
181
175
 
182
- Harness tool callbacks can only wait for results supplied by the server. Each job receives private harness configuration and a minimal environment; with native tools on, that private home also holds a CLI login for the run's host and organization so `specset` works from the harness's shell. Claude shares the selected native credential store and its refresh lock. Codex uses an authentication-only native process to refresh the selected login, then supplies temporary access tokens to isolated inference sessions. Neither copies rotating refresh credentials into job homes. Settings, hooks, plugins and global MCP servers are excluded from inference sessions. Run `claude auth login` first if the harness reports authentication is required. It still runs as the local OS user, not inside an OS sandbox. Use a dedicated account or isolated host for untrusted project content; do not share this personal runner across users. This command requires the matching personal-runner and local-inference server APIs and ships in the next CLI release.
176
+ Harness tool callbacks can only wait for results supplied by the server. Each job receives private harness configuration and a minimal environment; with native tools on, that private home also holds a CLI login for the run's host and organization so `specset` works from the harness's shell. Claude shares the selected native credential store and its refresh lock. Codex uses an authentication-only native process to refresh the selected login, then supplies temporary access tokens to isolated inference sessions. Neither copies rotating refresh credentials into job homes. Settings, hooks, plugins and global MCP servers are excluded from inference sessions. Run `claude auth login` first if the harness reports authentication is required. It still runs as the local OS user, not inside an OS sandbox. Use a dedicated account or isolated host for untrusted project content; do not share this personal runner across users.
183
177
 
184
178
  Use `specset agent runners list --json` to inspect your registrations.
185
179
  Use `specset agent runners revoke <runner-id>` to stop and revoke one remotely, including an offline runner after a crash.
@@ -18,8 +18,6 @@ Maintenance has three layers:
18
18
  - **MaintenancePlan** — a schedule on exactly one Product, Asset, Location, or System. Product plans fan out to installed assets. Its `tiers` are independent schedule items that pair a Procedure with a calendar cadence, meter trigger, or both.
19
19
  - **WorkOrder** — a concrete occurrence or ad-hoc job. Generated work orders snapshot their checklist fields, so history remains stable when a Procedure changes.
20
20
 
21
- `MaintenanceTask` and its completion API no longer exist. Use Procedure, MaintenancePlan, and WorkOrder operations below.
22
-
23
21
  ## Discover Before Mutating
24
22
 
25
23
  Input objects evolve, especially checklist fields and plan tiers. Introspect the relevant input before composing a mutation:
@@ -315,12 +313,7 @@ specset files download <file-resource-id> --out manual.pdf # once workflow.s
315
313
 
316
314
  ## Enabling closeout
317
315
 
318
- `CloseoutAuthService.isCloseoutActive` requires the org SKU **and** (unless the org is in `fmMode`) the project toggle. Both are superadmin operations; `updateOrg(skus)` replaces the whole SKU object, so read the current flags and resend them:
319
-
320
- ```bash
321
- specset api --query '{ org(id: "<org-id>") { skus { closeout fmMode dailyLog scheduling estimation agentSessions agentSkills customAgents whitelabel modelRoutingV2 } } }'
322
- specset api --query 'mutation { updateOrg(id: "<org-id>", skus: { closeout: true, dailyLog: true, scheduling: true }) { id } updateProject(id: "<project-id>", toolSettings: { closeout: true }) { id } }'
323
- ```
316
+ `CloseoutAuthService.isCloseoutActive` requires the org's closeout SKU **and** (unless the org is in `fmMode`) the project's closeout toggle. Specset staff turn both on; when closeout operations report closeout as inactive, ask your Specset contact to enable it.
324
317
 
325
318
  ## Dedup / Re-pointing
326
319
 
@@ -26,7 +26,7 @@ project(id: ID!): Project!
26
26
 
27
27
  `createProject` does **not** add the creator as a project member, so the new project won't appear in the default `projects` list until someone adds them — fetch it by `project(id)`. The `createProject` mutation takes `userIds` and `teamIds` to add members in the same call; `specset projects create` doesn't, so add them as a second step.
28
28
 
29
- 1. Create it with the project command. New projects automatically support drawing graphs; no opt-in is required:
29
+ 1. Create it with the project command (new projects support drawing graphs automatically):
30
30
 
31
31
  ```bash
32
32
  specset projects create 'Riverside Medical Center' --json
@@ -14,6 +14,13 @@ How the data is shaped:
14
14
 
15
15
  The sketches below are minimal — inline enums, ints, and lists in the operation text (`-F` is strings-only; Variable Limitations and Schema Discovery live in the `specset` skill).
16
16
 
17
+ Two common flows have purpose-built commands; prefer them to hand-written mutations:
18
+
19
+ ```bash
20
+ specset submittals create --project <projectId> --file ./package.pdf --json # uploads the file and creates the submittal from it; --title, repeatable --specSection <id>
21
+ specset submittals review --submittal <submittalId|link> --wait --json # runs a compliance review and prints its issues; repeatable --specSection, --prompt, --timeout (default 3600)
22
+ ```
23
+
17
24
  ## Reading
18
25
 
19
26
  ```bash
@@ -73,7 +73,7 @@ The retrieval tools return **extracted text**, which is authoritative for schedu
73
73
 
74
74
  All commands support `--json` (structured `{files: [{path, bytes, ...}]}` output) and `--out` (file path, or directory for multi-file downloads). A citation passed to the wrong command errors with the right one to use.
75
75
 
76
- `drawings download` also accepts `--org <slug|id>` to pin the source organization when parallel sessions might change the active organization, for example `specset drawings download P2.120 --project <id> --org specbook --host <host> --format pdf`.
76
+ `drawings download`, `files download` and `specs download` also accept `--org <slug|id>` to pin the source organization when parallel sessions might change the active organization, for example `specset drawings download P2.120 --project <id> --org <slug> --host <host> --format pdf` or `specset specs download '08 71 00' --project <id> --org <slug> --host <host> --out hardware.pdf`.
77
77
 
78
78
  To inspect an existing detail crop, add `--node <shortId|UUID>`, for example `specset drawings download <sheet-ref> --node d6 --format image --out detail.png`. Use `--format pdf` for the saved crop PDF. This downloads the current revision's stored crop without regenerating it; missing nodes or crops return an error. Node crops do not support `--format file`. JSON output adds the resolved `nodeId` to the normal sheet download metadata.
79
79
 
@@ -99,7 +99,7 @@ Graph tools are automatically available with `--project` for eligible projects (
99
99
  specset drawings build-graph --project <id> --wait --timeout 1800 --host <host> --json
100
100
  ```
101
101
 
102
- Omit `--wait` to return after requesting the build. Waiting confirms a newly persisted graph snapshot, not complete ingestion or review readiness; inspect the returned statistics and `getDrawingGraphOverview` for stale nodes and bundles before reviewing. The server build continues after a timeout, so inspect the overview before requesting another build. This does not reprocess drawings. The command requires the existing `resolveProjectDrawingGraph` and `projectDrawingGraph` server API; it and these instructions ride the next CLI release.
102
+ Omit `--wait` to return after requesting the build. Waiting confirms a newly persisted graph snapshot, not complete ingestion or review readiness; inspect the returned statistics and `getDrawingGraphOverview` for stale nodes and bundles before reviewing. The server build continues after a timeout, so inspect the overview before requesting another build. This does not reprocess drawings.
103
103
 
104
104
  Use `getDrawingGraphOverview` to discover bundle keys, `getCoordinationBundle` for their views, `traverseDrawingReferences` for callout links, and `findDrawingGraphElements` for labeled, schedule-derived assets and rooms. For graphical devices, including unlabeled glyphs, use the candidate symbol lookup when ingestion and a graph rebuild have populated it:
105
105
 
@@ -21,6 +21,7 @@ This is the core skill — setup and mechanics only. Domain workflows live in si
21
21
  | `specset-projects` | Creating projects, uploading spec/drawing PDFs, publishing spec and drawing sets |
22
22
  | `specset-submittals` | Submittal lifecycle, attachments, approvers, and AI compliance reviews |
23
23
  | `specset-rfis` | RFI logging, tracking, and responses |
24
+ | `specset-issues` | Listing a project's design-review issues and their verification verdicts |
24
25
  | `specset-closeout` | Assets, locations, products, companies, warranties, and maintenance |
25
26
  | `specset-agent` | Delegating deep project questions to Specset's in-app AI agent |
26
27
  | `specset-admin` | Org members, invites, and whitelabel branding |
@@ -38,8 +39,6 @@ Run this when the user installs or updates the skill/plugin, asks to get started
38
39
 
39
40
  Credentials persist across sessions in `~/.config/specset/config.yml` (mode 0600) — setup only needs to happen once per machine.
40
41
 
41
- If `specset auth status` reports an invalid session, run `specset logout`, then sign in again. Pin the same `--host` on both commands when using a development or non-default host; `login` does not replace an existing stored session.
42
-
43
42
  ## Running GraphQL
44
43
 
45
44
  Use the `api` subcommand. It accepts the operation via `--query` or stdin, and string variables via `-F key=value` (repeatable). Output preserves the raw JSON GraphQL envelope (`{ data, errors }`) — non-zero exit on HTTP errors or `errors[]`.
@@ -118,7 +117,7 @@ specset api --query 'query($id: ID!) {
118
117
  }' -F id=<bulk-action-id>
119
118
  ```
120
119
 
121
- Processing large PDF sets takes minutes; poll every 15–30 seconds and tell the user what's in flight rather than blocking silently.
120
+ Processing large PDF sets takes minutes; poll every 15–30 seconds and tell the user what's in flight rather than blocking silently. A workflow `status` of `Queued` (documents from an integration sync, an upload of more than 10 files, a portal or a reprocess) means it is waiting its turn for background processing: count it as in progress, like `NotStarted` and `Running`.
122
121
 
123
122
  ## Safety
124
123
 
@@ -40,11 +40,9 @@ specset agent show <threadId>
40
40
  specset agent export <artifactId> --format docx --out ./filled-rfi.docx
41
41
  specset agent export <artifactId> --format pdf --out ./filled-rfi.pdf
42
42
 
43
- # Pin the host and organization when inspecting a local test run
44
- specset agent show <threadId-or-link> --host https://app2.specset.dev --org <slug-or-id> --json
43
+ # Pin the host and organization when inspecting a run on another deployment
44
+ specset agent show <threadId-or-link> --host <host> --org <slug-or-id> --json
45
45
 
46
- # Super-admin: inspect the current system prompt, tools, and model-input messages
47
- specset agent inspect <threadId-or-link> --host https://app2.specset.dev --org <slug-or-id> --json
48
46
  ```
49
47
 
50
48
  Use `--json` for machine-readable output (all commands accept it). Long-running questions may need `--timeout <seconds>` — document analysis can take a few minutes.
@@ -119,22 +117,16 @@ specset agent start --type DrawingReview --project <projectId> \
119
117
 
120
118
  - `--type` accepts any top-level agent type (`DesignReview`, `DrawingReview`, `DesignQualityReview`, `StructuredReview`, `SubmittalLog`, …). The kickoff message is the review's scope: name the building areas, disciplines, sections or sheets, what to exclude, and any special coordination checks — the same text a user would type when launching the review in the app.
121
119
  - `--type DrawingReview` also needs `--coordinationTaskTypes` (`all`, or a comma-separated subset of the 16 families: `CeilingOverhead`, `EquipmentPowerControls`, `LifeSafetyEgress`, `ArchitectureStructureOpenings`, `ArchitectureMepPenetrations`, `StructuralMepInterfaces`, `EnvelopeWaterproofing`, `FireLifeSafetyProtection`, `CivilSiteUtilities`, `ElectricalDistribution`, `MechanicalSystemsContinuity`, `PlumbingSystemsContinuity`, `StructuralSystemsContinuity`, `FireSuppressionSystemsContinuity`, `FireAlarmEmergencyCommunications`, `TechnologySecurityCommunications`). The server refuses a Drawing Review whose first message carries no scope, and the scope cannot change afterwards, so these flags apply only to new threads. `--drawingArea` limits the review to one building-scoped drawing area, and `--noDrawingArea` limits it to the sheets that belong to no drawing area (the site-wide set; exclusive with `--drawingArea`); `--coordinationTaskIds` narrows it to exact graph task ids for a bounded pilot or rerun (ids must belong to the selected families and area). `--executionIntent` decides how earlier reviews' runs of the same tasks are treated: `Reuse` (the default) answers a task from another review's completed run while the drawings it read are unchanged and leaves Blocked or Failed tasks alone (reported as incomplete), `RetryIncomplete` also re-runs those, and `Fresh` ignores earlier runs. The project needs a current drawing graph (`drawingCoordinationReviewAvailability.graphState` is `Ready`); otherwise the review cannot start.
122
- - `--debugTrace` writes the thread's agent transcript and drawing-coordination trace to the development server's `.local/debug` for an investigation. `--noDebugTrace` turns it off for a continued thread; omitting the flag preserves its setting. Both flags also work with `agent chat`.
123
120
  - Local Drawing Review kickoff uses the same required `--coordinationTaskTypes` and optional `--coordinationTaskIds` / `--drawingArea` flags as `agent start`. Pass them with the first message to `agent serve`; an existing thread keeps its original scope.
124
- - `--autoApprovePlan` skips plan sign-off. To inspect a plan before execution, pass `--noAutoApprovePlan`: this also disables the CLI's default blanket tool approval, so the session parks at `finalizePlan`. Approve it with `agent approve <threadId> --tool finalizePlan`. Omitting the flag preserves the existing plan setting, but blanket approval defaults on. `--isolateIssues` hides the project's pre-existing issues; `--noIsolateIssues` explicitly restores ordinary issue reads. `--reviewEffort Quick|Standard|Deep` sets a Project Review's effort: Quick investigates the strongest few leads on the root; Standard covers the brief within an approved worker budget; Deep covers the whole surveyed inventory. The plan states the expected worker count and estimated worker cost for approval. Omitting it keeps the thread's setting (Quick for a new thread).
125
- - `--scanParallelism <n>` sets a positive integer thread override for concurrent scan/coordination tasks (superadmin only). It uses the server's protected settings mutation, preserves other settings, and persists when later messages omit the flag. Each scan reads it at startup; changing it does not resize an already-running scan. For a scoped drawing-review benchmark, add `--scanParallelism 8` to the `agent start` command above or to `agent chat --type DrawingReview --timeout 2400`; select at least eight tasks to exercise that limit. It does not change the shared default or the review's internal visual/admission limits.
121
+ - `--autoApprovePlan` skips plan sign-off. To inspect a plan before execution, pass `--noAutoApprovePlan`: this also disables the CLI's default blanket tool approval, so the session parks at `finalizePlan`. Approve it with `agent approve <threadId> --tool finalizePlan`. Omitting the flag preserves the existing plan setting, but blanket approval defaults on. `--isolateIssues` hides the project's pre-existing issues; `--noIsolateIssues` explicitly restores ordinary issue reads. `--reviewEffort Quick|Standard|Deep` sets a Project Review's effort: Quick investigates the strongest few leads on the root; Standard covers the brief within an approved worker budget; Deep covers the whole surveyed inventory. The plan states the expected worker count and estimated worker cost for approval. Omitting it keeps the thread's setting (Quick for a new thread). For a quick test of a Standard or Deep review, `--reviewMaxWorkers 3` caps the workers it starts (the server refuses more; the root records the rest as not examined). Native tools let a local run's harness use its own tools in the run's workspace and run sandboxed code over document and drawing reads, cropping and enlarging a detail. A thread that starts running locally has them on unless it already chose; `--noNativeTools` (both commands) or the conversation's Settings toggle turns them off.
126
122
  - `--title` names the session in Agent Sessions. `agent start` is `agent chat --detach` for a new thread; use `chat --type … --timeout …` instead when you want to wait for a short run to finish.
127
123
 
128
124
  ## Notes
129
125
 
130
126
  - Keep one thread per topic: follow-ups via `--thread` give the agent the prior context and produce better answers than fresh threads.
131
- - The agent may propose changes (creating submittals, updating records) but those are applied through the Specset UI thread where the user approves them — CLI chat is best treated as read/analysis oriented. To make changes headlessly, use the mutations documented in the domain skills instead.
127
+ - `agent chat` approves every tool by default, so changes the agent makes (creating submittals, updating records) are applied without a confirmation step. Confirm with the user before asking it to change data, or pass `--noAutoApprove` so its proposals wait for approval in the Specset UI or `agent approve`. To make changes headlessly yourself, use the mutations documented in the domain skills.
132
128
  - The agent answers from the project you scope it to; double-check the `--project` id when results look unrelated.
133
129
 
134
- For local drawing evaluations, add `--freshVisualReads` to `agent chat` or `agent start` to make every drawing examination a fresh response. It bypasses application response caching only in development; provider prefix discounts remain enabled. Use `--noFreshVisualReads` to restore normal behavior on that task.
135
-
136
- For the local comparison-reader arm, add `--drawingComparisonModel OpenAI6Astra` alongside `--freshVisualReads`. Only multi-view, region, or subject-window drawing examinations use Astra medium; single-view overviews keep normal routing. `--drawingComparisonModel Auto` clears that override on an existing task. This switch is ignored in production and does not change planner or worker reasoning models.
137
-
138
130
  ## Run agent threads locally with your own Claude Code / Codex
139
131
 
140
132
  `specset agent serve` connects this machine to Specset. A conversation switched to **Execute locally** (conversation Settings) runs its model calls through the user's own coding harness (Claude Code or Codex) instead of a cloud model, while Specset keeps the agent loop, its tools, approvals and the transcript. Nothing else changes for the user: the thread stays the record.
@@ -151,7 +143,7 @@ Codex uses `CODEX_PATH` when set, then `codex` on PATH, then the managed runtime
151
143
  **When the user asks to run a thread locally**, start the runner in the background so your own tool timeout does not cut it off, then check the thread:
152
144
 
153
145
  ```bash
154
- specset agent serve --host <deployment> --org <slug> --harness codex & # or --harness claude
146
+ specset agent serve --host <deployment> --org <slug> & # --account claude2,codex limits it to those accounts
155
147
  specset agent show <thread link> # the transcript so far
156
148
  ```
157
149
 
@@ -159,17 +151,19 @@ What the harness spends is recorded on the thread as unbilled local usage (per m
159
151
 
160
152
  ### Native tools and the run workspace
161
153
 
162
- Native tools are off by default: the harness only calls Specset functions, which the server authorizes and executes (approvals stay in the web app). Turn on **Native tools** in the conversation's Settings to let it also run shell commands and read, search or edit files. Each action is mirrored into the conversation as a local action card, and the thread's **Permissions** setting bounds what happens without asking: Read only, Accept edits, Auto (edits accepted, escalations reviewed) or Full access; for Codex these map to its sandbox (read-only, workspace-write, full access). Native sub-agents stay off; Specset's own sub-agent and fan-out tools run through the same machine.
154
+ Native tools are on for a thread that starts running locally, unless the thread already chose (an earlier on or off stands): the harness can then run shell commands and read, search or edit files in the run workspace. Turn them off with **Native tools** in the conversation's Settings or `--noNativeTools`; with them off, the harness only calls Specset functions, which the server authorizes and executes (approvals stay in the web app). Each action is mirrored into the conversation as a local action card, and the thread's **Permissions** setting bounds what happens without asking: Read only, Accept edits, Auto (edits accepted, escalations reviewed) or Full access; for Codex these map to its sandbox (read-only, workspace-write, full access). Native sub-agents stay off; Specset's own sub-agent and fan-out tools run through the same machine.
163
155
 
164
156
  Each run (a root thread and its children) works in one private directory under `--directory` (`~/.specset/personal-runs/<runner>/runs/<thread>/` by default) with `specs/`, `drawings/`, `docs/`, `inputs/` and `out/`. It starts empty. The `specset` CLI is logged in inside the session as the user for that host and organization, so the harness downloads what it needs: `specset specs download <ref> --out specs/`, `specset drawings download <ref> --format pdf --out drawings/`, `specset docs download <ref> --out docs/`, `specset files download <ref> --out inputs/`, or `specset projects hydrate <project> --out . --include specs,drawings,docs` for a whole project. `.specset/manifest.json` records each file's Specset link, version id and checksum; repeating a download is idempotent and replaces a stale version. Findings cite the Specset link, never the local path.
165
157
 
158
+ With Native tools on and Permissions Auto or Full, the vision tier's document and drawing reads (`examineDrawingSheets`, `examineDocument`, `examineFile` and the like) may also run code to look closer at their attachments: crop a dense detail from the full-resolution file and view it enlarged. Such a read runs in its own scratch directory holding only its attachments (`inputs/attachment-N.png|pdf`), never the run workspace. Its commands are sandboxed: no network, no credentials in their environment, and nothing readable but the system, developer tools, Homebrew (for Python and Pillow) and that directory. Your own temp directory, where other applications keep files, stays closed except, under Claude Code, for the scratch files macOS's `sips` saves there; the shared `/tmp` stays closed. Claude Code's command sandbox denies reading by default, a hook holds its Read tool to the directory, and zsh skips your startup files; Codex runs under a permissions profile that adds only Homebrew and its own binary, with the core environment, so it crops with Pillow and `sips` fails; the runner first checks once that the binary enforces the profile (Codex before 0.157.1 ignores its deny entries), and otherwise runs these reads without code. Code execution needs macOS: on Linux, Claude Code's bubblewrap sandbox leaves the credentials it removes readable to commands through its own process, so these reads run without code there. Its actions are printed in the `agent serve` terminal, because a helper read's actions never reach the conversation. These reads were evaluated on the cloud models without code execution, so treat code-execution results as unevaluated.
159
+
166
160
  Files the harness writes under `out/` are the run's deliverables: after each turn that used native tools, and when the run ends, the runner uploads new or changed ones and attaches them to the root thread at their `out/…` path (a re-synced path replaces the earlier attachment). The workspace is removed once its run has ended (checked when the runner starts and stops and every ten minutes) or after seven untouched days; outputs that could not be attached keep the directory for a retry.
167
161
 
168
162
  Sessions are ephemeral (`persistSession: false` for Claude, `ephemeral: true` for Codex): a restarted runner needs a new machine assignment and starts fresh sessions seeded from Specset's transcript. A lost native continuation fails visibly rather than replaying writes or switching to a cloud model. This is a personal runner executing project content as the local OS user, not an OS sandbox: use a separate account or host for untrusted content.
169
163
 
170
164
  ### Serve multiple local threads
171
165
 
172
- Connect to an organization with `specset agent serve --host <host> --org <slug|id>`; no project or thread is required. Enable **Execute locally** in conversation Settings. A sole eligible connected runner automatically receives your queued local request; with multiple connected runners, choose **Machine** in Settings. The connection command disappears once a machine is connected. Completed, stopped, or expired runs offer **Start a new local run** above the composer; viewing them does not restart them. `--thread <id>` immediately assigns an existing root; `--message "Review electrical coordination" --type DrawingReview --coordinationTaskTypes ElectricalDistribution` creates a local root in the selected project. `--org <slug|id>` pins the org; otherwise the selected org or sole membership on that host is used. Omit `--project` for organization scope, or supply a comma-separated project allowlist. A new message-created thread requires exactly one project. Omit `--harness` to use that host’s saved default or its sole available native runtime; ambiguity requires an explicit choice. Claude uses the CLI’s bundled SDK runtime, then native `claude` on PATH. Codex uses `CODEX_PATH`, native `codex` on PATH, then the managed native runtime from `specset harness install codex`. Startup checks that runtime before registering. Run a separate `serve --host <deployment>` process for each dev worktree. Each process prints and pins its host/org/harness at startup; later CLI host/org changes cannot redirect it. Login, selected org, and harness defaults are stored per host; execution limits apply per runner. For a bounded smoke test, add `--stopAfterIssues 2`; the root counts issues across its children and stops that tree when the threshold is reached (an in-flight batch can exceed it). Only this signed-in user can assign work, and children inherit the same machine, project scope, deadline and thread budget.
166
+ Connect to an organization with `specset agent serve --host <host> --org <slug|id>`; no project or thread is required. Enable **Execute locally** in conversation Settings. A sole eligible connected runner automatically receives your queued local request; with multiple connected runners, choose **Machine** in Settings. The connection command disappears once a machine is connected. Completed, stopped, or expired runs offer **Start a new local run** above the composer; viewing them does not restart them. `--thread <id>` immediately assigns an existing root; `--message "Review electrical coordination" --type DrawingReview --coordinationTaskTypes ElectricalDistribution` creates a local root in the selected project. `--org <slug|id>` pins the org; otherwise the selected org or sole membership on that host is used. Omit `--project` for organization scope, or supply a comma-separated project allowlist. A new message-created thread requires exactly one project. It serves from the accounts `specset harness list` shows (config.yml's `runner:` block, or the logins this shell would use when none are listed); `specset harness add claude2 --harness claude --home ~/.claude2 --preferred` adds another login, and `--account` limits one run. Claude uses the CLI’s bundled SDK runtime, then native `claude` on PATH. Codex uses `CODEX_PATH`, native `codex` on PATH, then the managed native runtime from `specset harness install codex`. Startup checks each account's runtime before registering. Run a separate `serve --host <deployment>` process for each dev worktree. Each process prints and pins its host/org/accounts at startup; later CLI host/org changes cannot redirect it. Login and selected org are stored per host; execution limits apply per runner. For a bounded smoke test, add `--stopAfterIssues 2`; the root counts issues across its children and stops that tree when the threshold is reached (an in-flight batch can exceed it). Only this signed-in user can assign work, and children inherit the same machine, project scope, deadline and thread budget.
173
167
 
174
168
  `agent serve` uses server-owned orchestration: Temporal executes the agent and its tools, while model requests run through the connected machine. This includes generic drawing-coordination assessments, image inputs and structured output. The runner keeps a native session alive across each complete parallel tool batch and sends back the server's authorized results. All Specset approvals remain in the web app; native tools follow the thread's **Native tools** setting (see above) and native delegation stays off. Independent model requests use independent sessions. Claude uses `persistSession: false`; Codex uses `ephemeral: true`.
175
169
 
@@ -177,9 +171,9 @@ For an unattended kickoff, `--autoApprovePlan` skips the plan sign-off and `--au
177
171
 
178
172
  Pin both `--host <deployment>` and `--org <slug>` when using `agent chat`, `agent start`, `agent show`, `agent inspect`, `agent approve` or `agent stop`; these overrides do not change the CLI’s saved selection.
179
173
 
180
- The conversation's Settings lists the models the connected machine reported (Codex's catalog, Claude's supported models) and pins one per harness for the thread, plus a reasoning effort from that model's reported levels (agent steps only; helper calls keep the harness default); `--model` on the machine pins one for every job and shows as fixed there. `--concurrency` defaults to 5 and limits active model calls; tool and approval waits release their slot so even 1 can complete nested fan-out. `--maxThreads` defaults to 100 and `--maxRunSeconds` to 3600 per root authorization. `--model` is fixed on the machine. Specset’s `--autoApprove` message setting controls tool approval; the thread's Permissions setting bounds native tools when they are on. Ctrl-C revokes the registration and stops queued/running descendants. A restart needs a new assignment. A lost native continuation fails visibly rather than replaying writes or switching to a cloud model.
174
+ Every model call carries its routing tier (conversation, orchestrator, planner, analyst, worker, lite, balanced, query, vision), and each tier names a model that any account whose harness offers it serves. The defaults match the app; `specset harness list` prints each tier's current model and the class it runs as. Antigravity is opt-in: it serves those tiers only after you add an account for it (`specset harness add agy --harness antigravity`); until then they run their model's class on Claude Code or Codex, or in the cloud with `harness fallback`. A model no account offers runs as its class (frontier, standard, fast) on a harness the machine has. Change a tier with `specset harness tier <tier> <model[:effort]>`, a class's model with `specset harness model <harness> <class> <model> [--effort e]`, or one run's with `agent serve --tier conversation=opus`. The conversation's Settings pins a class or one of the reported models per harness for that thread's own steps, plus a reasoning effort; children and helper calls keep the tiers. When the preferred accounts for a model are at their limits, `specset harness failover sameModel|any|off` decides where its calls go (default sameModel: other accounts with the same model; any: also the same class elsewhere); a call that already streamed fails instead and the next one goes elsewhere. A provider rate limit (HTTP 429) is waited out rather than failing the run: the server retries the call once the account's short wait passes (on another account if one has room), unless it already ran a native command or edit, which a retry could repeat; only every account being at its usage limit stops the run. `specset harness fallback <tier|all> cloud` (or `agent serve --fallback analyst=cloud`) sends a tier's calls to Specset's cloud model, billed to the organization, instead of another provider's whenever no account here can serve its model (none offers it, or its accounts are at their limits); `local` is the default. `--concurrency` defaults to 5 (at most 16) and limits active model calls; tool and approval waits release their slot so even 1 can complete nested fan-out. `--maxThreads` defaults to 100 and `--maxRunSeconds` to 3600 per root authorization. `specset harness limits --concurrency 16 --maxThreads 300 --maxRunSeconds 43200` saves them in config.yml for every `agent serve` (a flag still wins for one run; `default` clears one; no flags prints them). Specset’s `--autoApprove` message setting controls tool approval; the thread's Permissions setting bounds native tools when they are on. Ctrl-C revokes the registration and stops queued/running descendants. A restart needs a new assignment. A lost native continuation fails visibly rather than replaying writes or switching to a cloud model.
181
175
 
182
- Harness tool callbacks can only wait for results supplied by the server. Each job receives private harness configuration and a minimal environment; with native tools on, that private home also holds a CLI login for the run's host and organization so `specset` works from the harness's shell. Claude shares the selected native credential store and its refresh lock. Codex uses an authentication-only native process to refresh the selected login, then supplies temporary access tokens to isolated inference sessions. Neither copies rotating refresh credentials into job homes. Settings, hooks, plugins and global MCP servers are excluded from inference sessions. Run `claude auth login` first if the harness reports authentication is required. It still runs as the local OS user, not inside an OS sandbox. Use a dedicated account or isolated host for untrusted project content; do not share this personal runner across users. This command requires the matching personal-runner and local-inference server APIs and ships in the next CLI release.
176
+ Harness tool callbacks can only wait for results supplied by the server. Each job receives private harness configuration and a minimal environment; with native tools on, that private home also holds a CLI login for the run's host and organization so `specset` works from the harness's shell. Claude shares the selected native credential store and its refresh lock. Codex uses an authentication-only native process to refresh the selected login, then supplies temporary access tokens to isolated inference sessions. Neither copies rotating refresh credentials into job homes. Settings, hooks, plugins and global MCP servers are excluded from inference sessions. Run `claude auth login` first if the harness reports authentication is required. It still runs as the local OS user, not inside an OS sandbox. Use a dedicated account or isolated host for untrusted project content; do not share this personal runner across users.
183
177
 
184
178
  Use `specset agent runners list --json` to inspect your registrations.
185
179
  Use `specset agent runners revoke <runner-id>` to stop and revoke one remotely, including an offline runner after a crash.
@@ -18,8 +18,6 @@ Maintenance has three layers:
18
18
  - **MaintenancePlan** — a schedule on exactly one Product, Asset, Location, or System. Product plans fan out to installed assets. Its `tiers` are independent schedule items that pair a Procedure with a calendar cadence, meter trigger, or both.
19
19
  - **WorkOrder** — a concrete occurrence or ad-hoc job. Generated work orders snapshot their checklist fields, so history remains stable when a Procedure changes.
20
20
 
21
- `MaintenanceTask` and its completion API no longer exist. Use Procedure, MaintenancePlan, and WorkOrder operations below.
22
-
23
21
  ## Discover Before Mutating
24
22
 
25
23
  Input objects evolve, especially checklist fields and plan tiers. Introspect the relevant input before composing a mutation:
@@ -315,12 +313,7 @@ specset files download <file-resource-id> --out manual.pdf # once workflow.s
315
313
 
316
314
  ## Enabling closeout
317
315
 
318
- `CloseoutAuthService.isCloseoutActive` requires the org SKU **and** (unless the org is in `fmMode`) the project toggle. Both are superadmin operations; `updateOrg(skus)` replaces the whole SKU object, so read the current flags and resend them:
319
-
320
- ```bash
321
- specset api --query '{ org(id: "<org-id>") { skus { closeout fmMode dailyLog scheduling estimation agentSessions agentSkills customAgents whitelabel modelRoutingV2 } } }'
322
- specset api --query 'mutation { updateOrg(id: "<org-id>", skus: { closeout: true, dailyLog: true, scheduling: true }) { id } updateProject(id: "<project-id>", toolSettings: { closeout: true }) { id } }'
323
- ```
316
+ `CloseoutAuthService.isCloseoutActive` requires the org's closeout SKU **and** (unless the org is in `fmMode`) the project's closeout toggle. Specset staff turn both on; when closeout operations report closeout as inactive, ask your Specset contact to enable it.
324
317
 
325
318
  ## Dedup / Re-pointing
326
319
 
@@ -26,7 +26,7 @@ project(id: ID!): Project!
26
26
 
27
27
  `createProject` does **not** add the creator as a project member, so the new project won't appear in the default `projects` list until someone adds them — fetch it by `project(id)`. The `createProject` mutation takes `userIds` and `teamIds` to add members in the same call; `specset projects create` doesn't, so add them as a second step.
28
28
 
29
- 1. Create it with the project command. New projects automatically support drawing graphs; no opt-in is required:
29
+ 1. Create it with the project command (new projects support drawing graphs automatically):
30
30
 
31
31
  ```bash
32
32
  specset projects create 'Riverside Medical Center' --json
@@ -14,6 +14,13 @@ How the data is shaped:
14
14
 
15
15
  The sketches below are minimal — inline enums, ints, and lists in the operation text (`-F` is strings-only; Variable Limitations and Schema Discovery live in the `specset` skill).
16
16
 
17
+ Two common flows have purpose-built commands; prefer them to hand-written mutations:
18
+
19
+ ```bash
20
+ specset submittals create --project <projectId> --file ./package.pdf --json # uploads the file and creates the submittal from it; --title, repeatable --specSection <id>
21
+ specset submittals review --submittal <submittalId|link> --wait --json # runs a compliance review and prints its issues; repeatable --specSection, --prompt, --timeout (default 3600)
22
+ ```
23
+
17
24
  ## Reading
18
25
 
19
26
  ```bash
@@ -73,7 +73,7 @@ The retrieval tools return **extracted text**, which is authoritative for schedu
73
73
 
74
74
  All commands support `--json` (structured `{files: [{path, bytes, ...}]}` output) and `--out` (file path, or directory for multi-file downloads). A citation passed to the wrong command errors with the right one to use.
75
75
 
76
- `drawings download` also accepts `--org <slug|id>` to pin the source organization when parallel sessions might change the active organization, for example `specset drawings download P2.120 --project <id> --org specbook --host <host> --format pdf`.
76
+ `drawings download`, `files download` and `specs download` also accept `--org <slug|id>` to pin the source organization when parallel sessions might change the active organization, for example `specset drawings download P2.120 --project <id> --org <slug> --host <host> --format pdf` or `specset specs download '08 71 00' --project <id> --org <slug> --host <host> --out hardware.pdf`.
77
77
 
78
78
  To inspect an existing detail crop, add `--node <shortId|UUID>`, for example `specset drawings download <sheet-ref> --node d6 --format image --out detail.png`. Use `--format pdf` for the saved crop PDF. This downloads the current revision's stored crop without regenerating it; missing nodes or crops return an error. Node crops do not support `--format file`. JSON output adds the resolved `nodeId` to the normal sheet download metadata.
79
79
 
@@ -99,7 +99,7 @@ Graph tools are automatically available with `--project` for eligible projects (
99
99
  specset drawings build-graph --project <id> --wait --timeout 1800 --host <host> --json
100
100
  ```
101
101
 
102
- Omit `--wait` to return after requesting the build. Waiting confirms a newly persisted graph snapshot, not complete ingestion or review readiness; inspect the returned statistics and `getDrawingGraphOverview` for stale nodes and bundles before reviewing. The server build continues after a timeout, so inspect the overview before requesting another build. This does not reprocess drawings. The command requires the existing `resolveProjectDrawingGraph` and `projectDrawingGraph` server API; it and these instructions ride the next CLI release.
102
+ Omit `--wait` to return after requesting the build. Waiting confirms a newly persisted graph snapshot, not complete ingestion or review readiness; inspect the returned statistics and `getDrawingGraphOverview` for stale nodes and bundles before reviewing. The server build continues after a timeout, so inspect the overview before requesting another build. This does not reprocess drawings.
103
103
 
104
104
  Use `getDrawingGraphOverview` to discover bundle keys, `getCoordinationBundle` for their views, `traverseDrawingReferences` for callout links, and `findDrawingGraphElements` for labeled, schedule-derived assets and rooms. For graphical devices, including unlabeled glyphs, use the candidate symbol lookup when ingestion and a graph rebuild have populated it:
105
105