dsh-completion-guard 0.2.1 → 0.3.1
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/CHANGELOG.md +35 -1
- package/CHANGELOG.zh-CN.md +35 -1
- package/README.md +47 -5
- package/README.zh-CN.md +47 -5
- package/bin/dsh-completion-guard-host-lock.mjs +52 -0
- package/dist/domain/index.d.ts +2 -2
- package/dist/domain/index.js +2 -2
- package/dist/domain-CBvBQHTL.js +5828 -0
- package/dist/index-GvKLkTqV.d.ts +957 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.js +2463 -119
- package/docs/ARCHITECTURE.md +11 -7
- package/docs/COMPATIBILITY.md +23 -3
- package/docs/LOCAL_ACCEPTANCE.md +221 -1
- package/docs/SEMANTIC_COMPATIBILITY.md +118 -0
- package/docs/distribution.md +54 -0
- package/docs/upstream-deltas.json +217 -0
- package/manifests/action-manifest.v1.json +33 -0
- package/manifests/git-command-manifest.v2.json +52 -0
- package/manifests/supported-host.v1.json +66 -0
- package/package.json +48 -8
- package/dist/domain-BN3_AuUr.js +0 -1997
- package/dist/index-Dk4SkQ8H.d.ts +0 -448
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -26,7 +26,9 @@ The in-memory `GuardProjection` is a rebuildable cache: `deriveProjection` appli
|
|
|
26
26
|
|
|
27
27
|
## Synchronization
|
|
28
28
|
|
|
29
|
-
The runtime rebuilds the projection from the log before each step. Before evidence is produced, the runtime awaits `ctx.sessions.flush(session)`; if no durability listener participated, evidence is
|
|
29
|
+
The runtime rebuilds the projection from the log before each step. Before evidence is produced, the runtime awaits `ctx.sessions.flush(session)`; if no durability listener participated, evidence is marked `durability-unknown`, which fails closed.
|
|
30
|
+
|
|
31
|
+
The v0.3 runtime accepts host identity only from `hostLockPackages` generated from the active runtime/profile graphs and bound to the active platform/profile kind. It does not infer identity from the nearest `pnpm-lock.yaml`: DSH core and profile plugins have separate locks, and the runtime lock can contain several historical versions. Missing, unreadable, duplicate, multi-version, or drifted identity disables the dependent capability. The audited values and action/platform capability groups live in `manifests/supported-host.v1.json`. `deriveProjection` receives this exact evaluation before it replays any checkpoint, so a certificate is never validated under a default lock and overwritten later; a changed digest retains historical evidence but makes current authority stale. Ordinary persisted `bash`/`pwsh` results are replayed only when the active platform's agent-loop and terminal group is exact; wrong-platform tool names fail closed. Ordinary `read`/`write`/`edit` results require the independent filesystem group, which pins the tool schemas and result/presentation contract together with the local/sandbox provider, observation policy, sandbox policy, and approval services. A filesystem-group failure disables only `create`/`modify` and filesystem-derived facts, not an independently valid terminal action.
|
|
30
32
|
|
|
31
33
|
Evidence is produced only from persisted `tool/call` + `tool/result` pairs. Guard never inserts context between a Code Mode sub-call and its durable result.
|
|
32
34
|
|
|
@@ -34,9 +36,11 @@ Evidence is produced only from persisted `tool/call` + `tool/result` pairs. Guar
|
|
|
34
36
|
|
|
35
37
|
1. `classifyUserInteraction` drops session-layer utterances before capture: bare progression/acknowledgement phrases (`继续`, `continue`), meta questions (`这个收尾具体要做什么`, `是不是bug`), and meta comments/objections. The classifier fails closed — an artifact path, an explicit method, or a non-negated operation verb always keeps the message (or the individual clause inside a mixed message) a captured instruction.
|
|
36
38
|
2. `classifyClause` / `captureClause` classify the remaining direct human message into requirement, acceptance, or prohibition.
|
|
37
|
-
3. `
|
|
38
|
-
4. `
|
|
39
|
-
5. `certifyCheckpoint`
|
|
40
|
-
6.
|
|
41
|
-
7. `
|
|
42
|
-
8. `
|
|
39
|
+
3. `segmentAuthorityBlocks` keeps quoted/code/reference material outside the contract, supports explicit section adoption, and captures uncertain material fail-closed.
|
|
40
|
+
4. `context_guard_evidence` produces read-only resolution/state facts and validates already persisted effects; `context_guard_action` owns the explicitly mutating install/apply/restart/publish and Git paths. Before any executable, command, HTTP request, or durable intent, the action tool flushes and replays the resolution/contract chain, then runtime authorization binds the action to one exact pending root-owned requirement/revision (never a prohibition or acceptance), rejects any matching pending root prohibition, and rechecks Guard integrity, host identity, semantic action, target-capture status, and every action-specific requested/resolved identity field. Exact package version/profile/registry and explicit Git remote/full refspec are required; resolution-only integrity, boot generation, and Git OIDs remain bound by the target digest and live prestate. `evidenceFromPersistedToolResult` maps persisted results to versioned semantic actions, evidence roles, exact resolved targets, observed state, executable identity, immutable resolution-time expected transition, and bounded diagnostics. Only exact adapter and command-manifest IDs/versions in the shipped manifests may supply structured state facts. On Windows, audited `.cmd`/`.bat` shims are version-probed through a closed invocation whose interpreter is pinned to the canonical `SystemRoot\\System32\\cmd.exe` realpath and version. Resolution and effect bind both identities; execution reuses the revalidated paths and rejects shell-control or expansion characters rather than re-resolving the logical name through `PATH` or trusting a changed `ComSpec`. Modify transition construction first re-hashes the current source bytes against the resolved pre-digest, then applies the pinned unique UTF-8 replacement. Commit readback parses the raw post-commit parent tuple and accepts exactly one parent equal to the resolved pre-effect HEAD; fetch freezes that HEAD and requires the post-effect HEAD to remain identical. Pre-execute revalidation is a correctness gate, not isolation from a concurrently malicious process running as the same user; a mismatching post-action readback remains non-certifiable.
|
|
41
|
+
5. `certifyCheckpoint` flushes and resynchronizes first. Non-stateful actions require an action-compatible minimal facet; every action in the ten-member `STATEFUL_ACTIONS` set requires distinct resolution, effect, and independent state evidence, one shared resolved target, non-overlapping state observations, and an expected-transition predicate frozen and digested by the resolution fact before effect. The binding must reproduce that payload exactly before observed state is compared.
|
|
42
|
+
6. A certificate freezes protocol/certificate versions, epoch, `sessionRefDigest`, `hostLockDigest`, contract revision/hash, explicit null-or-current Goal ref, open/evidence/binding digests, and the final certification digest. The tool computes a candidate without mutating runtime authority; only a persisted tool result that re-derives byte-for-byte becomes current authority.
|
|
43
|
+
7. `goalCompletionDenial` rejects the Guard-owned `update_goal(action=complete)` model-tool path before the Goal mutation unless that certificate is current. A trusted in-process producer can bypass the tool guard; replay detects the durable `goal/change complete` without a certificate and records an integrity violation, but the plugin does not claim to prevent or roll it back.
|
|
44
|
+
8. `context_guard_boundary` persists only qualified `user_wait`, `external_wait`, or `deferred` candidates. After the accepted tool result is flushed and replayed, the post-commit path reads the same active/armed Goal ref, calls `goals.disarm(agent)`, and independently reads the same ref as disarmed. Pre-effect, still-armed, and post-effect-unknown failures have separate fail-closed/fail-loud outcomes.
|
|
45
|
+
9. `decideTurnBoundary` reads only structured Guard/Goal state. Assistant completion prose is diagnostic and never a stop or continuation control source; active/armed continuation belongs to the Goal Round Driver.
|
|
46
|
+
10. `renderRecoveryPacket` re-injects open requirements after compaction, resume, enable, rejection, or integrity loss. Injection is content-deduplicated: a re-armed packet with unchanged content is injected once, while resume, compaction, an enablement transition, new evidence, or a new contract revision change or forget the digest and always re-remind.
|
package/docs/COMPATIBILITY.md
CHANGED
|
@@ -17,9 +17,11 @@ The package exposes a named `apply(ctx)` function and a named `inject` array (`[
|
|
|
17
17
|
|
|
18
18
|
The plugin accepts an `activation` configuration value of `opt-in` or `always`. The default is `opt-in`; `always` initializes the projection as enabled before the persisted session log is replayed. Invalid values fail during plugin configuration instead of silently falling back. A DSH profile can select `always` with an ID-targeted `config` override in its `cordis.patch.yml`; see the README quick start for the complete example and the replay implications for existing sessions.
|
|
19
19
|
|
|
20
|
+
Version 0.3 additionally accepts `hostLockPackages`, `hostLockPlatform`, and `hostLockProfile`, generated from the active DSH runtime and profile graphs. Each critical row carries the exact resolved version and registry tarball integrity. Missing, duplicate, multi-version, or drifted identity is not inferred from a nearby lockfile and fails closed. Capabilities are evaluated separately for base/Goal, agent loop, POSIX or Windows terminal, filesystem tools, DSH CLI, plugin inventory, Web control, and jobs; a missing platform- or action-specific group disables only the dependent path. The filesystem group freezes pinned `read`/`write`/`edit` registration, closed result and presentation shapes, the `ctx.fs` local/sandbox implementation, read-before-mutation observation policy, sandbox policy, and approval provider. Consequently a missing or drifted filesystem row disables only `create`/`modify` and ordinary filesystem facts, while a valid terminal or jobs capability remains usable. The audited identity is [`../manifests/supported-host.v1.json`](../manifests/supported-host.v1.json). The packaged `dsh-completion-guard-host-lock inspect|inject|verify-dump` flow in the README is the supported generation and readback path; the default patch has no `hostLockPackages` and therefore fails closed until that flow succeeds.
|
|
21
|
+
|
|
20
22
|
## Peer dependencies
|
|
21
23
|
|
|
22
|
-
Runtime packages are host-provided and declared as peer dependencies: `@deepseek-ai/cordis`, `@deepseek-ai/dsh-agent`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-llm`, `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`.
|
|
24
|
+
Runtime packages are host-provided and declared as peer dependencies: `@deepseek-ai/cordis`, `@deepseek-ai/dsh-agent`, `@deepseek-ai/dsh-commands`, `@deepseek-ai/dsh-llm`, `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`. Goal uses two exact optional peers as one capability: `@deepseek-ai/dsh-goal@0.1.1-rc.2` owns state, and `@deepseek-ai/dsh-tool-goal@0.1.1-rc.2` owns the audited `update_goal` name/schema/arguments. Both graph rows and the live Goal service/tool must agree. Profiles without this complete capability still load, but Goal-dependent integration is inactive. The other peer ranges remain compatible package declarations, while runtime acceptance is constrained by the exact injected host lock.
|
|
23
25
|
|
|
24
26
|
## Terminal outcome contract
|
|
25
27
|
|
|
@@ -39,12 +41,20 @@ unsupported or malformed syntax produces no executable or operation facts and
|
|
|
39
41
|
no certifying subject/capability combination, so it cannot close a contract even
|
|
40
42
|
when the host execution itself succeeded.
|
|
41
43
|
|
|
44
|
+
Replay also binds the ordinary tool name to the active host surface: `bash`
|
|
45
|
+
requires the exact POSIX terminal group and `pwsh` the exact Windows group.
|
|
46
|
+
The opposite-platform name is `adapter_unavailable`, not a portable alias.
|
|
47
|
+
Likewise, ordinary `read`, `write`, and `edit` results require the exact
|
|
48
|
+
filesystem capability group. Base-lock support alone is insufficient; the
|
|
49
|
+
bounded fact retains an explicit host-capability reason code, carries no
|
|
50
|
+
certifying capability, and has unknown outcome.
|
|
51
|
+
|
|
42
52
|
## Verified surfaces
|
|
43
53
|
|
|
44
54
|
- `dsh --profile web --dump-config` and `--profile headless --dump-config` both include `context-guard`.
|
|
45
55
|
- A real headless boot loads the plugin (apply, `ctx.sessions` access, and listener registration succeed) and only stops at missing provider credentials.
|
|
46
56
|
|
|
47
|
-
The slash command renders in the Web command directory and its on/off/clear/status/diagnose subcommands produce the expected `command/run`/`command/done`.
|
|
57
|
+
The slash command renders in the Web command directory and its on/off/clear/status/diagnose subcommands produce the expected `command/run`/`command/done`. The v0.3 runtime baseline exercises 352 deterministic tests in 19 files, including all 37 mirrored portable semantic cases and all 29 digest vectors: macOS passed 351 tests with the one Windows-only shim test capability-skipped, while native Windows passed all 352 with no skips. The same canonical pre-release tgz passed isolated Web/Headless install, host-lock inspect/inject/dump/verify, real dshmarket restart readback, HTTP recovery, and cleanup on both native platforms; Headless loaded to the intentional missing-credential boundary. CI covered Ubuntu, macOS, and Windows on Node.js 22 and 24. A credentialed model session verified an accepted evidence binding and persisted typed-boundary/disarm path; an intentionally over-broad prompt remained incomplete and received no false certificate. Version 0.3.1 preserves those runtime bytes and repairs only the frozen-package provenance path after the 0.3.0 registry entry omitted `gitHead`. The final 0.3.1 tgz remains separately bound to native-platform and public registry readback, as recorded in `LOCAL_ACCEPTANCE.md`. Evidence and certificates are session-scoped: a later DSH session cannot import or certify evidence IDs from an earlier session, so a workflow requiring a certificate must produce its evidence and checkpoint in one session. The published 0.1.x and 0.2.x releases retain separate historical evidence. The fail-closed invariants below are asserted as regressions.
|
|
48
58
|
|
|
49
59
|
## Session-layer capture filter and goal completion (v0.2.1)
|
|
50
60
|
|
|
@@ -72,7 +82,17 @@ Recovery packet injection is content-deduplicated: an unchanged packet is
|
|
|
72
82
|
injected once per re-arm, while resume, compaction, an enablement transition,
|
|
73
83
|
new evidence, or a new contract revision always re-remind.
|
|
74
84
|
|
|
75
|
-
##
|
|
85
|
+
## v0.3 semantic action and binding contract
|
|
86
|
+
|
|
87
|
+
[`../manifests/action-manifest.v1.json`](../manifests/action-manifest.v1.json) freezes the action vocabulary, compatibility matrix, required target/state keys, expected-transition predicates, and accepted structured evidence adapter versions. `generic_run` is not a wildcard and cannot certify another semantic action.
|
|
88
|
+
|
|
89
|
+
The full `STATEFUL_ACTIONS` set is `install | apply | create | modify | restart | commit | push | publish | pull | fetch`. Each requires distinct resolution/effect/state evidence IDs, exact same-target closure, independent state readback, and a versioned expected-transition payload. An effect-only success is incomplete. Old v0.2 scope-run certificates are retained as `legacy_generic_run` audit facts and do not become current v0.3 authority; unprovable legacy authority is also non-certifiable.
|
|
90
|
+
|
|
91
|
+
`context_guard_evidence` is a read-only producer for resolution, persisted-effect validation, and state readback. `context_guard_action` is the explicitly mutating surface for exact-tgz install/apply/publish, two-phase dshmarket restart, and exact Git commit/push/pull/fetch. It first flushes and replays the resolution/contract chain, then requires the exact target digest and id/revision of one current pending `root_instruction` or `root_adoption` requirement whose action and complete requested identity match this resolution; a matching pending root prohibition denies the mutation regardless of message order, while prohibitions and acceptance clauses never grant authority. Install/apply require exact package id, version, and profile; publish requires exact artifact id, version, and canonical registry (v0.3 does not authorize `latest` or ranges); push/pull/fetch require repository, remote, and canonical explicit full ref/refspec; restart requires the exact service id. Disabled, integrity-unknown, stale-host, missing, passed, superseded, clarification-required, incomplete-target, action-swapped, target-swapped, and unrebound legacy paths are rejected before executable inspection, command execution, HTTP, or intent persistence. Unknown selector, command-manifest, or Git argument keys are rejected. `install` requires package absence, while `apply` requires an existing package and a changed version/integrity. Publish executes the exact resolved tgz with `--ignore-scripts`; its registry is a canonical HTTPS base shared by capture, argv, and standard packument readback, with credentials, query, fragment, encoded separators, control characters, and ambiguous path segments rejected. Resolution and effect bind the same canonical executable realpath and version. Windows `.cmd`/`.bat` shims additionally bind the canonical `SystemRoot\\System32\\cmd.exe` realpath and version; arguments containing shell-control, expansion, quote, NUL, or newline characters are unsupported, and execution never performs a second `PATH` search or trusts a changed `ComSpec`. Modify re-hashes the source bytes against the frozen pre-digest before deriving the unique UTF-8 replacement post-digest. Restart persists an intent before POST and closes only after a restored process observes a changed boot ID. Git operations reject aliases, implicit/delete/wildcard/force refs, target substitution, and prestate drift. Commit certification additionally rejects root, merge, or substituted-parent commits; fetch certification requires its resolved pre-HEAD, post-HEAD readback, and predicate parameter to be equal. Pre-execute revalidation is a correctness gate rather than isolation from same-user concurrent tampering; any divergent post-action readback is not certified.
|
|
92
|
+
|
|
93
|
+
Every stateful resolution freezes its expected transition before effect and binds a stable digest of that payload. Checkpoint diagnostics copy this immutable payload from the resolution fact; callers cannot construct create/modify predicates from post-effect state. Create hashes the exact UTF-8 content from the closed write manifest. Modify first reads the original bytes, requires valid UTF-8 and exactly one `old_string` match, applies the pinned single replacement in memory, and hashes the resulting bytes. Restart freezes `health=healthy` as a manifest constant. A later successful effect whose independent state differs from these values remains incomplete.
|
|
94
|
+
|
|
95
|
+
## Legacy v0.2 command parsing subset
|
|
76
96
|
|
|
77
97
|
Context Guard v0.2 is **not** a general Bash or PowerShell static analyzer. Only
|
|
78
98
|
the small, auditable grammar below can produce `executable`, `operation` and
|
package/docs/LOCAL_ACCEPTANCE.md
CHANGED
|
@@ -1,6 +1,226 @@
|
|
|
1
1
|
# Local Acceptance
|
|
2
2
|
|
|
3
|
-
Deterministic checks
|
|
3
|
+
Each section names its evidence boundary. Deterministic checks, isolated DSH_HOME composition, native-platform lifecycle runs, model sessions, CI, and public release readback are separate claims; none substitutes for another.
|
|
4
|
+
|
|
5
|
+
## v0.3.1 release-repair gates
|
|
6
|
+
|
|
7
|
+
Version 0.3.1 preserves the v0.3 runtime and digest behavior while repairing
|
|
8
|
+
the public provenance path. `scripts/release-pack.mjs` requires a clean Git
|
|
9
|
+
root, resolves the full 40-character HEAD, stages the exact npm file set,
|
|
10
|
+
injects that HEAD as `gitHead` only in the staged package manifest, and packs
|
|
11
|
+
the staged package twice. It fails unless both tgz outputs are byte-identical
|
|
12
|
+
and retain the same file count, then emits the single frozen tgz,
|
|
13
|
+
`SHA256SUMS.txt`, and `release-artifact.json`. Publishing must use that tgz
|
|
14
|
+
without repacking. The registry manifest, downloaded registry tgz, annotated
|
|
15
|
+
tag, GitHub Release target, and checksum must all read back to the same commit
|
|
16
|
+
and bytes.
|
|
17
|
+
|
|
18
|
+
The focused Node test covers exact-HEAD injection, repeated-pack byte identity,
|
|
19
|
+
checksum and artifact-record output, and dirty-tree rejection. Acceptance of
|
|
20
|
+
the final tgz requires the full isolated Web/Headless install, no-op, package parity,
|
|
21
|
+
host-lock, real restart, HTTP recovery, and cleanup lifecycle on native macOS
|
|
22
|
+
and Windows before publication. CI, native-platform evidence, registry
|
|
23
|
+
publication, tag identity, and GitHub Release remain separate gates.
|
|
24
|
+
|
|
25
|
+
## v0.3.0 incomplete publication (2026-08-31)
|
|
26
|
+
|
|
27
|
+
Release preparation froze one canonical pre-release package from commit
|
|
28
|
+
`a33b69326eb46fbefc56affc55e2a486695f545c`. The 26-file, 170158-byte tgz
|
|
29
|
+
had SHA-256
|
|
30
|
+
`72d848e313a0e35e06fd1f493215cc0338b86a79a8001a4f07156e782157fe08`.
|
|
31
|
+
The same bytes passed isolated Web and Headless installation, strict second
|
|
32
|
+
no-op, package-file parity, host-lock inspect/inject/dump/verify, plugin load,
|
|
33
|
+
real dshmarket restart, HTTP recovery, process cleanup, and the intentional
|
|
34
|
+
Headless `MISSING_CREDENTIAL` boundary on native macOS and Windows. The
|
|
35
|
+
Windows source run passed all 352 tests without skips; macOS passed 351 with
|
|
36
|
+
the Windows-only command-shim test capability-skipped.
|
|
37
|
+
|
|
38
|
+
GitHub Actions run 33320743166 passed that exact commit on Ubuntu, macOS, and
|
|
39
|
+
Windows with Node.js 22 and 24. The four mirrored conformance files remained
|
|
40
|
+
byte-identical to their upstream pin, all 37 portable semantic cases ran
|
|
41
|
+
without skips, and all 29 digest-v3 vectors re-derived successfully.
|
|
42
|
+
|
|
43
|
+
A separate credentialed model-session gate used that exact package. A real
|
|
44
|
+
test result produced an accepted evidence binding with no rejected binding,
|
|
45
|
+
and a persisted typed `user_wait` boundary was accepted; independent
|
|
46
|
+
post-hook observation read back the same Goal as disarmed. An intentionally
|
|
47
|
+
over-broad prompt captured additional non-certifiable clauses, so its
|
|
48
|
+
checkpoint remained incomplete and no completion certificate was issued.
|
|
49
|
+
This proves the bounded evidence, boundary, and disarm paths without claiming
|
|
50
|
+
that arbitrary model instructions are semantically certifiable.
|
|
51
|
+
|
|
52
|
+
The final documentation-inclusive source was commit
|
|
53
|
+
`12e8411537b7f843aed267bc150a9403ddbb04c9`. Its frozen 26-file,
|
|
54
|
+
171419-byte tgz had SHA-256
|
|
55
|
+
`416b3539d38c13ea0e01b2154f342d911d4c14b81cc90d71f99e8b9bd6d6de45`
|
|
56
|
+
and passed the same isolated lifecycle and same-byte package readback on native
|
|
57
|
+
macOS and Windows. Main CI run 33347875843 and tag CI run 33347976931 passed
|
|
58
|
+
Ubuntu, macOS, and Windows with Node.js 22 and 24. Annotated tag `v0.3.0`
|
|
59
|
+
peels to that commit.
|
|
60
|
+
|
|
61
|
+
The exact tgz was published as `dsh-completion-guard@0.3.0`; registry shasum
|
|
62
|
+
`4c881b83b6046833229d5f54a062bfa2eea5be6f` and integrity
|
|
63
|
+
`sha512-WSxbxD5N/79SJ/6UW0/XonCUlmckUhMHtj4LhUpa9u3XGC+MFZ/GUX935Y4Aqp8HJmxnj2gdHmAYmk8pcccykg==`
|
|
64
|
+
identify the validated bytes. However, npm did not populate registry
|
|
65
|
+
`gitHead` when publishing the prebuilt tgz. That fails this release's frozen
|
|
66
|
+
public-identity gate. The version and tag remain immutable historical facts,
|
|
67
|
+
but no GitHub Release is created for `v0.3.0`, and 0.3.0 is not claimed as a
|
|
68
|
+
completed release. Version 0.3.1 repairs the packaging path instead of moving
|
|
69
|
+
the tag, reusing the npm version, or weakening the gate after publication.
|
|
70
|
+
|
|
71
|
+
## Windows exact-source readback (2026-08-30)
|
|
72
|
+
|
|
73
|
+
Direct readback of the isolated Windows TEMP acceptance evidence verifies
|
|
74
|
+
source commit `b75868e9e73d29f50530ddaba15cfaef82e03ece` (`origin/main` at checkout
|
|
75
|
+
time), tested in a fresh Windows 11 checkout with Windows PowerShell 5.1,
|
|
76
|
+
Python 3.12.10, Node.js 24.18.0, pnpm 11.22.0, and effective
|
|
77
|
+
`core.autocrlf=true`.
|
|
78
|
+
|
|
79
|
+
The source and conformance matrix is verified:
|
|
80
|
+
|
|
81
|
+
- `pnpm test` -> 0; 7 test files, 170 tests passed.
|
|
82
|
+
- `pnpm run typecheck` -> 0.
|
|
83
|
+
- `pnpm run lint` -> 0.
|
|
84
|
+
- `pnpm run build` -> 0.
|
|
85
|
+
- `pnpm run pack:check` -> 0.
|
|
86
|
+
- `git diff --check` -> 0.
|
|
87
|
+
- The raw SHA-256 values of all four mirrored conformance fixture files matched
|
|
88
|
+
their entries in `tests/fixtures/conformance/UPSTREAM_PIN.json`.
|
|
89
|
+
|
|
90
|
+
The exact-source artifact and load chain is also verified from the TEMP
|
|
91
|
+
clone/log evidence. It used a tarball built from that checkout and a fresh
|
|
92
|
+
isolated `DSH_HOME`:
|
|
93
|
+
|
|
94
|
+
- All six tracked `dist/` files matched across the HEAD blobs, local build,
|
|
95
|
+
tarball, and isolated installation.
|
|
96
|
+
- `dsh --profile web --dump-config` read back the `context-guard` bundle, and a
|
|
97
|
+
Node import smoke loaded the installed package.
|
|
98
|
+
- `dsh --profile web --dump-config`, Web startup logging, process stop, and
|
|
99
|
+
cleanup completed. An HTTP 200 appeared only in the first-run stdout; that
|
|
100
|
+
response was not persisted and the readback did not rerun the GET, so HTTP
|
|
101
|
+
200 itself is not independently confirmed.
|
|
102
|
+
|
|
103
|
+
With effective `core.autocrlf=true`, the build made all six tracked `dist/`
|
|
104
|
+
paths appear as `M` even though `git hash-object` matched the corresponding
|
|
105
|
+
HEAD blob for 6/6 files and `git diff` contained no content changes. This was
|
|
106
|
+
an EOL status phantom, not an artifact mismatch; `dist/** text eol=lf` now
|
|
107
|
+
pins the generated files to LF while preserving the existing conformance
|
|
108
|
+
fixture LF rule.
|
|
109
|
+
|
|
110
|
+
Evidence boundary: source checks and the exact-source install/load/startup and
|
|
111
|
+
cleanup chain are verified. A real model-session smoke was not run, and the
|
|
112
|
+
HTTP response lacks independently persisted/read-back evidence. This does not
|
|
113
|
+
establish v0.3 runtime behavior, npm publication, a tag, or a GitHub Release.
|
|
114
|
+
|
|
115
|
+
## v0.3.0 source candidate gates (2026-08-30)
|
|
116
|
+
|
|
117
|
+
Source commit `4f079499509822425c80e0b5ab98d1ebc58da9d5` on
|
|
118
|
+
`codex/v0.3.0-sequence-2` passed the deterministic source matrix on macOS and
|
|
119
|
+
native Windows. The commit remains an unpublished source candidate; it is not
|
|
120
|
+
a tag, npm artifact, GitHub Release, or public-package readback.
|
|
121
|
+
|
|
122
|
+
The macOS source matrix used Node.js 25.1.0 and pnpm 11.22.0:
|
|
123
|
+
|
|
124
|
+
- `pnpm install --frozen-lockfile` -> 0.
|
|
125
|
+
- `pnpm run typecheck` -> 0.
|
|
126
|
+
- `pnpm test` -> 0; 19 test files, 351 tests passed and the one Windows-only
|
|
127
|
+
command-shim test was capability-skipped.
|
|
128
|
+
- `pnpm run lint` -> 0 with no warnings.
|
|
129
|
+
- `pnpm run build` -> 0; a second build produced the same generated file names
|
|
130
|
+
and SHA-256 values.
|
|
131
|
+
- `pnpm run pack:check` -> 0; package identity is
|
|
132
|
+
`dsh-completion-guard@0.3.0`, and the action, Git command, and supported-host
|
|
133
|
+
manifests plus the host-lock CLI are included.
|
|
134
|
+
- The portable runner executed all 37 mirrored semantic cases without skips.
|
|
135
|
+
- The DSH digest runner re-derived all 29 digest-v3 vectors; the four mirror
|
|
136
|
+
file SHA-256 values remain identical to `UPSTREAM_PIN.json`.
|
|
137
|
+
|
|
138
|
+
The native Windows matrix used a fresh Windows 11 checkout, Windows PowerShell
|
|
139
|
+
5.1, Python 3.12.10, Node.js 24.18.0, pnpm 11.22.0, Git 2.53.0.windows.2, and
|
|
140
|
+
effective `core.autocrlf=true`:
|
|
141
|
+
|
|
142
|
+
- The focused host-lock/evidence suite passed 33/33 tests with no skips. It
|
|
143
|
+
executed a `.cmd` shim from a path containing spaces and parentheses, bound
|
|
144
|
+
both the shim and canonical `SystemRoot\\System32\\cmd.exe` identities,
|
|
145
|
+
ignored later `PATH`/`ComSpec` substitution, rejected expansion characters,
|
|
146
|
+
detected a fake `git.cmd` identity swap, and completed the real Git
|
|
147
|
+
commit/push/fetch/pull round trip within its Windows timeout.
|
|
148
|
+
- `pnpm test` -> 0; all 19 test files and all 352 tests passed with no skips.
|
|
149
|
+
- Typecheck, lint, build, package dry-run, documentation audit, documentation
|
|
150
|
+
unit tests, `git diff --check`, generated-`dist` parity, and final clean-tree
|
|
151
|
+
readback passed.
|
|
152
|
+
- All 37 portable semantic cases, all 29 digest-v3 vectors, the four pinned
|
|
153
|
+
mirror hashes, and cross-repository fixture byte equality passed.
|
|
154
|
+
|
|
155
|
+
Each platform built and recorded its own local exact-source tarball. The macOS
|
|
156
|
+
artifact SHA-256 is
|
|
157
|
+
`d613d88edbc44ccc020ad48dff6d180e79c04ed5bcabb73d7fae09d449500890`;
|
|
158
|
+
the Windows artifact SHA-256 is
|
|
159
|
+
`397975f720f0c6d734e7faf7279fab3feee1f92433ff457122755d9296adb19f`.
|
|
160
|
+
These raw archive hashes are platform-local build provenance, not a requirement
|
|
161
|
+
that independently packed gzip/tar containers be byte-identical. Both were
|
|
162
|
+
built from a clean checkout of the exact commit, reported the same package
|
|
163
|
+
identity and 26-file package list, retained build-to-`dist` parity, and were
|
|
164
|
+
installed from the artifact that was hashed on that platform. A future release
|
|
165
|
+
must instead freeze one canonical tarball, bind it to the release commit, tag,
|
|
166
|
+
npm `gitHead`, and registry integrity, and verify that same artifact on every
|
|
167
|
+
required native platform.
|
|
168
|
+
|
|
169
|
+
Both platform-local exact-source artifacts were installed into fresh isolated
|
|
170
|
+
Web and Headless profiles without modifying the user profile. For both
|
|
171
|
+
profiles, the packaged host-lock CLI completed `inspect -> inject -> inject
|
|
172
|
+
(idempotence) -> dsh --dump-config -> verify-dump` against the active
|
|
173
|
+
runtime/profile graphs. The Web tuple contained 34 exact package rows with Web
|
|
174
|
+
control available; the Headless tuple contained 33 rows with Web control
|
|
175
|
+
unavailable by profile while the other applicable capabilities remained
|
|
176
|
+
supported.
|
|
177
|
+
|
|
178
|
+
On both macOS and Windows, an isolated Web profile loaded real
|
|
179
|
+
`dshmarket@1.36.0`, returned HTTP 200, accepted the correct restart request
|
|
180
|
+
with HTTP 202, replaced the process, and returned a different boot ID after
|
|
181
|
+
restart. The Windows run also verified that a wrong restart origin was rejected.
|
|
182
|
+
Each replacement process returned HTTP 200 before teardown; the temporary
|
|
183
|
+
listener, helper, and profile processes were then read back as stopped. Each
|
|
184
|
+
isolated Headless profile loaded the plugin and advanced to the expected
|
|
185
|
+
`MISSING_CREDENTIAL` boundary with `DEEPSEEK_API_KEY` removed from the child
|
|
186
|
+
environment.
|
|
187
|
+
|
|
188
|
+
This establishes deterministic source behavior plus native macOS and Windows
|
|
189
|
+
package composition, host-lock readback, load, and Web restart lifecycle for
|
|
190
|
+
commit `4f079499509822425c80e0b5ab98d1ebc58da9d5`. It is not a credentialed
|
|
191
|
+
model-session Goal/checkpoint/boundary round. CI, a canonical release artifact,
|
|
192
|
+
npm/GitHub publication, tag identity, and a real model-session smoke remain
|
|
193
|
+
independent pending release gates.
|
|
194
|
+
|
|
195
|
+
### npm statistics integration boundary (2026-08-30)
|
|
196
|
+
|
|
197
|
+
The validation branch later integrated the bilingual npm download chart in
|
|
198
|
+
`131b2db7f7ee555e6e4794395a8aa5118275fa80` and hardened its collector and
|
|
199
|
+
publication workflow in `0ebda88312bf226869543c65de70159fe0abdaca`.
|
|
200
|
+
The collector's 8 focused tests pass on macOS and cover leap-year date chunks,
|
|
201
|
+
missing and unordered days, duplicate/out-of-range/negative rows, range/point
|
|
202
|
+
reconciliation, scoped package URL encoding, HTTP and JSON failures, and
|
|
203
|
+
preservation of the previous output set when collection fails. The fixed-date
|
|
204
|
+
2026-08-29 render reconciled 780 requests for `dsh-context-guard` and 140 for
|
|
205
|
+
`dsh-completion-guard` into a 920-request project line. Both 960 x 540 SVGs
|
|
206
|
+
parsed as XML, retained `<title>` and `<desc>` accessibility text, rendered
|
|
207
|
+
without invalid numeric tokens, and were visually inspected in English and
|
|
208
|
+
Simplified Chinese.
|
|
209
|
+
|
|
210
|
+
Publication is fail-closed to the repository default branch before checkout.
|
|
211
|
+
The collection job has read-only contents permission and does not retain Git
|
|
212
|
+
credentials; only the downstream publication job receives contents write
|
|
213
|
+
permission. The four official Actions used by the workflow are pinned to
|
|
214
|
+
immutable commits. No `stats` branch or chart asset was published during this
|
|
215
|
+
candidate integration.
|
|
216
|
+
|
|
217
|
+
Evidence boundary: the runtime source paths, `dist/`, CLI, manifests, and lock
|
|
218
|
+
file remain unchanged from the native-platform candidate above. The chart
|
|
219
|
+
integration does change packaged README and package metadata, and this
|
|
220
|
+
acceptance document is itself shipped in the package. The earlier macOS and
|
|
221
|
+
Windows tarball hashes therefore cannot be inherited by the final candidate.
|
|
222
|
+
One canonical tarball must be built from the final exact commit and the same
|
|
223
|
+
bytes installed and read back on macOS and native Windows before release.
|
|
4
224
|
|
|
5
225
|
## macOS v0.2.0 acceptance (2026-08-28)
|
|
6
226
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Semantic Compatibility
|
|
2
|
+
|
|
3
|
+
`dsh-completion-guard` adapts the Context Guard protocol semantics whose
|
|
4
|
+
canonical owner is `codex-context-guard`. The two products keep separate
|
|
5
|
+
runtimes, persistence, lifecycle, and scheduling; what they share is a
|
|
6
|
+
testable semantic contract tracked by a machine-readable delta ledger and
|
|
7
|
+
byte-mirrored conformance fixtures. This document describes the shared assets
|
|
8
|
+
from the DSH side and their current implementation status. It does not claim
|
|
9
|
+
full feature parity with the Codex product.
|
|
10
|
+
|
|
11
|
+
## Shared assets in this repository
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
docs/upstream-deltas.json
|
|
15
|
+
tests/fixtures/conformance/UPSTREAM_PIN.json
|
|
16
|
+
tests/fixtures/conformance/context_guard_semantics_v1.json
|
|
17
|
+
tests/fixtures/conformance/context_guard_semantics_v1.schema.json
|
|
18
|
+
tests/fixtures/conformance/digest_v3/cases.json
|
|
19
|
+
tests/fixtures/conformance/digest_v3/expected.json
|
|
20
|
+
src/domain/digest.ts
|
|
21
|
+
manifests/action-manifest.v1.json
|
|
22
|
+
manifests/supported-host.v1.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Authority rules:
|
|
26
|
+
|
|
27
|
+
- The portable conformance fixture and the digest v3 fixture are canonical in
|
|
28
|
+
codex-context-guard. This repository holds byte mirrors whose SHA-256
|
|
29
|
+
values are pinned in `tests/fixtures/conformance/UPSTREAM_PIN.json`; the
|
|
30
|
+
vitest suite fails when any mirror drifts from its pinned hash.
|
|
31
|
+
- `UPSTREAM_PIN.json` records the upstream head at mirror time, the mirror
|
|
32
|
+
date, and per-file hashes. The canonical files were created in an upstream
|
|
33
|
+
working tree pending commit, so `canonicalCommit` is `pending` until the
|
|
34
|
+
upstream commit that lands them exists; refresh the pin when re-syncing.
|
|
35
|
+
- New protocol cases discovered on the DSH side are turned into
|
|
36
|
+
platform-neutral fixture cases upstream first; host-specific expectations
|
|
37
|
+
never enter the shared fixture.
|
|
38
|
+
- `docs/UPSTREAM_BASE.md` records the historical v0.1.0 baseline. It is a
|
|
39
|
+
historical fact, not a claim that DSH implements Codex protocol versions;
|
|
40
|
+
current alignment status lives in this document and the delta ledger.
|
|
41
|
+
|
|
42
|
+
## Digest v3
|
|
43
|
+
|
|
44
|
+
Certificate, boundary, and evidence manifests bind to versioned canonical
|
|
45
|
+
digests. The derivation contract is frozen as digest version 3 (typed token
|
|
46
|
+
value language, length-prefixed fields with an explicit presence byte,
|
|
47
|
+
semantic-key-ordered canonical collections, closed per-manifest allowlists
|
|
48
|
+
with domain separators). The full contract, the golden-vector gate, and the
|
|
49
|
+
fail-closed edges are documented in the upstream
|
|
50
|
+
`docs/SEMANTIC_COMPATIBILITY.md`; the fixtures are byte mirrors here.
|
|
51
|
+
|
|
52
|
+
DSH-side facts:
|
|
53
|
+
|
|
54
|
+
- `src/domain/digest.ts` re-derives the complete digest contract in
|
|
55
|
+
TypeScript, including the verifier-side role matrix and binding closure.
|
|
56
|
+
- `tests/domain/digest-v3.test.ts` runs all 29 golden vectors from the byte
|
|
57
|
+
mirror and asserts byte-identical agreement with the upstream-generated
|
|
58
|
+
`expected.json`, plus the fail-closed negatives (semantic-key sorting, the
|
|
59
|
+
two collision layers, lone surrogates, NFC vs NFD, duplicate members,
|
|
60
|
+
camelCase rejection, surface cardinality, frozen length boundaries, and
|
|
61
|
+
cross-paired evidence rejection).
|
|
62
|
+
- The upstream gate command
|
|
63
|
+
(`python scripts/reference_digest_encoder.py --check ...`) stays the
|
|
64
|
+
canonical check; the mirrored fixtures make both implementations answer to
|
|
65
|
+
the same bytes.
|
|
66
|
+
- Version 0.3 wires the module into checkpoint creation/replay and the
|
|
67
|
+
Guard-owned Goal-complete gate. Certificates freeze the full versioned field
|
|
68
|
+
table, including session and host identity, and are authoritative only after
|
|
69
|
+
the tool result persists and re-derives exactly.
|
|
70
|
+
|
|
71
|
+
## Portable conformance fixture
|
|
72
|
+
|
|
73
|
+
`context_guard_semantics_v1.json` holds 37 platform-neutral cases built from the
|
|
74
|
+
event vocabulary `root_message`, `delegated_message`, `tool_result`,
|
|
75
|
+
`checkpoint_request`, `boundary_request`, `completion_request`, `compact`,
|
|
76
|
+
`resume`, and `goal_change`, with bounded expectations (`completed`,
|
|
77
|
+
`completion_allowed`, `force_continue`, `pending_preserved`, `boundary`,
|
|
78
|
+
`integrity`, `reason_codes`). All content is synthetic. The DSH-side portable
|
|
79
|
+
runner executes every mirrored case without skips and compares the bounded
|
|
80
|
+
result contract; it does not translate a missing capability into a pass.
|
|
81
|
+
|
|
82
|
+
## Current alignment status (honest boundaries)
|
|
83
|
+
|
|
84
|
+
Implemented in v0.3.0:
|
|
85
|
+
|
|
86
|
+
- Digest v3 derivation, byte-mirror pinning, and 29-vector agreement.
|
|
87
|
+
- All-case portable semantic fixture runner implemented as a thin adapter over production derive/checkpoint/boundary/Goal/stop functions, without fixture-ID rewrites or skipped cases.
|
|
88
|
+
- Assistant-prose diagnostic-only stop decisions and typed boundary
|
|
89
|
+
qualification/effectuation with phase-specific fault results.
|
|
90
|
+
- Exact semantic action/target binding, explainable checkpoint rejection, and
|
|
91
|
+
resolution/effect/state role closure for all ten stateful actions.
|
|
92
|
+
- Exact paired optional Goal state/tool peers, supported-host/action manifests, injected active
|
|
93
|
+
graph identity, unknown-host fail-closed behavior, and pre-mutation gating of
|
|
94
|
+
the Guard-owned `update_goal(action=complete)` path.
|
|
95
|
+
- Legacy generic-run and unprovable-authority fail-closed migration behavior.
|
|
96
|
+
|
|
97
|
+
This is not a full product-parity claim. It does not copy the Codex private
|
|
98
|
+
ledger, Hook lifecycle, cache, or installer, and it cannot prevent all trusted
|
|
99
|
+
in-process Goal/session bypasses. Exact-artifact isolated Web/Headless install,
|
|
100
|
+
host-lock readback, Web restart lifecycle, and Headless load were exercised on
|
|
101
|
+
native macOS and Windows, with cross-platform CI and a bounded credentialed
|
|
102
|
+
model-session evidence/boundary round. Source, native-platform, model-session,
|
|
103
|
+
registry, tag, and GitHub Release evidence remain separate scopes; see
|
|
104
|
+
`LOCAL_ACCEPTANCE.md`.
|
|
105
|
+
|
|
106
|
+
## Validation boundaries
|
|
107
|
+
|
|
108
|
+
- `pnpm install --frozen-lockfile && pnpm typecheck && pnpm test && pnpm
|
|
109
|
+
lint && pnpm build` covers deterministic tests and build health on this
|
|
110
|
+
machine. That is not native platform acceptance: Web/Headless profile load,
|
|
111
|
+
real checkpoint/boundary/Goal round flows, and macOS/Windows native
|
|
112
|
+
acceptance are separate records and are not claimed here.
|
|
113
|
+
- Deterministic test evidence never substitutes for npm/GitHub Release
|
|
114
|
+
identity readback or the identity migration gates recorded in the plan for
|
|
115
|
+
the v0.3.0 release.
|
|
116
|
+
- The delta ledger separates source facts, plan status, implementation
|
|
117
|
+
status, deterministic tests, native platform acceptance, and release
|
|
118
|
+
readback; keep all six aligned when a capability moves.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Distribution status
|
|
2
|
+
|
|
3
|
+
This page records where `dsh-completion-guard` is published and independently
|
|
4
|
+
read back. Only verified, publicly live destinations are listed here; the
|
|
5
|
+
private submission pipeline and in-review entries are tracked outside the
|
|
6
|
+
repository and are intentionally not disclosed.
|
|
7
|
+
|
|
8
|
+
## Rename note (2026-08-29)
|
|
9
|
+
|
|
10
|
+
The project was renamed from `dsh-context-guard` to `dsh-completion-guard` to
|
|
11
|
+
avoid a name collision with an unrelated DeepSeek Harness plugin
|
|
12
|
+
(`kpl0111/dsh-context-guard`, a token-efficient tool-result pruning plugin
|
|
13
|
+
created 2026-08-16). The internal Cordis bundle id stays `context-guard`, so
|
|
14
|
+
installed profiles keep their runtime identity. The previous npm package
|
|
15
|
+
`dsh-context-guard` is deprecated across all published versions (0.1.0 –
|
|
16
|
+
0.2.1) with a pointer to this package.
|
|
17
|
+
|
|
18
|
+
## Incomplete v0.3.0 identity
|
|
19
|
+
|
|
20
|
+
`dsh-completion-guard@0.3.0` is publicly readable from npm and its tarball
|
|
21
|
+
passed same-byte native macOS and Windows validation. The registry metadata
|
|
22
|
+
omits the release contract's required `gitHead`, however, so `v0.3.0` is not
|
|
23
|
+
listed as a completed destination and has no GitHub Release. The immutable npm
|
|
24
|
+
version and annotated tag are retained for audit history. Version 0.3.1 repairs
|
|
25
|
+
the provenance-bearing frozen-package workflow.
|
|
26
|
+
|
|
27
|
+
## Published v0.2.1 destinations
|
|
28
|
+
|
|
29
|
+
1. [GitHub Release `v0.2.1`](https://github.com/GreenLv/dsh-completion-guard/releases/tag/v0.2.1)
|
|
30
|
+
is published as a non-draft, non-prerelease release; the repository was
|
|
31
|
+
renamed after tagging and the release URL follows the rename (old URLs
|
|
32
|
+
301-redirect). The tag points at commit `ba8f05d`; the published npm
|
|
33
|
+
artifact was built from `8497300`, whose dist is byte-identical to the
|
|
34
|
+
gate build.
|
|
35
|
+
2. [`dsh-completion-guard@0.2.1` on npm](https://www.npmjs.com/package/dsh-completion-guard)
|
|
36
|
+
is published and `latest` resolves to `0.2.1`. The registry packument
|
|
37
|
+
`gitHead` equals the rename commit `8497300`, maintainer `greenlv`.
|
|
38
|
+
3. The committed `dist/` tree is byte-identical to the published npm tarball
|
|
39
|
+
(verified 2026-08-29 by diffing the registry tarball against the local
|
|
40
|
+
build; only `.DS_Store` is excluded and git-ignored).
|
|
41
|
+
|
|
42
|
+
## Community indexes
|
|
43
|
+
|
|
44
|
+
| Channel | Entry | Status | Evidence |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) | `GreenLv/dsh-completion-guard` (category `security`) | Listed | Added via [PR #3693](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/pull/3693) (merge commit `299f0b5c`, 2026-08-29); read back live the same day from the generated `README.md` (line 2469, security-category section) and `README.zh.md`, the committed `data/plugins/GreenLv__dsh-completion-guard.yml`, and the published catalog at [`awesome-dsh-plugin.com/plugins.json`](https://awesome-dsh-plugin.com/plugins.json), which exposes the storefront page [`awesome-dsh-plugin.com/p/GreenLv/dsh-completion-guard/`](https://awesome-dsh-plugin.com/p/GreenLv/dsh-completion-guard/). Screenshots: declared in this repository's [`screenshots.json`](../screenshots.json) per the maintainer's post-#2937 convention (change images by pushing here; no listing PR needed). |
|
|
47
|
+
| [Awesome DeepSeek Harness](https://github.com/Dominic789654/awesome-deepseek-harness#security--permissions) | `GreenLv/dsh-completion-guard` | Listed | Rows merged via [PR #332](https://github.com/Dominic789654/awesome-deepseek-harness/pull/332) (merge commit `ba414c4`, 2026-08-29) and read back live the same day from both generated READMEs (`README.md` line 940, `README.zh-CN.md` line 946), under **Security & Permissions** alongside the other fail-closed gates and verifier plugins. |
|
|
48
|
+
|
|
49
|
+
## Update route
|
|
50
|
+
|
|
51
|
+
Directory entries resolve the npm `latest` tag or link the repository, so
|
|
52
|
+
routine releases refresh automatically. Row wording changes go through a pull
|
|
53
|
+
request against the listing repository. Historical acceptance evidence for
|
|
54
|
+
each release is kept in [`docs/LOCAL_ACCEPTANCE.md`](LOCAL_ACCEPTANCE.md).
|