docs: replace vague provenance prose with recorded facts

This commit is contained in:
Turtle
2026-08-09 15:35:02 +08:00
parent 8c124f84b6
commit 9704749b01
380 changed files with 946 additions and 874 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/hooks/hook-protocol/README.md
README.md: e807d9597eb5f811195bab9a0ad2b30b545e1205
README.zh.md: c206224b45a5b12a7aa85d24de301f3d949f294b
README.md: 797d15c357bd26e0db072b30b61c251005021905
README.zh.md: 8a96cd2f1f91ad2d7a12fc15ffc06ea0c2c1d80f

View File

@@ -29,7 +29,7 @@ Why a shared lib at all: Codex deliberately reimplements a *subset* of the Claud
Declaration-merged into `SessionEventMap` (log-only, like `compact/*` — NOT a `SurfaceEventType`, no `surfaceOp`): `hook/invoked` (a hook command ran) and `hook/result` (its outcome, paired by `handlerId`, with `appendHookResult` owning the decision rule). Payloads and per-event JSDoc are in the generated [persistence log event catalog](../../../docs/persistence-catalog.md); `stderrSummary` is truncated to the record's `stderrSummaryMaxChars` (the bridge's config, reference default `DEFAULT_STDERR_SUMMARY_MAX_CHARS` = 500; omitted when empty).
Hook provenance records must sit inside an open turn. `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, and `Stop` satisfy that owner-defined relation by construction. `SessionStart` runs before turn 1 and gets no `hook/*` record; its allowed context remains pending in the inbox until a waking delivery opens a turn — see the hooks Agent Note.
Hook invocation/result records must sit inside an open turn. `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, and `Stop` satisfy that owner-defined relation by construction. `SessionStart` runs before turn 1 and gets no `hook/*` record; its allowed context remains pending in the inbox until a waking delivery opens a turn — see the hooks Agent Note.
## Model Experience

View File

@@ -29,7 +29,7 @@ Claude CodeCodex hook 协议格式wire format的**共享核心**。它
通过 declaration merging 合并到 `SessionEventMap`(仅日志,与 `compact/*` 相同;不是 `SurfaceEventType`,没有 `surfaceOp``hook/invoked`hook 命令已运行)与 `hook/result`(其结果,按 `handlerId` 配对,决策规则由 `appendHookResult` 负责。Payload 与每事件 JSDoc 位于生成的 [持久化日志事件目录](../../../docs/persistence-catalog.md)`stderrSummary` 会截断到记录的 `stderrSummaryMaxChars`(桥接配置,参考默认值 `DEFAULT_STDERR_SUMMARY_MAX_CHARS` = 500为空时省略
Hook 溯源记录必须位于一个尚未结束的轮次内。`UserPromptSubmit``PreToolUse``PostToolUse``Stop` 按构造满足这条由所有者定义的关系。`SessionStart` 在轮次 1 之前运行,因此没有 `hook/*` 记录;其获准的上下文会在 inbox 中保持待处理,直到唤醒交付打开一个轮次,详见 hooks Agent Note。
Hook 调用/结果记录必须位于一个尚未结束的轮次内。`UserPromptSubmit``PreToolUse``PostToolUse``Stop` 按构造满足这条由所有者定义的关系。`SessionStart` 在轮次 1 之前运行,因此没有 `hook/*` 记录;其获准的上下文会在 inbox 中保持待处理,直到唤醒交付打开一个轮次,详见 hooks Agent Note。
## 模型体验

View File

@@ -68,7 +68,7 @@ export function summarizeStderr(stderr: string, maxChars: number): string | unde
}
/**
* Append a `hook/invoked` provenance event to `session`.
* Append a `hook/invoked` event naming the handler and hook point to `session`.
* @param session - the session whose open turn records the event.
* @param invocation - the invocation identity; an absent `matcher` is omitted from the payload.
*/

View File

