kiokuko-dsh 0.2.34 → 0.2.37
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/PERMISSIONS.md +22 -7
- package/README.ja.md +56 -23
- package/README.ko.md +55 -24
- package/README.md +54 -23
- package/README.zh-CN.md +55 -24
- package/dist/deep-thinker/abortable-stream.d.ts.map +1 -1
- package/dist/deep-thinker/abortable-stream.js +2 -0
- package/dist/deep-thinker/abortable-stream.js.map +1 -1
- package/dist/deep-thinker/core/contracts.d.ts +5 -5
- package/dist/deep-thinker/memory-finalizer.d.ts +1 -1
- package/dist/deep-thinker/store.d.ts +1 -1
- package/dist/dsh/agenticreplay-security.d.ts +1 -0
- package/dist/dsh/agenticreplay-security.d.ts.map +1 -1
- package/dist/dsh/agenticreplay-security.js +1 -1
- package/dist/dsh/agenticreplay-security.js.map +1 -1
- package/dist/dsh/auxiliary-recovery.d.ts +68 -0
- package/dist/dsh/auxiliary-recovery.d.ts.map +1 -0
- package/dist/dsh/auxiliary-recovery.js +218 -0
- package/dist/dsh/auxiliary-recovery.js.map +1 -0
- package/dist/dsh/boundary-worker.js +1 -0
- package/dist/dsh/boundary-worker.js.map +1 -1
- package/dist/dsh/coding-workflow/intent.d.ts.map +1 -1
- package/dist/dsh/coding-workflow/intent.js +2 -0
- package/dist/dsh/coding-workflow/intent.js.map +1 -1
- package/dist/dsh/config.d.ts +16 -2
- package/dist/dsh/config.d.ts.map +1 -1
- package/dist/dsh/core/host.d.ts +14 -0
- package/dist/dsh/core/host.d.ts.map +1 -1
- package/dist/dsh/core/host.js +20 -6
- package/dist/dsh/core/host.js.map +1 -1
- package/dist/dsh/core/index.d.ts +56 -2
- package/dist/dsh/core/index.d.ts.map +1 -1
- package/dist/dsh/core/tasks.d.ts +4 -0
- package/dist/dsh/core/tasks.d.ts.map +1 -1
- package/dist/dsh/core/tasks.js +9 -0
- package/dist/dsh/core/tasks.js.map +1 -1
- package/dist/dsh/core-runtime.d.ts +2 -0
- package/dist/dsh/core-runtime.d.ts.map +1 -1
- package/dist/dsh/core-runtime.js +4 -0
- package/dist/dsh/core-runtime.js.map +1 -1
- package/dist/dsh/decisions/config.d.ts +29 -0
- package/dist/dsh/decisions/config.d.ts.map +1 -1
- package/dist/dsh/decisions/config.js +13 -2
- package/dist/dsh/decisions/config.js.map +1 -1
- package/dist/dsh/decisions/diagnostics.d.ts +30 -8
- package/dist/dsh/decisions/diagnostics.d.ts.map +1 -1
- package/dist/dsh/decisions/diagnostics.js +2 -1
- package/dist/dsh/decisions/diagnostics.js.map +1 -1
- package/dist/dsh/decisions/host.d.ts.map +1 -1
- package/dist/dsh/decisions/host.js +25 -6
- package/dist/dsh/decisions/host.js.map +1 -1
- package/dist/dsh/decisions/intent-assessment.d.ts +3 -1
- package/dist/dsh/decisions/intent-assessment.d.ts.map +1 -1
- package/dist/dsh/decisions/intent-assessment.js +1 -1
- package/dist/dsh/decisions/intent-assessment.js.map +1 -1
- package/dist/dsh/decisions/openai.d.ts +27 -0
- package/dist/dsh/decisions/openai.d.ts.map +1 -0
- package/dist/dsh/decisions/openai.js +107 -0
- package/dist/dsh/decisions/openai.js.map +1 -0
- package/dist/dsh/decisions/providers.d.ts +10 -1
- package/dist/dsh/decisions/providers.d.ts.map +1 -1
- package/dist/dsh/decisions/providers.js +2 -2
- package/dist/dsh/decisions/providers.js.map +1 -1
- package/dist/dsh/decisions/request-intent.d.ts +1 -1
- package/dist/dsh/decisions/service.d.ts +12 -1
- package/dist/dsh/decisions/service.d.ts.map +1 -1
- package/dist/dsh/decisions/service.js +63 -14
- package/dist/dsh/decisions/service.js.map +1 -1
- package/dist/dsh/execution-selection.d.ts +5 -5
- package/dist/dsh/host-adapter/routing.d.ts.map +1 -1
- package/dist/dsh/host-adapter/routing.js +8 -3
- package/dist/dsh/host-adapter/routing.js.map +1 -1
- package/dist/dsh/host-adapter/session-access.d.ts +2 -0
- package/dist/dsh/host-adapter/session-access.d.ts.map +1 -1
- package/dist/dsh/host-adapter/session-access.js +2 -0
- package/dist/dsh/host-adapter/session-access.js.map +1 -1
- package/dist/dsh/host-adapter.d.ts.map +1 -1
- package/dist/dsh/host-adapter.js +11 -3
- package/dist/dsh/host-adapter.js.map +1 -1
- package/dist/dsh/index.d.ts +32 -6
- package/dist/dsh/index.d.ts.map +1 -1
- package/dist/dsh/lisp/code-intelligence-contracts.js +2 -2
- package/dist/dsh/lisp/coding-choice.d.ts +7 -0
- package/dist/dsh/lisp/coding-choice.d.ts.map +1 -1
- package/dist/dsh/lisp/coding-choice.js +2 -0
- package/dist/dsh/lisp/coding-choice.js.map +1 -1
- package/dist/dsh/lisp/coding-preparation.d.ts +6 -1
- package/dist/dsh/lisp/coding-preparation.d.ts.map +1 -1
- package/dist/dsh/lisp/coding-preparation.js +40 -3
- package/dist/dsh/lisp/coding-preparation.js.map +1 -1
- package/dist/dsh/lisp/manager.d.ts +2 -0
- package/dist/dsh/lisp/manager.d.ts.map +1 -1
- package/dist/dsh/lisp/manager.js +74 -14
- package/dist/dsh/lisp/manager.js.map +1 -1
- package/dist/dsh/lisp/store.d.ts.map +1 -1
- package/dist/dsh/lisp/store.js +6 -10
- package/dist/dsh/lisp/store.js.map +1 -1
- package/dist/dsh/lisp/surface.d.ts.map +1 -1
- package/dist/dsh/lisp/surface.js +3 -2
- package/dist/dsh/lisp/surface.js.map +1 -1
- package/dist/dsh/lisp/worker.d.ts +4 -1
- package/dist/dsh/lisp/worker.d.ts.map +1 -1
- package/dist/dsh/lisp/worker.js +56 -6
- package/dist/dsh/lisp/worker.js.map +1 -1
- package/dist/dsh/lisp-config.js +1 -1
- package/dist/dsh/lisp-config.js.map +1 -1
- package/dist/dsh/managed-file-deployment.d.ts.map +1 -1
- package/dist/dsh/managed-file-deployment.js +3 -1
- package/dist/dsh/managed-file-deployment.js.map +1 -1
- package/dist/dsh/model-auto/coordinator.js +1 -1
- package/dist/dsh/model-auto/coordinator.js.map +1 -1
- package/dist/dsh/model-configuration.d.ts +6 -6
- package/dist/dsh/modules/enno.d.ts +1 -1
- package/dist/dsh/on-demand-intake.d.ts +15 -2
- package/dist/dsh/on-demand-intake.d.ts.map +1 -1
- package/dist/dsh/on-demand-intake.js +130 -9
- package/dist/dsh/on-demand-intake.js.map +1 -1
- package/dist/dsh/session-export-analysis.d.ts +20 -0
- package/dist/dsh/session-export-analysis.d.ts.map +1 -0
- package/dist/dsh/session-export-analysis.js +90 -0
- package/dist/dsh/session-export-analysis.js.map +1 -0
- package/dist/dsh/session-log-export.d.ts +1 -0
- package/dist/dsh/session-log-export.d.ts.map +1 -1
- package/dist/dsh/session-log-export.js +19 -3
- package/dist/dsh/session-log-export.js.map +1 -1
- package/dist/dsh/session-log-mirror.d.ts +1 -1
- package/dist/dsh/session-log-mirror.d.ts.map +1 -1
- package/dist/dsh/session-log-mirror.js +5 -2
- package/dist/dsh/session-log-mirror.js.map +1 -1
- package/dist/dsh/setup.d.ts +22 -0
- package/dist/dsh/setup.d.ts.map +1 -1
- package/dist/dsh/setup.js +50 -4
- package/dist/dsh/setup.js.map +1 -1
- package/dist/dsh/skill-prompts.json +1 -1
- package/dist/dsh/standard-skill-deployment.d.ts +12 -1
- package/dist/dsh/standard-skill-deployment.d.ts.map +1 -1
- package/dist/dsh/standard-skill-deployment.js +76 -4
- package/dist/dsh/standard-skill-deployment.js.map +1 -1
- package/dist/dsh/task-startup.d.ts +24 -0
- package/dist/dsh/task-startup.d.ts.map +1 -0
- package/dist/dsh/task-startup.js +126 -0
- package/dist/dsh/task-startup.js.map +1 -0
- package/dist/dsh/tool-exposure-config.d.ts +1 -1
- package/dist/locale/en.json +1 -1
- package/dist/locale/ja.json +1 -1
- package/dist/locale/ko.json +1 -1
- package/dist/locale/zh-CN.json +1 -1
- package/dist/memory/lifecycle.d.ts +1 -1
- package/docs/README.ja.md +1 -0
- package/docs/README.md +1 -0
- package/docs/dsh-plugin.md +42 -14
- package/docs/getting-started.ja.md +2 -0
- package/docs/getting-started.md +2 -0
- package/docs/lisp-hot-tools.md +7 -4
- package/docs/lisp.md +19 -5
- package/docs/model-selection.ja.md +2 -2
- package/docs/model-selection.md +2 -2
- package/docs/store-evidence.md +6 -0
- package/docs/typed-decisions.md +103 -2
- package/docs/typesafe.md +8 -3
- package/docs/verification.md +28 -3
- package/lisp/process-identity.d.mts +2 -0
- package/lisp/process-identity.mjs +34 -0
- package/lisp/repository-owner.d.mts +1 -0
- package/lisp/repository-owner.mjs +58 -0
- package/lisp/supervisor.mjs +19 -2
- package/lisp/tools.lisp +17 -5
- package/migrations/050_auxiliary_recovery.sql +11 -0
- package/package.json +6 -4
- package/scripts/prepare-build.mjs +13 -0
- package/scripts/setup-dsh.mjs +8 -3
- package/skills/kiokuko-lisp/SKILL.md +5 -3
|
@@ -14,7 +14,7 @@ DSHの権限判定、必要な検証を維持し、役小角の契約・WorkUnit
|
|
|
14
14
|
|
|
15
15
|
Webプロファイルでは [Kiokuko Models](kiokuko-models.md) から接続を設定できます。DSH本体のModelsで設定する必要はありません。登録したモデルは、通常会話・Enno・Deepでネイティブ接続と併用できます。
|
|
16
16
|
|
|
17
|
-
通常版・modular coreとも `modelAutoMode.mode: off` が既定です。同じDSHプロファイルでKiokuko Modelsまたはdsh-codexからCodexを認証し、Jev
|
|
17
|
+
通常版・modular coreとも `modelAutoMode.mode: off` が既定です。同じDSHプロファイルでKiokuko Modelsまたはdsh-codexからCodexを認証し、Jev・Laya・[OpenAI](typed-decisions.md#openai-credentials)のいずれかの判定を準備したうえで、まず `observe` で選択案を確認します。
|
|
18
18
|
|
|
19
19
|
```yaml
|
|
20
20
|
modelAutoMode:
|
|
@@ -34,7 +34,7 @@ modelAutoMode:
|
|
|
34
34
|
|
|
35
35
|
初期候補は `gpt-6-luna` の low・medium・high と `gpt-6-sol` の high です。`modelAutoMode.routes` には最大4件、`id`(`luna-low`、`luna-medium`、`luna-high`、`sol-high`)と `binding`(`provider`、`model`、`reasoningEffort`)を指定できます。IDは経路のラベルなので、登録済みのAstraなども正確なbindingで割り当てられます。候補はCodex由来とResponses方式を確認でき、現在のモデル一覧、文脈容量・入力形式・推論強度、要求設定の検証、token meterを通った接続に限定します。ネイティブの `openai-codex` とKiokuko所有のCodex接続が対象です。名前だけを似せた接続やOpenAI API接続は対象外です。有効なbindingが2件未満なら判定しません。
|
|
36
36
|
|
|
37
|
-
新しい受付済みの通常タスクでは、現在の依頼文、タスク種別、添付の種類、経路IDと判定基準を選択中のJev
|
|
37
|
+
新しい受付済みの通常タスクでは、現在の依頼文、タスク種別、添付の種類、経路IDと判定基準を選択中のJev・Laya・OpenAIへ送ります。この判定のために添付の内容、全履歴、リポジトリ全体は送信しません。Choice 1問の結果をrunに保存し、継続では同じ経路を使います。再起動時に判定結果が不明なら再送せず元のモデルを維持します。`observe`、棄権、probe失敗、metadata不足、非対応effort、timeout、入力超過でも元のモデルを維持します。取消、セッション同一性の不一致、保存の整合性エラーでは要求を止めます。認証・利用枠・モデル利用不可によるdispatch失敗を別モデルへ自動再送しません。
|
|
38
38
|
|
|
39
39
|
状態表示では、設定・準備状態・選択案・適用したbindingと、nativeの `request/header` で確認した実モデルを区別します。初期候補は判定基準であり、品質・時間・利用枠の改善を保証しません。Enno、Deep、子、雑談、回答の再検討、保護されたLisp実行は既存の経路を使います。実装失敗後の自動昇格は初期版に含めません。
|
|
40
40
|
|
package/docs/model-selection.md
CHANGED
|
@@ -15,7 +15,7 @@ plan approval or automatic Enno continuation.
|
|
|
15
15
|
|
|
16
16
|
In Web profiles, [Kiokuko Models](kiokuko-models.md) manages connections without requiring DSH's Models settings. Its registered models are available to ordinary chat, Enno and Deep alongside native connections.
|
|
17
17
|
|
|
18
|
-
`modelAutoMode` is off by default in both the full plugin and modular core. To try it, authenticate Codex through Kiokuko Models or dsh-codex in the same DSH profile, configure a Jev or
|
|
18
|
+
`modelAutoMode` is off by default in both the full plugin and modular core. To try it, authenticate Codex through Kiokuko Models or dsh-codex in the same DSH profile, configure a Jev, Laya or [OpenAI typed-decision backend](typed-decisions.md#openai-credentials), then use `observe` before enabling automatic routing:
|
|
19
19
|
|
|
20
20
|
```yaml
|
|
21
21
|
modelAutoMode:
|
|
@@ -35,7 +35,7 @@ The command changes only the current native session. `on` also clears its manual
|
|
|
35
35
|
|
|
36
36
|
The initial preset offers `gpt-6-luna` at low, medium and high effort, plus `gpt-6-sol` at high effort. Up to four exact route bindings can be configured under `modelAutoMode.routes`; each has an `id` from `luna-low`, `luna-medium`, `luna-high`, `sol-high`, and a `binding` with `provider`, `model`, and `reasoningEffort`. These are route labels, so a registered Astra or other GPT model may be assigned explicitly. No new model ID is guessed or substituted. A candidate must have a validated Codex origin and Responses protocol, live model context and modality metadata, supported efforts, call-config validation and token meter. Both native `openai-codex` and Kiokuko-owned Codex routes qualify; an arbitrary provider name or OpenAI API connection does not. Fewer than two valid bindings skips classification.
|
|
37
37
|
|
|
38
|
-
For a new admitted normal task, Kiokuko sends the current task text, task type, attachment kinds, route IDs and rubric to the selected Jev or
|
|
38
|
+
For a new admitted normal task, Kiokuko sends the current task text, task type, attachment kinds, route IDs and rubric to the selected Jev, Laya or OpenAI backend. It does not send attachment bytes, full history or repository contents for this classification. One Choice result selects a route or abstains. The route is stored against the exact run and reused for continuations; an unknown in-flight decision after restart is retained without another classifier call. `observe` records a proposal but keeps the current model. A failed probe, missing metadata, unsupported effort, timeout, oversized input or abstention also keeps the current model. Cancellation, stale session identity and storage integrity failures stop the request. Dispatch authentication, quota and unavailable-model errors remain ordinary failures; no alternate model is retried automatically.
|
|
39
39
|
|
|
40
40
|
The status distinguishes the configured mode, readiness, proposal and selected binding from the model observed in a native `request/header`. The initial preset is a rubric, not a claim that it improves quality, elapsed time or subscription usage. Enno, Deep, children, chat, review continuation and protected Lisp execution retain their existing owners. Automatic escalation after a failed implementation pass is not enabled.
|
|
41
41
|
|
package/docs/store-evidence.md
CHANGED
|
@@ -17,6 +17,12 @@ permissions, and disposable-profile result independently.
|
|
|
17
17
|
| npm lifecycle | `prepare: npm run build` |
|
|
18
18
|
| Automatic size policy | intentionally exceeded; manual `user-reviewed` track |
|
|
19
19
|
|
|
20
|
+
This table records the **0.1.3 review snapshot**, including its original lifecycle
|
|
21
|
+
command; it is not the current package's release evidence. Current source uses
|
|
22
|
+
`prepare: node scripts/prepare-build.mjs` with normal builds and an explicit CI-only
|
|
23
|
+
deferral. See [current lifecycle and permissions](../PERMISSIONS.md#installation-lifecycle)
|
|
24
|
+
and [CI build ownership](verification.md#consolidated-duplicate-invocations).
|
|
25
|
+
|
|
20
26
|
The Commit field is filled only after the user commits and pushes the verified
|
|
21
27
|
working tree. The catalog must point to that full immutable Commit, not a branch
|
|
22
28
|
name or moving tag.
|
package/docs/typed-decisions.md
CHANGED
|
@@ -23,7 +23,7 @@ excerpted or rewritten, and classification grants no execution permission.
|
|
|
23
23
|
The common API also accepts explicit `noul` (yes probability) and `score`
|
|
24
24
|
(ordered rubric) questions. Their validated answers have `status: "measured"`;
|
|
25
25
|
they grant no permission. The existing Choice request and answer shapes remain
|
|
26
|
-
valid. TypeSafe can evaluate all three question types in one batch. Nimble and
|
|
26
|
+
valid. TypeSafe and OpenAI can evaluate all three question types in one batch. Nimble and
|
|
27
27
|
Laya accept Choice only and return `DECISION_UNSUPPORTED` before inference for
|
|
28
28
|
other kinds. The separate Lisp `kioku.typesafe:evaluate` API retains its own
|
|
29
29
|
wire contract.
|
|
@@ -33,6 +33,7 @@ Switch backends in DSH without a restart:
|
|
|
33
33
|
```text
|
|
34
34
|
/kioku-decisions use jev
|
|
35
35
|
/kioku-decisions use laya
|
|
36
|
+
/kioku-decisions use openai
|
|
36
37
|
/kioku-decisions use nimble
|
|
37
38
|
/kioku-decisions use default
|
|
38
39
|
```
|
|
@@ -48,8 +49,107 @@ base configuration. A stale host cannot overwrite a selection saved by another
|
|
|
48
49
|
host; restart it to load the latest choice. Changing the base configuration uses
|
|
49
50
|
that configuration's selection, with the YAML provider as the default.
|
|
50
51
|
|
|
52
|
+
<a id="openai-credentials"></a>
|
|
53
|
+
## OpenAI credentials
|
|
54
|
+
|
|
55
|
+
Jev remains the default; OpenAI, local Laya and Nimble are alternatives. OpenAI uses the official [Decisions API](https://developers.openai.com/api/docs/guides/decisions), `POST /v1/decisions`, with `gpt-6-luna` as this checkout's default decision model. This is separate from the main chat model: ChatGPT/Codex OAuth login does not supply `OPENAI_API_KEY`, and a TypeSafe/Jev key cannot replace it.
|
|
56
|
+
|
|
57
|
+
These instructions describe the current source. They do not assert that the published npm `latest` already includes OpenAI support. If `use openai` is unavailable, check the installed build's command support first.
|
|
58
|
+
|
|
59
|
+
1. Create an API key for your OpenAI API project and add it to the credential store used by the running DSH. With the standard `credentials-local` provider, choose the path as follows:
|
|
60
|
+
|
|
61
|
+
| Configuration | Credential file |
|
|
62
|
+
|---|---|
|
|
63
|
+
| Default harness home | `~/.dsh/.credentials.yaml` |
|
|
64
|
+
| Custom `DSH_HOME` | `$DSH_HOME/.credentials.yaml` |
|
|
65
|
+
| Explicit `credentials.path` (the provider's `config.path`) | The configured path, overriding the home default |
|
|
66
|
+
|
|
67
|
+
`--profile web` keeps profile packages and patches under `$DSH_HOME/profiles/web`; it does **not** by itself move credentials there. A profile can override `credentials.path`, or its launcher can use another `DSH_HOME`. Use that effective file, not a guessed `profiles/web/.credentials.yaml`.
|
|
68
|
+
|
|
69
|
+
2. In an existing file, add only `OPENAI_API_KEY` under `refs` and preserve all other `refs` and `records`. This is a minimal **new-file example**, with a nonfunctional placeholder:
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
version: 1
|
|
73
|
+
refs:
|
|
74
|
+
OPENAI_API_KEY: "OPENAI_API_KEY_EXAMPLE_ONLY"
|
|
75
|
+
records: {}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Replace the placeholder privately with your key. On macOS/Linux, protect the actual file; for the default path:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
chmod 600 "$HOME/.dsh/.credentials.yaml"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Use your configured path instead when it differs. The default `watch: true` reloads valid file edits automatically for subsequent requests; restarting DSH is unnecessary. Do not paste keys into chat, screenshots or Git.
|
|
85
|
+
|
|
86
|
+
3. In DSH's command input, select OpenAI and inspect the result:
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
/kioku-decisions use openai
|
|
90
|
+
/kioku-decisions status
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`use openai` makes a real API probe, which may incur usage charges. Only a successful probe and save persist the choice for this project and new requests; failure or cancellation keeps the prior choice. Existing requests keep their binding. `status` makes no inference call. Optional `/kioku-decisions probe` makes another real probe.
|
|
94
|
+
|
|
95
|
+
The standard provider resolves **saved file > launch environment > project `.env` > harness-home `.env`**. Environment variables still work when the credentials service is present, unless a saved value overrides them. For an environment-only setup, export the key **before** launching DSH from that shell:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
export OPENAI_API_KEY='OPENAI_API_KEY_EXAMPLE_ONLY'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This is a placeholder, not a usable key. An export in another shell after DSH has started does not update its launch snapshot; use the watched file to update an already running instance. Keep credential-bearing `.env` files out of Git.
|
|
102
|
+
|
|
103
|
+
## Provider configuration
|
|
104
|
+
|
|
51
105
|
Configure `typedDecisions` on the full plugin or modular core:
|
|
52
106
|
|
|
107
|
+
OpenAI uses the distinct official [Decisions API](https://developers.openai.com/api/docs/guides/decisions),
|
|
108
|
+
`POST https://api.openai.com/v1/decisions`, rather than Responses JSON output.
|
|
109
|
+
It maps Choice, Noul (predicate) and Score to the native API and validates ordered
|
|
110
|
+
named answers, distributions, rubric levels and individual refusals. The default
|
|
111
|
+
model is `gpt-6-luna`; probability ≥ 0.9 and margin ≥ 0.2 are required for Choice.
|
|
112
|
+
Kiokuko resolves `OPENAI_API_KEY` through `ctx.credentials.resolve` when the service
|
|
113
|
+
exists; the standard local provider includes the launch environment and `.env`
|
|
114
|
+
fallbacks described [above](#openai-credentials). Only a composition without that
|
|
115
|
+
service uses Kiokuko's direct `process.env` fallback. A different credential
|
|
116
|
+
provider may have different resolution rules. TypeSafe credentials are never substituted. No redirects,
|
|
117
|
+
automatic retries, or provider fallback are added. `use openai` probes before
|
|
118
|
+
persisting; missing credentials, failed probes and cancellation leave selection unchanged.
|
|
119
|
+
Existing Jev/Laya stored configuration digests retain their original shape.
|
|
120
|
+
Current token records retain input/output totals; cached-token breakdown is not recorded.
|
|
121
|
+
|
|
122
|
+
To select OpenAI in the plugin or core configuration instead of a project command:
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
typedDecisions:
|
|
126
|
+
mode: auto
|
|
127
|
+
provider: openai
|
|
128
|
+
openai:
|
|
129
|
+
model: gpt-6-luna
|
|
130
|
+
timeoutMs: 5000
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Keep keys in the credential store, not in `typedDecisions`. A configured provider
|
|
134
|
+
is not evidence of a successful API call; use the command probe to verify access.
|
|
135
|
+
|
|
136
|
+
The normal startup card offers the four decision/Lisp ON/OFF combinations and Cancel
|
|
137
|
+
in one question before model tool assembly. It uses the currently selected backend,
|
|
138
|
+
shown in the card; selection does not prove authentication or successful inference.
|
|
139
|
+
Immutable existing decision bindings also retain the task choice, without granting
|
|
140
|
+
tool or file authority. The same request and explicit continuation reuse the choice;
|
|
141
|
+
an unrelated new request asks again. Cancel/Skip starts no task. Headless operation
|
|
142
|
+
keeps the configured decision mode and explicit manual Lisp preference; an explicit
|
|
143
|
+
`typedDecisions.startup: { decision: true, lisp: true }` config selects both.
|
|
144
|
+
Runtime failures retain the choice and permit explicit recovery without a new question.
|
|
145
|
+
|
|
146
|
+
Semantic-comparison diagnostics retain only the known criterion names
|
|
147
|
+
(`action`, `reference`, `constraints`, `latest-answer`) and finite verdicts, with
|
|
148
|
+
backend, elapsed time, gate outcome and existing request/decision correlation.
|
|
149
|
+
They contain no source text, credentials or private reasoning. `providerDispatched`
|
|
150
|
+
means the provider adapter was invoked; it does not prove a successful HTTP exchange.
|
|
151
|
+
These diagnostic fields never change acceptance or native permissions.
|
|
152
|
+
|
|
53
153
|
```yaml
|
|
54
154
|
typedDecisions:
|
|
55
155
|
mode: auto
|
|
@@ -99,7 +199,8 @@ A live comparison requires explicit
|
|
|
99
199
|
`TYPESAFE_API_KEY`; it sends only the checked-in synthetic fixture and must not
|
|
100
200
|
be interpreted as a production accuracy estimate.
|
|
101
201
|
|
|
102
|
-
|
|
202
|
+
The following commands manage only the TypeSafe/Jev key; for OpenAI, use the
|
|
203
|
+
[credential-file setup](#openai-credentials). Set the TypeSafe key through DSH, then inspect status:
|
|
103
204
|
|
|
104
205
|
```text
|
|
105
206
|
/kioku-typesafe-key <key>
|
package/docs/typesafe.md
CHANGED
|
@@ -31,9 +31,14 @@ not verified. Invoke the same command with a new key to replace it immediately.
|
|
|
31
31
|
|
|
32
32
|
The first command reports configuration, source and writability. Clear removes
|
|
33
33
|
the stored key and reports any remaining source. DSH resolves `TYPESAFE_API_KEY`
|
|
34
|
-
for each call.
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
for each call. With the standard credentials-local provider, the saved file wins,
|
|
35
|
+
then the launch environment, project `.env` and harness-home `.env`. Saving writes
|
|
36
|
+
the higher-priority file even when an environment fallback exists. Default file
|
|
37
|
+
watching applies valid edits without a restart; an environment-only change must
|
|
38
|
+
be present when DSH is launched. Preserve existing `refs` and `records`.
|
|
39
|
+
See [credential paths, permissions and precedence](typed-decisions.md#openai-credentials).
|
|
40
|
+
Those storage rules also apply to `TYPESAFE_API_KEY`, but `/kioku-typesafe-key`
|
|
41
|
+
does not set `OPENAI_API_KEY`; ChatGPT/Codex OAuth is separate from both keys.
|
|
37
42
|
With no credential provider, evaluation can use the host's `TYPESAFE_API_KEY`,
|
|
38
43
|
but save/clear return `TYPESAFE_STORAGE_UNAVAILABLE`. Kiokuko creates no separate
|
|
39
44
|
credential file and never supplies the key to workers or their subprocesses.
|
package/docs/verification.md
CHANGED
|
@@ -15,9 +15,19 @@ Native fixture preparation is deferred until a selected, executable check declar
|
|
|
15
15
|
root dependencies (`npm ci`), not the DSH runtime fixture. Missing or invalid native
|
|
16
16
|
fixtures remain `prerequisite-missing` for checks that require them.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
CI schedules **Linux x64** and **macOS ARM64**. Full selection has 21 jobs:
|
|
19
|
+
selection, two native micro-judge builds, 17 verification lanes and the aggregate.
|
|
20
|
+
Linux ARM64 is not scheduled or claimed as CI coverage. Its runtime/build support
|
|
21
|
+
remains in the native target registry; this workflow does not produce its binary.
|
|
22
|
+
|
|
23
|
+
The required `verify` aggregate consumes `select`, `micro-judge-native` and `checks`.
|
|
24
|
+
Every selected lane and native artifact must be present, successful, fresh and
|
|
25
|
+
bound to the same selected plan and source. Failure, cancellation, a missing
|
|
26
|
+
selected report, an extra target or an altered artifact fails acceptance. Only
|
|
27
|
+
prose-only selection can legitimately skip both executable job groups. The
|
|
28
|
+
remaining Linux x64/macOS ARM64 check inventories and their deadlines are unchanged.
|
|
29
|
+
The CI review bundle contains exactly its selected targets; standalone native
|
|
30
|
+
bundle verification still requires the complete supported-target inventory.
|
|
21
31
|
|
|
22
32
|
Output defaults to a fresh OS temporary directory. Supply an empty directory
|
|
23
33
|
outside the repository with `--output`. `plan.json`, per-command logs, official
|
|
@@ -80,6 +90,21 @@ arbitrary stdout or a successful no-op process is insufficient.
|
|
|
80
90
|
|
|
81
91
|
## Consolidated duplicate invocations
|
|
82
92
|
|
|
93
|
+
Selected CI dependency installs set `KIOKUKO_CI_DEFER_PREPARE=1` only on the root
|
|
94
|
+
`npm ci` step. With `CI=true`, this defers this package's `prepare` build to the
|
|
95
|
+
verifier's required clean build; it does not disable dependency lifecycle scripts.
|
|
96
|
+
Ordinary npm/pnpm preparation still builds, including in CI without this explicit
|
|
97
|
+
flag, and build failure remains a failed prepare. The verifier's source/build
|
|
98
|
+
digests, packed-artifact receipts and stale-source rejection remain mandatory.
|
|
99
|
+
|
|
100
|
+
For full coverage, Linux ARM64 removal changes the planned job count from 27 to
|
|
101
|
+
21 and official DSH fixture builds from 19 to 15. Deferring prepare removes one
|
|
102
|
+
redundant plugin build in each of the remaining 17 verification lanes. This is an
|
|
103
|
+
execution-plan comparison, not a measured hosted-CI duration improvement. Official
|
|
104
|
+
DSH still builds separately for each selected fixture lane; no OS/architecture,
|
|
105
|
+
Node/ABI or native dependency is reused across platforms.
|
|
106
|
+
|
|
107
|
+
|
|
83
108
|
- `skill-prompts` is covered by `native-unit`: `tests/dsh/unit/skill-compiler.test.ts`, `tests/dsh/unit/skill-snapshot.test.ts`.
|
|
84
109
|
- `index-reasoning` is covered by `native-integration`: `tests/dsh/integration/index-reasoning.test.ts`, `tests/dsh/integration/index-reasoning-native.test.ts`, `tests/dsh/integration/index-reasoning-evaluation.test.ts`.
|
|
85
110
|
- `index-evaluation` is covered by `native-integration`: `tests/dsh/integration/index-reasoning-evaluation.test.ts`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { execFileSync } from 'node:child_process'
|
|
3
|
+
import { createHash } from 'node:crypto'
|
|
4
|
+
|
|
5
|
+
/** OS birth identity, not PID liveness alone. Unavailable identity stays conservative. */
|
|
6
|
+
export function processIdentity(pid) {
|
|
7
|
+
if (!Number.isSafeInteger(pid) || pid < 1) throw new Error('INVALID_PROCESS_ID')
|
|
8
|
+
try {
|
|
9
|
+
let birth
|
|
10
|
+
if (process.platform === 'linux') {
|
|
11
|
+
const stat=readFileSync(`/proc/${pid}/stat`,'utf8')
|
|
12
|
+
birth=[readFileSync('/proc/sys/kernel/random/boot_id','utf8').trim(),stat.slice(stat.lastIndexOf(')')+2).split(' ')[19]]
|
|
13
|
+
if(!/^\d+$/.test(birth[1]??''))throw new Error('INVALID_PROCESS_IDENTITY')
|
|
14
|
+
} else if(process.platform === 'darwin') {
|
|
15
|
+
const started=execFileSync('/bin/ps',['-p',String(pid),'-o','lstart='],{encoding:'utf8',timeout:1000,stdio:['ignore','pipe','ignore'],env:{...process.env,LC_ALL:'C',TZ:'UTC'}}).trim()
|
|
16
|
+
if(!started)return undefined
|
|
17
|
+
birth=[started]
|
|
18
|
+
} else return undefined
|
|
19
|
+
return createHash('sha256').update(JSON.stringify([process.platform,pid,...birth])).digest('hex')
|
|
20
|
+
} catch(error) {
|
|
21
|
+
if(['ENOENT','ESRCH'].includes(error.code)||error.status===1)return undefined
|
|
22
|
+
throw error
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function sameProcess(pid, identity) {
|
|
27
|
+
try { process.kill(pid,0) } catch(error) { if(error.code==='ESRCH')return false;throw error }
|
|
28
|
+
if(process.platform==='linux'){
|
|
29
|
+
try{const stat=readFileSync(`/proc/${pid}/stat`,'utf8');if(['Z','X'].includes(stat.slice(stat.lastIndexOf(')')+2).split(' ')[0]))return false}
|
|
30
|
+
catch(error){if(error.code==='ENOENT')return false;throw error}
|
|
31
|
+
}
|
|
32
|
+
const current=identity?processIdentity(pid):undefined
|
|
33
|
+
return !current || !identity || current===identity
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function claimRepository(root: string): { recordRuntime(pid: number): string | null; close(): void }
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// The existing supervisor holds this OS-backed SQLite lock until its runtime exits.
|
|
2
|
+
// The user directory is independent of DSH's DB, session and worker TMPDIR.
|
|
3
|
+
import { DatabaseSync } from 'node:sqlite'
|
|
4
|
+
import { createHash } from 'node:crypto'
|
|
5
|
+
import { lstatSync, mkdirSync, realpathSync, readFileSync, writeFileSync, renameSync, unlinkSync } from 'node:fs'
|
|
6
|
+
import { randomUUID } from 'node:crypto'
|
|
7
|
+
import { processIdentity, sameProcess } from './process-identity.mjs'
|
|
8
|
+
import { tmpdir } from 'node:os'
|
|
9
|
+
import { join } from 'node:path'
|
|
10
|
+
|
|
11
|
+
export function claimRepository(root) {
|
|
12
|
+
const canonical = realpathSync(root)
|
|
13
|
+
const directory = join(process.platform === 'win32' ? tmpdir() : '/tmp', `kiokuko-lisp-owners-${process.getuid?.() ?? 'user'}`)
|
|
14
|
+
mkdirSync(directory, { recursive: true, mode: 0o700 })
|
|
15
|
+
const info = lstatSync(directory)
|
|
16
|
+
if (!info.isDirectory() || info.isSymbolicLink() || (process.getuid && info.uid !== process.getuid()) || (info.mode & 0o077))
|
|
17
|
+
throw new Error('REPOSITORY_LOCK_DIRECTORY')
|
|
18
|
+
const path = join(directory, `${createHash('sha256').update(canonical).digest('hex')}.sqlite3`)
|
|
19
|
+
try { const file=lstatSync(path);if (!file.isFile() || file.isSymbolicLink()) throw new Error('REPOSITORY_LOCK_FILE') }
|
|
20
|
+
catch(error) { if(error.code !== 'ENOENT') throw error }
|
|
21
|
+
const db = new DatabaseSync(path)
|
|
22
|
+
const metadata=path+'.owner.json',token=randomUUID()
|
|
23
|
+
try {
|
|
24
|
+
// Opening a new SQLite file briefly takes reader locks in *both* contenders.
|
|
25
|
+
// A zero busy timeout can make both exclusive acquisitions fail before
|
|
26
|
+
// either owns the repository. Allow those short initialization reads to
|
|
27
|
+
// drain; an existing owner's lifetime transaction still rejects in 250ms.
|
|
28
|
+
db.exec('PRAGMA busy_timeout=250; BEGIN EXCLUSIVE; CREATE TABLE IF NOT EXISTS repository_owner(root TEXT NOT NULL)')
|
|
29
|
+
try {
|
|
30
|
+
const owner=JSON.parse(readFileSync(metadata,'utf8'))
|
|
31
|
+
if(!Number.isSafeInteger(owner.pid)||owner.pid<1||owner.root!==canonical||typeof owner.token!=='string'
|
|
32
|
+
||owner.identity!==null&&!/^[a-f0-9]{64}$/.test(owner.identity))throw new Error('REPOSITORY_LOCK_METADATA')
|
|
33
|
+
// A supervisor killed before cleanup must not donate its still-live runtime.
|
|
34
|
+
if(sameProcess(owner.pid,owner.identity??undefined))throw new Error('REPOSITORY_IN_USE')
|
|
35
|
+
} catch(error) { if(error.code!=='ENOENT')throw error }
|
|
36
|
+
db.prepare('DELETE FROM repository_owner').run()
|
|
37
|
+
db.prepare('INSERT INTO repository_owner VALUES(?)').run(canonical)
|
|
38
|
+
let recorded=false
|
|
39
|
+
return {
|
|
40
|
+
recordRuntime(pid){
|
|
41
|
+
const temporary=metadata+'.'+token
|
|
42
|
+
const identity=processIdentity(pid)??null
|
|
43
|
+
writeFileSync(temporary,JSON.stringify({root:canonical,pid,identity,token})+'\n',{flag:'wx',mode:0o600})
|
|
44
|
+
renameSync(temporary,metadata);recorded=true
|
|
45
|
+
return identity
|
|
46
|
+
},
|
|
47
|
+
close(){
|
|
48
|
+
// Called only after runtime exit. A crash leaves evidence for the next owner.
|
|
49
|
+
if(recorded){const owner=JSON.parse(readFileSync(metadata,'utf8'));if(owner.token===token)unlinkSync(metadata)}
|
|
50
|
+
db.close()
|
|
51
|
+
},
|
|
52
|
+
} // Transaction stays uncommitted; the OS releases it when this supervisor dies.
|
|
53
|
+
} catch(error) {
|
|
54
|
+
db.close()
|
|
55
|
+
if(error.errcode === 5 || error.code === 'SQLITE_BUSY') throw new Error('REPOSITORY_IN_USE')
|
|
56
|
+
throw error
|
|
57
|
+
}
|
|
58
|
+
}
|
package/lisp/supervisor.mjs
CHANGED
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
// pipe. It stays outside the worker sandbox so arbitrary Lisp cannot disable it.
|
|
3
3
|
import { spawn } from 'node:child_process'
|
|
4
4
|
import { openSync, closeSync, writeSync } from 'node:fs'
|
|
5
|
+
import { claimRepository } from './repository-owner.mjs'
|
|
5
6
|
const launch = JSON.parse(process.argv[2])
|
|
7
|
+
let repositoryLease
|
|
8
|
+
if (launch.repositoryRoot) {
|
|
9
|
+
try { repositoryLease = claimRepository(launch.repositoryRoot) }
|
|
10
|
+
catch(error) {
|
|
11
|
+
writeSync(4, JSON.stringify({ type: 'error', code: error.message === 'REPOSITORY_IN_USE' ? 'REPOSITORY_IN_USE' : 'REPOSITORY_LOCK_FAILED' })+'\n')
|
|
12
|
+
process.exit(73)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
6
15
|
let child, closing = false, terminationSent = false
|
|
7
16
|
const kill = () => {
|
|
8
17
|
if (!child?.pid || terminationSent) return
|
|
@@ -28,10 +37,18 @@ child = spawn(launch.command, launch.args, { cwd: launch.cwd, env: launch.env, s
|
|
|
28
37
|
if (filter !== undefined) closeSync(filter)
|
|
29
38
|
// Stream one JSON object: older readers still consume the complete terminal
|
|
30
39
|
// object, while current readers observe the prefix only after actual spawn.
|
|
31
|
-
child.once('spawn',()=>{
|
|
40
|
+
child.once('spawn',()=>{
|
|
41
|
+
if(launch.repositoryRoot){
|
|
42
|
+
try{const identity=repositoryLease.recordRuntime(child.pid);writeSync(4,JSON.stringify({type:'runtime',pid:child.pid,identity})+'\n')}
|
|
43
|
+
catch{try{writeSync(4,JSON.stringify({type:'error',code:'REPOSITORY_LOCK_FAILED'})+'\n')}finally{stop()}}
|
|
44
|
+
}
|
|
45
|
+
if(launch.report){try{writeSync(4,'{"processStarted":true,')}catch{/* host already stopped */}}
|
|
46
|
+
})
|
|
32
47
|
child.once('error', error => { process.stderr.write(`LISP_LAUNCH_ERROR: ${error.message}\n`); process.exit(70) })
|
|
33
48
|
child.once('exit', (code, signal) => {
|
|
34
49
|
if(launch.report){try{writeSync(4,JSON.stringify({exitCode:code,signal}).slice(1)+'\n')}catch{/* host already stopped */}}
|
|
35
|
-
if (launch.group) kill()
|
|
50
|
+
if (launch.group) kill()
|
|
51
|
+
repositoryLease?.close()
|
|
52
|
+
process.exit(signal ? 128 : code ?? 70)
|
|
36
53
|
})
|
|
37
54
|
if (closing) kill()
|
package/lisp/tools.lisp
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
(defvar *generation* (uiop:getenv "KIOKU_GENERATION"))
|
|
21
21
|
(defvar *counter* 0)
|
|
22
22
|
(defvar *request* nil)
|
|
23
|
+
(defvar *task-scratch* nil)
|
|
23
24
|
(defun object (&rest pairs)
|
|
24
25
|
(let ((h (make-hash-table :test 'equal)))
|
|
25
26
|
(loop for (key value) on pairs by #'cddr do (setf (gethash key h) value)) h))
|
|
@@ -68,7 +69,7 @@
|
|
|
68
69
|
(if (< (length (sb-ext:string-to-octets json :external-format :utf-8)) 524288) (kioku.data:parse-json json) nil))
|
|
69
70
|
(error () nil)))))
|
|
70
71
|
(defun compile-task (code)
|
|
71
|
-
(let ((*
|
|
72
|
+
(let ((*read-eval* nil))
|
|
72
73
|
(let ((form (with-input-from-string (stream code)
|
|
73
74
|
(let ((value (read stream nil stream)))
|
|
74
75
|
(when (or (eq value stream) (not (eq (read stream nil stream) stream)))
|
|
@@ -78,7 +79,7 @@
|
|
|
78
79
|
(compile nil form))))
|
|
79
80
|
(defun evaluate-task (code input-path)
|
|
80
81
|
"Run one generated function with JSON data; leave the full result in scratch."
|
|
81
|
-
(let ((*
|
|
82
|
+
(let ((*read-eval* nil))
|
|
82
83
|
(let* ((function (compile-task code))
|
|
83
84
|
(input (kioku.data:parse-json (uiop:read-file-string input-path)))
|
|
84
85
|
(result (funcall function input))
|
|
@@ -88,6 +89,18 @@
|
|
|
88
89
|
(error "TASK_RESULT_LIMIT"))
|
|
89
90
|
(kioku.files:write-text path json)
|
|
90
91
|
(object "path" "task-result.json" "bytes" (length (sb-ext:string-to-octets json :external-format :utf-8))))))
|
|
92
|
+
(defun task-request (request)
|
|
93
|
+
;; Fresh unqualified symbols and object refs; the same owner's process remains.
|
|
94
|
+
;; Arbitrary Common Lisp is not a heap security boundary.
|
|
95
|
+
(let* ((*package* (make-package (symbol-name (gensym "KIOKU.TASK.")) :use '(:cl)))
|
|
96
|
+
(*objects* (make-hash-table :test 'equal))
|
|
97
|
+
(*task-scratch* (let ((scratch (gethash "scratch" request)))
|
|
98
|
+
(when scratch (uiop:ensure-directory-pathname scratch)))))
|
|
99
|
+
(unwind-protect
|
|
100
|
+
(if (equal "task-compile" (gethash "method" request))
|
|
101
|
+
(progn (compile-task (gethash "code" request)) (object "compiled" yason:true))
|
|
102
|
+
(evaluate-task (gethash "code" request) (gethash "input" request)))
|
|
103
|
+
(delete-package *package*))))
|
|
91
104
|
(defun serve ()
|
|
92
105
|
(setf *wire* (sb-sys:make-fd-stream 3 :input t :output t :element-type 'character :external-format :utf-8 :buffering :line))
|
|
93
106
|
(emit (object "version" 1 "type" "ready"))
|
|
@@ -95,8 +108,7 @@
|
|
|
95
108
|
(let ((*request* (gethash "id" request)) (*proposals* nil) (*inputs* (gethash "inputs" request #())))
|
|
96
109
|
(handler-case
|
|
97
110
|
(let ((value (cond ((equal "eval" (gethash "method" request)) (evaluate-code (gethash "code" request)))
|
|
98
|
-
((
|
|
99
|
-
((equal "task-compile" (gethash "method" request)) (progn (compile-task (gethash "code" request)) (object "compiled" yason:true)))
|
|
111
|
+
((member (gethash "method" request) '("task" "task-compile") :test #'equal) (task-request request))
|
|
100
112
|
((equal "describe" (gethash "method" request)) (kioku.tools:describe-symbol (gethash "symbol" request "")))
|
|
101
113
|
((equal "inspect" (gethash "method" request)) (kioku.objects:inspect-ref (gethash "ref" request)))
|
|
102
114
|
(t (error "UNKNOWN_METHOD")))))
|
|
@@ -129,7 +141,7 @@
|
|
|
129
141
|
(defun regex-matches (pattern text) (cl-ppcre:all-matches-as-strings pattern text))
|
|
130
142
|
(defun regex-replace (pattern text replacement) (cl-ppcre:regex-replace-all pattern text replacement))
|
|
131
143
|
(in-package :kioku.files)
|
|
132
|
-
(defun scratch () (pathname (uiop:getenv "KIOKU_SCRATCH")))
|
|
144
|
+
(defun scratch () (or kioku.internal::*task-scratch* (pathname (uiop:getenv "KIOKU_SCRATCH"))))
|
|
133
145
|
(defun %scratch-path (name &key must-exist)
|
|
134
146
|
"Resolve NAME below scratch without accepting absolute paths, traversal, or links."
|
|
135
147
|
(let* ((root (truename (scratch)))
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Payload-free quarantine. These rows never grant execution or adopt memory.
|
|
2
|
+
CREATE TABLE dsh_auxiliary_recovery (
|
|
3
|
+
id TEXT PRIMARY KEY, session_id TEXT NOT NULL, native_turn INTEGER NOT NULL,
|
|
4
|
+
origin TEXT NOT NULL CHECK(origin IN ('answer-context','intent-assessment')),
|
|
5
|
+
source_digest TEXT NOT NULL, context_digest TEXT NOT NULL,
|
|
6
|
+
state TEXT NOT NULL CHECK(state IN ('pending','running','retry_wait','verified','rejected','stale')),
|
|
7
|
+
attempts INTEGER NOT NULL DEFAULT 0 CHECK(attempts BETWEEN 0 AND 3),
|
|
8
|
+
lease_nonce TEXT, lease_until INTEGER, next_at INTEGER NOT NULL DEFAULT 0,
|
|
9
|
+
last_reason TEXT NOT NULL, updated_at INTEGER NOT NULL
|
|
10
|
+
);
|
|
11
|
+
CREATE INDEX dsh_auxiliary_recovery_session ON dsh_auxiliary_recovery(session_id,native_turn);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kiokuko-dsh",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.37",
|
|
4
4
|
"description": "Kiokuko plugin for DeepSeek Harness",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"skills/",
|
|
25
25
|
"dsh/cordis.patch.yml",
|
|
26
26
|
"docs/",
|
|
27
|
+
"scripts/prepare-build.mjs",
|
|
27
28
|
"scripts/backfill-akinator-memory.mjs",
|
|
28
29
|
"scripts/setup-dsh.mjs",
|
|
29
30
|
"scripts/repair-session-log.mjs",
|
|
@@ -147,7 +148,7 @@
|
|
|
147
148
|
"DSH-configured model providers for explicitly started Deep planning and its budgeted memory extraction",
|
|
148
149
|
"The explicitly selected DSH model provider for a user-started Diff review without tools",
|
|
149
150
|
"DSH-configured model provider for automatic memory review (active by default, up to 12 worker dispatches per project per UTC day), ordinary finalization and configured memory evolution",
|
|
150
|
-
"Configured TypeSafe fixed endpoint or explicit Nimble HTTPS/loopback endpoint for automatic task/Skill/draft decisions and independent original-source/candidate comparison, projected memory reuse after a synthetic readiness probe, and Lisp; no redirects, retries or provider substitution; exact roles.check no-tool fallback for complete draft review",
|
|
151
|
+
"Configured TypeSafe or explicitly selected OpenAI Decisions fixed endpoint, or explicit Nimble HTTPS/loopback endpoint, for automatic task/Skill/draft decisions and independent original-source/candidate comparison, projected memory reuse after a synthetic readiness probe, and Lisp; no redirects, retries or provider substitution; exact roles.check no-tool fallback for complete draft review",
|
|
151
152
|
"Explicit Laya-CoreML Unix socket for local finite decisions using the existing v1 worker or optional strict operations; no subprocess client, automatic worker startup, model downloads or provider substitution",
|
|
152
153
|
"DSH-configured admitted provider/model for default-active source-backed index reasoning: up to 8 worker dispatches per workspace per UTC day; no retrieval-time generation or automatic resend of uncertain dispatches",
|
|
153
154
|
"User-configured AI API endpoints and vendored provider OAuth flows through Kiokuko Models"
|
|
@@ -155,6 +156,7 @@
|
|
|
155
156
|
"credentials": [
|
|
156
157
|
"Optional user-provided GitHub or embedding credentials; never bundled or persisted by the plugin",
|
|
157
158
|
"TYPESAFE_API_KEY resolved per explicit call; optional DSH-managed set/unset via /kioku-typesafe-key, inherited environment precedence, no worker or Kiokuko storage exposure; input visible while typing",
|
|
159
|
+
"OPENAI_API_KEY resolved separately through DSH credentials, or inherited environment only without a credentials service; never stored in decision records or substituted with a TypeSafe key",
|
|
158
160
|
"Optional separate Nimble bearer credential reference through DSH; TYPESAFE_API_KEY is prohibited for Nimble; credentials are never persisted in decision records",
|
|
159
161
|
"Shared dsh-auth credentials: human Web login/key replacement/logout; logout also affects dsh-cli"
|
|
160
162
|
],
|
|
@@ -167,7 +169,7 @@
|
|
|
167
169
|
"Enabled source-candidate assessment distinguishes unavailable and incomplete checks from proof; the micro judge is native-verified on Apple Silicon macOS only, unsupported platforms report unavailable, and explicit typed-decision OFF records no assessment"
|
|
168
170
|
],
|
|
169
171
|
"lifecycleEvidence": [
|
|
170
|
-
"prepare
|
|
172
|
+
"prepare builds by default; selected CI installs defer to the verifier clean build",
|
|
171
173
|
"Git installs use repository-scoped pnpm allowBuilds approval on a supporting pnpm version; source revision pinning is optional and separate",
|
|
172
174
|
"Disposable-profile install, Web start, and uninstall evidence is recorded by CI"
|
|
173
175
|
]
|
|
@@ -200,7 +202,7 @@
|
|
|
200
202
|
"publint": "publint",
|
|
201
203
|
"pack:check": "node scripts/pack-check.mjs",
|
|
202
204
|
"prepublishOnly": "node scripts/prepublish.mjs",
|
|
203
|
-
"prepare": "
|
|
205
|
+
"prepare": "node scripts/prepare-build.mjs",
|
|
204
206
|
"test:agenticreplay:package": "npm run build && node scripts/verify-agenticreplay-consumer.mjs && node scripts/verify-agenticreplay-consumer.mjs --pnpm",
|
|
205
207
|
"test:memory-review": "node scripts/run-tests.mjs tests/dsh/unit/memory-review tests/dsh/integration/memory-review",
|
|
206
208
|
"test:evolution": "node scripts/run-tests.mjs tests/dsh/unit/evolution tests/dsh/integration/evolution",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// CI dependency installation may defer only this package's duplicate build.
|
|
2
|
+
// Dependency lifecycle scripts still run; the selected verifier builds from source.
|
|
3
|
+
import { spawnSync } from 'node:child_process'
|
|
4
|
+
|
|
5
|
+
if (process.env.CI === 'true' && process.env.KIOKUKO_CI_DEFER_PREPARE === '1') {
|
|
6
|
+
console.log('Deferring package prepare build to the selected verifier clean build.')
|
|
7
|
+
} else {
|
|
8
|
+
const runner=process.env.npm_execpath
|
|
9
|
+
if (!runner) throw new Error('Run prepare through npm or pnpm.')
|
|
10
|
+
const result=spawnSync(process.execPath,[runner,'run','build'],{stdio:'inherit'})
|
|
11
|
+
if (result.error) throw result.error
|
|
12
|
+
process.exitCode=result.status ?? 1
|
|
13
|
+
}
|
package/scripts/setup-dsh.mjs
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { parseArgs } from 'node:util'
|
|
2
|
-
import { setupDsh } from '../dist/dsh/setup.js'
|
|
2
|
+
import { removeDshSetup, setupDsh } from '../dist/dsh/setup.js'
|
|
3
3
|
|
|
4
4
|
try {
|
|
5
5
|
const { values } = parseArgs({ options: {
|
|
6
6
|
cwd: { type: 'string' }, home: { type: 'string' },
|
|
7
7
|
check: { type: 'boolean', default: false }, json: { type: 'boolean', default: false },
|
|
8
|
+
remove: { type: 'boolean', default: false },
|
|
8
9
|
} })
|
|
9
|
-
const result = await setupDsh({ cwd: values.cwd, homeDirectory: values.home, check: values.check })
|
|
10
|
+
const result = await (values.remove ? removeDshSetup : setupDsh)({ cwd: values.cwd, homeDirectory: values.home, check: values.check })
|
|
10
11
|
if (values.json) console.log(JSON.stringify(result, null, 2))
|
|
11
|
-
else {
|
|
12
|
+
else if (values.remove) {
|
|
13
|
+
console.log(values.check ? result.current ? 'Removal is current.' : 'Removal is needed; run again without --check.' : 'Removal complete.')
|
|
14
|
+
console.log(`Skills: ${result.skills.directory} (${result.skills.removed} ${values.check ? 'removable' : 'removed'}, ${result.skills.preserved} preserved)`)
|
|
15
|
+
console.log(`Project instructions: ${result.instructions.path} (${result.instructions.status})`)
|
|
16
|
+
} else {
|
|
12
17
|
console.log(values.check ? result.current ? 'Setup is current.' : 'Setup needs updating; run again without --check.' : 'Setup complete. Reload existing sessions to refresh their instructions.')
|
|
13
18
|
console.log(`Skills: ${result.skills.directory} (${result.skills.created} ${values.check ? 'missing' : 'created'}, ${result.skills.updated} ${values.check ? 'stale' : 'updated'}, ${result.skills.unchanged} unchanged)`)
|
|
14
19
|
console.log(`Project instructions: ${result.instructions.path} (${result.instructions.status})`)
|
|
@@ -145,8 +145,10 @@ Clear native implementation requests offer Lisp before model generation. A task
|
|
|
145
145
|
## Project-shared functions
|
|
146
146
|
|
|
147
147
|
Project-shared functions work in both Lisp modes without a mode switch after the
|
|
148
|
-
coding choice.
|
|
149
|
-
|
|
148
|
+
coding choice. The exact session/agent/repo owner reuses its resident worker, preserving
|
|
149
|
+
PID, generation and definitions. Each call uses a fresh package, object table and result scratch;
|
|
150
|
+
this is not heap security isolation. Use pure functions with explicit dependencies. Other owners
|
|
151
|
+
cannot borrow that worker. Without a resident worker, task mode uses disposable workers. `lisp_hot_contract` applies the profile approval policy to
|
|
150
152
|
schemas and 1–32 finite input/expected cases. Only the host grants approval. `lisp_hot_install` validates against that immutable contract and replaces
|
|
151
153
|
the active version only at the expected revision. Dependency code is snapshotted.
|
|
152
154
|
`lisp_hot_call` pins the active version by name; input/result refs stay owner-local.
|
|
@@ -154,7 +156,7 @@ the active version only at the expected revision. Dependency code is snapshotted
|
|
|
154
156
|
uses the same profile approval policy. Approving new conditions preserves the old active
|
|
155
157
|
version until a candidate passes; old conditions cannot authorize a new install.
|
|
156
158
|
Finite cases are not a proof for every input. Active code/dependencies do not
|
|
157
|
-
expire; retired versions may be collected after 30 days.
|
|
159
|
+
expire; retired versions may be collected after 30 days. Resident shared-function requests deny host RPC.
|
|
158
160
|
Use `/kioku-lisp hot [NAME]` for human inspection. Never rerun UNKNOWN operations.
|
|
159
161
|
|
|
160
162
|
## Task-mode API details
|