You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
scale spec import-myspec <dir> — ingests a MySpec 4-file SDD bundle (constitution/requirements/solution/tasks) into both SCALE spec layers: originals + registry under .scale/specs/myspec/<slug>/, a session-injectable digest at .scale/specs/<slug>.md, and (unless --no-artifacts) a FSM-governed Spec → Plan → Tasks artifact hierarchy. Constitution invariants ([INV-xx] / MUST lines) become spec constraints; EARS+ acceptance criteria (WHEN/WHILE/IF … THEN … SHALL, FR-ids) become successCriteria + verificationSurface; error-pattern criteria also feed edgeCases.
scale spec conformance — the gate-checkable traceability audit: every imported EARS+ criterion must be referenced by at least one task, task references must resolve to real requirement ids, and unchecked tasks fail unless --allow-open-tasks. Exits non-zero on failure and records a RuntimeEvidence gate record either way — wire it into any gate chain as a command.
New module src/spec/MySpecImporter.ts (pure parser/mapper/traceability) + src/cli/specCommands.ts; registered as the spec command group. 8 unit tests against a faithful synthetic bundle (story grouping, criterion classification, invariant extraction, checkbox parsing, payload mapping, digest shape, traceability pass/fail); live-verified end-to-end (import → artifacts SPEC/PLAN/TASK created, conformance strict exit 1 / lenient exit 0, evidence recorded).
Skills governance audit (2026-10-24): 64 skills referenced by .scale/skills.json domains, 27 present across the 7 configured roots, 37 missing — including 4 requiredSkills (impeccable, turix-cua, code-reviewer ×2). The expired mcp-chrome-devtools waiver (2026-07-31) was renewed to 2027-01-22 with an updated reason (browser tooling on this machine comes from host agent plugins). Full list persisted to .scale/reports/skills-audit-2026-10-24.txt.
The four missing requiredSkills were then installed after content review (prompt-level security scan of all 14 files incl. the turix shell script — no exfiltration/credential patterns): impeccable v4.7.1 from pbakaus/impeccable (SKILL.md + 6 reference docs), turix-cua from TurixAI/TuriX-CUA (SKILL.md + helper script; the underlying agent is macOS-only — on Windows it serves as routing/reference), and code-reviewer from aiskillstore/marketplace 9tykeshav (SKILL.md + 6 MERN reference docs). All installed into ~/.agents/skills/; all 7 requiredSkills references now resolve (coverage 32/64, the remaining 32 are recommended-tier). Provenance registered in docs/EXTERNAL_REFERENCES.md.
DeepSeek Harness (DSH) plugin — T2 + T3
Slash commands (T2.1): six governance gates exposed as DSH commands — /scale-preflight, /scale-gate-quality, /scale-verify, /scale-shield-status, /scale-cortex-metrics, /scale-doctor-env. Each spawns the real scale CLI from the resolved main package with fixed allowlisted argv (user rawInput is never appended), a 120–300s timeout, and capped output; handlers always settle inside the dsh-commands CommandResult contract. Daemons (open/dashboard/orch start) stay excluded. Live-verified: all six register against the real commands service (registered 6 slash commands).
Skills provider (T2.2): .scale/skills/<PHASE>/<name>.md phase-workflow skills enter the DSH skills registry through a registerProvider (sync registration per contract; bodies lazy-load in get()). Names are kebab-cased from the # skill: header, description from ## Purpose, whenToUse from ## Triggers; _INDEX.md is skipped. skills.json domain-routing metadata is deliberately not registered — those entries point at external skills in global roots that DSH's own filesystem discovery owns.
Client half (T3): exports["./client"] + dsh.client.platform: "web" manifest; registers tool.call.toolview cards for all 25 exposed mcp__scale__* tools. Route decision closes plan U4: lightweight React via the client React global + styles.insert (no JSX, no Vue mounting bridge — the R6-sanctioned fallback), props consumed defensively, renders purely from conversation data (no filesystem, no new host RPC).
New module cliExecutor: resolves the scale CLI by walking up node_modules to the installed @hongmaple0820/scale-engine (realpath through npm/pnpm symlinks) — require.resolve on the bare name always throws because the main package's exports map is import-only, a bug the new tests caught before it reached DSH.
Tests: command allowlist grammar + daemon exclusion + real-CLI handler settle, skills scan/kebab/provider list+get against a fixture tree, client registration count (25 keys, shell pair excluded), teardown, and graceful no-op without slots/React. tests/dsh now 34 tests, all green; live boot confirms no regression in the Shield self-test.
DeepSeek Harness (DSH) plugin — T0 + T1
MCP stdio entry (src/api/mcpStdio.ts, npm run mcp:stdio): wraps the 27-tool ScaleMCPServer behind @modelcontextprotocol/sdkStdioServerTransport. shell_run/shell_plan are omitted by default (SCALE_MCP_EXPOSE_SHELL=1 restores them) so models cannot route dangerous commands around the Shield bridge via mcp__scale__shell_run; the filter lives in this DSH-only entry point, so other MCP clients keep the full tool list.
Governance plugin packages/dsh-scale/ (@hongmaple0820/dsh-scale, its own npm package outside the main files): one apply() mounts three bridges — tools/pre-execute (block→deny, warn→ask, pwsh/write/edit/read → Bash/Write/Edit/Read mapping, mcp__scale__ prefix unpacking), systemPrompt.context (Cortex injection), tools/post-execute (evidence recording).
Cortex bridge now reads instincts through InstinctStore + SessionInjector (real <domain>/<id>.yaml format); the first implementation read manifest.json + flat .md files that InstinctStore never writes and silently injected nothing.
Evidence bridge writes asynchronously (RuntimeEvidenceLedger.recordAsync, new fs/promises entry point) through a serialized queue — the sync writeFileSync path would block the DSH Electron host on every tool call — and defaults to failures-only (evidenceMode: 'all' records everything; write volume unmeasured).
Plugin hygiene: the §5.6 self-test driver now requires SCALE_DSH_SELFTEST=1 (previously it fired rm -rf probes on every DSH start), tools/post-execute forwards through next() per waterfall semantics, imports use the package name instead of a relative ../../../dist/ path (broken once installed outside the repo), main/files point at prebuilt lib/ (avoids the git-install build-authorization trap), and packages/dsh-scale/ is tracked by git (was caught by the packages/ ignore rule).
Live DSH acceptance (dsh 0.2.1-rc.2, independent scale-dev profile) surfaced and fixed three load-time blockers invisible to static checks: Config must be a schemastery Schema.object (a plain object dies with reading 'validate'), ctx.tools/ctx.systemPrompt require export const inject = ['tools', 'systemPrompt'], and tools.execute() takes a typed exec object ({name, arguments, signal} — signal is required in 0.2.1; outcome is {isError, content[]}). R7 drift confirmed in the wild: dsh-mcp-client@0.0.1-rc.1 is rejected against dsh 0.2.1-rc.2 — install the runtime-matched version (@0.2.1-rc.2).
Acceptance results: T0 stdio end-to-end green (initialize scale-engine 0.55.3; 25 tools with shell_run/shell_plan narrowed away; 27 with SCALE_MCP_EXPOSE_SHELL=1; capability_list call returns live data; mcp-scale layer composes in --dump-config). T1 self-test on the live runtime: BLOCK (rm -rf → [destructive] deny) and PROTECT (.scale/policy.yaml → [Protected Path] deny) pass through the real tools/pre-execute pipeline, and both blocked calls landed as RTE-*.json evidence with source: dsh-scale. The ALLOW probe and warn→ask confirmation need a real session (boot-time contextless probes cannot see session-scoped tools like read) — unit-tested meanwhile.
Main package exports for the plugin surface: InstinctStore, SessionInjector, RuntimeEvidenceLedger (+types), alongside the existing Shield helpers; new checkWarnHits() returns the warn-severity rules checkToolInput drops (the warn→ask mapping needs them).
Tests: DSH bridge mapping assertions from the plan's T1.1 acceptance list (unmapped names silently allow — these pin the mapping), cortex format-compatibility against a real InstinctStore.save(), evidence failures-only/async-queue behavior, mcpStdio shell filtering, and checkWarnHits severity partition.
Known gap surfaced while testing: the Shield blocklist matches POSIX forms only (/\brm\s+-rf\b/); PowerShell-native Remove-Item -Recurse -Force does not hit any rule. Existing Shield scope, not introduced here — tracked for a separate blocklist task.
Agent Ecosystem
Add ZCode adapter (23rd platform): writes .zcode/config.json with the nested hooks.events schema, force-enables hooks.enabled, and merges the SCALE section into AGENTS.md idempotently via <!-- SCALE:BEGIN/END --> markers.
Register ZCode across detection (detectPlatform), SkillDiscovery, doctor (now understands nested hooks.events), dashboard platform matrix, ACP aliases, and the external agent catalog.
Extend scale gate pre-tool/post-tool with --stdin to consume ZCode-style hook payloads (tool_input/tool_response/session_id), make the tool positional fall back to the payload tool_name, and silence pino logging inside hook processes so strict stdout validation never trips.
Map ZCode-exclusive events: PermissionRequest runs the pre-tool gate with exit-code allow/deny semantics, and PostToolUseFailure records failures into .scale/events/ for brute-retry detection.
Register Shield hooks into .zcode/config.json (nested events format) and compile Shield scripts as .cjs so they also work in type: module projects (previously const protected made them fail to parse there); extend the SecurityGate shield-literal allowlist to .cjs.
Dashboard chat loop one-click gate: new POST /api/agent-control/sessions/:id/enable-local-executor, a live-run button in the execution-mode banner (zh/en), fix the never-shown "local executor triggered" notice (payload.willExecute), and pass localExecutor through the admin model API.
Integration workbench T2: replace copy-only command boxes with real actions wherever an API already exists — feishu route preview gains dry-run-send/event-consume buttons, agent message command plans gain an inline dry-run action (timeline and virtual list), verify commands gain a run-acceptance button, readiness stages gain a daemon-ensure button; genuinely terminal-only commands (auth completion) are now labeled with a "Requires terminal" hint instead of pretending to be in-panel actions.
Integration workbench T2-P5: one-click scale setup from the panel via async POST /api/integrations/setup/run + GET status polling (spawn does not block the server thread), with confirm dialogs in Agent Connect and diagnostics; concurrent runs return 409.
Agent OS tasks (T3): the workbench task list is now an operating surface — create tasks (name + level) and drive the lifecycle with start/checkpoint/resume/complete actions; completing requires validation evidence (one per line), mirroring the server-side governance rule that rejects completion without proof.
Governance config management (T3): new Integrations "Governance" tab — view and edit policy.yaml (raw YAML with validation; saving recompiles Shield and re-registers hooks to every agent including ZCode), quality thresholds (coverage/retry/severity, kept in sync with gate G6), and memory provider routing (mode/order/external-write/evidence/max-results) via GET|PUT /api/v1/governance/config*.
Real agent dispatch (cc-connect pattern): sessions gain an executor choice — governed (in-process plan, previous behavior) or agent-cli, which spawns the local agent CLI asynchronously, streams its stdout/stderr back as the chat reply, and enforces a 10-minute timeout plus one-agent-per-session mutual exclusion. Platform defaults map Claude Code/Codex/Gemini/OpenCode/Qwen to their non-interactive commands; agentCommand overrides the template with {prompt}. On Windows the executor auto-detects git-bash for the claude CLI (CLAUDE_CODE_GIT_BASH_PATH), which otherwise exits immediately.
Feishu bridge (cc-connect pattern, inbound direction): a resident loop consumes im.message.receive_v1 events, dedupes by message id, ignores its own replies to avoid echo loops, routes each message into the agent control plane, and sends the agent reply back to the originating chat via lark-cli im +messages-send. GET|POST /api/integrations/feishu/bridge[/start|/stop] plus a readiness check that lists concrete blockers (lark-cli missing, route target unconfigured, session not live-guarded, executor off) instead of starting a bridge that can never execute. Fire-and-forget completion is now exception-safe so a late child-process exit can no longer crash the server.
Verification tooling for the new surfaces: npm run verify:agent-dispatch drives governance config, task lifecycle, agent dispatch (success + failure), and bridge readiness against a running dashboard; verify-dashboard-browser.mjs now covers the agentos and integrations pages (previously unchecked) and asserts the governance tab, bridge panel, task controls, and executor selector actually render.
Fixed
Feishu setup was a dead end: the panel only printed lark-cli config init --new --lang zh for the user to copy, and that command is refused outright in any environment with HERMES_HOME/OPENCLAW_HOME set (the normal case here). The panel now runs lark-cli config init --new --force-init in the background, extracts the real verification URL from its output, and renders it as a clickable "Open authorization page" button with live job status — matching lark-cli's documented agent guidance ("run it in the background and retrieve the verification URL from its output").
Feishu auth flow is now two-step and real: auth login --recommend --no-wait --json returns an actionable URL plus device code, and a new "I have authorized" button runs auth login --device-code <code> to finish — instead of the old "go run config init first" wall.
Windows spawn ENOENT: npm-installed CLIs (lark-cli, claude, codex, …) are .cmd shims, so spawning the extensionless resolved path failed with ENOENT. Added buildSpawnInvocation() in src/core/ExternalCommand.ts (resolve → shim → cmd.exe /d /c call wrapper) and applied it to all four spawn sites: agent dispatch, Feishu event consumption, Feishu config jobs, and the panel's scale setup runner. Without this, agent dispatch could never work on Windows even with valid CLI auth.
Removed server-side English strings that leaked into the Chinese UI (Feishu next-action hints).
Bridge conversation quality (cc-connect parity): inbound messages must start with the session's command prefix (/scale by default) — group small talk no longer triggers a full agent run; replies route to the exact originating chat via message-id→chat-id mapping instead of "most recent chat"; long replies chunk at newline boundaries with 【n/m】 markers instead of truncating at 2000 chars; and same-session agent-cli runs stay continuous (claude --continue, codex exec resume --last, gemini --checkpoint on second and later messages).