driftseal 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DriftSeal contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,140 @@
1
+ # DriftSeal
2
+
3
+ > **Seal the intent. Stop the drift.**
4
+
5
+ [简体中文](README.zh-CN.md)
6
+
7
+ Agentic coding moves fast. **DriftSeal keeps it honest.**
8
+
9
+ Before an agent touches the code, DriftSeal records what this round will accomplish and how completion will be proved. When the work ends, it records what actually happened. The result is a tiny, auditable contract that survives context loss, scope creep, and optimistic “done” claims.
10
+
11
+ ```text
12
+ seal intent → do the work → prove the result → close the round
13
+ ```
14
+
15
+ **One open intent. One declared proof. One durable trail.** No service, no database, no runtime dependencies—just a Node.js CLI and plain files that travel with the repo.
16
+
17
+ ## The problem is not speed. It is drift.
18
+
19
+ | Without DriftSeal | With DriftSeal |
20
+ | --- | --- |
21
+ | Scope quietly expands halfway through a task | One visible intent defines the active round |
22
+ | “Done” arrives without meaningful evidence | Verification is declared before implementation |
23
+ | Context compaction erases the original goal | `status` and `log` restore the exact intent and history |
24
+ | Old architectural debates repeat forever | Selective [MADR](https://adr.github.io/madr/) records preserve the reasoning that matters |
25
+ | Concurrent or interrupted writes leave uncertainty | Locks, schema checks, atomic writes, and recovery make failures explicit and recoverable |
26
+
27
+ DriftSeal complements Git instead of competing with it: the intent says what was planned, the decision log preserves why, and the commit shows what landed.
28
+
29
+ ## Start in 30 seconds
30
+
31
+ ```sh
32
+ npm install --global driftseal
33
+ cd your-project
34
+ driftseal init
35
+ ```
36
+
37
+ `driftseal init` safely adds the protocol to `AGENTS.md` and can be run again without duplicating it. DriftSeal requires Node.js 18+.
38
+
39
+ For local development from this checkout:
40
+
41
+ ```sh
42
+ npm link
43
+ ```
44
+
45
+ ## Give your coding agent the complete workflow
46
+
47
+ The package includes `skills/use-driftseal`, an agent-agnostic companion skill that drives repository work through the complete DriftSeal loop while keeping decision records selective. Install or link it using your agent runtime’s skill discovery convention, then invoke `use-driftseal` by name.
48
+
49
+ ## A work round
50
+
51
+ Declare the round before changing files:
52
+
53
+ ```sh
54
+ driftseal begin "add rate limiting to /api/login" \
55
+ --verify "npm test test/rate-limit.test.js"
56
+ ```
57
+
58
+ Do the work, run the declared check, then reconcile the result:
59
+
60
+ ```sh
61
+ driftseal end \
62
+ --status completed \
63
+ --note "Added the limiter and covered the failure path" \
64
+ --verify-result "4 tests pass"
65
+ ```
66
+
67
+ If the scope changes, close the current intent as `partial` or `abandoned`, then start a new one. After context loss, use `driftseal status` and `driftseal log --last 3` to re-anchor.
68
+
69
+ If the user has authorized a Git commit, staging and committing only the verified changes and the just-closed intent log finalizes that round; it does not need a commit-only intent. Any content change made while preparing the commit starts a new round.
70
+
71
+ ## Commands
72
+
73
+ | Command | Purpose |
74
+ | --- | --- |
75
+ | `driftseal begin "<intent>" [-v "<verify>"] [--decision id] [--force]` | Open a work-round intent and optionally link existing decisions. |
76
+ | `driftseal end [id] [-s status] [-n note] [-r verify-result]` | Close an intent honestly. |
77
+ | `driftseal status` | Show the intent currently in progress. |
78
+ | `driftseal log [-n N]` | Review intent history. |
79
+ | `driftseal decision add "<title>" -c "..." -o "..."` | Write a numbered MADR decision. |
80
+ | `driftseal decision update <id> [-s status] -n "..."` | Reconcile a linked decision in the open intent. |
81
+ | `driftseal decision list [-s status] [--last N \| --count]` | List or count decision records, optionally filtered by status. |
82
+ | `driftseal decision show <id>` | Read one decision record. |
83
+ | `driftseal init` | Add the adoption protocol to `AGENTS.md`. |
84
+ | `driftseal help` | Print CLI usage. |
85
+
86
+ When `begin` declares one or more `--decision <id>` links, every linked
87
+ decision must be reconciled with `driftseal decision update` before that intent can
88
+ close as `completed` or `partial`. The update changes the current status when
89
+ requested and appends a timestamped history entry tied to the intent. Intents
90
+ without decision links keep the ordinary workflow.
91
+
92
+ ## Consistency and recovery
93
+
94
+ DriftSeal serializes mutating commands with locks on the configured intent and
95
+ decision-log roots, acquired in a stable order. Decision reconciliation is
96
+ journaled as prepare and commit events around an atomic MADR replacement. If
97
+ the process stops between those steps, the next linked `decision update` or
98
+ successful `end` recovers the transaction from content hashes. A successful
99
+ linked-intent close also verifies that the decision file has not changed since
100
+ its latest reconciliation. Unlinked intents do not parse the decision log, and
101
+ `failed` or `abandoned` remains an escape path when decision recovery cannot
102
+ complete. Those terminal statuses cancel recovery for their pending
103
+ transactions, and recovery is scoped to the current intent so historical
104
+ conflicts cannot block later decision work.
105
+
106
+ New events carry a schema version. DriftSeal rejects newer unsupported schemas and
107
+ fails closed if a legacy client closes a linked intent without reconciliation.
108
+ `driftseal init` writes versioned managed blocks and upgrades only exact, recognized
109
+ older blocks. It refuses newer protocol versions and any unrecognized or
110
+ customized block without changing `AGENTS.md`.
111
+
112
+ `--count` prints only the number of records remaining after status filtering.
113
+ It cannot be combined with `--last`, whose limiting semantics would make the
114
+ count ambiguous. Decision filenames form a lightweight in-memory index: `show`
115
+ parses only the requested record, and an unfiltered `--count` reads no MADR
116
+ contents. Status-filtered listing and counting parse all records because status
117
+ is stored in each MADR document; DriftSeal does not maintain a stale-prone sidecar
118
+ index.
119
+
120
+ ## Storage
121
+
122
+ - `.intent-log/events.jsonl` is the append-only intent log.
123
+ - `.decision-log/` contains numbered MADR decision records.
124
+ - Set `DRIFTSEAL_HOME` or `DRIFTSEAL_DECISION_HOME` to store either log outside the current project.
125
+
126
+ Together, intent events, selective decision records, and Git commits form a layered project log: intent events capture what a work round set out to do and how it would be verified; decision records preserve rationale, rejected paths, or deferred choices that the other layers cannot reconstruct; commits show the coherent change that actually landed. DriftSeal complements Git history rather than duplicating or replacing it.
127
+
128
+ Keeping the DriftSeal logs in version control makes the project’s working agreements and decision trail travel with the code. The npm package uses an explicit file allowlist, so project-local agent logs are not published to npm.
129
+
130
+ ## Development
131
+
132
+ ```sh
133
+ npm test
134
+ ```
135
+
136
+ Contributions are welcome. Keep changes focused, add regression coverage for behavior changes, and run the test suite before opening a pull request.
137
+
138
+ ## License
139
+
140
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,135 @@
1
+ # DriftSeal
2
+
3
+ > **Seal the intent. Stop the drift.**
4
+
5
+ [English](README.md)
6
+
7
+ Agentic coding 可以很快。**DriftSeal 让这种快不以失控为代价。**
8
+
9
+ 在 agent 动手改代码之前,DriftSeal 先记下这一轮究竟要完成什么、准备如何证明完成;工作结束后,再记录实际发生了什么。这个轻量契约不会因为 context loss、范围悄悄膨胀,或者一句过于乐观的“完成了”而消失。
10
+
11
+ ```text
12
+ 封存 intent → 执行工作 → 证明结果 → 关闭本轮
13
+ ```
14
+
15
+ **一个 open intent,一份预先声明的验证标准,一条可靠留存的工作轨迹。** 不需要 service,不需要 database,也没有 runtime dependencies;只有一个 Node.js CLI,以及跟着 repo 一起走的普通文件。
16
+
17
+ ## 真正麻烦的不是慢,而是偏航
18
+
19
+ | 没有 DriftSeal | 使用 DriftSeal |
20
+ | --- | --- |
21
+ | 任务做到一半,范围悄悄扩大 | 当前轮次始终只有一个清晰可见的 intent |
22
+ | 没有可靠证据,也可以宣布“完成” | 实现前就先声明 verification |
23
+ | Context compaction 后忘记最初目标 | `status` 和 `log` 能准确找回 intent 与历史 |
24
+ | 同一场架构争论被不同 agent 反复重演 | 克制使用的 [MADR](https://adr.github.io/madr/) 记录保留真正重要的理由 |
25
+ | 并发或中断写入让状态变得可疑 | Lock、schema check、atomic write 与 recovery 让异常可检测、可恢复 |
26
+
27
+ DriftSeal 不会取代 Git,而是补上 Git 不负责记录的部分:intent 说明原本要做什么,decision log 保存为什么,commit 展示最终落地了什么。
28
+
29
+ ## 30 秒开始使用
30
+
31
+ ```sh
32
+ npm install --global driftseal
33
+ cd your-project
34
+ driftseal init
35
+ ```
36
+
37
+ `driftseal init` 会安全地把协议加入 `AGENTS.md`,重复运行也不会产生副本。DriftSeal 需要 Node.js 18+。
38
+
39
+ 从当前 checkout 本地开发时:
40
+
41
+ ```sh
42
+ npm link
43
+ ```
44
+
45
+ ## 让 coding agent 掌握完整工作流
46
+
47
+ npm package 内含 `skills/use-driftseal`。这是一个不绑定特定 agent runtime 的配套 skill,会按完整 DriftSeal 闭环执行仓库任务,同时克制地使用 decision record。按照所用 agent runtime 的 skill discovery 约定安装或 link,之后通过名称 `use-driftseal` 调用即可。
48
+
49
+ ## 一轮标准工作流
50
+
51
+ 修改文件前,先声明这轮工作的目标:
52
+
53
+ ```sh
54
+ driftseal begin "add rate limiting to /api/login" \
55
+ --verify "npm test test/rate-limit.test.js"
56
+ ```
57
+
58
+ 完成工作并运行约定的 check 后,记录实际结果:
59
+
60
+ ```sh
61
+ driftseal end \
62
+ --status completed \
63
+ --note "Added the limiter and covered the failure path" \
64
+ --verify-result "4 tests pass"
65
+ ```
66
+
67
+ 如果范围发生变化,先把当前 intent 以 `partial` 或 `abandoned` 关闭,再开启新的 intent。发生 context loss 后,用 `driftseal status` 和 `driftseal log --last 3` 重新锚定当前目标。
68
+
69
+ 如果用户已经授权创建 Git commit,只把已验证的改动和刚关闭的 intent log 进行 stage 和 commit,就属于这一轮的持久化收尾,不需要额外开启一个只用于 commit 的 intent。准备 commit 时一旦需要修改内容,就必须开启新一轮。
70
+
71
+ ## 命令速览
72
+
73
+ | Command | 用途 |
74
+ | --- | --- |
75
+ | `driftseal begin "<intent>" [-v "<verify>"] [--decision id] [--force]` | 开启一轮工作,并可关联已有 decision。 |
76
+ | `driftseal end [id] [-s status] [-n note] [-r verify-result]` | 诚实地关闭 intent。 |
77
+ | `driftseal status` | 查看当前进行中的 intent。 |
78
+ | `driftseal log [-n N]` | 查看 intent 历史。 |
79
+ | `driftseal decision add "<title>" -c "..." -o "..."` | 写入编号化的 MADR decision。 |
80
+ | `driftseal decision update <id> [-s status] -n "..."` | 在当前 intent 中 reconcile 已关联的 decision。 |
81
+ | `driftseal decision list [-s status] [--last N \| --count]` | 列出或统计 decision records,也可按 status 筛选。 |
82
+ | `driftseal decision show <id>` | 查看单条 decision record。 |
83
+ | `driftseal init` | 把接入协议写入 `AGENTS.md`。 |
84
+ | `driftseal help` | 查看 CLI 用法。 |
85
+
86
+ 如果 `begin` 通过一个或多个 `--decision <id>` 声明了关联,那么 intent
87
+ 以 `completed` 或 `partial` 关闭前,必须用 `driftseal decision update` reconcile
88
+ 每一条关联 decision。update 可以改变当前 status,并会追加一条包含时间和
89
+ intent ID 的 history。没有关联 decision 的 intent 仍沿用普通流程。
90
+
91
+ ## 一致性与恢复
92
+
93
+ DriftSeal 会对配置后的 intent log 与 decision log 根目录加锁,并按固定顺序获取这些
94
+ lock,从而串行执行 mutating commands。Decision reconciliation 会先写 prepare
95
+ event,再以 atomic replacement 更新 MADR,最后写 commit event。如果进程在中间
96
+ 停止,下一次 linked `decision update` 或 successful `end` 会根据 content hash
97
+ 恢复 transaction。linked intent 成功关闭前,还会验证 decision 文件自最近一次
98
+ reconciliation 后没有发生变化。未关联 decision 的 intent 不会解析 decision log;
99
+ 当 decision recovery 无法完成时,`failed` 与 `abandoned` 仍可作为退出路径。
100
+ 这两个 terminal status 会取消对应 pending transaction 的后续 recovery;同时,
101
+ recovery 只处理当前 intent,因此历史冲突不会阻塞之后的 decision 工作。
102
+
103
+ 新 event 带有 schema version。遇到更高且不支持的版本时,DriftSeal 会拒绝继续;如果
104
+ 旧 client 未经 reconciliation 就关闭 linked intent,新 client 也会 fail closed。
105
+ `driftseal init` 会写入带版本的 managed blocks,并且只升级内容完全匹配的已知旧版本。
106
+ 遇到更新的协议版本、无法识别的 block 或自定义内容时,它会保持 `AGENTS.md`
107
+ 不变并拒绝继续。
108
+
109
+ `--count` 只输出 status 筛选后的记录总数。它不能与 `--last` 一起使用,以免
110
+ “先限制再计数”造成歧义。Decision 文件名会构成一个轻量的内存索引:`show` 只
111
+ 解析目标 record;不带 status 的 `--count` 完全不读取 MADR 正文。按 status 筛选
112
+ 时仍需解析全部 records,因为 status 保存在各个 MADR 文档中;DriftSeal 不维护容易
113
+ 滞后的 sidecar index。
114
+
115
+ ## 数据保存在哪里
116
+
117
+ - `.intent-log/events.jsonl`:append-only intent log。
118
+ - `.decision-log/`:编号化的 MADR decision records。
119
+ - 设置 `DRIFTSEAL_HOME` 或 `DRIFTSEAL_DECISION_HOME`,即可把对应 log 放到当前项目之外。
120
+
121
+ Intent event、克制使用的 decision record 和 Git commit 共同构成分层的项目日志:intent event 说明一轮工作准备做什么、将如何验证;decision record 保存其他两层无法重建的理由、被拒绝路径或暂缓选择;commit 则展示最终实际落地的完整改动。DriftSeal 是对 Git history 的补充,不是对它的重复或替代。
122
+
123
+ 建议把 DriftSeal logs 和代码一起放进 version control,让项目的工作约定与决策轨迹能够共同演进。npm package 使用显式文件白名单,因此项目本地的 agent log 不会被发布到 npm。
124
+
125
+ ## 开发与贡献
126
+
127
+ ```sh
128
+ npm test
129
+ ```
130
+
131
+ 欢迎贡献。请尽量保持改动聚焦;如果改变了行为,请补充 regression coverage,并在提交 pull request 前运行测试。
132
+
133
+ ## License
134
+
135
+ MIT,详见 [`LICENSE`](LICENSE)。