@sayknow-cli/coding-agent 0.3.5 → 0.3.7
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/README.md +76 -0
- package/dist/types/capability/mcp.d.ts +2 -0
- package/dist/types/cli/local-provider-smoke.d.ts +59 -0
- package/dist/types/cli/notify-cli.d.ts +1 -1
- package/dist/types/cli/telegram-cli.d.ts +13 -0
- package/dist/types/cli/update-cli.d.ts +24 -1
- package/dist/types/commands/local-provider.d.ts +34 -0
- package/dist/types/commands/telegram.d.ts +22 -0
- package/dist/types/config/keybindings.d.ts +12 -6
- package/dist/types/config/model-registry.d.ts +5 -0
- package/dist/types/config/models-config-schema.d.ts +5 -0
- package/dist/types/config/settings-schema.d.ts +284 -4
- package/dist/types/config/settings.d.ts +7 -0
- package/dist/types/config/telegram-autostart.d.ts +14 -0
- package/dist/types/config/telegram-env-bridge.d.ts +18 -0
- package/dist/types/coordinator-mcp/server.d.ts +8 -0
- package/dist/types/defaults/skc-defaults.d.ts +7 -0
- package/dist/types/discovery/cursor.d.ts +4 -1
- package/dist/types/discovery/index.d.ts +0 -1
- package/dist/types/discovery/windsurf.d.ts +3 -1
- package/dist/types/extensibility/extensions/types.d.ts +11 -0
- package/dist/types/i18n/messages/en.d.ts +1 -0
- package/dist/types/modes/components/custom-editor.d.ts +6 -1
- package/dist/types/modes/components/custom-model-preset-wizard.d.ts +1 -1
- package/dist/types/modes/components/hook-selector.d.ts +5 -0
- package/dist/types/modes/components/model-selector.d.ts +2 -0
- package/dist/types/modes/components/settings-selector.d.ts +5 -1
- package/dist/types/modes/components/skill-message.d.ts +1 -0
- package/dist/types/modes/components/status-line/types.d.ts +5 -7
- package/dist/types/modes/components/status-line.d.ts +15 -3
- package/dist/types/modes/components/two-column-body.d.ts +9 -0
- package/dist/types/modes/components/welcome.d.ts +9 -1
- package/dist/types/modes/controllers/command-controller.d.ts +1 -0
- package/dist/types/modes/controllers/input-controller.d.ts +6 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +10 -1
- package/dist/types/modes/interactive-mode.d.ts +2 -0
- package/dist/types/modes/prompt-action-autocomplete.d.ts +3 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +1 -0
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +41 -7
- package/dist/types/modes/slash-command-visibility.d.ts +1 -0
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/modes/tmux-scroll.d.ts +18 -0
- package/dist/types/modes/types.d.ts +5 -1
- package/dist/types/modes/utils/terminal-bell.d.ts +3 -0
- package/dist/types/notifications/daemon-paths.d.ts +9 -0
- package/dist/types/notifications/html-format.d.ts +2 -0
- package/dist/types/notifications/recent-activity.d.ts +5 -1
- package/dist/types/notifications/telegram-daemon-cli.d.ts +21 -4
- package/dist/types/notifications/telegram-daemon-control.d.ts +8 -0
- package/dist/types/notifications/telegram-daemon.d.ts +4 -10
- package/dist/types/notifications/telegram-reference.d.ts +4 -0
- package/dist/types/notifications/threaded-render.d.ts +1 -0
- package/dist/types/runtime-mcp/config-writer.d.ts +9 -0
- package/dist/types/runtime-mcp/config.d.ts +2 -0
- package/dist/types/runtime-mcp/loader.d.ts +2 -0
- package/dist/types/runtime-mcp/manager.d.ts +2 -0
- package/dist/types/runtime-mcp/types.d.ts +6 -0
- package/dist/types/sdk.d.ts +1 -1
- package/dist/types/skc-runtime/launch-tmux.d.ts +2 -2
- package/dist/types/skc-runtime/ralplan-runtime.d.ts +3 -2
- package/dist/types/skc-runtime/restricted-role-agent-bash.d.ts +1 -0
- package/dist/types/skc-runtime/session-state-sidecar.d.ts +5 -0
- package/dist/types/skc-runtime/state-writer.d.ts +1 -0
- package/dist/types/skc-runtime/team-runtime.d.ts +1 -1
- package/dist/types/skc-runtime/tmux-common.d.ts +12 -0
- package/dist/types/skc-runtime/ultragoal-guard.d.ts +7 -1
- package/dist/types/skc-runtime/ultragoal-runtime.d.ts +0 -4
- package/dist/types/slash-commands/types.d.ts +2 -0
- package/dist/types/system-prompt.d.ts +7 -0
- package/dist/types/tools/skill.d.ts +1 -1
- package/dist/types/utils/cmux-workspace.d.ts +52 -0
- package/dist/types/web/search/index.d.ts +4 -2
- package/dist/types/web/search/provider.d.ts +14 -0
- package/dist/types/web/search/providers/utils.d.ts +42 -13
- package/dist/types/web/search/render.d.ts +1 -0
- package/dist/types/workflow/workflow-intent-diff.d.ts +19 -0
- package/package.json +8 -8
- package/scripts/build-binary.ts +3 -0
- package/scripts/verify-insane-vendor.ts +0 -5
- package/src/capability/mcp.ts +2 -0
- package/src/cli/local-provider-smoke.ts +632 -0
- package/src/cli/notify-cli.ts +4 -2
- package/src/cli/telegram-cli.ts +156 -0
- package/src/cli/update-cli.ts +179 -13
- package/src/cli/web-search-cli.ts +5 -7
- package/src/cli.ts +20 -1
- package/src/commands/launch.ts +47 -2
- package/src/commands/local-provider.ts +62 -0
- package/src/commands/notify.ts +1 -1
- package/src/commands/ralplan.ts +1 -0
- package/src/commands/telegram.ts +47 -0
- package/src/config/keybindings.ts +15 -6
- package/src/config/mcp-schema.json +4 -0
- package/src/config/model-registry.ts +55 -1
- package/src/config/models-config-schema.ts +9 -0
- package/src/config/settings-schema.ts +256 -4
- package/src/config/settings.ts +11 -0
- package/src/config/telegram-autostart.ts +107 -0
- package/src/config/telegram-env-bridge.ts +92 -0
- package/src/coordinator-mcp/server.ts +276 -34
- package/src/defaults/skc/skills/ralplan/SKILL.md +29 -20
- package/src/defaults/skc/skills/ultragoal/SKILL.md +37 -112
- package/src/defaults/skc-defaults.ts +16 -0
- package/src/discovery/builtin.ts +12 -0
- package/src/discovery/cursor.ts +5 -84
- package/src/discovery/gemini.ts +3 -89
- package/src/discovery/index.ts +4 -1
- package/src/discovery/mcp-json.ts +11 -0
- package/src/discovery/opencode.ts +5 -122
- package/src/discovery/windsurf.ts +4 -82
- package/src/edit/read-file.ts +9 -1
- package/src/extensibility/extensions/runner.ts +2 -1
- package/src/extensibility/extensions/types.ts +11 -0
- package/src/extensibility/skills.ts +30 -2
- package/src/hooks/skill-state.ts +33 -73
- package/src/i18n/messages/de.ts +1 -0
- package/src/i18n/messages/en.ts +1 -0
- package/src/i18n/messages/es.ts +1 -0
- package/src/i18n/messages/fr.ts +1 -0
- package/src/i18n/messages/ja.settings.ts +28 -0
- package/src/i18n/messages/ja.ts +1 -0
- package/src/i18n/messages/ko.settings.ts +28 -0
- package/src/i18n/messages/ko.ts +1 -0
- package/src/i18n/messages/zh.settings.ts +28 -0
- package/src/i18n/messages/zh.ts +1 -0
- package/src/internal-urls/docs-index.generated.ts +12 -7
- package/src/main.ts +5 -2
- package/src/migrate/executor.ts +23 -6
- package/src/modes/acp/acp-agent.ts +7 -6
- package/src/modes/components/agent-dashboard.ts +3 -35
- package/src/modes/components/custom-editor.ts +26 -0
- package/src/modes/components/custom-model-preset-wizard.ts +30 -189
- package/src/modes/components/extensions/extension-dashboard.ts +2 -48
- package/src/modes/components/hook-selector.ts +21 -3
- package/src/modes/components/model-selector.ts +246 -11
- package/src/modes/components/session-observer-overlay.ts +3 -3
- package/src/modes/components/session-selector.ts +19 -9
- package/src/modes/components/settings-selector.ts +551 -11
- package/src/modes/components/skill-message.ts +18 -10
- package/src/modes/components/status-line/presets.ts +11 -0
- package/src/modes/components/status-line/segments.ts +16 -19
- package/src/modes/components/status-line/types.ts +6 -2
- package/src/modes/components/status-line.ts +281 -117
- package/src/modes/components/tree-selector.ts +28 -8
- package/src/modes/components/two-column-body.ts +36 -0
- package/src/modes/components/welcome.ts +165 -30
- package/src/modes/controllers/command-controller.ts +26 -2
- package/src/modes/controllers/event-controller.ts +102 -4
- package/src/modes/controllers/extension-ui-controller.ts +21 -2
- package/src/modes/controllers/input-controller.ts +214 -47
- package/src/modes/controllers/selector-controller.ts +35 -33
- package/src/modes/interactive-mode.ts +36 -30
- package/src/modes/prompt-action-autocomplete.ts +48 -8
- package/src/modes/rpc/rpc-types.ts +1 -0
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +72 -15
- package/src/modes/shared/agent-wire/workflow-gate-schema.ts +20 -0
- package/src/modes/slash-command-visibility.ts +9 -0
- package/src/modes/theme/theme.ts +5 -1
- package/src/modes/tmux-scroll.ts +92 -0
- package/src/modes/types.ts +8 -1
- package/src/modes/utils/hotkeys-markdown.ts +5 -2
- package/src/modes/utils/terminal-bell.ts +48 -0
- package/src/modes/utils/ui-helpers.ts +76 -3
- package/src/notifications/daemon-paths.ts +22 -0
- package/src/notifications/html-format.ts +75 -1
- package/src/notifications/index.ts +32 -2
- package/src/notifications/lifecycle-control-runtime.ts +12 -3
- package/src/notifications/recent-activity.ts +32 -8
- package/src/notifications/telegram-daemon-cli.ts +125 -13
- package/src/notifications/telegram-daemon-control.ts +9 -0
- package/src/notifications/telegram-daemon.ts +88 -46
- package/src/notifications/telegram-reference.ts +36 -14
- package/src/notifications/threaded-render.ts +14 -6
- package/src/prompts/agents/architect.md +7 -4
- package/src/prompts/agents/critic.md +15 -6
- package/src/prompts/agents/planner.md +8 -3
- package/src/prompts/system/system-prompt.md +20 -2
- package/src/prompts/tools/bash.md +1 -1
- package/src/runtime-mcp/config-writer.ts +28 -0
- package/src/runtime-mcp/config.ts +7 -0
- package/src/runtime-mcp/loader.ts +3 -0
- package/src/runtime-mcp/manager.ts +3 -0
- package/src/runtime-mcp/types.ts +6 -0
- package/src/sdk.ts +10 -11
- package/src/session/agent-session.ts +103 -13
- package/src/session/session-manager.ts +58 -18
- package/src/skc-runtime/launch-tmux.ts +34 -8
- package/src/skc-runtime/launch-worktree.ts +16 -2
- package/src/skc-runtime/ralplan-runtime.ts +22 -6
- package/src/skc-runtime/restricted-role-agent-bash.ts +1 -0
- package/src/skc-runtime/session-state-sidecar.ts +167 -24
- package/src/skc-runtime/state-runtime.ts +8 -5
- package/src/skc-runtime/state-writer.ts +5 -5
- package/src/skc-runtime/team-runtime.ts +21 -6
- package/src/skc-runtime/tmux-common.ts +16 -0
- package/src/skc-runtime/tmux-sessions.ts +13 -9
- package/src/skc-runtime/ultragoal-guard.ts +150 -24
- package/src/skc-runtime/ultragoal-runtime.ts +16 -124
- package/src/skc-runtime/workflow-manifest.generated.json +0 -8
- package/src/skc-runtime/workflow-manifest.ts +0 -1
- package/src/slash-commands/builtin-registry.ts +136 -23
- package/src/slash-commands/types.ts +2 -0
- package/src/system-prompt.ts +8 -0
- package/src/task/executor.ts +5 -0
- package/src/tools/ast-grep.ts +10 -7
- package/src/tools/bash.ts +39 -14
- package/src/tools/index.ts +8 -1
- package/src/tools/skill.ts +1 -1
- package/src/utils/cmux-workspace.ts +233 -0
- package/src/utils/title-generator.ts +2 -0
- package/src/web/kagi.ts +1 -1
- package/src/web/parallel.ts +2 -2
- package/src/web/search/index.ts +137 -52
- package/src/web/search/provider.ts +80 -0
- package/src/web/search/providers/anthropic.ts +1 -1
- package/src/web/search/providers/brave.ts +1 -1
- package/src/web/search/providers/codex.ts +1 -1
- package/src/web/search/providers/duckduckgo.ts +1 -1
- package/src/web/search/providers/exa.ts +1 -1
- package/src/web/search/providers/gemini.ts +7 -3
- package/src/web/search/providers/jina.ts +1 -1
- package/src/web/search/providers/kimi.ts +6 -1
- package/src/web/search/providers/openai-compatible.ts +1 -1
- package/src/web/search/providers/parallel.ts +1 -1
- package/src/web/search/providers/perplexity.ts +2 -2
- package/src/web/search/providers/searxng.ts +1 -1
- package/src/web/search/providers/synthetic.ts +1 -1
- package/src/web/search/providers/tavily.ts +1 -1
- package/src/web/search/providers/utils.ts +67 -17
- package/src/web/search/providers/xai.ts +1 -1
- package/src/web/search/providers/zai.ts +1 -1
- package/src/web/search/render.ts +3 -0
- package/src/workflow/workflow-intent-diff.ts +199 -0
- package/vendor/insane-search/MANIFEST.json +1 -3
- package/vendor/insane-search/engine/tests/test_u1.py +0 -28
- package/vendor/insane-search/engine/transport.py +2 -3
- package/vendor/insane-search/engine/validators.py +0 -14
- package/src/defaults/skc/rules/ponytail.md +0 -68
|
@@ -19,7 +19,7 @@ Ralplan is the consensus planning workflow. It triggers iterative planning with
|
|
|
19
19
|
|
|
20
20
|
## Flags
|
|
21
21
|
|
|
22
|
-
- `--interactive`: Enables user prompts
|
|
22
|
+
- `--interactive`: Enables extra mid-loop user prompts (draft review in step 2 and one-at-a-time reconciliation in step 6c). Regardless of this flag, the workflow always finishes the post-interview gate with an `ask`-tool prompt offering Refine further / Approve ultragoal / Approve team / Stop here, and never auto-executes — execution always requires explicit approval through that prompt.
|
|
23
23
|
- `--deliberate`: Forces deliberate mode for high-risk work. Adds pre-mortem (3 scenarios) and expanded test planning (unit/integration/e2e/observability). Without this flag, deliberate mode can still auto-enable when the request explicitly signals high risk (auth/security, migrations, destructive changes, production incidents, compliance/PII, public API breakage).
|
|
24
24
|
- `--architect openai-code`: Use OpenAI code for the Architect pass when OpenAI code CLI is available. Otherwise, briefly note the fallback and keep the default SKC Architect review.
|
|
25
25
|
- `--critic openai-code`: Use OpenAI code for the Critic pass when OpenAI code CLI is available. Otherwise, briefly note the fallback and keep the default SKC Critic review.
|
|
@@ -45,13 +45,15 @@ Planning artifacts and stage handoffs MUST be persisted through the ralplan CLI
|
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
47
|
skc ralplan --write --stage <type> --stage_n <N> --artifact "markdown file path or markdown string"
|
|
48
|
+
# restricted role agents use:
|
|
49
|
+
skc ralplan --write --stage <type> --stage_n <N> --artifact-env SKC_RALPLAN_ARTIFACT
|
|
48
50
|
```
|
|
49
51
|
|
|
50
|
-
Use stage values that match the producer or artifact kind, such as `planner`, `architect`, `critic`, `revision`, `post-interview`, `adr`, or `final`. Increment `--stage_n` for each consensus-loop pass. The `--artifact` value may be either a markdown file path prepared outside `.skc/` for ingestion or the markdown content string itself. The native `--write` handler persists markdown under `.skc/_session-{sessionid}/plans/ralplan/<run-id>/stage-<NN>-<stage>.md`, maintains an `index.jsonl` audit log, and for `final` stages additionally writes a `pending-approval.md` copy. Direct `write`, `edit`, or `ast_edit` calls against `.skc/_session-{sessionid}/specs`, `.skc/_session-{sessionid}/plans`, `.skc/_session-{sessionid}/state`, or any other `.skc/` path are forbidden unless an explicit force override is active.
|
|
52
|
+
Use stage values that match the producer or artifact kind, such as `planner`, `architect`, `critic`, `revision`, `post-interview`, `adr`, or `final`. Increment `--stage_n` for each consensus-loop pass. The `--artifact` value may be either a markdown file path prepared outside `.skc/` for ingestion or the markdown content string itself. The native `--write` handler also accepts `--artifact-env SKC_RALPLAN_ARTIFACT` to read markdown from that per-command env override. It persists markdown under `.skc/_session-{sessionid}/plans/ralplan/<run-id>/stage-<NN>-<stage>.md`, maintains an `index.jsonl` audit log, and for `final` stages additionally writes a `pending-approval.md` copy. Direct `write`, `edit`, or `ast_edit` calls against `.skc/_session-{sessionid}/specs`, `.skc/_session-{sessionid}/plans`, `.skc/_session-{sessionid}/state`, or any other `.skc/` path are forbidden unless an explicit force override is active.
|
|
51
53
|
|
|
52
|
-
While ralplan is active it is a pre-approval planning phase: product-code mutation tools (`write`/`edit`/`ast_edit`) and product-mutating `bash` (e.g. `tee src/...`, redirects into the project tree) are blocked, exactly like deep-interview.
|
|
54
|
+
While ralplan is active it is a pre-approval planning phase: product-code mutation tools (`write`/`edit`/`ast_edit`) and product-mutating `bash` (e.g. `tee src/...`, redirects into the project tree) are blocked, exactly like deep-interview. Leaders may pass `--artifact` markdown inline or, when an artifact is too large to pass inline, stage it as a file in a system temp directory (`os.tmpdir()`/`$TMPDIR`, `/tmp`, `/var/tmp`) outside the project tree and pass that path — never write scratch files into the repo or `.skc/`. Product code is mutated only after the plan is approved and execution begins.
|
|
53
55
|
|
|
54
|
-
Restricted read-only role agents (`planner`, `architect`, and `critic`) must pass markdown content
|
|
56
|
+
Restricted read-only role agents (`planner`, `architect`, and `critic`) must pass markdown content through the `SKC_RALPLAN_ARTIFACT` env override with `--artifact-env SKC_RALPLAN_ARTIFACT`; their restricted bash environment intentionally disables artifact file-path ingestion so a verdict command cannot persist arbitrary file contents.
|
|
55
57
|
|
|
56
58
|
After a role agent persists a stage artifact, its model-facing response to the caller SHOULD be receipt-only: return the `skc ralplan --write --json` receipt (`run_id`, `path`, `stage`, `stage_n`, `sha256`, `created_at`) plus the minimal verdict/status fields the caller needs for routing, and do **not** paste the full persisted markdown back into the parent conversation. Downstream reviewers should receive the artifact path/receipt and read the persisted file themselves when they actually need the body. This preserves the audit trail while preventing Planner/Architect/Critic verdict bodies from being duplicated into the main-agent context.
|
|
57
59
|
|
|
@@ -60,7 +62,7 @@ RECEIPT-ONLY guideline: role agents (`planner`, `architect`, and `critic`) persi
|
|
|
60
62
|
This skill runs SKC planning in consensus mode for the provided arguments.
|
|
61
63
|
|
|
62
64
|
The consensus workflow:
|
|
63
|
-
1. **Planner** creates the initial plan and a compact **RALPLAN-DR summary** before review. Launch the Planner ONCE per run as a detached, resumable subagent (await it before the Architect) and record its returned subagent id as the run's persisted Planner id; persist the stage with `skc ralplan --write --stage planner --stage_n 1 --artifact
|
|
65
|
+
1. **Planner** creates the initial plan and a compact **RALPLAN-DR summary** before review. Launch the Planner ONCE per run as a detached, resumable subagent (await it before the Architect) and record its returned subagent id as the run's persisted Planner id; persist the stage with `skc ralplan --write --stage planner --stage_n 1 --artifact-env SKC_RALPLAN_ARTIFACT --planner-id <id> --planner-resumable <true|false>` (see **Persisted Planner** below):
|
|
64
66
|
- After persistence, return only the receipt/path plus compact planning status; do not paste the full plan markdown back to the caller unless explicitly requested.
|
|
65
67
|
- Principles (3-5)
|
|
66
68
|
- Decision Drivers (top 3)
|
|
@@ -69,27 +71,34 @@ The consensus workflow:
|
|
|
69
71
|
- Deliberate mode only: pre-mortem (3 scenarios) + expanded test plan (unit/integration/e2e/observability)
|
|
70
72
|
2. **User feedback** *(--interactive only)*: If `--interactive` is set, use the `ask` tool to present the draft plan **plus the Principles / Drivers / Options summary** before review (Proceed to review / Request changes / Skip review). Otherwise, automatically proceed to review.
|
|
71
73
|
3. **Architect** reviews for architectural soundness and must provide the strongest steelman antithesis, at least one real tradeoff tension, and (when possible) synthesis — **await completion before step 4**. In deliberate mode, Architect should explicitly flag principle violations.
|
|
72
|
-
- The Architect agent/subagent must persist its review with `skc ralplan --write --stage architect --stage_n <N> --artifact
|
|
74
|
+
- The Architect agent/subagent must persist its review with `skc ralplan --write --stage architect --stage_n <N> --artifact-env SKC_RALPLAN_ARTIFACT --json`, then return the receipt/path plus compact verdict/status (`CLEAR`/`WATCH`/`BLOCK`, `APPROVE`/`COMMENT`/`REQUEST CHANGES`) instead of pasting the full review body.
|
|
73
75
|
4. **Critic** evaluates against quality criteria — run only after step 3 completes. Critic must enforce principle-option consistency, fair alternatives, risk mitigation clarity, testable acceptance criteria, and concrete verification steps. In deliberate mode, Critic must reject missing/weak pre-mortem or expanded test plan.
|
|
74
|
-
- The Critic agent/subagent must persist its evaluation with `skc ralplan --write --stage critic --stage_n <N> --artifact
|
|
75
|
-
5. **Re-review loop** (max 5 iterations): Any non-`
|
|
76
|
+
- The Critic agent/subagent must persist its evaluation with `skc ralplan --write --stage critic --stage_n <N> --artifact-env SKC_RALPLAN_ARTIFACT --json`, then return the receipt/path plus compact verdict/status (`OKAY`/`ITERATE`/`REJECT`) instead of pasting the full evaluation body.
|
|
77
|
+
5. **Re-review loop** (max 5 iterations): Any non-`OKAY` Critic verdict (`ITERATE` or `REJECT`) MUST run the same full closed loop:
|
|
76
78
|
a. Collect Architect + Critic feedback
|
|
77
79
|
b. Revise the plan by resuming the SAME persisted Planner subagent with consolidated Architect + Critic feedback (see **Persisted Planner** below); fall back to a fresh Planner spawn only per the fallback routing table
|
|
78
80
|
c. Return to Architect review
|
|
79
|
-
- Persist each Planner revision with `skc ralplan --write --stage revision --stage_n <N> --artifact
|
|
81
|
+
- Persist each Planner revision with `skc ralplan --write --stage revision --stage_n <N> --artifact-env SKC_RALPLAN_ARTIFACT --json` before re-review, then pass the receipt/path forward instead of duplicating the full revision markdown in the parent conversation.
|
|
80
82
|
d. Return to Critic evaluation
|
|
81
|
-
e. Repeat this loop until Critic returns `
|
|
82
|
-
f. If 5 iterations are reached without `
|
|
83
|
-
6. **Post-ralplan interview** (intent reconciliation gate): After Critic returns `
|
|
83
|
+
e. Repeat this loop until Critic returns `OKAY` or 5 iterations are reached
|
|
84
|
+
f. If 5 iterations are reached without `OKAY`, present the best version to the user
|
|
85
|
+
6. **Post-ralplan interview** (intent reconciliation gate): After Critic returns `OKAY` and before the plan is finalized, reconcile the consensus plan against the user's actual intent. The goal is to make sure ralplan did not silently bake in assumptions that conflict with what the user wants.
|
|
84
86
|
a. **Collect open items** from the run: every assumption the Planner/Architect/Critic resolved by assumption rather than by stated fact, every ambiguity flagged during review, and every decision the loop made without explicit user input. Source these from the persisted `planner`/`architect`/`critic`/`revision` stage artifacts, not from memory.
|
|
85
87
|
b. **Cross-check prior context for conflicts**: glob `.skc/_session-{sessionid}/specs/deep-interview-*.md` and other prior specs/plans/context relevant by topic. For each, list points where the consensus plan contradicts, weakens, or expands beyond a previously crystallized decision, constraint, or non-goal. Cite the conflicting artifact and line/section.
|
|
86
|
-
c. **Reconcile with the user**:
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
c. **Reconcile with the user via the `ask` tool (always, regardless of `--interactive`)**: Never stop idle with plain-text prose after the consensus loop. Every reconciliation question MUST go through the `ask` tool with contextual options plus free-text.
|
|
89
|
+
- If open items exist, confirm the open assumptions and conflicts **one at a time** with the `ask` tool, weakest/highest-impact first, polishing intent. If any confirmation reveals that the plan diverges from user intent, route the consolidated correction back into the re-review loop (step 5b Planner revision) and re-run Architect + Critic before returning here. Cap at the same 5-iteration ceiling.
|
|
90
|
+
- If the plan is crystal clear (no open assumptions or prior-context conflicts), skip straight to the step 8 final-options `ask` instead of inventing filler questions.
|
|
91
|
+
- For every confirmed open item, embed the resolved outcome into the final plan under an **## Intent Reconciliation** section so the `pending approval` artifact records each decision; record any item the user explicitly defers as an open confirmation under that same section.
|
|
92
|
+
d. Persist the reconciliation with `skc ralplan --write --stage post-interview --stage_n <N> --artifact-env SKC_RALPLAN_ARTIFACT --json`, then return the receipt/path plus a compact status (reconciled-clean / reconciled-with-revision / open-confirmations-pending) instead of pasting the full body.
|
|
93
|
+
7. On reconciliation completion, mark the plan `pending approval` unless explicit execution approval has already been captured, persist the ADR/final plan via `skc ralplan --write --stage final --stage_n <N> --artifact-env SKC_RALPLAN_ARTIFACT`, and do not directly edit `.skc/_session-{sessionid}/plans`. Final plan must include ADR (Decision, Drivers, Alternatives considered, Why chosen, Consequences, Follow-ups) and, when present, the **## Intent Reconciliation** section.
|
|
94
|
+
8. **Always** present the finalized plan via the `ask` tool (regardless of `--interactive`) with `workflowGate: { stage: "ralplan", kind: "approval" }` on the final question so RPC/headless clients receive a `ralplan`/`approval` workflow gate, not a deep-interview question gate. Use these options:
|
|
95
|
+
- **Refine further** — re-run the consensus loop / request changes, then return here
|
|
96
|
+
- **Approve execution via ultragoal (Recommended)** — goal-tracked autonomous execution
|
|
97
|
+
- **Approve execution via team** — only when tmux-based interactive worker parallelization is required
|
|
98
|
+
- **Stop here** — keep the plan as `pending approval` and make no further changes
|
|
99
|
+
|
|
100
|
+
Always include a free-text option. Do not stop with plain text and no `ask`; the post-interview gate's terminal action is this `ask`.
|
|
101
|
+
9. On approval: invoke `/skill:ultragoal` for execution by default; invoke `/skill:team` only when the user explicitly needs tmux-based interactive worker parallelization. On **Refine further**, return to the step 5 re-review loop. On **Stop here**, leave the `pending approval` artifact and stop. Never implement directly.
|
|
93
102
|
|
|
94
103
|
Before invoking `/skill:team` or `/skill:ultragoal`, mark ralplan ready for handoff so the skill tool's chain guard permits the transition:
|
|
95
104
|
|
|
@@ -121,7 +130,7 @@ The Planner is a **same-session persisted subagent**: launched detached once, aw
|
|
|
121
130
|
**Recording persisted-Planner metadata** (audit/routing only — never claim `subagent list` proves resumability, since the snapshot does not expose `resumable`). Ride these optional flags on the normal `--write` for the planner/revision stage of the pass:
|
|
122
131
|
|
|
123
132
|
```
|
|
124
|
-
skc ralplan --write --stage revision --stage_n <N> --artifact
|
|
133
|
+
skc ralplan --write --stage revision --stage_n <N> --artifact-env SKC_RALPLAN_ARTIFACT \
|
|
125
134
|
--planner-id <id> --planner-resumable <true|false> \
|
|
126
135
|
--fallback-reason <context_unavailable|not_found|no_runner|resume_failed|process_restart|missing_record> \
|
|
127
136
|
--fallback-attempted-id <id> --fallback-stage-n <N> \
|
|
@@ -11,7 +11,7 @@ Use when the user asks for `ultragoal`, `create-goals`, `complete-goals`, durabl
|
|
|
11
11
|
|
|
12
12
|
## Purpose
|
|
13
13
|
|
|
14
|
-
`ultragoal` turns a brief into repo-native artifacts and then drives
|
|
14
|
+
`ultragoal` turns a brief into repo-native durable artifacts and then drives execution through the unified `goal` tool as a UX bridge only. `goals.json` is the canonical source of goal identity and state; `ledger.jsonl` is the canonical proof stream for checkpoints, receipts, blockers, steering, and reviews. The inline `goal` tool and goal-mode-request create-bridge exist only to keep the agent's interactive loop focused on the current aggregate or story objective. Completion is verified purely from durable `goals.json` plus fresh `ledger.jsonl` receipts, never from inline goal state. The agent, not the CLI or hooks, calls `goal({"op":"complete"})` or `goal({"op":"drop"})` after durable run completion or cleanup; CLI commands and hooks never mutate goal state.
|
|
15
15
|
|
|
16
16
|
- `.skc/_session-{sessionid}/ultragoal/brief.md`
|
|
17
17
|
- `.skc/_session-{sessionid}/ultragoal/goals.json`
|
|
@@ -36,7 +36,7 @@ skc ultragoal complete-goals
|
|
|
36
36
|
skc ultragoal complete-goals --retry-failed
|
|
37
37
|
skc ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --quality-gate-json <quality-gate-json-or-path>
|
|
38
38
|
skc ultragoal checkpoint --goal-id <id> --status failed --evidence "<blocker/evidence>"
|
|
39
|
-
skc ultragoal record-review-blockers --goal-id <id> --title "Resolve final review blockers" --objective "<blocker-resolution objective>" --evidence "<review findings>"
|
|
39
|
+
skc ultragoal record-review-blockers --goal-id <id> --title "Resolve final review blockers" --objective "<blocker-resolution objective>" --evidence "<review findings>"
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
Use these exact goal-tool calls for the inline goal state:
|
|
@@ -50,7 +50,7 @@ goal({"op":"resume"})
|
|
|
50
50
|
```
|
|
51
51
|
`drop` clears the active goal without exiting goal mode; `resume` reactivates a paused goal.
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Durable completion is single-source: `goals.json` defines which goals exist and their required state, while `ledger.jsonl` provides the receipt proof used to verify completion. Inline goal state is UX-only and is reconciled by the agent after durable completion, not by CLI checkpoints or hooks.
|
|
54
54
|
|
|
55
55
|
## Create goals
|
|
56
56
|
|
|
@@ -98,13 +98,13 @@ Loop until `skc ultragoal status` reports all goals complete:
|
|
|
98
98
|
5. Complete the current SKC story only.
|
|
99
99
|
6. Run a completion audit against the story objective and real artifacts/tests.
|
|
100
100
|
7. Before any `--status complete` checkpoint, run the mandatory final cleanup/review gate below. In aggregate mode, do **not** call `goal({"op":"complete"})` for intermediate stories; checkpoint each story while the aggregate objective is still `active`. On the final story, create the final aggregate receipt first; only after that receipt exists may `goal({"op":"complete"})` run.
|
|
101
|
-
8. Checkpoint the durable ledger. Complete checkpoints require `--quality-gate-json
|
|
101
|
+
8. Checkpoint the durable ledger. Complete checkpoints require `--quality-gate-json` only:
|
|
102
102
|
`skc ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --quality-gate-json <quality-gate-json-or-path>`
|
|
103
103
|
A successful complete checkpoint is story completion, not automatic run completion. Read the checkpoint output: when it prints `Next ultragoal goal: <id>`, continue that active story under the same aggregate SKC goal; when it prints `All ultragoal goals are complete`, the durable run is terminal. `skc ultragoal complete-goals` remains the supported manual next-story command if continuation output was missed.
|
|
104
104
|
9. If blocked or failed, checkpoint failure:
|
|
105
105
|
`skc ultragoal checkpoint --goal-id <id> --status failed --evidence "<blocker/evidence>"`
|
|
106
106
|
10. For legacy per-story completed-goal blockers, preserve the non-terminal blocker with:
|
|
107
|
-
`skc ultragoal checkpoint --goal-id <id> --status blocked --evidence "<completed legacy SKC goal blocks goal create in this thread>"
|
|
107
|
+
`skc ultragoal checkpoint --goal-id <id> --status blocked --evidence "<completed legacy SKC goal blocks goal create in this thread>"`
|
|
108
108
|
11. Resume failed goals with `skc ultragoal complete-goals --retry-failed`.
|
|
109
109
|
|
|
110
110
|
## Blocker triage and pause discipline
|
|
@@ -167,19 +167,36 @@ Ultragoal execution should use SKC's bundled role-agent roster when a durable st
|
|
|
167
167
|
- Use `architect` for read-only architecture and code-review lanes, including `CLEAR` / `WATCH` / `BLOCK` status.
|
|
168
168
|
- Use `critic` for read-only plan or handoff critique before execution proceeds.
|
|
169
169
|
|
|
170
|
+
### Mandatory implementation delegation on big scope
|
|
171
|
+
|
|
172
|
+
When a story's implementation scope is **big enough**, the Ultragoal leader MUST delegate the implementation to one or more `executor` subagents instead of writing the code inline itself. This is a hard requirement, not a preference: solo inline implementation of a big-scope story is a gate violation, and the completion cleanup/review gate must treat missing delegation on a big-scope story as a blocker.
|
|
173
|
+
|
|
174
|
+
A story's implementation scope is **big enough** to force delegation when any of the following hold:
|
|
175
|
+
|
|
176
|
+
- It spans **3+ files** or **2+ cleanly separable surfaces/modules** that can be implemented against bounded, independent acceptance criteria.
|
|
177
|
+
- It is estimated at **~200+ lines of net implementation change**, or is otherwise large enough that a single inline pass would crowd out the leader's checkpoint/verification duties.
|
|
178
|
+
- It decomposes into **independent slices** that can proceed in parallel without shared-file contention.
|
|
179
|
+
- The leader has already made **2+ inline edit passes** on the same story and implementation is still materially incomplete.
|
|
180
|
+
|
|
181
|
+
Forced-delegation rules:
|
|
182
|
+
|
|
183
|
+
- Split the story into cleanly separable slices, give each `executor` bounded targets and explicit acceptance criteria, and keep checkpoint/goal-state ownership in the leader.
|
|
184
|
+
- Prefer **parallel** `executor` subagents for independent slices; sequence only slices with a real dependency.
|
|
185
|
+
- If a big-scope story cannot be cleanly split, record the reason as a durable ledger note and delegate the whole implementation to a single `executor` rather than doing it inline; the leader still owns verification.
|
|
186
|
+
- Small, atomic, single-file changes below these thresholds stay with the leader — do not over-delegate trivial work.
|
|
187
|
+
- After integrating delegated slices, run `architect` / `critic` review lanes; worker agents never mutate `.skc/_session-{sessionid}/ultragoal` or call goal tools.
|
|
188
|
+
|
|
170
189
|
When delegating with native subagents, an await timeout only limits the leader's wait. It is not subagent failure evidence and must not be used as a cancellation reason; inspect or continue independent work, and cancel only when the subagent has actually failed, gone off-track, or become unrecoverably wrong.
|
|
171
190
|
|
|
172
191
|
If an Ultragoal request has no approved plan or consensus artifact, run `ralplan` first and preserve its PRD, test spec, role roster, and verification guidance in the Ultragoal ledger. Do not silently substitute ad-hoc execution for missing planning.
|
|
173
192
|
|
|
174
193
|
The Ultragoal leader owns `.skc/_session-{sessionid}/ultragoal/goals.json` and `.skc/_session-{sessionid}/ultragoal/ledger.jsonl`. Role agents return implementation/review evidence; they do not checkpoint Ultragoal or mutate goal state.
|
|
175
194
|
|
|
176
|
-
For large subgoals with independent slices, the Ultragoal leader must spawn parallel `executor` subagents instead of doing serial solo work. Split only cleanly separable files/surfaces, give each executor bounded targets and acceptance criteria, and keep checkpoint ownership in the leader. Use `architect` / `critic` review lanes after integration; do not let worker agents mutate `.skc/_session-{sessionid}/ultragoal` or call goal tools.
|
|
177
|
-
|
|
178
195
|
## Use Ultragoal and Team together
|
|
179
196
|
|
|
180
197
|
Use ultragoal and team together for a durable Ultragoal story that benefits from one visible tmux worker session. Ultragoal remains leader-owned: `.skc/_session-{sessionid}/ultragoal/goals.json` stores the story plan and `.skc/_session-{sessionid}/ultragoal/ledger.jsonl` stores checkpoints. Team is the single-worker tmux execution engine and returns task/evidence status to the leader.
|
|
181
198
|
|
|
182
|
-
The leader checkpoints Ultragoal from Team evidence
|
|
199
|
+
The leader checkpoints Ultragoal from Team evidence plus the current-session SKC goal snapshot; durable state remains leader-owned in `goals.json` and `ledger.jsonl`:
|
|
183
200
|
|
|
184
201
|
```sh
|
|
185
202
|
skc ultragoal checkpoint --goal-id <id> --status complete --evidence "<team evidence mentioning .skc/_session-{sessionid}/ultragoal and <id>>" --quality-gate-json <quality-gate-json-or-path>
|
|
@@ -219,10 +236,10 @@ An ultragoal story cannot be checkpointed `complete` until the active agent has
|
|
|
219
236
|
8. Run a final code review pass and fold it into the strict quality gate. Clean means `architectReview.architectureStatus`, `architectReview.productStatus`, and `architectReview.codeStatus` are all `"CLEAR"`, `architectReview.recommendation` is `"APPROVE"`, executor QA statuses are `"passed"`, iteration is `"passed"` with `fullRerun: true`, every evidence field is non-empty, every required matrix row is present, and every blockers array is empty. `COMMENT`, `WATCH`, `REQUEST CHANGES`, `BLOCK`, missing evidence, missing or shallow matrix rows, plan/code mismatches, or non-empty blockers are non-clean.
|
|
220
237
|
9. If any lane finds an issue, do **not** checkpoint `complete` and do **not** call `goal({"op":"complete"})`. Record durable blocker work instead:
|
|
221
238
|
```sh
|
|
222
|
-
skc ultragoal record-review-blockers --goal-id <id> --title "Resolve verification blockers" --objective "<blocker-resolution objective>" --evidence "<architect/executor findings>"
|
|
239
|
+
skc ultragoal record-review-blockers --goal-id <id> --title "Resolve verification blockers" --objective "<blocker-resolution objective>" --evidence "<architect/executor findings>"
|
|
223
240
|
```
|
|
224
241
|
10. Complete or steer through the blocker story, then rerun the full blocking verification loop. Repeat until all verifier lanes are clean.
|
|
225
|
-
11. Only after the loop is clean, checkpoint the story as complete with a structured quality gate
|
|
242
|
+
11. Only after the loop is clean, checkpoint the story as complete with a structured quality gate. The checkpoint creates a receipt in `ledger.jsonl`; `goals.json.status` alone is not proof. In aggregate mode, the final aggregate receipt must exist before the agent calls `goal({"op":"complete"})` to reconcile the inline UX goal state.
|
|
226
243
|
|
|
227
244
|
While an Ultragoal run is active, the `ask` tool is blocked for all agents. Record unresolved review decisions as durable blockers with `skc ultragoal record-review-blockers` instead of prompting interactively.
|
|
228
245
|
|
|
@@ -235,7 +252,7 @@ The native `checkpoint --status complete` command rejects missing or shallow gat
|
|
|
235
252
|
"productStatus": "CLEAR",
|
|
236
253
|
"codeStatus": "CLEAR",
|
|
237
254
|
"recommendation": "APPROVE",
|
|
238
|
-
"evidence": "architect review synthesis
|
|
255
|
+
"evidence": "architect review synthesis across architecture/product/code",
|
|
239
256
|
"commands": ["architect review command or agent evidence id"],
|
|
240
257
|
"blockers": []
|
|
241
258
|
},
|
|
@@ -247,116 +264,22 @@ The native `checkpoint --status complete` command rejects missing or shallow gat
|
|
|
247
264
|
"e2eCommands": ["bun test:e2e"],
|
|
248
265
|
"redTeamCommands": ["bun test:red-team"],
|
|
249
266
|
"artifactRefs": [
|
|
250
|
-
{
|
|
251
|
-
"id": "browser-run",
|
|
252
|
-
"kind": "browser-automation",
|
|
253
|
-
"path": "artifacts/browser-run.json",
|
|
254
|
-
"description": "valid automation transcript with actions, monotonic timestamps, and selectors"
|
|
255
|
-
},
|
|
256
|
-
{
|
|
257
|
-
"id": "gui-screenshot",
|
|
258
|
-
"kind": "screenshot",
|
|
259
|
-
"path": "artifacts/gui-screenshot.png",
|
|
260
|
-
"description": "non-uniform screenshot evidence for the GUI/web result"
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
"id": "cli-replay",
|
|
264
|
-
"kind": "command-replay",
|
|
265
|
-
"path": "artifacts/cli-replay.json",
|
|
266
|
-
"description": "artifact file containing argv-only CLI replay JSON: schemaVersion 1, kind cli-replay, replaySafe true, allowlisted command such as bun/node --version or deterministic bun/node -e console.log(...), recordedStdout"
|
|
267
|
-
},
|
|
268
|
-
{
|
|
269
|
-
"id": "adversarial-report",
|
|
270
|
-
"kind": "failure-mode-test",
|
|
271
|
-
"path": "artifacts/adversarial-report.txt",
|
|
272
|
-
"description": "boundary, property, adversarial, or failure-mode result"
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
"id": "api-package-report",
|
|
276
|
-
"kind": "api-package-test-report",
|
|
277
|
-
"path": "artifacts/api-package-report.txt",
|
|
278
|
-
"description": "API/package consumer or endpoint verification output"
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
"id": "algorithm-report",
|
|
282
|
-
"kind": "property-test-report",
|
|
283
|
-
"path": "artifacts/algorithm-report.txt",
|
|
284
|
-
"description": "Algorithm/math property, boundary, or invariant verification output"
|
|
285
|
-
}
|
|
267
|
+
{ "id": "<ref-id>", "kind": "<surface-appropriate kind; see step 6>", "path": "artifacts/<file>", "description": "live-surface evidence" }
|
|
286
268
|
],
|
|
287
269
|
"contractCoverage": [
|
|
288
|
-
{
|
|
289
|
-
"id": "contract-goal",
|
|
290
|
-
"contractRef": "approved plan/spec/acceptance criterion or user-facing contract id",
|
|
291
|
-
"obligation": "required behavior from the approved contract",
|
|
292
|
-
"status": "covered",
|
|
293
|
-
"surfaceEvidenceRefs": ["surface-gui"],
|
|
294
|
-
"adversarialCaseRefs": ["case-invalid-input"]
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
"id": "contract-out-of-scope",
|
|
298
|
-
"contractRef": "contract intentionally outside this story",
|
|
299
|
-
"obligation": "explicitly omitted approved-contract surface",
|
|
300
|
-
"status": "not_applicable",
|
|
301
|
-
"reason": "why this contract does not apply to the current story"
|
|
302
|
-
}
|
|
270
|
+
{ "id": "<id>", "contractRef": "<approved contract id>", "obligation": "<required behavior>", "status": "covered", "surfaceEvidenceRefs": ["<surface-id>"], "adversarialCaseRefs": ["<case-id>"] }
|
|
303
271
|
],
|
|
304
272
|
"surfaceEvidence": [
|
|
305
|
-
{
|
|
306
|
-
"id": "surface-gui",
|
|
307
|
-
"contractRef": "user-facing surface or public interface under test",
|
|
308
|
-
"surface": "gui|web|cli|api|package|algorithm|math|native|desktop|tui",
|
|
309
|
-
"invocation": "real browser action, CLI command, API/package consumer call, or algorithm/property check",
|
|
310
|
-
"verdict": "passed",
|
|
311
|
-
"artifactRefs": ["browser-run", "gui-screenshot"]
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
"id": "surface-cli",
|
|
315
|
-
"contractRef": "CLI or command-line interface under test",
|
|
316
|
-
"surface": "cli",
|
|
317
|
-
"invocation": "argv replay executed by the Ultragoal runtime",
|
|
318
|
-
"verdict": "passed",
|
|
319
|
-
"artifactRefs": ["cli-replay"]
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
"id": "surface-api",
|
|
323
|
-
"contractRef": "API/package public interface under test",
|
|
324
|
-
"surface": "api/package",
|
|
325
|
-
"invocation": "real endpoint call, package consumer call, or schema contract check",
|
|
326
|
-
"verdict": "passed",
|
|
327
|
-
"artifactRefs": ["api-package-report"]
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
"id": "surface-algorithm",
|
|
331
|
-
"contractRef": "algorithm/math invariant under test",
|
|
332
|
-
"surface": "algorithm/math",
|
|
333
|
-
"invocation": "property, boundary, or invariant test run",
|
|
334
|
-
"verdict": "passed",
|
|
335
|
-
"artifactRefs": ["algorithm-report"]
|
|
336
|
-
},
|
|
337
|
-
{
|
|
338
|
-
"id": "surface-out-of-scope",
|
|
339
|
-
"contractRef": "surface intentionally outside this story",
|
|
340
|
-
"surface": "gui|web|cli|api|package|algorithm|math|native|desktop|tui",
|
|
341
|
-
"status": "not_applicable",
|
|
342
|
-
"reason": "why this surface does not apply to the current story"
|
|
343
|
-
}
|
|
273
|
+
{ "id": "<surface-id>", "contractRef": "<surface under test>", "surface": "gui|web|cli|api|package|algorithm|math|native|desktop|tui", "invocation": "<real invocation>", "verdict": "passed", "artifactRefs": ["<ref-id>"] }
|
|
344
274
|
],
|
|
345
275
|
"adversarialCases": [
|
|
346
|
-
{
|
|
347
|
-
"id": "case-invalid-input",
|
|
348
|
-
"contractRef": "approved plan/spec/acceptance criterion or user-facing contract id",
|
|
349
|
-
"scenario": "boundary/property/adversarial/failure-mode input or user action",
|
|
350
|
-
"expectedBehavior": "contract-required rejection, handling, or invariant preservation",
|
|
351
|
-
"verdict": "passed",
|
|
352
|
-
"artifactRefs": ["adversarial-report"]
|
|
353
|
-
}
|
|
276
|
+
{ "id": "<case-id>", "contractRef": "<approved contract id>", "scenario": "<boundary/adversarial input>", "expectedBehavior": "<required handling>", "verdict": "passed", "artifactRefs": ["<ref-id>"] }
|
|
354
277
|
],
|
|
355
278
|
"blockers": []
|
|
356
279
|
},
|
|
357
280
|
"iteration": {
|
|
358
281
|
"status": "passed",
|
|
359
|
-
"evidence": "blockers
|
|
282
|
+
"evidence": "blockers absent or resolved and the full loop was rerun cleanly",
|
|
360
283
|
"fullRerun": true,
|
|
361
284
|
"rerunCommands": ["bun test:e2e", "bun test:red-team"],
|
|
362
285
|
"blockers": []
|
|
@@ -364,6 +287,8 @@ The native `checkpoint --status complete` command rejects missing or shallow gat
|
|
|
364
287
|
}
|
|
365
288
|
```
|
|
366
289
|
|
|
290
|
+
Provide one `artifactRefs` entry per live surface actually exercised, using the surface-appropriate `kind` and evidence rules from steps 6–7 above; the CLI rejects missing or shallow gates. `status: "not_applicable"` rows are allowed only in `contractCoverage` and `surfaceEvidence` and each requires `contractRef` plus `reason`.
|
|
291
|
+
|
|
367
292
|
For CLI replay artifacts, the JSON at `path` must be an object like `{"schemaVersion":1,"kind":"cli-replay","replaySafe":true,"command":["bun","-e","console.log(\"ultragoal-cli-ok\")"],"recordedStdout":"ultragoal-cli-ok\n"}`. Use `replayExempt` only for audited unsafe/non-deterministic invocations, with exact fields `reasonCode`, `reason`, `approvedBy`, and `fallbackArtifactRefs`. `reason` must be substantive and audited, `approvedBy` must identify the verifier, and `fallbackArtifactRefs` must reference same-surface structurally valid fallback artifacts. Allowed `reasonCode` values are exactly `unsafe_side_effect`, `requires_credentials`, `requires_network`, `non_deterministic_external`, `destructive`, `interactive_only`, and `platform_unavailable`.
|
|
368
293
|
|
|
369
294
|
## Review mode
|
|
@@ -392,6 +317,6 @@ The skill tool then dispatches `/skill:ralplan` or `/skill:deep-interview` same-
|
|
|
392
317
|
- For back-to-back ultragoal runs in the same session/thread, when `goal({"op":"get"})` still reports an active aggregate, call `goal({"op":"drop"})` before `goal({"op":"create"})`; when no active goal exists or the prior aggregate is already complete or dropped, call `goal({"op":"create"})` directly. The goal tool remains callable across drop; no slash-command cleanup exists or is required.
|
|
393
318
|
- Never call `goal({"op":"create"})` when `goal({"op":"get"})` reports a different active goal.
|
|
394
319
|
- Never call `goal({"op":"complete"})` unless the aggregate run or legacy per-story goal is actually complete.
|
|
395
|
-
- In aggregate mode, intermediate and final story checkpoints
|
|
396
|
-
- Completion checkpoints require
|
|
320
|
+
- In aggregate mode, intermediate and final story checkpoints update durable `goals.json` state and append receipt proof to `ledger.jsonl`; the final story checkpoint creates the final aggregate receipt before the agent may call `goal({"op":"complete"})`.
|
|
321
|
+
- Completion checkpoints require `--quality-gate-json` only. Shell commands and hooks must not mutate goal state; the agent reconciles inline goal-tool state after durable completion.
|
|
397
322
|
- Treat `ledger.jsonl` as the durable audit trail; checkpoint after every success or failure.
|
|
@@ -44,6 +44,13 @@ export type DefaultSkcDefinition = DefaultSkcSkillDefinition | DefaultSkcSkillFr
|
|
|
44
44
|
export interface InstallDefaultSkcDefinitionsOptions {
|
|
45
45
|
check?: boolean;
|
|
46
46
|
force?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Only rewrite default definition files that already exist on disk but whose
|
|
49
|
+
* content differs from the embedded defaults. Files that are absent are left
|
|
50
|
+
* absent (status "missing"). Used by `skc update` to refresh opted-in copies
|
|
51
|
+
* without materializing new on-disk copies for users who never installed them.
|
|
52
|
+
*/
|
|
53
|
+
refreshOnly?: boolean;
|
|
47
54
|
targetRoot?: string;
|
|
48
55
|
}
|
|
49
56
|
|
|
@@ -160,6 +167,15 @@ export async function installDefaultSkcDefinitions(
|
|
|
160
167
|
|
|
161
168
|
if (options.check) {
|
|
162
169
|
status = existing === undefined ? "missing" : existing === definition.content ? "matching" : "different";
|
|
170
|
+
} else if (options.refreshOnly) {
|
|
171
|
+
if (existing === undefined) {
|
|
172
|
+
status = "missing";
|
|
173
|
+
} else if (existing === definition.content) {
|
|
174
|
+
status = "matching";
|
|
175
|
+
} else {
|
|
176
|
+
await Bun.write(destination, definition.content);
|
|
177
|
+
status = "written";
|
|
178
|
+
}
|
|
163
179
|
} else if (existing !== undefined && !options.force) {
|
|
164
180
|
status = "skipped";
|
|
165
181
|
} else {
|
package/src/discovery/builtin.ts
CHANGED
|
@@ -165,9 +165,21 @@ async function loadMCPServers(ctx: LoadContext): Promise<LoadResult<MCPServer>>
|
|
|
165
165
|
timeout = undefined;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
// Validate autoload: boolean only, warn on other types
|
|
169
|
+
let autoload: boolean | undefined;
|
|
170
|
+
if (serverConfig.autoload === undefined || serverConfig.autoload === null) {
|
|
171
|
+
autoload = undefined;
|
|
172
|
+
} else if (typeof serverConfig.autoload === "boolean") {
|
|
173
|
+
autoload = serverConfig.autoload;
|
|
174
|
+
} else {
|
|
175
|
+
logger.warn(`MCP server "${serverName}": invalid autoload type ${typeof serverConfig.autoload}, ignoring`);
|
|
176
|
+
autoload = undefined;
|
|
177
|
+
}
|
|
178
|
+
|
|
168
179
|
result.push({
|
|
169
180
|
name: serverName,
|
|
170
181
|
enabled,
|
|
182
|
+
autoload,
|
|
171
183
|
timeout,
|
|
172
184
|
command: serverConfig.command as string | undefined,
|
|
173
185
|
args: serverConfig.args as string[] | undefined,
|
package/src/discovery/cursor.ts
CHANGED
|
@@ -9,99 +9,28 @@
|
|
|
9
9
|
* - Project: .cursor/ (cwd only)
|
|
10
10
|
*
|
|
11
11
|
* Capabilities:
|
|
12
|
-
* - mcps: From mcp.json with mcpServers key
|
|
13
12
|
* - rules: From rules/*.mdc files with MDC frontmatter (description, globs, alwaysApply)
|
|
14
13
|
* - settings: From settings.json if present
|
|
14
|
+
*
|
|
15
|
+
* MCP servers are intentionally NOT inherited live from Cursor config: SKC owns
|
|
16
|
+
* MCP runtime execution. Use `skc mcp import cursor` to copy definitions into
|
|
17
|
+
* SKC's own mcp.json instead.
|
|
15
18
|
*/
|
|
16
19
|
|
|
17
20
|
import { tryParseJson } from "@sayknow-cli/utils";
|
|
18
21
|
import { registerProvider } from "../capability";
|
|
19
22
|
import { readFile } from "../capability/fs";
|
|
20
|
-
import { type MCPServer, mcpCapability } from "../capability/mcp";
|
|
21
23
|
import type { Rule } from "../capability/rule";
|
|
22
24
|
import { ruleCapability } from "../capability/rule";
|
|
23
25
|
import type { Settings } from "../capability/settings";
|
|
24
26
|
import { settingsCapability } from "../capability/settings";
|
|
25
27
|
import type { LoadContext, LoadResult, SourceMeta } from "../capability/types";
|
|
26
|
-
import {
|
|
27
|
-
buildRuleFromMarkdown,
|
|
28
|
-
createSourceMeta,
|
|
29
|
-
expandEnvVarsDeep,
|
|
30
|
-
getProjectPath,
|
|
31
|
-
getUserPath,
|
|
32
|
-
loadFilesFromDir,
|
|
33
|
-
} from "./helpers";
|
|
28
|
+
import { buildRuleFromMarkdown, createSourceMeta, getProjectPath, getUserPath, loadFilesFromDir } from "./helpers";
|
|
34
29
|
|
|
35
30
|
const PROVIDER_ID = "cursor";
|
|
36
31
|
const DISPLAY_NAME = "Cursor";
|
|
37
32
|
const PRIORITY = 50;
|
|
38
33
|
|
|
39
|
-
// =============================================================================
|
|
40
|
-
// MCP Servers
|
|
41
|
-
// =============================================================================
|
|
42
|
-
|
|
43
|
-
function parseMCPServers(
|
|
44
|
-
content: string,
|
|
45
|
-
path: string,
|
|
46
|
-
level: "user" | "project",
|
|
47
|
-
): { items: MCPServer[]; warning?: string } {
|
|
48
|
-
const items: MCPServer[] = [];
|
|
49
|
-
|
|
50
|
-
const parsed = tryParseJson<{ mcpServers?: Record<string, unknown> }>(content);
|
|
51
|
-
if (!parsed?.mcpServers) {
|
|
52
|
-
return { items, warning: `${path}: missing or invalid 'mcpServers' key` };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const servers = expandEnvVarsDeep(parsed.mcpServers);
|
|
56
|
-
for (const [name, config] of Object.entries(servers)) {
|
|
57
|
-
const serverConfig = config as Record<string, unknown>;
|
|
58
|
-
items.push({
|
|
59
|
-
name,
|
|
60
|
-
command: serverConfig.command as string | undefined,
|
|
61
|
-
args: serverConfig.args as string[] | undefined,
|
|
62
|
-
env: serverConfig.env as Record<string, string> | undefined,
|
|
63
|
-
url: serverConfig.url as string | undefined,
|
|
64
|
-
headers: serverConfig.headers as Record<string, string> | undefined,
|
|
65
|
-
transport: ["stdio", "sse", "http"].includes(serverConfig.type as string)
|
|
66
|
-
? (serverConfig.type as "stdio" | "sse" | "http")
|
|
67
|
-
: undefined,
|
|
68
|
-
timeout: typeof serverConfig.timeout === "number" ? serverConfig.timeout : undefined,
|
|
69
|
-
_source: createSourceMeta(PROVIDER_ID, path, level),
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return { items };
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async function loadMCPServers(ctx: LoadContext): Promise<LoadResult<MCPServer>> {
|
|
77
|
-
const items: MCPServer[] = [];
|
|
78
|
-
const warnings: string[] = [];
|
|
79
|
-
|
|
80
|
-
const userPath = getUserPath(ctx, "cursor", "mcp.json");
|
|
81
|
-
|
|
82
|
-
const [userContent, projectPath] = await Promise.all([
|
|
83
|
-
userPath ? readFile(userPath) : Promise.resolve(null),
|
|
84
|
-
getProjectPath(ctx, "cursor", "mcp.json"),
|
|
85
|
-
]);
|
|
86
|
-
|
|
87
|
-
const projectContentPromise = projectPath ? readFile(projectPath) : Promise.resolve(null);
|
|
88
|
-
|
|
89
|
-
if (userContent && userPath) {
|
|
90
|
-
const result = parseMCPServers(userContent, userPath, "user");
|
|
91
|
-
items.push(...result.items);
|
|
92
|
-
if (result.warning) warnings.push(result.warning);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const projectContent = await projectContentPromise;
|
|
96
|
-
if (projectContent && projectPath) {
|
|
97
|
-
const result = parseMCPServers(projectContent, projectPath, "project");
|
|
98
|
-
items.push(...result.items);
|
|
99
|
-
if (result.warning) warnings.push(result.warning);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return { items, warnings };
|
|
103
|
-
}
|
|
104
|
-
|
|
105
34
|
// =============================================================================
|
|
106
35
|
// Rules
|
|
107
36
|
// =============================================================================
|
|
@@ -195,14 +124,6 @@ async function loadSettings(ctx: LoadContext): Promise<LoadResult<Settings>> {
|
|
|
195
124
|
// Provider Registration
|
|
196
125
|
// =============================================================================
|
|
197
126
|
|
|
198
|
-
registerProvider(mcpCapability.id, {
|
|
199
|
-
id: PROVIDER_ID,
|
|
200
|
-
displayName: DISPLAY_NAME,
|
|
201
|
-
description: "Load MCP servers from ~/.cursor/mcp.json and .cursor/mcp.json",
|
|
202
|
-
priority: PRIORITY,
|
|
203
|
-
load: loadMCPServers,
|
|
204
|
-
});
|
|
205
|
-
|
|
206
127
|
registerProvider(ruleCapability.id, {
|
|
207
128
|
id: PROVIDER_ID,
|
|
208
129
|
displayName: DISPLAY_NAME,
|