driftseal 1.3.2 → 1.4.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/README.md CHANGED
@@ -251,15 +251,32 @@ driftseal end \
251
251
 
252
252
  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.
253
253
 
254
- Git operations are entirely outside the intent log because Git maintains their
255
- history. Inspection, branch and worktree management, staging, commits, merges,
256
- rebases, cherry-picks, tags, and pushes never need an intent of their own. They
257
- still require normal authorization and safety checks. A command whose result
258
- can be reconstructed from Git state, such as a patch file regenerated from a
259
- commit range or a scratch harness that re-runs, needs no intent either; content
260
- that will be committed and cannot be reconstructed, such as a `.gitignore`
261
- edit, does. Single-step builds and checks, such as compiling or running tests,
262
- also need no intent. Any other non-Git content change starts a new work round.
254
+ Record an intent for changes intended to persist in the project: edits to code,
255
+ configuration, documentation, dependencies, and equivalent project files. The
256
+ boundary does not depend on Git: inside a worktree it includes content intended
257
+ for commit, while outside Git it includes durable project files. Everything else
258
+ is exempt. Git operations are entirely outside the intent log because Git
259
+ maintains their history; inspection, branch and worktree management, staging,
260
+ commits, merges, rebases, cherry-picks, tags, and pushes never need an intent of
261
+ their own, though they still require normal authorization and safety checks.
262
+ Single-step builds and checks, such as compiling or running tests, need no
263
+ intent. Auxiliary file or shell operations whose results remain outside durable
264
+ project content — an `rsync` scratch copy, temp scaffolding — need none either.
265
+ State changes to a remote machine or the local environment are also exempt when
266
+ they do not write durable project content into this workspace. When an external
267
+ operation does bring durable content into the project, record the intent for
268
+ that project-content change, not for the external operation itself.
269
+
270
+ In multi-agent work the scope belongs to the worktree, not the writer. One
271
+ worktree holds one open intent; every agent or subagent changing durable project
272
+ content there re-anchors and continues that matching intent. Agents in separate
273
+ worktrees hold separate intents. A configured project root outside Git follows
274
+ the same single-intent rule. An agent that only receives another agent's changes
275
+ through Git or into a shared worktree records no receiving intent and lets
276
+ `verify` expose misalignment. Handoff files are exempt while ignored or
277
+ otherwise kept outside durable project content and require an intent when
278
+ promoted into it. Taking over work in the same root is a re-anchor, not a
279
+ boundary: resume the open intent when its objective still matches the task.
263
280
 
264
281
  ## Commands
265
282
 
package/README.zh-CN.md CHANGED
@@ -235,12 +235,23 @@ driftseal end \
235
235
 
236
236
  如果范围发生变化,先把当前 intent 以 `partial` 或 `abandoned` 关闭,再开启新的 intent。发生 context loss 后,用 `driftseal status` 和 `driftseal log --last 3` 重新锚定当前目标。
237
237
 
238
- Git 操作完全不计入 intent log,因为 Git 会自行维护历史。查看状态、管理 branch
239
- worktree、stage、commit、merge、rebase、cherry-pick、tag push 都不需要
240
- 单独开启 intent,但仍须遵守正常的授权与安全要求。结果能从 Git 状态重建的命令
241
- ——比如从 commit range 重新生成的 patch 文件、可以重跑的临时 harness——也不需要
242
- intent;会被提交且无法重建的内容改动(比如编辑 `.gitignore`)则需要。编译、跑测试
243
- 等单步构建或检查同样不需要 intent;除此之外的非 Git 内容改动,都要开启新一轮。
238
+ 需要记录 intent 的是准备作为项目内容长期保留的改动,包括代码、配置、文档、依赖及同类
239
+ 项目文件。这个边界不取决于 Git:在 worktree 中,它包括准备提交的内容;在非 Git 项目中,
240
+ 它包括要长期保留的项目文件。其余操作一律免记。Git 会自行维护操作历史,因此查看状态、
241
+ 管理 branch worktree、stage、commit、merge、rebase、cherry-pick、tag push
242
+ 不需要单独开启 intent,但仍须遵守正常的授权与安全要求。编译、跑测试等单步构建或检查也
243
+ 不需要 intent。结果不会成为持久项目内容的辅助文件或 shell 操作——比如 `rsync` 临时拷贝、
244
+ 临时脚手架——同样免记。远程机器或本机环境的状态变更,只要不把持久项目内容写入当前
245
+ workspace,也不属于 intent log;如果外部操作确实把持久内容带进项目,记录的是落入项目的
246
+ 内容改动,而不是外部操作本身。
247
+
248
+ 多 agent 协作时,intent 的作用域属于 worktree,而不是写入者。一个 worktree 只能有一个
249
+ open intent;在那里改动持久项目内容的所有 agent 和 subagent 都要先重新锚定,再继续同一个
250
+ 匹配的 intent。不同 worktree 各自持有 intent;非 Git 项目的 configured root 同样只持有
251
+ 一个。只通过 Git 或共享 worktree 接收其他 agent 变更的一方不另记 receiving intent,交给
252
+ `verify` 暴露不一致。handoff 文件在被 ignore 或以其他方式排除在持久项目内容之外时免记,
253
+ 一旦转为正式项目内容就需要 intent。在同一个 root 中途接手工作属于重新锚定而非边界:目标
254
+ 仍然匹配就继续沿用 open intent。
244
255
 