@@ -1,4 +1,4 @@
/** Package-owned hook provenance-stream invariants. @module @deepseek-ai/dsh-hook-protocol/invariant */
/** Package-owned hook invocation/result stream invariants. @module @deepseek-ai/dsh-hook-protocol/invariant */
import type { Context } from 'cordis'
import type { Session, SessionEvent } from '@deepseek-ai/dsh-session'
@@ -98,7 +98,7 @@ const install: InvariantInstaller = Object.assign((ctx: Context, fail: Invariant
}
if (event.type !== 'hook/invoked' && event.type !== 'hook/result') return
const candidate = staged.get(event)
/* v8 ignore next -- internal/dispatch stages every hook provenance event */
/* v8 ignore next -- internal/dispatch stages every hook invocation/result event */
if (candidate === undefined || candidate.session !== session) return fail('hook event published without pre-commit validation')
staged.delete(event)
applyHookTransition(trace.pending, candidate.transition)

View File

@@ -8,7 +8,7 @@
declare module '@deepseek-ai/dsh-session' {
interface SessionEventMap {
/**
* A hook command was invoked at a hook point — log-only provenance (like
* A hook command was invoked at a hook point — a log-only record (like
* `compact/*`; NOT a {@link SurfaceEventType}, carries no `surfaceOp`).
* `dialect` is the bridge that ran it (`claude`/`codex`), `point`
* the hook point (`PreToolUse`, `Stop`, …), `matcher` the matcher-group
@@ -43,7 +43,7 @@ declare module '@deepseek-ai/dsh-session' {
/**
* The bridge that ran a hook — the CC bridge stamps `'claude'`, the Codex
* bridge `'codex'`. A native plugin on the interception seams is not a bridge
* and writes no `hook/*` provenance (see the interception-seams Agent Note).
* and writes no `hook/*` invocation/result records (see the interception-seams Agent Note).
*/
export type HookDialect = 'claude' | 'codex'

View File

@@ -45,7 +45,7 @@ describe('hook-protocol invariants', () => {
session.append('hook/result', result())
})
it('rebuilds pending hook provenance from an existing session', async () => {
it('rebuilds pending hook invocations from an existing session', async () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
const session = ctx.sessions.create()

View File

@@ -195,7 +195,7 @@ export function apply(ctx: Context, config: Config): void {
return createUserMessage({ content, source: PLUGIN_SOURCE })
}
/** Prepend one context without flattening downstream provenance or metadata. */
/** Prepend one context without flattening source fields or other downstream metadata. */
function prependContext(ours: UserMessage, theirs: UserMessage[] | undefined): UserMessage[] {
return [ours, ...theirs ?? []]
}

View File

@@ -16,7 +16,7 @@ export const inject = ['invariants']
/**
* No runtime invariant: this bridge publishes hook-protocol session events, whose companion owns
* their cross-event provenance relation.
* which invocation event each result cites.
*/
const install: InvariantInstaller = () => {}

View File

@@ -107,7 +107,7 @@ export function apply(ctx: Context, config: Config): void {
/**
* Run and fold one configured Codex hook point.
*
* A supplied turn records the hook provenance pair inside that open turn.
* A supplied turn records the hook invocation/result pair inside that open turn.
* Detached lifecycle points omit it.
*/
async function runPoint(
@@ -177,7 +177,7 @@ export function apply(ctx: Context, config: Config): void {
return createUserMessage({ content, source: PLUGIN_SOURCE })
}
/** Prepend one context without flattening downstream provenance or metadata. */
/** Prepend one context without flattening source fields or other downstream metadata. */
function prependContext(ours: UserMessage, theirs: UserMessage[] | undefined): UserMessage[] {
return [ours, ...theirs ?? []]
}

View File

@@ -16,7 +16,7 @@ export const inject = ['invariants']
/**
* No runtime invariant: this bridge publishes hook-protocol session events, whose companion owns
* their cross-event provenance relation.
* which invocation event each result cites.
*/
const install: InvariantInstaller = () => {}