docs: replace vague provenance prose with recorded facts
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ Claude Code/Codex 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。
|
||||
|
||||
## 模型体验
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 ?? []]
|
||||
}
|
||||
|
||||
@@ -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 = () => {}
|
||||
|
||||
|
||||
@@ -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 ?? []]
|
||||
}
|
||||
|
||||
@@ -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 = () => {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user