245
256
  ## 命令速览
246
257
 
package/bin/driftseal.js CHANGED
@@ -41,7 +41,7 @@ const DECISION_STATUSES = [
41
41
  'superseded',
42
42
  ];
43
43
  const EVENT_SCHEMA_VERSION = 4;
44
- const PROTOCOL_VERSION = 13;
44
+ const PROTOCOL_VERSION = 14;
45
45
  const DEFAULT_LOG_LANGUAGE = 'en';
46
46
  const IN_PROGRESS_GIT_PATH = 'driftseal-in-progress.jsonl';
47
47
  const LOCK_STALE_MS = 30 * 60 * 1000;
@@ -1874,20 +1874,31 @@ MCP and lifecycle hooks are optional adapters.
1874
1874
 
1875
1875
  ${intentLogLanguageParagraph(language)}
1876
1876
 
1877
- 1. **Write intent first**, before modifying, creating, or deleting files, or
1878
- making any other non-Git change that may need a rollback:
1877
+ 1. **Write intent first**, before changing durable project content:
1879
1878
  \`driftseal begin "<what this round will accomplish>" --accept "<observable outcome>" --verify "<exact command that proves it>"\`.
1880
1879
  Repeat \`--accept\` when completion has multiple independently observable criteria.
1881
1880
  Add one \`--decision <id>\` for each existing decision this round may change.
1882
- Git operations never need an intent and are not included in the intent log;
1883
- Git maintains their history. This includes inspection, branch and worktree
1884
- management, staging, commits, merges, rebases, cherry-picks, tags, and pushes.
1885
- A command whose result can be reconstructed from Git state (for example a
1886
- patch file regenerated from a commit range, or a scratch harness that
1887
- re-runs) needs no intent; content that will be committed and cannot be
1888
- reconstructed (for example a .gitignore edit) does.
1889
- Single-step commands that only build or check work already done, such as
1890
- compiling or running tests, also need no intent.
1881
+ Record intents for changes intended to persist in the project: edits to code,
1882
+ configuration, documentation, dependencies, and equivalent project files,
1883
+ whether or not the project is inside a Git worktree. Everything else is
1884
+ exempt: Git operations (Git maintains their history inspection, branch
1885
+ and worktree management, staging, commits, merges, rebases, cherry-picks,
1886
+ tags, and pushes); single-step commands that only build or check work
1887
+ already done, such as compiling or running tests; auxiliary file or shell
1888
+ operations whose results remain outside durable project content (for example
1889
+ an rsync scratch copy or temp scaffolding); and state changes to a remote
1890
+ machine or the local environment that do not write durable project content
1891
+ into this workspace. When an external operation does bring durable content
1892
+ into the project, record an intent for that project-content change, not for
1893
+ the external operation itself.
1894
+ In multi-agent work, one open intent belongs to one worktree, or to one
1895
+ configured project root outside Git. Every agent or subagent that changes
1896
+ durable project content in the same root first re-anchors and continues its
1897
+ matching open intent; agents working in separate worktrees hold separate
1898
+ intents. An agent that only receives another agent's changes through Git or
1899
+ into a shared worktree records no receiving intent and lets \`verify\` expose
1900
+ misalignment; handoff files are exempt while ignored or otherwise kept
1901
+ outside durable project content and require an intent when promoted into it.
1891
1902
  Size an intent to the smallest unit that leaves the tree self-consistent
1892
1903
  and can be verified on its own.
1893
1904
  2. **Execute only the intent.** Scope change? Close the current intent
@@ -1914,12 +1925,15 @@ ${intentLogLanguageParagraph(language)}
1914
1925
  by the next linked \`decision update\` or successful \`end\`. Closing as
1915
1926
  \`failed\` or \`abandoned\` cancels pending recovery for that intent.
1916
1927
  Git operations remain subject to normal authorization and safety requirements
1917
- even though they do not require an intent. Any non-Git content change made while
1918
- preparing a Git operation does require a new intent, per the step 1 test.
1928
+ even though they do not require an intent. Any content change made while
1929
+ preparing a Git operation still requires an intent when it meets the
1930
+ durable-project-content rule in step 1.
1919
1931
  4. **Re-anchor after context loss**: run \`driftseal status\` and \`driftseal log --last 3\` before
1920
1932
  doing anything else. The open intent is the source of truth: resume it when its
1921
1933
  objective still matches the current task; otherwise close it (\`partial\` or
1922
- \`abandoned\`, with a note) and \`begin\` a new one.
1934
+ \`abandoned\`, with a note) and \`begin\` a new one. Taking over work in the
1935
+ same root from another agent is the same re-anchor: resume the open intent
1936
+ when its objective still matches.
1923
1937
 
1924
1938
  **Log access goes only through DriftSeal.** Never read, edit, move, or delete
1925
1939
  \`.intent-log/events.jsonl\` (or anything under \`$DRIFTSEAL_HOME\`) directly; use
@@ -1935,7 +1949,75 @@ ${INTENT_PROTOCOL_END}`;
1935
1949
  }
