{"_id":"@buddhilive/dsh-goal","name":"@buddhilive/dsh-goal","dist-tags":{"alpha":"0.1.2-alpha.3","latest":"0.1.2-alpha.3"},"versions":{"0.1.2-alpha.3":{"name":"@buddhilive/dsh-goal","description":"Event-sourced same-session goal state and lifecycle service for the DeepSeek Harness","version":"0.1.2-alpha.3","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/Buddhilive/buddhi-ai-harness.git","directory":"packages/goal/goal"},"type":"module","main":"lib/index.js","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./types":{"types":"./lib/types/types.d.ts","default":"./lib/types/types.js"},"./client":{"types":"./lib/types/client.d.ts","default":"./lib/types/client.js"},"./typert":{"types":"./lib/typert.host.d.ts","default":"./lib/typert.host.js"},"./remote":{"types":"./lib/typert.remote-client.d.ts","default":"./lib/typert.remote-client.js"},"./src/*":"./src/*","./package.json":"./package.json"},"license":"MIT","peerDependencies":{"@buddhilive/dsh-agent":"^0.1.2-alpha.3","@buddhilive/dsh-session-projection":"^0.1.2-alpha.3","@buddhilive/dsh-brand":"^0.1.2-alpha.3","@buddhilive/dsh-invariants":"^0.1.2-alpha.3","@buddhilive/dsh-llm":"^0.1.2-alpha.3","@buddhilive/dsh-scope":"^0.1.2-alpha.3","@buddhilive/dsh-session":"^0.1.2-alpha.3","@buddhilive/dsh-typert-protocol":"^0.1.2-alpha.3","@deepseek-ai/cordis":"^4.0.2"},"dependencies":{"zod":"^4.4.3","@deepseek-ai/schemastery":"^3.18.2"},"devDependencies":{"@buddhilive/dsh-agent-spine-demo":"^0.1.2-alpha.3","@buddhilive/dsh-agent":"^0.1.2-alpha.3","@buddhilive/dsh-bash-local":"^0.1.2-alpha.3","@buddhilive/dsh-session-projection":"^0.1.2-alpha.3","@buddhilive/dsh-brand":"^0.1.2-alpha.3","@buddhilive/dsh-invariants":"^0.1.2-alpha.3","@buddhilive/dsh-llm":"^0.1.2-alpha.3","@buddhilive/dsh-scope":"^0.1.2-alpha.3","@buddhilive/dsh-session":"^0.1.2-alpha.3","@buddhilive/dsh-loader-smoke":"^0.1.2-alpha.3","@buddhilive/dsh-session-checkpoint-policy":"^0.1.2-alpha.3","@buddhilive/dsh-session-persistence-jsonl":"^0.1.2-alpha.3","@buddhilive/dsh-subprocess-local":"^0.1.2-alpha.3","@deepseek-ai/cordis":"^4.0.2","@buddhilive/dsh-typert-protocol":"^0.1.2-alpha.3"},"_id":"@buddhilive/dsh-goal@0.1.2-alpha.3","bugs":{"url":"https://github.com/Buddhilive/buddhi-ai-harness/issues"},"homepage":"https://github.com/Buddhilive/buddhi-ai-harness#readme","_integrity":"sha512-SJ/Iel/L1D2xEI0sX4zcYI+QpxYkXdrxMPZTLDoyQdPV0NqVbMdHxRonPDkO9sI84Vwz6GugLEKQTsY+LrR++A==","_resolved":"C:\\DevDojo\\Buddhi\\buddhi-ai-harness\\dist\\npm\\buddhilive-dsh-goal-0.1.2-alpha.3.tgz","_from":"file:C:/DevDojo/Buddhi/buddhi-ai-harness/dist/npm/buddhilive-dsh-goal-0.1.2-alpha.3.tgz","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-SJ/Iel/L1D2xEI0sX4zcYI+QpxYkXdrxMPZTLDoyQdPV0NqVbMdHxRonPDkO9sI84Vwz6GugLEKQTsY+LrR++A==","shasum":"092d66680c898397f3d4eede95d5437cf5f3287b","tarball":"https://registry.npmjs.org/@buddhilive/dsh-goal/-/dsh-goal-0.1.2-alpha.3.tgz","fileCount":25,"unpackedSize":207940,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDZyOBHHp8fzMe7v3r3qkPqezSyUhdmZ3HyMjmGTwP+NwIgXk7Yx/Ek64moPUjWa4MySisIVbDXoaOmir/UvQ3zjfw="}]},"_npmUser":{"name":"buddhilive","email":"visitbudkavin@gmail.com"},"directories":{},"maintainers":[{"name":"buddhilive","email":"visitbudkavin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-goal_0.1.2-alpha.3_1788165208174_0.5143438674429825"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T08:33:27.934Z","0.1.2-alpha.3":"2026-08-31T08:33:28.313Z","modified":"2026-08-31T08:33:28.497Z"},"maintainers":[{"name":"buddhilive","email":"visitbudkavin@gmail.com"}],"description":"Event-sourced same-session goal state and lifecycle service for the DeepSeek Harness","homepage":"https://github.com/Buddhilive/buddhi-ai-harness#readme","repository":{"type":"git","url":"git+https://github.com/Buddhilive/buddhi-ai-harness.git","directory":"packages/goal/goal"},"bugs":{"url":"https://github.com/Buddhilive/buddhi-ai-harness/issues"},"license":"MIT","readme":"---\ndescription: \"面向选择、配置或排查同会话持久 goal 服务的用户与维护者：每会话一个持久的完成目标。\"\nkind: \"package-reference\"\n---\n\n# @buddhilive/dsh-goal\n\n[English](README.md) | 中文\n\n## 概述\n\n`dsh-goal` 为每个 agent 会话保留一个持久的完成目标：目标的文本、phase、Round 数量与 revision 历史都保存在会话日志中，因此会话 resume（恢复）、fork 与进程重启后依然存在。你可以 create、edit、pause、resume、complete、block 和 clear 一个 goal，且每次变更都是比较并设置，陈旧的视图不会覆盖更新的状态。goal 带有 Round 上限（默认 256）以约束自动续行，被阻塞的 goal 会保留稳定的策略代码和面向人的说明。它是状态而非调度器：服务不决定工作何时继续，续行权限是进程本地的且绝不持久化。当单个长期目标需要横跨多轮时选择它；常规单轮工作不要使用。\n\n## 目录\n\n- [使用本包](#use-this-package)\n- [理解实现](#understand-the-implementation)\n- [进一步探索](#further-exploration)\n- [模型体验](#model-experience)\n- [已知限制与延期工作](#known-limitations-and-deferred-work)\n- [开发备注](#dev-note)\n\n-----\n\n<a id=\"use-this-package\"></a>\n## 使用本包\n\n当会话需要在多轮与多次重启之间记住一个长期完成目标时，挂载 `dsh-goal`。本包是服务：模型工具、`/goal` 命令与续行驱动器都是消费同一 goal 状态的独立包，因此只挂载本包只会存储和提供 goal，不会启动任何工作。\n\n### 何时使用\n\ngoal 适合一个需要跨自动 Goal Round 持续的长期完成目标——例如完成一次迁移，或修复所有失败的文档门禁。常规单轮工作不应创建 goal。服务每会话至多保留一个当前 goal：未完成的 goal 必须先 edit、pause、resume、block 或 clear，才能被另一个替代；已完成的 goal 可以直接被替换。\n\n### 配置服务\n\n通过组合配置项加载本包；唯一的部署选择是默认 Round 上限，应用于未自行指定上限的 create。\n\n```yaml\n- name: '@buddhilive/dsh-goal'\n  config:\n    defaultMaxGoalRounds: 256\n```\n\n| 字段 | 默认值 | 含义 |\n|---|---|---|\n| `defaultMaxGoalRounds` | `256` | 当 create 请求省略上限时应用的 Round 上限 |\n\n`defaultMaxGoalRounds` 必须是正的安全整数；指定了自身上限的 create 请求会覆盖它。生成的[配置目录](../../../docs/config-catalog.zh.md#buddhilivedsh-goal)是每个受支持字段的穷尽式真源。\n\n### 会话投影\n\n`GoalService` 要求组合提供 `ctx.sessionProjections`（[`@buddhilive/dsh-session-projection`](../../session/session-projection/README.zh.md)），并在启动时注册 `goal` 投影单元；未组合投影注册表的组合无法激活 `ctx.goals`。该单元版本为 6，其宿主状态保留最新的有效当前 goal、所有曾使用的 goal id，以及第一次严格回放失败。客户端 view 提供当前 goal；首次 create 前与 clear tombstone 后为 `null`。该 key 同时合并到 `SessionProjectionStateMap` 与 `SessionProjectionMap`；载体通过历史尾页和 `session/projection` 推送帧提供客户端值。\n\n### 驱动生命周期\n\ngoal 经历四种持久 phase——`active`、`paused`、`blocked`、`complete`——外加一个进程本地标志，表示自动续行是否已启用。动词如下：\n\n| 操作 | 作用 |\n|---|---|\n| `create` | 以目标和 Round 上限启动一个 active goal |\n| `edit` | 修改目标和/或 Round 上限，不改变 phase |\n| `pause` | 停止自动续行并保留状态 |\n| `resume` | 重新开始续行；也用于会话 resume 或 fork 后重新启用 active goal |\n| `complete` | 标记 goal 已完成并停止续行 |\n| `block` | 记录稳定的 blocker 代码与说明 |\n| `clear` | 移除当前 goal；其历史保留在会话日志中 |\n\npause、complete、block 和 clear 都会停用续行。block 是唯一保留策略自有 lower-kebab-case 代码与自由文本说明的 phase，因此提供方限制、预算耗尽、执行错误与请求人工输入共用一种持久 phase，而不是扩增生命周期状态。resume 只在 Round 上限仍有剩余容量时接受已停止的 goal，或 active 但已停用续行的 goal，并清除任何先前的 blocker reason。\n\n### 什么会保留，什么不会\n\n每项被接受的变更都会持久记录到会话日志——goal 状态的唯一存储——因此 goal 状态绝不依赖临时消息投递。会话 resume 或 fork 后，goal、其 phase、其 revision 与已准入 Round 数量都仍然存在。自动续行是例外：任何会话开始边界之后，`active` 的 goal 都会被停用续行——在有人显式 resume 之前，agent 不会自行继续。\n\n### 观察 goal\n\n消费方用 `ctx.goals.get(agent)` 读取当前 goal，获得脱离内部状态的视图：目标、phase、已开始与上限 Round 数量、被阻塞时的 blocker reason，以及续行是否已启用。变更必须携带该视图中的精确 `{ id, revision }`，因此持有旧状态的消费方会收到清晰的陈旧 revision 错误，而不是静默覆盖更新的状态：\n\n```text\nconst view = ctx.goals.get(agent)      // undefined when no goal is current\nview.phase                             // 'active' | 'paused' | 'blocked' | 'complete'\nview.roundsStarted, view.maxGoalRounds // continuation progress\nview.activation                        // 'armed' | 'disarmed' — not persisted\n```\n\n-----\n\n<a id=\"understand-the-implementation\"></a>\n## 理解实现\n\n<details>\n<summary>实现细节——点击展开</summary>\n\n本节解释服务如何实现上述行为；可观察约定已在[使用本包](#use-this-package)中说明。\n\n### 设计\n\n- **事件溯源状态。** 每次变更都追加持久的 `goal/change` 事件（版本 1），携带变更后的完整快照；clear 写入带 revision 的 tombstone。会话日志是唯一的持久权威。\n- **比较并设置的变更。** `ctx.goals` 只接受以对应 id 注册的完全相同的活跃 `Agent` 实例。`get()` 返回脱离状态的 `GoalView`；变更携带 `GoalRef { id, revision }` 并拒绝陈旧引用。创建在提交前于内部解析部署默认值。\n- **续行启用状态是进程本地的。** `armed` 与 `disarmed` 保存在每会话缓存中，绝不持久化。新缓存与每次 `agent/session-start` 边界都会停用续行，即使回放发现持久 phase 为 active；`disarm()` 移除续行权限，不写入 revision 也不发出变更事件。\n- **严格回放。** 折叠只从 `goal/change` 派生生命周期变更，并拒绝形状错误、不连续 revision、非法 phase 转换、每目标时间戳非单调，以及不连续的已准入 Round。只有已准入的来源为 goal 的 `user/message` 事件会推进正数 Round；挂钟时间倒退时，变更时间戳会限制在不早于上一次更新的值。\n- **投影单元。** 本包要求提供投影注册表，并注册一个严格的 `goal` 单元。其宿主状态保留回放校验数据与第一次失败，客户端 view 提供最新有效的完整 goal 或 `null`；保留回放失败后，`GoalService` 会拒绝访问。\n\n### 源码地图\n\n| 文件 | 职责 |\n|---|---|\n| [`src/index.ts`](src/index.ts) | 插件入口：`GoalService`、config schema、变更、续行启用缓存、投影单元 |\n| [`src/domain.ts`](src/domain.ts) | 持久变更载荷、`goal/changed` 事件、goal 消息来源归属 |\n| [`src/types.ts`](src/types.ts) | 纯客户端安全类型：`GoalView`、`GoalSnapshot`、投影键声明 |\n| [`src/fold.ts`](src/fold.ts) | 持久 goal 变更的严格回放折叠与解码器 |\n| [`src/runtime.ts`](src/runtime.ts) | `GoalId` 品牌、`GoalError` 代码、变更版本常量 |\n| [`src/invariant.ts`](src/invariant.ts) | 不变式伴生：对每个已挂接会话的独立增量折叠 |\n\n### 事件与归属\n\n`goal/changed` 在持久事件提交后触发，监听器失败会被隔离；载荷携带操作、精确 ref 与最新视图（clear tombstone 时省略）。已准入的续行 Round 通过 `user/message` 事件上的 `GoalMessageSource { goalId, revision, round }` 归属，严格折叠会将其验证为当前 goal 的下一个已准入 Round。\n\n</details>\n\n-----\n\n<a id=\"further-exploration\"></a>\n## 进一步探索\n\n包级约定对大多数消费方已经足够；需要了解周边领域与设计理由时阅读以下页面。\n\n- [goal 子系统](../../../docs/subsystems/goal.zh.md)——goal 类型、持久的变更载荷与生成的服务 API。\n- [goal 组地图](../README.zh.md)——goal 各包及其组合方式。\n- [生成的配置目录](../../../docs/config-catalog.zh.md#buddhilivedsh-goal)——每个受支持配置字段及其源声明。\n- [goal 领域 Agent Note](../../../.agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.zh.md)——领域设计、备选方案与决策。\n\n-----\n\n<a id=\"model-experience\"></a>\n## 模型体验\n\n### 目标状态变更\n\n#### 模型看到什么\n\nGoal 变更不会注入模型上下文。`get_goal` 等工具返回当前状态；续行消费方可以在调度模型工作时渲染目标与 Round 状态。\n\n#### Token 影响\n\nGoal 变更事件本身不增加模型 token。工具结果与续行调度提示词各自暴露的状态会分别计入 token 用量。\n\n#### KV Cache 影响\n\n在其他组件把 goal 状态暴露为模型可见输入之前，不会影响 KV Cache。\n\n## 已知限制与延期工作\n\n<a id=\"known-limitations-and-deferred-work\"></a>\n\n\n这些限制说明 goal 服务何时不合适或需要特别注意。它们是当前包约束，不是任务积压。\n\n- **只负责状态，不负责任务调度**——本包不决定已启用续行的 goal 何时继续，不重试异常失败，也不取消活跃轮次；这些策略属于 `dsh-goal-round-driver` 等消费方包。\n- **只有 Round 数量预算**——`maxGoalRounds` 不计量 token、货币、挂钟时间或提供方配额。\n- **没有独立评估器**——记录完成或阻塞的调用方拥有最终决定权；由评估器支持的认证暂缓到独立策略层。\n- **只有一个当前 goal**——系统有意不支持并行目标或独立 goal 数据库；替换或清除后，历史仍可在会话日志中读取。\n- **信任进程内生产方**——能直接访问 `Session` 的插件可以追加伪造的 `goal/change` 数据。严格回放会检测格式错误或不一致的记录，并使 goal 访问从该记录起失败，直到日志修复；这是完整性检测，不是插件隔离。\n\n<a id=\"dev-note\"></a>\n### 开发备注\n\n<details>\n<summary>维护者的工作上下文——点击展开</summary>\n\n本开发备注是维护者的工作上下文，明确不具权威性。开放且未决的方向：为需要在每个模型请求中看到目标的部署提供始终可见的 goal 上下文插件，以及由评估器支持的完成与阻塞认证。\n\n</details>\n","readmeFilename":"README.zh.md","_rev":"1-721303da70cefef207db63741c204dd3"}