@etiquekit/etq 1.0.10 → 1.0.12
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/QuickStart.md +2 -1
- package/README.md +2 -6
- package/docs/AGENT_SPAWNING.md +78 -0
- package/docs/ARCHITECTURE.md +5 -5
- package/docs/CODEX_CLIENT_COMPATIBILITY.md +1 -1
- package/docs/CONCEPTS.md +22 -5
- package/docs/CORE_PROFILE.md +4 -2
- package/docs/INTEGRATION_UI.md +215 -0
- package/docs/OPERATOR_PLAYBOOK.md +77 -0
- package/docs/README.md +1 -0
- package/docs/SEAT_PROVISIONING.md +3 -3
- package/docs/TAG_ROUTE.md +95 -0
- package/docs/WORKTREE_QOL.md +6 -0
- package/docs/contracts/ledger-entry/ledger-entry.v0.2.md +1 -1
- package/lib/etiquette-core.js +143 -141
- package/lib/etiquette.js +333 -324
- package/package.json +1 -1
- package/templates/DISPATCH_PREMISES.md +39 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/ACCESS-ASSURANCE.md +1 -1
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/workspace-secure-profile.v0.json +1 -1
- package/templates/seat-packs-v0/source/claude-code-seat/README.md +26 -0
- package/templates/seat-packs-v0/source/codex-seat/README.md +14 -0
- package/templates/seat-packs-v0/source/gemini-seat/README.md +20 -0
package/QuickStart.md
CHANGED
|
@@ -64,7 +64,7 @@ envelope, and runbook. For branch hygiene, read [docs/WORKTREE_QOL.md](docs/WORK
|
|
|
64
64
|
|
|
65
65
|
## 4. Check And Record Evidence
|
|
66
66
|
|
|
67
|
-
Completion gate: write the receipt at the path `pickup` names, post it
|
|
67
|
+
Completion gate: write the receipt at the path `pickup` names (`etq receipt scaffold --task <ref> --seat <id>` writes a starter stub), post it
|
|
68
68
|
(`etq post --role implementation-return --lane <task> --from <seat> --to <seat>`),
|
|
69
69
|
then `etq return check`. Separately, `dispatch check` gates ROUTING before
|
|
70
70
|
work begins — create checkable dispatch examples, then run the generated
|
|
@@ -91,4 +91,5 @@ Per-runtime integrations are explicit, never automatic: `provision-seat claude-c
|
|
|
91
91
|
Stop when authority is unclear, validation cannot run, writes exceed the
|
|
92
92
|
envelope, a secret appears, or the session is unbounded.
|
|
93
93
|
|
|
94
|
+
Going further: `etq help advanced` catalogs the advanced subsystems — the memory journal, supervision sessions, release gates, sync outbox, and webhooks.
|
|
94
95
|
Docs: https://etiquekit.com/docs/ · Agents start at: https://etiquekit.com/llms.txt
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ and what proved it worked**. Etiquette gives each participant a *seat*, each
|
|
|
10
10
|
unit of work a *task envelope*, each completion a *receipt*, and each merge a
|
|
11
11
|
*promotion gate* — recorded as plain files and git history you can audit.
|
|
12
12
|
|
|
13
|
-
Docs: https://etiquekit.com/docs/ · Agents start at: https://etiquekit.com/llms.txt
|
|
13
|
+
Docs: https://etiquekit.com/docs/ · Agents start at: https://etiquekit.com/llms.txt · Going further (memory journal, supervision, release gates): `etq help advanced`
|
|
14
14
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
@@ -77,8 +77,4 @@ Then `openssl dgst -sha256 -verify <key> -signature SHA256SUMS.sig SHA256SUMS`
|
|
|
77
77
|
and `shasum -a 256 -c SHA256SUMS`. If any step fails: stop, do not install.
|
|
78
78
|
|
|
79
79
|
## License
|
|
80
|
-
|
|
81
|
-
Apache-2.0. Copyright (c) 2026 Leepick Inc, US. Distributed as compiled bundles for convenience.
|
|
82
|
-
|
|
83
|
-
"Etiquette" and "etq" are trademarks of Leepick Inc, US.
|
|
84
|
-
|
|
80
|
+
Apache-2.0 (see LICENSE); distributed as compiled bundles for convenience.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Agent Spawning: inline runners vs provisioned seats
|
|
2
|
+
|
|
3
|
+
Guidance for **implementing agents** (the seat doing the work): when to spawn a
|
|
4
|
+
helper yourself, when to ask the operator to provision a durable seat, and how
|
|
5
|
+
to bind either one to the workflow. (`OPERATOR_PLAYBOOK.md` is the operator's
|
|
6
|
+
side of this; this file is yours.)
|
|
7
|
+
|
|
8
|
+
## The two axes — never conflate them
|
|
9
|
+
|
|
10
|
+
- **Seat** = durable identity + evidence trail. It survives processes, carries
|
|
11
|
+
the receipts, and owns tasks. Seats are cheap to keep and expensive to blur.
|
|
12
|
+
- **Runner** = an execution process occupying a seat. Disposable by default.
|
|
13
|
+
|
|
14
|
+
The default pattern is the **hybrid**: bind a *disposable runner* to a
|
|
15
|
+
*durable seat*. The trail persists; the process is throwaway. Discard the
|
|
16
|
+
runner after its return — the seat keeps everything that matters.
|
|
17
|
+
|
|
18
|
+
## Spawn inline yourself (no operator needed) when ALL hold
|
|
19
|
+
|
|
20
|
+
- The work is **bounded and one-off**: a single review, an audit, a read-only
|
|
21
|
+
probe, a parallel fan-out of readers.
|
|
22
|
+
- It's **read-only toward your scope** — a spawned helper must never become a
|
|
23
|
+
second writer in your own `allowed_writes` (single-writer applies to your
|
|
24
|
+
spawns too).
|
|
25
|
+
- It can **finish inside your session**: if your process dies, nothing of value
|
|
26
|
+
dies with it beyond a re-run.
|
|
27
|
+
- You can bind it properly: seat + task + envelope + the same pickup/receipt
|
|
28
|
+
workflow you follow. An unbound helper produces unaccountable output.
|
|
29
|
+
|
|
30
|
+
## Ask the operator to provision instead when ANY hold
|
|
31
|
+
|
|
32
|
+
- The helper will own **repeated lanes over days** — recurring review, a
|
|
33
|
+
standing monitor, a specialist surface. Durable work deserves a durable
|
|
34
|
+
session the operator can see, resume, and audit.
|
|
35
|
+
- It needs its **own vendor/model/credentials** (a different provider is often
|
|
36
|
+
*desirable* for review — and it's the operator's call to provision).
|
|
37
|
+
- It must **outlive you**: long-running watches, anything that should survive
|
|
38
|
+
your session ending.
|
|
39
|
+
- It would **write product code** anywhere. New writers are an operator
|
|
40
|
+
decision, always.
|
|
41
|
+
|
|
42
|
+
Never be shy to ask. A well-formed ask is a sign of a healthy loop, not a
|
|
43
|
+
failure. But ask with a complete provisioning card, not a vibe:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Requesting a provisioned seat:
|
|
47
|
+
seat: <id> (new or existing)
|
|
48
|
+
why durable: <recurring lanes / credentials / outlives-me>
|
|
49
|
+
first task: <ref> — envelope ready at <path>
|
|
50
|
+
worktree: <prepared path + pinned base>
|
|
51
|
+
entry: <the exact join/pickup commands>
|
|
52
|
+
boundaries: <read-only? allowed_writes? never merge/push?>
|
|
53
|
+
vendor hint: <same or deliberately different model — and why>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Binding rules (both kinds)
|
|
57
|
+
|
|
58
|
+
- One seat, one active runner per task. If a second runner must take over,
|
|
59
|
+
it claims *explicitly* (exclusive claim, runner id recorded) — two runners
|
|
60
|
+
silently emitting as one seat corrupts the trail.
|
|
61
|
+
- Every spawned runner follows the full loop: join → pickup → work → receipt →
|
|
62
|
+
return. No side-channel results; if it didn't post, it didn't happen.
|
|
63
|
+
- Record provenance: the return should show which runner executed, especially
|
|
64
|
+
when it isn't the seat's usual occupant.
|
|
65
|
+
- Reviewers return **evidence and proposed amendments — never edits, never
|
|
66
|
+
merges**. Your spawns inherit your boundaries; they do not inherit your
|
|
67
|
+
write scope.
|
|
68
|
+
- Disposable means disposable: after the return is posted and verified, the
|
|
69
|
+
runner is gone. Anything worth keeping is in the receipt, not the process.
|
|
70
|
+
|
|
71
|
+
## The sequencing instinct (learned from real runs)
|
|
72
|
+
|
|
73
|
+
- **During implementation**: zero extra writers. Resist "help."
|
|
74
|
+
- **Branch ready**: exactly one reviewer — read-only, ideally a different
|
|
75
|
+
model/vendor than you.
|
|
76
|
+
- **Recurring specialization emerges** (per-provider adapters, standing
|
|
77
|
+
audits): *that* is the moment to request provisioned specialist seats —
|
|
78
|
+
not before.
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -22,9 +22,9 @@ Execution returns evidence; it never mints authority.
|
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
Execution is a substrate, not an authority layer. In Core it is the local shell,
|
|
25
|
-
worktree, or runner. In Full it may be a
|
|
26
|
-
managed runner. In every profile, execution remains
|
|
27
|
-
promotion gate accepts evidence.
|
|
25
|
+
worktree, or runner. In Full it may be a managed execution container,
|
|
26
|
+
EKS/kind sandbox, or managed runner. In every profile, execution remains
|
|
27
|
+
authority-false until the promotion gate accepts evidence.
|
|
28
28
|
|
|
29
29
|
## Authority
|
|
30
30
|
|
|
@@ -52,11 +52,11 @@ role occupants or composite gates and fails closed.
|
|
|
52
52
|
|
|
53
53
|
## Consumers
|
|
54
54
|
|
|
55
|
-
Consumers may read, render, route bounded work,
|
|
55
|
+
Consumers may read, render, route bounded work, start bounded runners, and return
|
|
56
56
|
receipts. They must not grant, close, merge, rewrite ledgers, or become the bus.
|
|
57
57
|
|
|
58
58
|
Good first consumers are verification-first managed runners, local coding seats,
|
|
59
|
-
context workbenches, dashboards, and MCP readers. Start remote as
|
|
59
|
+
context workbenches, dashboards, and MCP readers. Start remote as evidence-only.
|
|
60
60
|
|
|
61
61
|
## Package Boundary
|
|
62
62
|
|
|
@@ -23,7 +23,7 @@ Source: https://developers.openai.com/codex/changelog
|
|
|
23
23
|
| Remote-runtime app-server/exec-server canaries | `0.141.0` required | Block that canary until upgraded. |
|
|
24
24
|
| Plugin-scoped MCP adapter canaries | `0.141.0` required | Block that canary until upgraded. |
|
|
25
25
|
| Hook/action-auth resume canaries | `0.141.0` required | Block that canary until upgraded. |
|
|
26
|
-
| Usage-budget hygiene before long
|
|
26
|
+
| Usage-budget hygiene before long multi-runner windows | `0.140.0` minimum for `/usage` | Advisory only. |
|
|
27
27
|
|
|
28
28
|
## Operator Check
|
|
29
29
|
|
package/docs/CONCEPTS.md
CHANGED
|
@@ -38,8 +38,8 @@ autonomous execution.
|
|
|
38
38
|
## Session
|
|
39
39
|
|
|
40
40
|
A session is a bounded run inside one repo. Use one for a bug fix, feature
|
|
41
|
-
slice, review, release canary, or short
|
|
42
|
-
org.
|
|
41
|
+
slice, review, release canary, or short parallel review window; not for a
|
|
42
|
+
product, quarter, or org.
|
|
43
43
|
|
|
44
44
|
## Receipt
|
|
45
45
|
|
|
@@ -52,6 +52,23 @@ A ledger is the durable work record for a repo or workspace: decisions,
|
|
|
52
52
|
receipts, state changes, and refs. Raw execution chatter belongs in session
|
|
53
53
|
runbooks and scratch space.
|
|
54
54
|
|
|
55
|
+
### Durable Record vs Query Index
|
|
56
|
+
|
|
57
|
+
Two surfaces share the ledger name. They are different systems:
|
|
58
|
+
|
|
59
|
+
| Surface | Path | When it populates |
|
|
60
|
+
| --- | --- | --- |
|
|
61
|
+
| Durable record | `docs/work/ledger/LEDGER.md` | Automatically, as the workflow appends event lines |
|
|
62
|
+
| Query index | `.etiquette/state/ledger/index.db` | Only when you run `etiquette ledger index` |
|
|
63
|
+
|
|
64
|
+
The durable record is canonical and append-only. The query index is a
|
|
65
|
+
generated, regenerable SQLite cache read by `ledger search` and `ledger show`.
|
|
66
|
+
It ingests typed `schema=ledger-entry.v0*` lines and scanned documents, not
|
|
67
|
+
routine workflow event lines. `ledger_entries: 0` after a full workflow cycle
|
|
68
|
+
means no typed entries exist yet; the durable record is intact. Deleting the
|
|
69
|
+
index loses nothing. See
|
|
70
|
+
`docs/contracts/ledger-entry/ledger-query-cli.v0.1.md`.
|
|
71
|
+
|
|
55
72
|
## Promotion Gate
|
|
56
73
|
|
|
57
74
|
The promotion gate is where candidate work becomes accepted truth.
|
|
@@ -82,7 +99,8 @@ runner only through an explicit lease.
|
|
|
82
99
|
|
|
83
100
|
A child lease must be a strict subset of the parent lease. The subset covers
|
|
84
101
|
shorter or equal TTL, narrower or equal authority scope, subset write paths,
|
|
85
|
-
subset tools, inherited prohibitions, reduced
|
|
102
|
+
subset tools, inherited prohibitions, reduced child-runner budget, and reduced
|
|
103
|
+
depth.
|
|
86
104
|
|
|
87
105
|
Children return to their immediate parent. The parent synthesizes one upstream
|
|
88
106
|
receipt and remains accountable for child cleanup. A child or headless node is
|
|
@@ -91,7 +109,7 @@ not a durable seat unless it is separately enrolled and passes readiness.
|
|
|
91
109
|
## Exec
|
|
92
110
|
|
|
93
111
|
Exec is any runtime that does work: a local shell, Codex, Claude Code, Gemini,
|
|
94
|
-
Ollama, a script, a container, or a
|
|
112
|
+
Ollama, a script, a container, or a managed execution container.
|
|
95
113
|
|
|
96
114
|
Exec may run, observe, retry safe work, and return evidence. Exec must not
|
|
97
115
|
grant, merge, close, promote, or mutate canonical truth.
|
|
@@ -126,4 +144,3 @@ Portals display and coordinate.
|
|
|
126
144
|
Integrations project refs.
|
|
127
145
|
Execution returns evidence; it never mints authority.
|
|
128
146
|
```
|
|
129
|
-
|
package/docs/CORE_PROFILE.md
CHANGED
|
@@ -37,7 +37,8 @@ Core records, validates, gates, and dispatches:
|
|
|
37
37
|
|
|
38
38
|
Full remembers, consolidates, marinates, and projects. Memory stores,
|
|
39
39
|
consolidation rollups, marination modules, hosted portals, secure screening,
|
|
40
|
-
|
|
40
|
+
managed execution containers, and sharded drains belong there unless explicitly
|
|
41
|
+
enabled.
|
|
41
42
|
|
|
42
43
|
Use:
|
|
43
44
|
|
|
@@ -63,7 +64,8 @@ The Core promotion path is:
|
|
|
63
64
|
5. The ledger records the promoted result.
|
|
64
65
|
|
|
65
66
|
At Core scale, Git is the promotion mechanism. Drains, sharded import, hosted
|
|
66
|
-
planes, and
|
|
67
|
+
planes, and managed execution containers belong to the Full profile unless
|
|
68
|
+
explicitly enabled.
|
|
67
69
|
|
|
68
70
|
Core commands may advise, check, and record evidence. They do not authorize
|
|
69
71
|
work, attach grants, merge, close lanes, or promote candidates without the
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Integrating a UI/Consumer with the Event Log and Packets
|
|
2
|
+
|
|
3
|
+
How to build a read-model or composer UI (inbox, thread view, approvals queue,
|
|
4
|
+
seat roster) over an Etiquette project. Three file surfaces, all in one git
|
|
5
|
+
repo. The consumer is a read-model plus composer over them, never a writer of
|
|
6
|
+
record.
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
<project>/
|
|
10
|
+
├── .etiquette/events/local.ndjson # the EVENT LOG (append-only, seq-ordered)
|
|
11
|
+
├── docs/work/packets/*.json # the PACKETS (one file per message)
|
|
12
|
+
├── docs/work/ledger/LEDGER.md # the durable record (see CONCEPTS.md)
|
|
13
|
+
└── (ordinary git) # commits are durability; push is visibility
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 1. Event Schema (`local-event.v0`)
|
|
17
|
+
|
|
18
|
+
Every emitted packet post appends exactly one event line (ndjson, one JSON
|
|
19
|
+
object per line). Events are the index; packets are the content.
|
|
20
|
+
|
|
21
|
+
| field | type | notes |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `seq` | int | global monotonic sequence. THE ordering key. Never reuse, never renumber. |
|
|
24
|
+
| `schema` | string | `local-event.v0` |
|
|
25
|
+
| `event_ref` | string | `local://event/<seq>` — the durable ref other records cite |
|
|
26
|
+
| `created_at` | ISO8601 UTC | emit time |
|
|
27
|
+
| `type` | string | event kind, e.g. `packet_posted` |
|
|
28
|
+
| payload | spread | packet fields are spread into the event: `role`, `lane`, `from`, `to`, `next_owner`, `verdict`, `mode`, `packet_tier`, `packet_ref`, `changes_state`, and optionally `requires_ack`, `in_reply_to` |
|
|
29
|
+
|
|
30
|
+
Reader rules (learned the hard way):
|
|
31
|
+
|
|
32
|
+
- Track position by `seq` cursor, never by byte offset or `tail -F`. Git
|
|
33
|
+
operations can rewrite the file and replay it from line 1.
|
|
34
|
+
- Read through the CLI where possible: `etiquette notify poll --seat <id>
|
|
35
|
+
--after-seq <n>`, `etiquette bus view`, `etiquette timeline view`,
|
|
36
|
+
`etiquette status`. The write side must go through `etiquette post` — it
|
|
37
|
+
owns field validation, the event append lock, and the ledger mirror.
|
|
38
|
+
- Badge authority acts (decisions, grants) differently from routine traffic.
|
|
39
|
+
Key on the packet `role` and `verdict`, not on `changes_state` (see drift
|
|
40
|
+
note D5).
|
|
41
|
+
|
|
42
|
+
## 2. Packet Spec (`local-packet.v0`)
|
|
43
|
+
|
|
44
|
+
One JSON file per message, written by `etiquette post` to
|
|
45
|
+
`docs/work/packets/<created_at>-<lane>-<role>.json`. With `--emit` (implied
|
|
46
|
+
for return roles) the post also appends a `packet_posted` event and mirrors a
|
|
47
|
+
line into the durable ledger record.
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"schema": "local-packet.v0",
|
|
52
|
+
"role": "dispatch",
|
|
53
|
+
"lane": "wire-real-search-01",
|
|
54
|
+
"from": "team-orchestrator",
|
|
55
|
+
"to": "team-implementer-1",
|
|
56
|
+
"verdict": "routed",
|
|
57
|
+
"packet_tier": "3",
|
|
58
|
+
"mode": "product-implementation",
|
|
59
|
+
"next_owner": "team-implementer-1",
|
|
60
|
+
"created_at": "2026-07-11T09:00:12.000Z",
|
|
61
|
+
"changes_state": true,
|
|
62
|
+
"authority_boundary": {
|
|
63
|
+
"packet_authorizes_work": false,
|
|
64
|
+
"can_merge": false,
|
|
65
|
+
"can_close": false,
|
|
66
|
+
"can_grant": false
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Field notes:
|
|
72
|
+
|
|
73
|
+
- `role` — the message class. Conventional values: `dispatch`, `task-bundle`,
|
|
74
|
+
`implementation-return`, `review-return`, `counter`, `advisory`, `decision`,
|
|
75
|
+
`acknowledge`. Return roles always emit an event.
|
|
76
|
+
- `mode` — the authority class of the referenced work (see section 5).
|
|
77
|
+
- `next_owner` — who acts next; load-bearing for routing and wake queues.
|
|
78
|
+
- `packet_tier` — a string (`"2"` or `"3"`); governs how much body discipline
|
|
79
|
+
the packet's narrative carries (section 3).
|
|
80
|
+
- `authority_boundary` — always present, always false-by-default. A packet
|
|
81
|
+
never authorizes work by itself.
|
|
82
|
+
|
|
83
|
+
The write-scope envelope (what a task may touch) does not live in the packet.
|
|
84
|
+
It lives in the task bundle (`task-bundle.v1`): `allowed_writes` (required),
|
|
85
|
+
`validation` (required), `stop_conditions`, `forbidden_sources`,
|
|
86
|
+
`expected_return`, `evidence_sink`, `authority_boundary`. Packets reference
|
|
87
|
+
the lane/task; the bundle carries the envelope.
|
|
88
|
+
|
|
89
|
+
## 3. Body Discipline by Tier
|
|
90
|
+
|
|
91
|
+
Packets shipped by this CLI are compact JSON. When a deployment pairs packets
|
|
92
|
+
with markdown narrative bodies (correspondence artifacts), the tier rules
|
|
93
|
+
below are the required section headings. Composers should emit them exactly;
|
|
94
|
+
a suffix on a heading (`## Evidence Cited from X`) is the classic papercut.
|
|
95
|
+
|
|
96
|
+
| tier | required `##` headings | extra rule |
|
|
97
|
+
| --- | --- | --- |
|
|
98
|
+
| 2 | `## Verdict` (or `## Disposition`) + `## Evidence` + `## Next owner` | body <= 50 lines |
|
|
99
|
+
| 3 | tier-2 set plus `## Failure modes` + `## Confidence calibration` | — |
|
|
100
|
+
|
|
101
|
+
Note: this package does not lint markdown bodies today (drift note D4). Treat
|
|
102
|
+
the table as the portable packet-body convention a composer should enforce
|
|
103
|
+
client-side.
|
|
104
|
+
|
|
105
|
+
## 4. Sample Thread
|
|
106
|
+
|
|
107
|
+
A synthetic six-event thread covering every UI moment (dispatch, ack with a
|
|
108
|
+
runner swap, a stop-condition counter, an amended scope, a verified return,
|
|
109
|
+
and a human decision) ships in source checkouts as
|
|
110
|
+
`fixtures/ui-thread-example.json`. Fixtures are excluded from the published
|
|
111
|
+
package; use a source checkout. The fixture carries a `summary` convenience
|
|
112
|
+
field (extra payload, drift note D8) so list views have something to render.
|
|
113
|
+
|
|
114
|
+
Render test for a consumer:
|
|
115
|
+
|
|
116
|
+
- The thread reads as a conversation (`in_reply_to` chains to `event_ref`).
|
|
117
|
+
- The runner-swap badge shows where `execution_seat` differs from
|
|
118
|
+
`durable_owner`.
|
|
119
|
+
- The counter (a guardrail firing) is visually distinct — celebrate it, do
|
|
120
|
+
not bury it.
|
|
121
|
+
- Exactly one event is an authority act (the `decision` role).
|
|
122
|
+
|
|
123
|
+
## 5. The Envelope Model (what an approval UI must understand)
|
|
124
|
+
|
|
125
|
+
Four separate axes — never collapse them into one "agent type":
|
|
126
|
+
|
|
127
|
+
| axis | values | meaning |
|
|
128
|
+
| --- | --- | --- |
|
|
129
|
+
| coordination shape | `solo` \| `tango` \| `rig` \| `shadow` | one runner / pair-with-reviewer / fan-out / observe-only |
|
|
130
|
+
| `mode` (authority class) | `read-only-audit` \| `docs-only` \| `product-implementation` | what the seat may WRITE |
|
|
131
|
+
| perimeter | local \| sandboxed \| managed | WHERE it executes (never a topology) |
|
|
132
|
+
| risk posture | derived | from mode + write breadth + irreversibility + credentials/network + data sensitivity |
|
|
133
|
+
|
|
134
|
+
Authority doctrine the UI must encode, not just display:
|
|
135
|
+
|
|
136
|
+
- Agent-produced artifacts are authority-false. They cross into effect only
|
|
137
|
+
via a human decision. An approval screen renders the authority-false
|
|
138
|
+
artifact plus its evidence and captures the human decision as a new packet.
|
|
139
|
+
- Single-writer: one routed owner mutates a canonical surface at a time;
|
|
140
|
+
reviewers contribute evidence packets, never competing mutations.
|
|
141
|
+
- Dynamic execution, static authority: automation may advance work; only the
|
|
142
|
+
principal crosses merge/promote/ratify/spend gates. No auto-approval, ever.
|
|
143
|
+
An adapter or app synthesizing a decision is the named number-one failure
|
|
144
|
+
mode.
|
|
145
|
+
- Landing/merging is always the principal's act; seats hand branches back.
|
|
146
|
+
|
|
147
|
+
## 6. Composer Requirements (where a consumer earns its keep)
|
|
148
|
+
|
|
149
|
+
1. Emit valid packets: real `role`, valid `mode`, `next_owner` always set,
|
|
150
|
+
envelope present in the task bundle for `product-implementation` work.
|
|
151
|
+
2. Post through the CLI. `etiquette post --emit` performs the packet write,
|
|
152
|
+
event append (under the event lock), and ledger mirror as one act. The git
|
|
153
|
+
commit remains the operator's act — surface uncommitted
|
|
154
|
+
`.etiquette/events/` and `docs/work/` state prominently; a dirty canonical
|
|
155
|
+
surface blocks other seats' workflow steps.
|
|
156
|
+
3. Thread rendering: chain packets by `in_reply_to` / `event_ref` into a
|
|
157
|
+
conversation view (dispatch, counter, amend, return, confirm, decision).
|
|
158
|
+
4. Badges: model/provider identity, runner-vs-seat occupancy, authority
|
|
159
|
+
(`role`, `mode`), and verification level (self-reported vs
|
|
160
|
+
second-party-verified — a return another seat re-ran is gold).
|
|
161
|
+
5. Envelope-aware diff review: when reviewing a branch, show the diff against
|
|
162
|
+
the bundle's `allowed_writes` — out-of-scope files are instant red flags.
|
|
163
|
+
6. Never write canon autonomously. The app composes; the human sends.
|
|
164
|
+
|
|
165
|
+
## 7. Format Drift Notes
|
|
166
|
+
|
|
167
|
+
This document descends from a spec written against a markdown-packet bus.
|
|
168
|
+
Where that ancestor and this package disagree, this package's shipped formats
|
|
169
|
+
win. Known drift, kept honest rather than papered over:
|
|
170
|
+
|
|
171
|
+
- D1. Ancestor events carried `at`/`actor`/`action`/`packet_id`/`message`;
|
|
172
|
+
shipped `local-event.v0` uses `created_at`/`from`/`type` plus packet fields,
|
|
173
|
+
and has no self-contained `message` summary field.
|
|
174
|
+
- D2. Ancestor refs used a bus URI scheme keyed by bare seq; shipped refs are
|
|
175
|
+
`local://event/<seq>` in `event_ref` and `in_reply_to`.
|
|
176
|
+
- D3. Ancestor packets were markdown with YAML frontmatter named
|
|
177
|
+
`<timestamp>-<actor>-<slug>.md`; shipped packets are JSON
|
|
178
|
+
`local-packet.v0` files named `<created_at>-<lane>-<role>.json`.
|
|
179
|
+
- D4. Ancestor tier headings were lint-enforced at post time; this package
|
|
180
|
+
does not lint markdown bodies. `packet_tier` is also a string here, not an
|
|
181
|
+
int.
|
|
182
|
+
- D5. Ancestor `changes_state` meant "authority act". The shipped `post`
|
|
183
|
+
command sets `changes_state` to whether the packet was emitted to the event
|
|
184
|
+
log, so every `packet_posted` event carries `changes_state: true`. Until
|
|
185
|
+
this is reconciled, consumers must badge authority from `role`/`verdict`,
|
|
186
|
+
not `changes_state`.
|
|
187
|
+
- D6. Ancestor `mode` enum had a fourth value, `dirty-tree-extraction`; this
|
|
188
|
+
package ships three modes.
|
|
189
|
+
- D7. Ancestor envelopes (`repo`, `base_commit`, `branch`, `worktree_path`)
|
|
190
|
+
rode in packet frontmatter; the shipped envelope lives in `task-bundle.v1`
|
|
191
|
+
and does not include those four fields — base pinning and worktree layout
|
|
192
|
+
are handled at the git/CLI layer.
|
|
193
|
+
- D8. `cc`, `workflow_id`, `slice_id`, `content_class` (on packets), `summary`,
|
|
194
|
+
and the provenance fields `durable_owner`, `execution_seat`, `executed_by`,
|
|
195
|
+
`actual_model`, `operator_principal` have no shipped writer in `post`.
|
|
196
|
+
Events tolerate them as extra payload; projections surface only some. Treat
|
|
197
|
+
them as optional until promoted.
|
|
198
|
+
|
|
199
|
+
## 8. Glossary
|
|
200
|
+
|
|
201
|
+
- **seat** — durable agent identity plus authority envelope; provider-agnostic.
|
|
202
|
+
- **packet** — one message on the log; the unit of coordination.
|
|
203
|
+
- **lane / slice** — a thread of work / one bounded task within it.
|
|
204
|
+
- **envelope** — the write-scope + validation + stop-condition contract a task
|
|
205
|
+
runs under (carried by the task bundle).
|
|
206
|
+
- **harvest** — a defect found out of scope: recorded and routed, never fixed
|
|
207
|
+
inline.
|
|
208
|
+
- **receipt** — evidence attached to a return (commands run, output tails,
|
|
209
|
+
SHAs).
|
|
210
|
+
- **landing** — principal-gated merge to the default branch.
|
|
211
|
+
- **lease** — a seat's time-bounded authority to occupy a task.
|
|
212
|
+
- **promotion gate** — the human decision point where an authority-false
|
|
213
|
+
artifact becomes effective.
|
|
214
|
+
|
|
215
|
+
See `docs/CONCEPTS.md` for the core vocabulary these one-liners compress.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Operator Playbook
|
|
2
|
+
|
|
3
|
+
You are the principal. Agents execute; **you decide.** This is the when-X-do-Y
|
|
4
|
+
card for running the workflow on the go. (`AGENTS.md` tells agents how to
|
|
5
|
+
behave — this file tells *you* what move to make.)
|
|
6
|
+
|
|
7
|
+
## Starting work
|
|
8
|
+
|
|
9
|
+
- **Before dispatching, shape the task**: one agent or several? does review need
|
|
10
|
+
a separate mind? is checking cheap? If it's a judgment call — keep it yourself.
|
|
11
|
+
- **Write the envelope, always**: `allowed_writes`, validation, stop conditions,
|
|
12
|
+
pinned base commit. The envelope *is* the speed — it's what lets an agent run
|
|
13
|
+
unattended and lets you trust the result.
|
|
14
|
+
- **One task, one worktree, one branch.** Never work on a shared checkout.
|
|
15
|
+
|
|
16
|
+
## While an agent works
|
|
17
|
+
|
|
18
|
+
- **Don't add a second writer to the same scope.** Design can be parallel;
|
|
19
|
+
writing is single-writer. Resist "helping" in its files.
|
|
20
|
+
- **Don't steer mid-run.** Post an amendment packet instead; the agent's
|
|
21
|
+
stop-conditions are your remote control.
|
|
22
|
+
- Long silence ≠ progress. Check the session notes, not the vibe.
|
|
23
|
+
|
|
24
|
+
## When a return arrives
|
|
25
|
+
|
|
26
|
+
- **An agent STOPPED or COUNTERED? That is the system working.** Read its
|
|
27
|
+
evidence, then uphold or amend — never bulldoze past it. A lying green is
|
|
28
|
+
worse than an honest red.
|
|
29
|
+
- **Self-reported evidence is a claim, not a proof.** Before landing anything
|
|
30
|
+
that matters, get a second party to re-run the checks — runtime proof beats
|
|
31
|
+
reading code beats trusting a summary.
|
|
32
|
+
- **Review the diff against the envelope**: files outside `allowed_writes` are
|
|
33
|
+
red flags even when the code looks good.
|
|
34
|
+
|
|
35
|
+
## The reviewer moment (the most-missed nudge)
|
|
36
|
+
|
|
37
|
+
- **Branch ready → spin exactly one reviewer.** Read-only audit, a *different*
|
|
38
|
+
model/vendor than the implementer, returning evidence and proposed
|
|
39
|
+
amendments — never edits, never merges.
|
|
40
|
+
- Never be shy to add **reviewers**; be very shy to add **writers**.
|
|
41
|
+
- A good implementing agent will *ask* you for a reviewer at the right moment.
|
|
42
|
+
Honor the shape it proposes.
|
|
43
|
+
|
|
44
|
+
## Gates (yours alone)
|
|
45
|
+
|
|
46
|
+
- Merging, closing, promoting, granting scope, spending money, touching
|
|
47
|
+
credentials or production — these never delegate. An agent that "just did it"
|
|
48
|
+
is a defect, not initiative.
|
|
49
|
+
- Before approving: read the evidence, not the summary line.
|
|
50
|
+
- Anything needing secrets, network egress, or real user data is a *perimeter
|
|
51
|
+
decision*, not a task detail. Stop and decide it explicitly.
|
|
52
|
+
|
|
53
|
+
## Hygiene, on the go
|
|
54
|
+
|
|
55
|
+
- Lost? `etq whereami`. Broken? `etq doctor`.
|
|
56
|
+
- Finish your posts: a half-committed event blocks every other seat.
|
|
57
|
+
- Don't leave counters unanswered overnight — a stopped agent is parked
|
|
58
|
+
capacity waiting on *you*.
|
|
59
|
+
- The urge to skip the envelope for "a quick fix" is how quick fixes become
|
|
60
|
+
incidents. Small task, small envelope — but an envelope.
|
|
61
|
+
|
|
62
|
+
## The human gate ("what now?")
|
|
63
|
+
|
|
64
|
+
- When an agent stops and waits, ask: **is this a stall or a gate?** A good
|
|
65
|
+
agent tells you; if it doesn't, ask "gate or stalled?" before nudging.
|
|
66
|
+
- **"continue" / "proceed" are nudges, not authority.** Never let them double
|
|
67
|
+
as approval. A gated act needs its own *named phrase* — a good agent mints
|
|
68
|
+
one ("say 'accept and land' to merge"); echo it exactly or refuse it.
|
|
69
|
+
- At a gate, demand the card: what's decided, the options, the evidence, the
|
|
70
|
+
phrase. Deciding from a summary line is how gates rubber-stamp themselves.
|
|
71
|
+
|
|
72
|
+
## When you're the bottleneck
|
|
73
|
+
|
|
74
|
+
- Triage by type: **decisions** (only you) → **reviews** (route one reviewer) →
|
|
75
|
+
**FYI** (skim). Work the decisions first.
|
|
76
|
+
- If the same nudge keeps recurring, it belongs in a stop-condition or a
|
|
77
|
+
template — encode it once instead of remembering it nightly.
|
package/docs/README.md
CHANGED
|
@@ -11,6 +11,7 @@ References:
|
|
|
11
11
|
|
|
12
12
|
- [CODEX_CLIENT_COMPATIBILITY.md](CODEX_CLIENT_COMPATIBILITY.md)
|
|
13
13
|
- [RELEASE_SURFACE_AUDIT.md](RELEASE_SURFACE_AUDIT.md)
|
|
14
|
+
- [INTEGRATION_UI.md](INTEGRATION_UI.md) — building a UI/consumer over the event log and packets
|
|
14
15
|
|
|
15
16
|
Source checkouts also keep hosted parity, portal, managed-runtime parity, and root kernel notes for
|
|
16
17
|
maintainers. They are not part of the local devkit tarball.
|
|
@@ -7,7 +7,7 @@ Start with one project owner and one review seat. Add runtime-specific seats onl
|
|
|
7
7
|
1. Install project-local agent guidance with `setup`.
|
|
8
8
|
2. Initialize the project with `bootstrap local`.
|
|
9
9
|
3. Read `AGENTS.md`, `BOARD.md`, `SESSION_PICKUP.md`, and `SEAT_OPERATING_MANUAL.md`.
|
|
10
|
-
4.
|
|
10
|
+
4. After resume or runner/model swaps, run `resume check`; otherwise run `whereami`, `doctor`, and `status`.
|
|
11
11
|
5. Confirm the lead and review seats.
|
|
12
12
|
6. Use `$etiquette-seat-lifecycle` before pickup after stale context, resume, runner/model/profile swaps, or workflow migration.
|
|
13
13
|
7. Have the lead seat `join` and `pickup` the first generated task.
|
|
@@ -18,6 +18,7 @@ Start with one project owner and one review seat. Add runtime-specific seats onl
|
|
|
18
18
|
```sh
|
|
19
19
|
etiquette setup --target codex --project "$PWD"
|
|
20
20
|
etiquette bootstrap local --project "$PWD" --profile codex-cc-gemini --task-prefix APP
|
|
21
|
+
etiquette resume check --project "$PWD" --seat codex-seat --task APP-001 --json
|
|
21
22
|
etiquette whereami --project "$PWD" --seat codex-seat --task APP-001
|
|
22
23
|
etiquette doctor --project "$PWD"
|
|
23
24
|
etiquette status --project "$PWD"
|
|
@@ -96,5 +97,4 @@ Remote execution is a later layer. Plane provisioning is infra-admin scoped. Wor
|
|
|
96
97
|
- Start with the smallest useful topology.
|
|
97
98
|
- Add seats because work requires them.
|
|
98
99
|
- Product-write authority requires a task, allowed writes, validation, and the right promotion gate.
|
|
99
|
-
- Chat is not canonical record.
|
|
100
|
-
- Runtime packs are adapters, not doctrine.
|
|
100
|
+
- Chat is not canonical record; runtime packs are adapters, not doctrine.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Tag-Route v0 — paste a thread, get a bounded draft card
|
|
2
|
+
|
|
3
|
+
Tag-Route turns a pasted chat thread into a **draft task-bundle.v1 card**.
|
|
4
|
+
It is an entry door into the existing card lifecycle, not a new lifecycle:
|
|
5
|
+
drafts are non-canonical until promoted through normal pickup/return
|
|
6
|
+
discipline, and nothing in this path grants authority.
|
|
7
|
+
|
|
8
|
+
## Vocabulary: card vs bundle
|
|
9
|
+
|
|
10
|
+
- **Task card** (`task-envelope.v0`) — the local work envelope under
|
|
11
|
+
`docs/work/tasks/`. Pickup, allowed writes, validation, receipts.
|
|
12
|
+
- **Task bundle** (`task-bundle.v1`) — the same envelope lineage, extended
|
|
13
|
+
with namespaced interop fields (`strategy_policy`, `execution_hints`,
|
|
14
|
+
`requirements`, `preflight_refs`, `budgets`, `provenance_window`,
|
|
15
|
+
`requested_by`). Every shipped task card already validates as a bundle.
|
|
16
|
+
- Bundles are **strictly declarative**. Script-bearing fields
|
|
17
|
+
(`pre_execute`, `run`, `shell`, `script`, `hooks`, ...) are rejected.
|
|
18
|
+
Bundles may only *reference* preflights the executor already holds
|
|
19
|
+
(`etq://preflights/<id>`); unknown refs refuse pickup.
|
|
20
|
+
|
|
21
|
+
## Registries (declared, admin-signed, verified-never-authored)
|
|
22
|
+
|
|
23
|
+
- `.etiquette/bindings.yaml` — `channel-binding-registry.v1`. Each
|
|
24
|
+
`channel-binding.v1` entry binds a chat channel to one repository, the
|
|
25
|
+
write envelope compiled cards may declare, and the seat to notify.
|
|
26
|
+
- `.etiquette/roster/mappings.yaml` — `roster-mapping-registry.v1`. Each
|
|
27
|
+
`roster-mapping.v1` entry maps a chat user id to a seat card ref.
|
|
28
|
+
|
|
29
|
+
Unknown channel and unknown requesting user are refusals, not fallbacks.
|
|
30
|
+
|
|
31
|
+
## Walkthrough: paste a thread
|
|
32
|
+
|
|
33
|
+
1. Declare the registries once (admin act):
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
# .etiquette/bindings.yaml
|
|
37
|
+
schema: channel-binding-registry.v1
|
|
38
|
+
bindings:
|
|
39
|
+
- schema: channel-binding.v1
|
|
40
|
+
channel_id: team-help
|
|
41
|
+
repository_ref: github.example/org/demo-app
|
|
42
|
+
allowed_writes: [src/checkout/**]
|
|
43
|
+
notify_ref: impl-seat
|
|
44
|
+
admin_signature: sha256:<hex>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
2. Verify them any time:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
etiquette tag bindings verify --project .
|
|
51
|
+
etiquette tag roster resolve U12345 --project .
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
3. Save the chat thread as plain text, one `<user>: <message>` per line,
|
|
55
|
+
then compile (or pipe it via `-`):
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
etiquette tag compile thread.txt --channel team-help --project .
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
4. The compiled draft lands under `docs/work/drafts/<task-id>.yaml` with
|
|
62
|
+
`content_class: draft` and `authority: "false"`. Compile is the
|
|
63
|
+
canonicalization moment: the card cites its `provenance_window`
|
|
64
|
+
(line range + sha256 of the transcript slice) so chat-sourced context
|
|
65
|
+
stays auditable without ever becoming a startup doc.
|
|
66
|
+
|
|
67
|
+
5. The bound seat gets a wake notice on the existing notify queue
|
|
68
|
+
(`etiquette notify poll --seat impl-seat`). Promotion of the draft into
|
|
69
|
+
a real task card remains a separate, gated act by an authorized seat.
|
|
70
|
+
|
|
71
|
+
## Refusals (machine-checked)
|
|
72
|
+
|
|
73
|
+
- Channel not in `bindings.yaml` -> `unknown channel`.
|
|
74
|
+
- Requesting user (first speaker, or `--user`) not in the roster ->
|
|
75
|
+
`unknown requesting user` plus an enrollment hint.
|
|
76
|
+
- Execution content in the window (script-bearing directives, fenced
|
|
77
|
+
shell blocks) -> `execution content rejected`. The final card is also
|
|
78
|
+
re-validated against the bundle schema, which rejects script-bearing
|
|
79
|
+
fields wherever they nest.
|
|
80
|
+
|
|
81
|
+
## Security contract: executor inertness
|
|
82
|
+
|
|
83
|
+
The pickup/return executor treats the envelope as data. The only executable
|
|
84
|
+
surfaces are `validation` (sanctioned gate commands) and executor-held
|
|
85
|
+
`preflight_refs`. Every other field — `execution_strategy`, `rig_conductor`,
|
|
86
|
+
`topology_constraints`, `expected_return`, and any nested script-bearing key —
|
|
87
|
+
is inert: read, projected, printed, never executed. The executor spawns only
|
|
88
|
+
hard-coded programs; no shell interprets a bundle string. Pinned by
|
|
89
|
+
`contracts/tag-route-inertness.test.ts` (behavioral trap + static pin).
|
|
90
|
+
|
|
91
|
+
## Out of scope in v0
|
|
92
|
+
|
|
93
|
+
The always-on chat listener is a hosted-plane concern and ships
|
|
94
|
+
separately. It will call this same compile path; nothing in v0 assumes it
|
|
95
|
+
exists. A pasted transcript keeps the whole flow local and testable.
|