1936
1950
 
1937
1951
  function previousIntentProtocolBlock(version, language = DEFAULT_LOG_LANGUAGE, localLog = false) {
1938
- const v12 = intentProtocolBlock(version, language, localLog)
1952
+ const v13 = intentProtocolBlock(version, language, localLog)
1953
+ .replace(
1954
+ '1. **Write intent first**, before changing durable project content:\n' +
1955
+ ' `driftseal begin "<what this round will accomplish>" --accept "<observable outcome>" --verify "<exact command that proves it>"`.\n' +
1956
+ ' Repeat `--accept` when completion has multiple independently observable criteria.\n' +
1957
+ ' Add one `--decision <id>` for each existing decision this round may change.\n' +
1958
+ ' Record intents for changes intended to persist in the project: edits to code,\n' +
1959
+ ' configuration, documentation, dependencies, and equivalent project files,\n' +
1960
+ ' whether or not the project is inside a Git worktree. Everything else is\n' +
1961
+ ' exempt: Git operations (Git maintains their history — inspection, branch\n' +
1962
+ ' and worktree management, staging, commits, merges, rebases, cherry-picks,\n' +
1963
+ ' tags, and pushes); single-step commands that only build or check work\n' +
1964
+ ' already done, such as compiling or running tests; auxiliary file or shell\n' +
1965
+ ' operations whose results remain outside durable project content (for example\n' +
1966
+ ' an rsync scratch copy or temp scaffolding); and state changes to a remote\n' +
1967
+ ' machine or the local environment that do not write durable project content\n' +
1968
+ ' into this workspace. When an external operation does bring durable content\n' +
1969
+ ' into the project, record an intent for that project-content change, not for\n' +
1970
+ ' the external operation itself.\n' +
1971
+ ' In multi-agent work, one open intent belongs to one worktree, or to one\n' +
1972
+ ' configured project root outside Git. Every agent or subagent that changes\n' +
1973
+ ' durable project content in the same root first re-anchors and continues its\n' +
1974
+ ' matching open intent; agents working in separate worktrees hold separate\n' +
1975
+ " intents. An agent that only receives another agent's changes through Git or\n" +
1976
+ ' into a shared worktree records no receiving intent and lets `verify` expose\n' +
1977
+ ' misalignment; handoff files are exempt while ignored or otherwise kept\n' +
1978
+ ' outside durable project content and require an intent when promoted into it.\n' +
1979
+ ' Size an intent to the smallest unit that leaves the tree self-consistent\n' +
1980
+ ' and can be verified on its own.',
1981
+ '1. **Write intent first**, before modifying, creating, or deleting files, or\n' +
1982
+ ' making any other non-Git change that may need a rollback:\n' +
1983
+ ' `driftseal begin "<what this round will accomplish>" --accept "<observable outcome>" --verify "<exact command that proves it>"`.\n' +
1984
+ ' Repeat `--accept` when completion has multiple independently observable criteria.\n' +
1985
+ ' Add one `--decision <id>` for each existing decision this round may change.\n' +
1986
+ ' Git operations never need an intent and are not included in the intent log;\n' +
1987
+ ' Git maintains their history. This includes inspection, branch and worktree\n' +
1988
+ ' management, staging, commits, merges, rebases, cherry-picks, tags, and pushes.\n' +
1989
+ ' A command whose result can be reconstructed from Git state (for example a\n' +
1990
+ ' patch file regenerated from a commit range, or a scratch harness that\n' +
1991
+ ' re-runs) needs no intent; content that will be committed and cannot be\n' +
1992
+ ' reconstructed (for example a .gitignore edit) does.\n' +
1993
+ ' Single-step commands that only build or check work already done, such as\n' +
1994
+ ' compiling or running tests, also need no intent.\n' +
1995
+ ' Size an intent to the smallest unit that leaves the tree self-consistent\n' +
1996
+ ' and can be verified on its own.'
1997
+ )
1998
+ .replace(
1999
+ ' Git operations remain subject to normal authorization and safety requirements\n' +
2000
+ ' even though they do not require an intent. Any content change made while\n' +
2001
+ ' preparing a Git operation still requires an intent when it meets the\n' +
2002
+ ' durable-project-content rule in step 1.',
2003
+ ' Git operations remain subject to normal authorization and safety requirements\n' +
2004
+ ' even though they do not require an intent. Any non-Git content change made while\n' +
2005
+ ' preparing a Git operation does require a new intent, per the step 1 test.'
2006
+ )
2007
+ .replace(
2008
+ '4. **Re-anchor after context loss**: run `driftseal status` and `driftseal log --last 3` before\n' +
2009
+ ' doing anything else. The open intent is the source of truth: resume it when its\n' +
2010
+ ' objective still matches the current task; otherwise close it (`partial` or\n' +
2011
+ ' `abandoned`, with a note) and `begin` a new one. Taking over work in the\n' +
2012
+ ' same root from another agent is the same re-anchor: resume the open intent\n' +
2013
+ ' when its objective still matches.',
2014
+ '4. **Re-anchor after context loss**: run `driftseal status` and `driftseal log --last 3` before\n' +
2015
+ ' doing anything else. The open intent is the source of truth: resume it when its\n' +
2016
+ ' objective still matches the current task; otherwise close it (`partial` or\n' +
2017
+ ' `abandoned`, with a note) and `begin` a new one.'
2018
+ );
2019
+ if (version >= 13) return v13;
2020
+ const v12 = v13
1939
2021
  .replace(
1940
2022
  ' `driftseal begin "<what this round will accomplish>" --accept "<observable outcome>" --verify "<exact command that proves it>"`.\n' +
1941
2023
  ' Repeat `--accept` when completion has multiple independently observable criteria.',
@@ -2900,11 +2982,13 @@ function hookReminder(event, { readOnly = false } = {}) {
2900
2982
  if (!file) return null;
2901
2983
  if (event === 'prompt') {
2902
2984
  return (
2903
- 'DriftSeal reminder: if this round will modify files or anything else that may need a ' +
2904
- 'rollback, begin an intent first: driftseal begin "<intent>" --accept "<observable outcome>" ' +
2985
+ 'DriftSeal reminder: if this round will change durable project content in this workspace ' +
2986
+ '(code, configuration, documentation, dependencies), ' +
2987
+ 'begin an intent first: driftseal begin "<intent>" --accept "<observable outcome>" ' +
2905
2988
  '--verify "<command>". ' +
2906
- 'Questions, read-only exploration, and single-step checks need no intent skip this ' +
2907
- 'reminder when it does not apply.'
2989
+ 'Questions, read-only exploration, single-step checks, temporary work outside durable ' +
2990
+ 'project content, and external state changes that do not write project content here need ' +
2991
+ 'no intent — skip this reminder when it does not apply.'
2908
2992
  );
2909
2993
  }
2910
2994
  const open = openIntent(fold(readEvents({ file, readOnly })));
@@ -4607,6 +4691,8 @@ const commands = {
4607
4691
  knownManagedBlocks: [
4608
4692
  ...sourceLanguages.flatMap((source) => [
4609
4693
  protocolEol(intentProtocolBlock(PROTOCOL_VERSION, source), eol),
4694
+ protocolEol(previousIntentProtocolBlock(13, source), eol),
4695
+ protocolEol(previousIntentProtocolBlock(13, source, true), eol),
4610
4696
  protocolEol(previousIntentProtocolBlock(12, source), eol),
4611
4697
  protocolEol(previousIntentProtocolBlock(12, source, true), eol),
4612
4698
  protocolEol(previousIntentProtocolBlock(11, source), eol),
@@ -4634,6 +4720,8 @@ const commands = {
4634
4720
  knownManagedBlocks: [
4635
4721
  ...sourceLanguages.flatMap((source) => [
4636
4722
  protocolEol(decisionProtocolBlock(PROTOCOL_VERSION, source), eol),
4723
+ protocolEol(previousDecisionProtocolBlock(13, source), eol),
4724
+ protocolEol(previousDecisionProtocolBlock(13, source, true), eol),
4637
4725
  protocolEol(previousDecisionProtocolBlock(12, source), eol),
4638
4726
  protocolEol(previousDecisionProtocolBlock(12, source, true), eol),
4639
4727
  protocolEol(previousDecisionProtocolBlock(11, source), eol),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "driftseal",
3
- "version": "1.3.2",
3
+ "version": "1.4.0",
4
4
  "description": "Seal intent, verification, and decisions into an auditable workflow for agentic coding",
5
5
  "keywords": [
6
6
  "driftseal",