@junghanacs/entwurf 0.13.0 → 0.13.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/AGENTS.md +5 -3
- package/BASELINE.md +57 -203
- package/CHANGELOG.md +19 -0
- package/CONTRIBUTING.md +1 -1
- package/DELIVERY.md +117 -261
- package/README.md +68 -408
- package/VERIFY.md +58 -87
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +231 -0
- package/docs/external-mcp-host.md +132 -0
- package/docs/fresh-cut-policy.md +99 -0
- package/docs/setup-clean-host.md +123 -328
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +21 -48
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/acp-client.js +12 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +11 -10
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/config.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/engraving.js +42 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +4 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +3 -3
- package/mcp/entwurf-bridge/src/index.ts +21 -48
- package/package.json +12 -9
- package/pi-extensions/entwurf-control.ts +20 -49
- package/pi-extensions/lib/acp/acp-client.ts +22 -0
- package/pi-extensions/lib/acp/augment.ts +42 -3
- package/pi-extensions/lib/acp/backend-adapter.ts +12 -11
- package/pi-extensions/lib/acp/backend.ts +305 -36
- package/pi-extensions/lib/acp/config.ts +1 -1
- package/pi-extensions/lib/acp/engraving.ts +43 -1
- package/pi-extensions/lib/acp/event-mapper.ts +16 -13
- package/pi-extensions/lib/acp/models.ts +4 -4
- package/pi-extensions/lib/acp/overlay.ts +3 -3
- package/prompts/engraving.md +13 -5
- package/run.sh +244 -108
- package/scripts/check-acp-carrier-augment.ts +246 -10
- package/scripts/check-acp-cortex.ts +5 -5
- package/scripts/check-acp-prompt-lifecycle.ts +565 -0
- package/scripts/check-acp-sdk-surface.ts +60 -21
- package/scripts/check-acp-stop-reason.ts +342 -0
- package/scripts/check-entwurf-v2-surface.ts +41 -0
- package/scripts/check-gate-qualification.ts +6 -3
- package/scripts/check-probe-ordering.ts +39 -7
- package/scripts/check-release-gate-outcomes.ts +332 -0
- package/scripts/lib/live-skip.ts +33 -0
- package/scripts/lib/probe-acp-turn.ts +33 -12
- package/scripts/lib/step-outcome.sh +88 -0
- package/scripts/mutants/acp-augment.json +106 -0
- package/scripts/mutants/acp-cortex.json +2 -2
- package/scripts/mutants/acp-prompt-lifecycle.json +100 -0
- package/scripts/mutants/acp-stop-reason.json +80 -0
- package/scripts/mutants/probe-ordering.json +27 -5
- package/scripts/mutants/release-gate.json +105 -0
- package/scripts/mutants/v2-surface.json +26 -15
- package/scripts/smoke-acp-bundled-mcp-live.ts +4 -3
- package/scripts/smoke-acp-carrier-augment-live.ts +2 -2
- package/scripts/smoke-acp-cortex-live.ts +8 -14
- package/scripts/smoke-acp-long-turn-live.ts +185 -0
- package/scripts/smoke-acp-mcp-live.ts +2 -2
- package/scripts/smoke-acp-memory-containment-live.ts +2 -2
- package/scripts/smoke-acp-ordering-probe-live.ts +2 -2
- package/scripts/smoke-acp-overlay-live.ts +2 -2
- package/scripts/smoke-acp-provider-live.ts +2 -2
- package/scripts/smoke-acp-raw-turn-live.ts +3 -3
- package/scripts/smoke-acp-session-reuse-live.ts +2 -2
- package/scripts/smoke-acp-skill-live.ts +2 -2
- package/scripts/smoke-acp-socket-citizen-live.ts +4 -3
- package/scripts/smoke-acp-v2-send-live.ts +4 -3
- package/scripts/smoke-agy-native-push-live.ts +4 -3
- package/scripts/smoke-claude-native-resume-live.sh +13 -3
- package/scripts/smoke-entwurf-chain-live.ts +352 -0
- package/scripts/smoke-entwurf-v2-matrix-live.ts +2 -2
- package/scripts/smoke-entwurf-v2-spawn-resume-live.ts +2 -4
- package/scripts/smoke-meta-install-state.sh +4 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Wiring `entwurf-bridge` into an external MCP host
|
|
2
|
+
|
|
3
|
+
Per-harness registration for Claude Code, Codex CLI, and Antigravity, plus the
|
|
4
|
+
PATH/env boundary and the external vs garden-native semantics. `README.md` keeps only
|
|
5
|
+
the one-line registration; everything an operator needs to actually wire a host is here.
|
|
6
|
+
|
|
7
|
+
`entwurf-bridge` can also be registered in a separate MCP-aware harness (Claude Code, Codex CLI, Antigravity/`agy`, …). That host does **not** become a pi session and does **not** need to be ACP-backed. There are now two honest cases:
|
|
8
|
+
|
|
9
|
+
- **plain external MCP host**: no garden meta-record / sender marker. It can call the read surfaces (`entwurf_peers`, `entwurf_inbox_read`), but `entwurf_v2` sends are **refused by default** (#50 C4: "if we don't know who sent it, we don't send it"). The operator may wire the explicit hatch below; the send then goes out external/non-replyable.
|
|
10
|
+
- **garden-native native session**: a trusted lifecycle hook minted a garden id and sender marker — `SessionStart` for Claude Code, `PreInvocation` for agy. It is not a pi control-socket session, but it can be replyable by garden id when its own mailbox/probe rail says so.
|
|
11
|
+
|
|
12
|
+
**Which verb an external agent should reach for:** to deliver to / reply to a garden id, use **`entwurf_v2`** — it is the canonical delivery surface and the only one that reads whether the target is live pi, dormant pi, mailbox-backed Claude Code, or native-push Antigravity and routes correctly. Discover targets with `entwurf_peers`, confirm your own identity with `entwurf_self`, drain a mailbox with `entwurf_inbox_read`, and use `entwurf_register_native` only as the explicit/manual fallback for binding an already-running agy conversation (normal agy birth is automatic through the installed hook). Fresh sibling creation from nothing is a deferred lane. (The old v1 verbs `entwurf` / `entwurf_resume` / `entwurf_send` are gone.)
|
|
13
|
+
|
|
14
|
+
Observed: Claude Code, Codex CLI, and Antigravity CLI all reach the read surfaces through this MCP bridge from a plain external host — `entwurf_peers` is a pure fact projection, while `entwurf_inbox_read` is a **mutating drain** (it archives the messages and stamps the read-receipt), so "read" here does not mean side-effect-free; **sending** needs an identity lane. Claude becomes symmetric/replyable through its mailbox-backed meta-session; agy becomes symmetric/replyable through its record-backed sender marker plus live native-push probe. Codex has no managed citizen lifecycle yet, so a Codex host cannot send without the explicit anonymous hatch below.
|
|
15
|
+
|
|
16
|
+
Prerequisites on the host running the external MCP client:
|
|
17
|
+
|
|
18
|
+
- `pi` on PATH (for the `owned-outcome` spawn-bg resume path).
|
|
19
|
+
- A live pi session launched with `--entwurf-control` populates `~/.pi/entwurf-control/<gardenId>.sock` — the key is the **record's** garden id, never a transcript/session id (`PI_SESSION_ID` only carries the id record birth already established). Required for `entwurf_v2` control-socket dispatch and `entwurf_peers`.
|
|
20
|
+
|
|
21
|
+
> **PATH boundary.** MCP servers are often launched by GUI/editor daemons and may not inherit the interactive shell's PATH. If `pi` works in your terminal but an external-host `entwurf_v2` spawn-bg resume fails with `spawn pi ENOENT`, pass a full PATH in the MCP server `env`, set `ENTWURF_BRIDGE_ENV_FILE` to a small shell file that exports PATH, or point the host at a wrapper that can find `pi`. `start.sh` sources only the explicit `ENTWURF_BRIDGE_ENV_FILE`; it never reads personal dotfiles automatically.
|
|
22
|
+
|
|
23
|
+
Example env file:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# ~/.config/entwurf-bridge/env.sh
|
|
27
|
+
export PATH="$HOME/.local/share/pnpm:$HOME/.local/bin:$HOME/.nvm/versions/node/v24.15.0/bin:$PATH"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Then add it to the external MCP config:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"env": {
|
|
35
|
+
"ENTWURF_BRIDGE_ENV_FILE": "/home/operator/.config/entwurf-bridge/env.sh",
|
|
36
|
+
"ENTWURF_BRIDGE_EXTERNAL_AGENT_ID": "external-mcp/claude-code"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Anonymous sender hatch (explicit, documented — never a default).** The bridge refuses an `entwurf_v2` send when the process has neither pi-session env (`PI_SESSION_ID` + `PI_AGENT_ID`) nor a trusted meta-sender marker (#50 C4). A deliberately-anonymous external host — e.g. a Codex CLI wiring, which has no managed citizen lifecycle — may opt out by adding `"ENTWURF_BRIDGE_ALLOW_ANONYMOUS_SENDER": "1"` to the MCP server `env`. The cost is honest and fixed: the send lands with `origin: "external-mcp"`, `replyable: false` (there is no reply address), and `wants_reply: true` stays pointless. The retired opt-in `ENTWURF_BRIDGE_REQUIRE_META_SENDER` is no longer read — its demand became the default, so a stale copy in an old install env is inert.
|
|
42
|
+
|
|
43
|
+
Emergency/manual workaround when the MCP server environment is wrong but an existing entwurf session must be resumed: run `pi --session /path/to/entwurf.jsonl ...` from an interactive shell whose PATH is known-good. Treat this as a debug escape hatch, not a replacement for fixing the MCP launch environment.
|
|
44
|
+
|
|
45
|
+
External/meta-session semantics:
|
|
46
|
+
|
|
47
|
+
- `entwurf_v2` from a plain external host is **refused by default** (no authoritative sender — #50 C4). With the explicit `ENTWURF_BRIDGE_ALLOW_ANONYMOUS_SENDER=1` hatch it delivers with `origin: "external-mcp"` / `replyable: false`; there is still no reply address.
|
|
48
|
+
- `entwurf_v2` from a trusted meta-session delivers with `origin: "meta-session"`, and `replyable` is **derived from that sender's own rail — not granted by being trusted**: a self-fetch sender (Claude Code) is replyable only while its receiver is live and armed, and a native-push sender (Antigravity) only while its adapter probe finds the live conversation. Identity survives either way; only `replyable` drops to `false`. When it is `true`, `wants_reply: true` is allowed and the receiver can reply to the sender's garden id.
|
|
49
|
+
- `entwurf_v2` with `intent: "owned-outcome"` to a dormant pi target needs `pi` on PATH (it spawns a `pi --entwurf-control` resume child); async completion followUp requires a replyable pi control-socket caller.
|
|
50
|
+
- `entwurf_self` returns the same authoritative identity for pi sessions **and** trusted meta-sessions. A plain external host with no pi env and no trusted sender marker still fails because there is no reply address to report.
|
|
51
|
+
|
|
52
|
+
#### Claude Code
|
|
53
|
+
|
|
54
|
+
Plain MCP registration works independently of the native lifecycle. A garden-native
|
|
55
|
+
mailbox citizen requires Claude Code >=2.1.217 plus the managed meta-bridge installer;
|
|
56
|
+
older versions silently drop exec-hook arguments and are refused.
|
|
57
|
+
|
|
58
|
+
Claude Code supports both CLI registration and a separated global MCP config. The separated file is recommended for dotfile / `agent-config` workflows because `~/.claude.json` also carries OAuth-bearing state.
|
|
59
|
+
|
|
60
|
+
**Option A — CLI add:**
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
claude mcp add --scope user entwurf-bridge \
|
|
64
|
+
bash /absolute/path/to/entwurf/mcp/entwurf-bridge/start.sh
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This writes the entry into `~/.claude.json`'s top-level `mcpServers`. Good for one-off setup; do not version-control the resulting `~/.claude.json`.
|
|
68
|
+
|
|
69
|
+
**Option B — separated `~/.mcp.json`:**
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"entwurf-bridge": {
|
|
75
|
+
"type": "stdio",
|
|
76
|
+
"command": "bash",
|
|
77
|
+
"args": [
|
|
78
|
+
"/absolute/path/to/entwurf/mcp/entwurf-bridge/start.sh"
|
|
79
|
+
],
|
|
80
|
+
"env": {
|
|
81
|
+
"ENTWURF_BRIDGE_EXTERNAL_AGENT_ID": "external-mcp/claude-code"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Claude Code reads `~/.mcp.json` in addition to `~/.claude.json`'s top-level `mcpServers`. The `env` block identifies the calling host on the receiver render — omit it and `entwurf_v2` shows `external-mcp/unknown-host`. If Claude Code permissions are locked down, allow `mcp__*` or `mcp__entwurf-bridge__*` in `~/.claude/settings.json`.
|
|
89
|
+
|
|
90
|
+
#### Codex CLI
|
|
91
|
+
|
|
92
|
+
Add the server to `~/.codex/config.toml`:
|
|
93
|
+
|
|
94
|
+
```toml
|
|
95
|
+
[mcp_servers.entwurf-bridge]
|
|
96
|
+
command = "/absolute/path/to/entwurf/mcp/entwurf-bridge/start.sh"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Codex has no managed citizen lifecycle (no sender marker), so this wiring can read `entwurf_peers`/`entwurf_inbox_read` but `entwurf_v2` sends are refused by default (#50 C4). To send anonymously anyway, add the explicit hatch to the same block: `env = { ENTWURF_BRIDGE_ALLOW_ANONYMOUS_SENDER = "1" }` — the send is then marked external/non-replyable (see the hatch paragraph above).
|
|
100
|
+
|
|
101
|
+
#### Antigravity CLI (`agy`)
|
|
102
|
+
|
|
103
|
+
Use the managed install surface rather than editing agy's files by hand:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
entwurf install-agy-bridge
|
|
107
|
+
entwurf install-agy-statusline
|
|
108
|
+
entwurf install-agy-hooks
|
|
109
|
+
|
|
110
|
+
entwurf doctor-agy-bridge
|
|
111
|
+
entwurf doctor-agy-statusline
|
|
112
|
+
entwurf doctor-agy-hooks
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The three adapters deliberately own different atoms:
|
|
116
|
+
|
|
117
|
+
- bridge: one `entwurf-bridge` server in `~/.gemini/config/mcp_config.json`, plus one narrow permission string per tool the normal agy workflow calls — `mcp(entwurf-bridge/entwurf_v2)`, `mcp(entwurf-bridge/entwurf_peers)`, `mcp(entwurf-bridge/entwurf_self)` — in `~/.gemini/antigravity-cli/settings.json`. agy defaults every `mcp` action to Ask, so a tool that ships without its own rule stops for a y/n on every call; `entwurf_inbox_read` is deliberately not granted (native-push has no inbox) and neither is the manual `entwurf_register_native` fallback;
|
|
118
|
+
- statusline: the complete `statusLine` subtree pointing at the bare stable bin `entwurf-agy-statusline`;
|
|
119
|
+
- hooks: one named `PreInvocation` hook pointing at the bare stable bin `entwurf-agy-imprint`.
|
|
120
|
+
|
|
121
|
+
Unrelated servers, permissions, settings, and hooks are preserved; every adapter has a state-backed honest inverse and refuses symlink-owned SSOTs. The installer never grants broad `command(*)`, `unsandboxed(*)`, or other YOLO policy — those remain operator decisions.
|
|
122
|
+
|
|
123
|
+
The **global** MCP config live agy reads is `~/.gemini/config/mcp_config.json`. `~/.gemini/antigravity-cli/mcp_config.json` is not the global MCP root; the bridge installer one-way cleans only a stale entwurf-owned entry there. After the first model invocation, the imprint hook binds the native `conversationId` to a garden id, the statusline shows `🪛 <garden-id> agy`, and sends from that MCP child carry `agentId=meta-session/antigravity` with `replyable:true` only when the record exists and the live native-push probe succeeds.
|
|
124
|
+
|
|
125
|
+
#### External-host skills and commands
|
|
126
|
+
|
|
127
|
+
MCP registration gives the external harness the tools; the host still needs workflow guidance. Put the Mitsein-over-MCP (cross-harness collaboration) rules in that host's instruction file or, when supported, as a host-native skill. Do not assume pi slash commands are portable across external hosts — if a workflow must work across Claude Code, Codex CLI, Antigravity, and future hosts, make it a skill or MCP tool rather than a command shortcut.
|
|
128
|
+
|
|
129
|
+
For the maintained multi-harness setup and skill/command packaging details, see
|
|
130
|
+
[agent-config](https://github.com/junghan0611/agent-config). See also the
|
|
131
|
+
[concept primer](../README.md#concept-primer), the sender-envelope contract in
|
|
132
|
+
[AGENTS.md](../AGENTS.md), and [custom skills](../README.md#custom-skills).
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Fresh-cut policy
|
|
2
|
+
|
|
3
|
+
The bridge is a call relay, not a memory layer. Meta-records are routing state for
|
|
4
|
+
the **current generation**; native transcripts and external memory stores remain
|
|
5
|
+
owned by their harnesses.
|
|
6
|
+
|
|
7
|
+
## Generation contract
|
|
8
|
+
|
|
9
|
+
1. The active citizen store is **V3-only**. Garden addresses and resume authority
|
|
10
|
+
never continue across generations.
|
|
11
|
+
2. Install and citizen birth certify the active store **before writing**. Any
|
|
12
|
+
defect refuses the operation and names `entwurf meta-bridge-fresh-cut`.
|
|
13
|
+
3. A fresh cut requires proven quiescence, archives the whole active generation,
|
|
14
|
+
and opens an empty one. It never closes a session for the operator.
|
|
15
|
+
4. Archives are forensic bytes only. No runtime reads them, no restore verb exists,
|
|
16
|
+
and native transcripts and memory axes are untouched.
|
|
17
|
+
|
|
18
|
+
There is no legacy reader or migrator. A native conversation that survives a cut
|
|
19
|
+
receives a new garden id when its next trusted hook or registration births it in
|
|
20
|
+
the new generation.
|
|
21
|
+
|
|
22
|
+
## What certification checks
|
|
23
|
+
|
|
24
|
+
`certifyActiveStore` is shared by the doctor and all identity writers: pi birth,
|
|
25
|
+
Claude's `SessionStart`, agy's imprint, and `entwurf_register_native`. Every active
|
|
26
|
+
record must be:
|
|
27
|
+
|
|
28
|
+
- a regular, non-symlink `.meta.json` file;
|
|
29
|
+
- readable by the live V3 schema;
|
|
30
|
+
- named by the `gardenId` in its body;
|
|
31
|
+
- the unique owner of its `nativeSessionId`.
|
|
32
|
+
|
|
33
|
+
Previous-generation records, corruption, filename/body drift, duplicate native
|
|
34
|
+
identity, and symlinks all fail certification. Address-bearing reads additionally
|
|
35
|
+
refuse duplicate ownership before a record becomes a dispatch or resume target.
|
|
36
|
+
`entwurf_peers` keeps healthy citizens visible and reports bad entries as diagnostics;
|
|
37
|
+
it never turns an ambiguous record into authority.
|
|
38
|
+
|
|
39
|
+
Targeted mailbox and sender-marker reads enforce the per-entry half of the same
|
|
40
|
+
contract. They do not rescan the entire store on every relay operation. Record bytes
|
|
41
|
+
are opened without following symlinks; implementation and race proofs live beside
|
|
42
|
+
`readStoreRecordFile` and in the `check-meta-*` gates.
|
|
43
|
+
|
|
44
|
+
## Running a cut
|
|
45
|
+
|
|
46
|
+
First close every pi, Claude Code, and agy session that could own a citizen or
|
|
47
|
+
transport artifact. Then run:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
entwurf meta-bridge-fresh-cut
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Quiescence fails closed. A live control socket, a marker with a live owner, a
|
|
54
|
+
probe-alive native-push conversation, or a surface whose state cannot be proved
|
|
55
|
+
all refuse the cut before anything moves. Absence means `ENOENT`; unreadable,
|
|
56
|
+
indeterminate, or symlinked state is not treated as absent.
|
|
57
|
+
|
|
58
|
+
The one bounded exception is an impossible owner pid (`<=1` or non-integer) on the
|
|
59
|
+
certified Linux desktop/workstation axis. Current writers cannot mint such a marker,
|
|
60
|
+
so it is reported and swept as refuted legacy/corrupt residue. A harness running as
|
|
61
|
+
PID 1 is outside the certified axis and fails closed.
|
|
62
|
+
|
|
63
|
+
### Exit contract
|
|
64
|
+
|
|
65
|
+
| Exit | State | Next action |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `0` | Cut complete | Run the appropriate installer/setup. |
|
|
68
|
+
| `1` | Nothing moved | Fix the named live, unreadable, or occupied condition and retry. |
|
|
69
|
+
| `2` | Usage error; nothing moved | Fix the command. |
|
|
70
|
+
| `3` | Transition incomplete after at least one archive move | Inspect or rerun to finish under a new stamp. |
|
|
71
|
+
| `4` | Cut complete; stale marker/socket cleanup failed | Setup may proceed, but repair the named residue first when possible. |
|
|
72
|
+
|
|
73
|
+
Only exit `0` is ordinary success. Exit `4` confirms a new generation is open but
|
|
74
|
+
still reports cleanup debt. Do not rerun an exit-4 cut after new citizens have been
|
|
75
|
+
born: that would archive the new generation too.
|
|
76
|
+
|
|
77
|
+
For the common path:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
entwurf meta-bridge-fresh-cut && entwurf setup /path/to/project
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Upgrade order
|
|
84
|
+
|
|
85
|
+
A checkout-backed host can begin running new code immediately after `git pull`, so
|
|
86
|
+
make the boundary explicit:
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
quiesce sessions → update package/checkout → fresh-cut if prescribed → reinstall/setup → reopen
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The preflight is not a transaction or a global lock. Concurrent native births can
|
|
93
|
+
race after certification, which is why discovery and address-bearing reads still
|
|
94
|
+
check uniqueness. If a later doctor turns red, stop and preserve the store before
|
|
95
|
+
cutting again.
|
|
96
|
+
|
|
97
|
+
Source of truth: `pi-extensions/lib/meta-session.ts`, the fresh-cut implementation,
|
|
98
|
+
`check-meta-*`, and `check-fresh-cut-gate`. Historical incidents and defect chronology
|
|
99
|
+
belong in CHANGELOG/issues rather than this operator policy.
|