@etiquekit/etq 0.0.1 → 1.0.4
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 +28 -0
- package/QuickStart.md +86 -0
- package/README.md +77 -9
- package/bin/etiquette +1150 -0
- package/bin/etiquette-core +313 -0
- package/docs/ARCHITECTURE.md +100 -0
- package/docs/CODEX_CLIENT_COMPATIBILITY.md +83 -0
- package/docs/CONCEPTS.md +128 -0
- package/docs/CONCEPT_STATUS.md +67 -0
- package/docs/CORE_PROFILE.md +70 -0
- package/docs/LANE_PROVISIONING.md +157 -0
- package/docs/README.md +29 -0
- package/docs/RELEASE_SURFACE_AUDIT.md +156 -0
- package/docs/SEAT_DISCIPLINE.md +116 -0
- package/docs/SEAT_PROVISIONING.md +100 -0
- package/docs/TEAM_HANDOFF.md +190 -0
- package/docs/WORKTREE_QOL.md +92 -0
- package/docs/contracts/ledger-entry/README.md +83 -0
- package/docs/contracts/ledger-entry/ledger-entry.v0.1.md +116 -0
- package/docs/contracts/ledger-entry/ledger-entry.v0.2.md +90 -0
- package/docs/contracts/ledger-entry/ledger-entry.v0.md +123 -0
- package/docs/contracts/ledger-entry/ledger-query-cli.v0.1.md +64 -0
- package/package.json +42 -11
- package/scripts/install.sh +144 -0
- package/scripts/uninstall.sh +58 -0
- package/templates/etiquette-vanilla-v0/README.md +69 -0
- package/templates/etiquette-vanilla-v0/bin/stamp-vanilla +33 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/.llm-substrate/HANDOFF.md +22 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/README.md +16 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/_lib/http.sh +121 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/_lib/sanitize.sh +191 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/_lib/state.sh +67 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/access-assurance-check +55 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/compact-local-events +71 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/hooks/post-tool-use +64 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/hooks/session-end +64 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/hooks/session-start +64 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/hooks/stop +64 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/hooks/user-prompt-submit +64 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/local-event +53 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/post-receipt +143 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/post-telemetry +112 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/seat-consume-pass +115 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/seat-doctor +20 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/seat-init +86 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/seat-post-readiness +171 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/session-init +132 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/ACCESS-ASSURANCE.md +39 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/workspace-secure-profile.v0.json +53 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/ledger/LEDGER.md +7 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/playbacks/PLAYBACK_TEMPLATE.md +31 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/receipts/.gitkeep +1 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/tasks/CONTROL-001.yaml +13 -0
- package/templates/etiquette-vanilla-v0/source/etiquette-kernel/README.md +6 -0
- package/templates/etiquette-vanilla-v0/source/etiquette-kernel/bin/kernel-doctor +11 -0
- package/templates/etiquette-vanilla-v0/source/etiquette-kernel/contracts/playback.v0.md +37 -0
- package/templates/etiquette-vanilla-v0/source/etiquette-kernel/contracts/receipt.v0.md +25 -0
- package/templates/etiquette-vanilla-v0/source/etiquette-kernel/contracts/seat-readiness.v0.md +22 -0
- package/templates/etiquette-vanilla-v0/source/etiquette-kernel/contracts/task.v0.md +18 -0
- package/templates/etiquette-vanilla-v0/validate-vanilla.sh +43 -0
- package/templates/github-actions/README.md +30 -0
- package/templates/github-actions/w1-webhook-wake-canary.yml +111 -0
- package/templates/hosted-receiver/README.md +41 -0
- package/templates/hosted-receiver/w1-github-webhook-receiver.mjs +129 -0
- package/templates/seat-packs-v0/README.md +72 -0
- package/templates/seat-packs-v0/bin/provision-seat +70 -0
- package/templates/seat-packs-v0/source/claude-code-seat/.llm-substrate/HANDOFF.md +24 -0
- package/templates/seat-packs-v0/source/claude-code-seat/README.md +19 -0
- package/templates/seat-packs-v0/source/claude-code-seat/bin/seat-doctor +8 -0
- package/templates/seat-packs-v0/source/codex-seat/.llm-substrate/HANDOFF.md +25 -0
- package/templates/seat-packs-v0/source/codex-seat/README.md +22 -0
- package/templates/seat-packs-v0/source/codex-seat/bin/seat-doctor +8 -0
- package/templates/seat-packs-v0/source/gemini-seat/.llm-substrate/HANDOFF.md +23 -0
- package/templates/seat-packs-v0/source/gemini-seat/README.md +19 -0
- package/templates/seat-packs-v0/source/gemini-seat/bin/seat-doctor +8 -0
- package/templates/seat-packs-v0/source/ollama-seat/.llm-substrate/HANDOFF.md +24 -0
- package/templates/seat-packs-v0/source/ollama-seat/README.md +19 -0
- package/templates/seat-packs-v0/source/ollama-seat/bin/seat-doctor +8 -0
- package/templates/seat-packs-v0/source/openrouter-seat/.llm-substrate/HANDOFF.md +24 -0
- package/templates/seat-packs-v0/source/openrouter-seat/README.md +19 -0
- package/templates/seat-packs-v0/source/openrouter-seat/bin/seat-doctor +8 -0
- package/templates/seat-packs-v0/validate-seat-packs.sh +27 -0
- package/bin/etq +0 -4
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Ledger Entry Contracts
|
|
2
|
+
|
|
3
|
+
This contract keeps the ledger-query-mode work narrow. It hardens the spine first:
|
|
4
|
+
typed ledger entries that later reflex queries can read without guessing.
|
|
5
|
+
|
|
6
|
+
It does not ship a ledger query engine, sabbatical dossier engine, capsule
|
|
7
|
+
promotion loop, or remote ledger authority.
|
|
8
|
+
|
|
9
|
+
## Shape
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
raw local ledger entry
|
|
13
|
+
-> typed spine-eligible metadata
|
|
14
|
+
-> optional compact projection
|
|
15
|
+
-> later sabbatical capsule only after operator promotion
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Core Rule
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
Reflex routes the present.
|
|
22
|
+
Sabbatical understands the arc.
|
|
23
|
+
Capsules compress the arc back into reflex context.
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The brain may recommend. The spine may route. Grants authorize. Execution
|
|
27
|
+
mutates. Receipts prove. Audit accounts.
|
|
28
|
+
|
|
29
|
+
## Contracts
|
|
30
|
+
|
|
31
|
+
- [`ledger-entry.v0.md`](./ledger-entry.v0.md)
|
|
32
|
+
- [`ledger-entry.v0.1.md`](./ledger-entry.v0.1.md)
|
|
33
|
+
- [`ledger-query-cli.v0.1.md`](./ledger-query-cli.v0.1.md)
|
|
34
|
+
|
|
35
|
+
## V0.1 Retrieval Amendment
|
|
36
|
+
|
|
37
|
+
This contract keeps the amendment narrow:
|
|
38
|
+
|
|
39
|
+
- `topic_hints[]` gives compact, advisory retrieval hints.
|
|
40
|
+
- `status_effect` gives compact, advisory status-effect classification.
|
|
41
|
+
- Missing fields default to `topic_hints: []` and `status_effect: none`.
|
|
42
|
+
- The generated SQLite/FTS5 index is local, regenerable, and authority-false.
|
|
43
|
+
- The optional verbatim store is explicit-opt-in and local-private.
|
|
44
|
+
|
|
45
|
+
The amendment did not promote a query CLI by itself. The compact-first CLI
|
|
46
|
+
became eligible only after three manual topic snapshots showed stable
|
|
47
|
+
structure and repeated operator friction.
|
|
48
|
+
|
|
49
|
+
## V0.1 Query CLI
|
|
50
|
+
|
|
51
|
+
`etiquette ledger index/search/show` is the first promoted reader over the
|
|
52
|
+
generated cache. It stays compact-first:
|
|
53
|
+
|
|
54
|
+
- `search` returns ids, types, topic hints, status effect, refs, and
|
|
55
|
+
authority-false flags.
|
|
56
|
+
- `show` fetches one exact ledger entry by entry id or durable ref.
|
|
57
|
+
- search/show refuse a missing or stale cache.
|
|
58
|
+
- the CLI does not synthesize, score, rank, export, grant, close, or execute.
|
|
59
|
+
|
|
60
|
+
## Reserved Surfaces
|
|
61
|
+
|
|
62
|
+
These names are reserved vocabulary, not V0 machinery:
|
|
63
|
+
|
|
64
|
+
- `sqlite-vec-ledger-search` — reserved with vector, Chroma, and Postgres
|
|
65
|
+
search adapters; SQLite FTS5 is the only V0.1 retrieval accelerator.
|
|
66
|
+
- `ledger-topic-dossier.v0` — unlock only when an operator asks for a durable
|
|
67
|
+
long-horizon dossier over a real topic.
|
|
68
|
+
- `sabbatical-ledger-query` — reserved as the deliberate brain posture; it
|
|
69
|
+
cannot write the reflex spine directly.
|
|
70
|
+
- `capsule-to-spine-feedback` — unlock only when reviewed capsules have a human
|
|
71
|
+
promotion surface.
|
|
72
|
+
|
|
73
|
+
Deferred surfaces must name an operational consumer before implementation.
|
|
74
|
+
|
|
75
|
+
## Boundary
|
|
76
|
+
|
|
77
|
+
- The brain cannot write the spine directly. It may produce a capsule or
|
|
78
|
+
dossier that an operator later promotes.
|
|
79
|
+
- `spine_eligible: true` is explicit; reflex indexes do not infer eligibility
|
|
80
|
+
from entry type.
|
|
81
|
+
- Existing ledger lines remain readable as `pre_v0: true` legacy entries.
|
|
82
|
+
- Ledger entries do not authorize work unless a valid grant path says so.
|
|
83
|
+
- Remote projection remains metadata-only and cannot replace the local ledger.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# ledger-entry.v0.1
|
|
2
|
+
|
|
3
|
+
`ledger-entry.v0.1` is a narrow retrieval amendment over `ledger-entry.v0`.
|
|
4
|
+
It adds advisory topic and status metadata for local retrieval only. It does
|
|
5
|
+
not authorize work, attach grants, close tasks, or replace receipts.
|
|
6
|
+
|
|
7
|
+
## Compatibility
|
|
8
|
+
|
|
9
|
+
Existing `ledger-entry.v0` rows remain valid. Consumers must treat missing
|
|
10
|
+
fields as:
|
|
11
|
+
|
|
12
|
+
```yaml
|
|
13
|
+
topic_hints: []
|
|
14
|
+
status_effect: none
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Writers may populate these fields only from explicit operator input, explicit
|
|
18
|
+
agent input, or known command context. They must not infer topics or status
|
|
19
|
+
effects from narrative prose.
|
|
20
|
+
|
|
21
|
+
## Added Fields
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
topic_hints:
|
|
25
|
+
type: string[]
|
|
26
|
+
default: []
|
|
27
|
+
format: kebab-case
|
|
28
|
+
max_items: 8
|
|
29
|
+
authority: advisory_hint_only
|
|
30
|
+
|
|
31
|
+
status_effect:
|
|
32
|
+
type: enum
|
|
33
|
+
default: none
|
|
34
|
+
values:
|
|
35
|
+
- none
|
|
36
|
+
- observed
|
|
37
|
+
- changed
|
|
38
|
+
- gap_found
|
|
39
|
+
- reserved
|
|
40
|
+
- closed
|
|
41
|
+
- proved
|
|
42
|
+
authority: advisory_classification_only
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Compact Ledger Line
|
|
46
|
+
|
|
47
|
+
`LEDGER.md` may include the added fields as compact key-value tokens:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
- 2026-05-20T09:30:00.000Z schema=ledger-entry.v0.1 entry_id=ledger-entry:topic-snapshot-example entry_type=review spine_eligible=true authority_class=advisory grants_execution=false export_class=workspace_shared refs=bus:events://1870,artifacts:docs/work/topic-snapshots/example.md topic_hints=ledger-retrieval,local-remote-sync status_effect=gap_found authority=advisory-only
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Omitted `topic_hints` means no topic hints. Omitted `status_effect` means
|
|
54
|
+
`none`.
|
|
55
|
+
|
|
56
|
+
## Local Retrieval Index
|
|
57
|
+
|
|
58
|
+
V0.1 permits a generated local SQLite/FTS5 cache at:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
.etiquette/state/ledger/index.db
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The index is derived and uncommitted. It is not canonical. Search results from
|
|
65
|
+
the index must carry literal authority-false flags:
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
is_canonical: false
|
|
69
|
+
regenerable: true
|
|
70
|
+
can_authorize: false
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Index regeneration policy:
|
|
74
|
+
|
|
75
|
+
- rebuild from canonical docs and ledger files;
|
|
76
|
+
- never write through from the index into `LEDGER.md`;
|
|
77
|
+
- delete and recreate the generated cache on rebuild;
|
|
78
|
+
- either rebuild explicitly or run a stale-check before using search results.
|
|
79
|
+
|
|
80
|
+
V0.1 reserves vector search, `sqlite-vec`, Chroma, and Postgres adapters for a
|
|
81
|
+
future lane. SQLite FTS5 is the only retrieval accelerator in this version.
|
|
82
|
+
|
|
83
|
+
## Local-Private Verbatim Store
|
|
84
|
+
|
|
85
|
+
V0.1 also reserves an opt-in local-only verbatim store at:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
.etiquette/state/ledger/private-verbatim.db
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Rules:
|
|
92
|
+
|
|
93
|
+
- disabled by default;
|
|
94
|
+
- requires explicit operator opt-in;
|
|
95
|
+
- never committed;
|
|
96
|
+
- never exported to hosted or shared projection;
|
|
97
|
+
- no automatic capture of session chat, bus packets, prompts, or tool output;
|
|
98
|
+
- any stored chunks must carry `export_class: local_private`.
|
|
99
|
+
|
|
100
|
+
Shared exports may include summaries and durable refs only.
|
|
101
|
+
|
|
102
|
+
## Authority Boundary
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
authority_boundary:
|
|
106
|
+
can_authorize_work: false
|
|
107
|
+
can_execute_work: false
|
|
108
|
+
can_attach_grant: false
|
|
109
|
+
can_close_task: false
|
|
110
|
+
can_replace_receipt: false
|
|
111
|
+
can_replace_audit_log: false
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The ledger remains accountable truth. The index accelerates retrieval.
|
|
115
|
+
Verbatim memory stays local-private. Snapshots and capsules interpret with
|
|
116
|
+
citations. Receipts prove.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# ledger-entry.v0.2
|
|
2
|
+
|
|
3
|
+
`ledger-entry.v0.2` is a narrow bitemporal amendment over `ledger-entry.v0.1`.
|
|
4
|
+
It separates when a covered piece of work happened from when the ledger
|
|
5
|
+
learned about it, and it adds one entry type for honest late recording. It
|
|
6
|
+
does not authorize work, attach grants, close tasks, or replace receipts.
|
|
7
|
+
|
|
8
|
+
## The rule this encodes
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
The leading timestamp (created_at) is the RECORDING time. It is never
|
|
12
|
+
backdated. If work was done off the spine, it is reconciled with a late
|
|
13
|
+
entry recorded at its true time, pointing at contemporaneous evidence.
|
|
14
|
+
Synthesizing entries with past recording times is corruption, not repair:
|
|
15
|
+
one plausible fake timestamp devalues every real one.
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This mirrors standing practice elsewhere: accounting adjusting entries,
|
|
19
|
+
clinical late entries, court orders entered nunc pro tunc, and compensating
|
|
20
|
+
events in event-sourced systems. The formal model is bitemporal data:
|
|
21
|
+
`valid_time` (when it happened) vs transaction time (`created_at`, when it
|
|
22
|
+
was recorded).
|
|
23
|
+
|
|
24
|
+
## Compatibility
|
|
25
|
+
|
|
26
|
+
Existing `ledger-entry.v0` and `ledger-entry.v0.1` rows remain valid.
|
|
27
|
+
Consumers must treat missing fields as:
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
valid_time: (absent -> the covered work happened at recording time)
|
|
31
|
+
valid_time_end: (absent -> point-in-time, not a span)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Added Fields
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
valid_time:
|
|
38
|
+
type: iso8601 timestamp
|
|
39
|
+
optional: true
|
|
40
|
+
meaning: when the covered work actually happened (span start if
|
|
41
|
+
valid_time_end is present)
|
|
42
|
+
constraint: must not be after created_at
|
|
43
|
+
|
|
44
|
+
valid_time_end:
|
|
45
|
+
type: iso8601 timestamp
|
|
46
|
+
optional: true
|
|
47
|
+
requires: valid_time
|
|
48
|
+
constraint: valid_time <= valid_time_end <= created_at
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Added Entry Type
|
|
52
|
+
|
|
53
|
+
`entry_type: retroactive_import` — a late reconciliation entry covering work
|
|
54
|
+
that was executed without contemporaneous spine entries. Rules, enforced by
|
|
55
|
+
the validator:
|
|
56
|
+
|
|
57
|
+
- requires schema `ledger-entry.v0.2` (rejected on v0/v0.1);
|
|
58
|
+
- must declare `valid_time` (what period it covers);
|
|
59
|
+
- must carry at least one contemporaneous evidence ref among
|
|
60
|
+
`refs.commits`, `refs.receipts`, or `refs.artifacts` — evidence that
|
|
61
|
+
carries its own independent timestamps (git commits are the canonical
|
|
62
|
+
witness);
|
|
63
|
+
- authority class must be `advisory` or `audit` — a late entry never mints
|
|
64
|
+
grants or execution authority;
|
|
65
|
+
- one reconciliation entry covering a span with an index artifact is
|
|
66
|
+
preferred over many synthetic per-event entries.
|
|
67
|
+
|
|
68
|
+
## Compact Ledger Line
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
- 2026-07-02T11:00:00.000Z schema=ledger-entry.v0.2 entry_id=ledger-entry:recon-example entry_type=retroactive_import spine_eligible=true authority_class=audit grants_execution=false export_class=workspace_shared refs=commits:3919c0fa,artifacts:docs/work/huddle/recon-index.md valid_time=2026-07-02T00:40:00.000Z valid_time_end=2026-07-02T10:45:00.000Z
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Omitted `valid_time` means the entry covers its own recording moment.
|
|
75
|
+
|
|
76
|
+
## Consumers
|
|
77
|
+
|
|
78
|
+
- The local ledger index (`ledger-query-cli.v0.1`) admits v0.2 lines; the
|
|
79
|
+
bitemporal tokens flow through the parsed `extra` map (no first-class
|
|
80
|
+
index columns in this amendment).
|
|
81
|
+
- Marination/sabbatical record passes are the intended writer of
|
|
82
|
+
`retroactive_import` entries: they may reorganize projections and append
|
|
83
|
+
reconciliations; they must never rewrite or backdate sources (see
|
|
84
|
+
`internal/docs/operations/MARINATION_CHARTER.md`).
|
|
85
|
+
|
|
86
|
+
## Boundary
|
|
87
|
+
|
|
88
|
+
Advisory metadata only. No scoring engine, no automatic drift detection, no
|
|
89
|
+
hosted sync changes, no authority semantics beyond the explicit restriction
|
|
90
|
+
that retroactive entries cannot carry grant authority.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# ledger-entry.v0
|
|
2
|
+
|
|
3
|
+
`ledger-entry.v0` is the typed local ledger record used by the reflex spine.
|
|
4
|
+
It makes compact ledger lines structurally queryable without promoting the
|
|
5
|
+
ledger into an authority source.
|
|
6
|
+
|
|
7
|
+
## Required Shape
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
schema: ledger-entry.v0
|
|
11
|
+
entry_id: ledger-entry:dispatch-record-example
|
|
12
|
+
created_at: 2026-05-19T09:30:00.000Z
|
|
13
|
+
entry_type: decision
|
|
14
|
+
spine_eligible: true
|
|
15
|
+
authority:
|
|
16
|
+
class: advisory
|
|
17
|
+
grants_execution: false
|
|
18
|
+
refs:
|
|
19
|
+
lanes: []
|
|
20
|
+
commits: []
|
|
21
|
+
prs: []
|
|
22
|
+
bus: []
|
|
23
|
+
artifacts: []
|
|
24
|
+
receipts:
|
|
25
|
+
- docs/work/receipts/example.yaml
|
|
26
|
+
export_class: workspace_shared
|
|
27
|
+
summary: compact operator-readable statement
|
|
28
|
+
legacy:
|
|
29
|
+
pre_v0: false
|
|
30
|
+
low_authority: false
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Field Rules
|
|
34
|
+
|
|
35
|
+
`entry_type` must be one of:
|
|
36
|
+
|
|
37
|
+
- `decision`
|
|
38
|
+
- `review`
|
|
39
|
+
- `receipt`
|
|
40
|
+
- `audit`
|
|
41
|
+
- `event`
|
|
42
|
+
- `heartbeat`
|
|
43
|
+
- `capability`
|
|
44
|
+
- `incident`
|
|
45
|
+
- `doctrine`
|
|
46
|
+
- `task`
|
|
47
|
+
- `closeout`
|
|
48
|
+
|
|
49
|
+
`authority.class` must be one of:
|
|
50
|
+
|
|
51
|
+
- `advisory`
|
|
52
|
+
- `grant`
|
|
53
|
+
- `receipt`
|
|
54
|
+
- `audit`
|
|
55
|
+
- `status`
|
|
56
|
+
|
|
57
|
+
`authority.grants_execution` defaults to `false`. Only entries with
|
|
58
|
+
`authority.class: grant` may set it to `true`, and only when the entry carries
|
|
59
|
+
the durable grant reference required by the local workflow.
|
|
60
|
+
|
|
61
|
+
`spine_eligible` is explicit. A reflex index must not infer it from
|
|
62
|
+
`entry_type`. Entries that are useful for current-state routing should set it to
|
|
63
|
+
`true`; archival, noisy, or unreviewed entries should set it to `false`.
|
|
64
|
+
|
|
65
|
+
`export_class` must be one of:
|
|
66
|
+
|
|
67
|
+
- `local_private`
|
|
68
|
+
- `workspace_shared`
|
|
69
|
+
- `org_projected`
|
|
70
|
+
- `public_safe`
|
|
71
|
+
|
|
72
|
+
For entries where `authority.class != advisory`, at least one durable `refs`
|
|
73
|
+
item is required. If evidence is unavailable, the entry must set
|
|
74
|
+
`legacy.low_authority: true` and must not be exported beyond local scope.
|
|
75
|
+
|
|
76
|
+
## Compact Ledger Line
|
|
77
|
+
|
|
78
|
+
`LEDGER.md` may store the same object as one compact key-value line:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
- 2026-05-19T09:30:00.000Z schema=ledger-entry.v0 entry_id=ledger-entry:dispatch-record-example entry_type=decision spine_eligible=true authority_class=advisory grants_execution=false export_class=workspace_shared refs=receipts:docs/work/receipts/example.yaml authority=advisory-only
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Consumers must tolerate earlier compact lines without `schema=ledger-entry.v0`
|
|
85
|
+
by treating them as:
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
schema: ledger-entry.v0
|
|
89
|
+
legacy:
|
|
90
|
+
pre_v0: true
|
|
91
|
+
low_authority: true
|
|
92
|
+
spine_eligible: false
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Spine And Brain Boundary
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
Reflex routes the present.
|
|
99
|
+
Sabbatical understands the arc.
|
|
100
|
+
Capsules compress the arc back into reflex context.
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The reflex spine reads typed ledger entries. The sabbatical brain may produce a
|
|
104
|
+
capsule or dossier, but it cannot write back into the spine directly. Promotion
|
|
105
|
+
from capsule to spine requires an explicit operator gate.
|
|
106
|
+
|
|
107
|
+
## Authority Boundary
|
|
108
|
+
|
|
109
|
+
Ledger entries may record a grant reference, receipt, review, or status. They do
|
|
110
|
+
not independently authorize, execute, attach grants, close work, replace
|
|
111
|
+
receipts, or replace audit logs.
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
authority_boundary:
|
|
115
|
+
can_authorize_work: false
|
|
116
|
+
can_execute_work: false
|
|
117
|
+
can_attach_grant: false
|
|
118
|
+
can_replace_receipt: false
|
|
119
|
+
can_replace_audit_log: false
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The ledger is a durable operational record. It is not a scheduler, worker queue,
|
|
123
|
+
approval engine, or hosted source of truth.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# ledger-query-cli.v0.1
|
|
2
|
+
|
|
3
|
+
`ledger-query-cli.v0.1` is the compact-first local reader over the generated
|
|
4
|
+
ledger retrieval index. It does not replace `LEDGER.md`, receipts, grants, or
|
|
5
|
+
audit logs.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
etiquette ledger index [--project <path>] [--db <path>] [--json]
|
|
11
|
+
etiquette ledger search <query> [--project <path>] [--db <path>] [--limit <n>] [--json]
|
|
12
|
+
etiquette ledger search --topic <slug> [--project <path>] [--db <path>] [--limit <n>] [--json]
|
|
13
|
+
etiquette ledger show <entry-or-ref-id> [--project <path>] [--db <path>]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Behavior
|
|
17
|
+
|
|
18
|
+
- `index` rebuilds the generated SQLite/FTS5 cache from canonical local docs.
|
|
19
|
+
- `search` returns compact metadata only.
|
|
20
|
+
- `show` exact-fetches one ledger entry by entry id or durable ref.
|
|
21
|
+
- `search` and `show` fail if the cache is missing or stale.
|
|
22
|
+
- `--limit` is capped at 50.
|
|
23
|
+
|
|
24
|
+
## Compact Search Result
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
entry_id: ledger-entry:topic-snapshot:example
|
|
28
|
+
title: ledger-entry:topic-snapshot:example
|
|
29
|
+
type: review
|
|
30
|
+
topic_hints:
|
|
31
|
+
- ledger-retrieval
|
|
32
|
+
status_effect: proved
|
|
33
|
+
refs:
|
|
34
|
+
- bus:events://1890
|
|
35
|
+
confidence: metadata
|
|
36
|
+
is_canonical: false
|
|
37
|
+
regenerable: true
|
|
38
|
+
can_authorize: false
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Exact Fetch Result
|
|
42
|
+
|
|
43
|
+
`show` returns the compact fields plus the canonical source pointer:
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
source_path: docs/work/ledger/LEDGER.md
|
|
47
|
+
line_no: 3
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
It does not bulk dump historical documents.
|
|
51
|
+
|
|
52
|
+
## Authority Boundary
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
authority_boundary:
|
|
56
|
+
can_authorize_work: false
|
|
57
|
+
can_execute_work: false
|
|
58
|
+
can_attach_grant: false
|
|
59
|
+
can_close_task: false
|
|
60
|
+
can_replace_receipt: false
|
|
61
|
+
can_replace_audit_log: false
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The CLI accelerates retrieval. It does not make decisions.
|
package/package.json
CHANGED
|
@@ -1,17 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etiquekit/etq",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "Governance and evidence CLI for AI-assisted engineering seats.",
|
|
5
|
+
"private": false,
|
|
6
|
+
"type": "module",
|
|
6
7
|
"bin": {
|
|
7
|
-
"etq": "bin/
|
|
8
|
+
"etq": "bin/etiquette",
|
|
9
|
+
"etiquette": "bin/etiquette",
|
|
10
|
+
"etiquette-core": "bin/etiquette-core"
|
|
11
|
+
},
|
|
12
|
+
"engines": {
|
|
13
|
+
"bun": ">=1.3.0",
|
|
14
|
+
"git": ">=2.40.0"
|
|
8
15
|
},
|
|
9
16
|
"files": [
|
|
10
|
-
"
|
|
11
|
-
"
|
|
17
|
+
"AGENTS.md",
|
|
18
|
+
"QuickStart.md",
|
|
19
|
+
"README.md",
|
|
20
|
+
"bin/",
|
|
21
|
+
"docs/",
|
|
22
|
+
"scripts/install.sh",
|
|
23
|
+
"scripts/uninstall.sh",
|
|
24
|
+
"templates/",
|
|
25
|
+
"!docs/work/"
|
|
12
26
|
],
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
"scripts": {
|
|
28
|
+
"test": "bun test contracts",
|
|
29
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
30
|
+
"cli": "bun packages/control/src/cli.ts",
|
|
31
|
+
"core:cli": "bun packages/control/src/core-cli.ts",
|
|
32
|
+
"release:scan": "sh scripts/release-scan.sh",
|
|
33
|
+
"release:pack": "sh scripts/release-pack-canary.sh",
|
|
34
|
+
"release:checksum": "sh scripts/release-checksum.sh",
|
|
35
|
+
"release:sign": "sh scripts/release-sign.sh",
|
|
36
|
+
"release:build": "sh scripts/release-build.sh",
|
|
37
|
+
"prepack": "sh scripts/release-build.sh"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/bun": "^1.2.17",
|
|
41
|
+
"typescript": "^5.7.3"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"yaml": "2.8.3",
|
|
45
|
+
"zod": "4.3.6"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://etiquekit.com"
|
|
48
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Install Etiquette from a signed release tarball into a user-local prefix.
|
|
3
|
+
set -eu
|
|
4
|
+
|
|
5
|
+
BASE_URL=${ETIQUETTE_INSTALL_BASE_URL:-https://etiquette.example.com/releases}
|
|
6
|
+
VERSION=${ETIQUETTE_INSTALL_VERSION:-latest}
|
|
7
|
+
INSTALL_ROOT=${ETIQUETTE_INSTALL_ROOT:-"$HOME/.etiquette"}
|
|
8
|
+
PUBLIC_KEY=${ETIQUETTE_RELEASE_PUBLIC_KEY:-}
|
|
9
|
+
PUBLIC_KEY_URL=${ETIQUETTE_RELEASE_PUBLIC_KEY_URL:-}
|
|
10
|
+
PUBLIC_KEY_SHA256=${ETIQUETTE_RELEASE_PUBLIC_KEY_SHA256:-}
|
|
11
|
+
MODIFY_PROFILE=0
|
|
12
|
+
|
|
13
|
+
usage() {
|
|
14
|
+
cat <<'USAGE'
|
|
15
|
+
usage: install.sh [--version <version>] [--base-url <url>] [--install-root <path>] [--public-key <path>] [--public-key-url <url>] [--public-key-sha256 <hex>] [--modify-profile]
|
|
16
|
+
|
|
17
|
+
Environment:
|
|
18
|
+
ETIQUETTE_INSTALL_BASE_URL release base URL, default https://etiquette.example.com/releases
|
|
19
|
+
ETIQUETTE_INSTALL_VERSION release version or latest
|
|
20
|
+
ETIQUETTE_INSTALL_ROOT install root, default ~/.etiquette
|
|
21
|
+
ETIQUETTE_RELEASE_PUBLIC_KEY RSA public key used to verify SHA256SUMS.sig
|
|
22
|
+
ETIQUETTE_RELEASE_PUBLIC_KEY_URL
|
|
23
|
+
HTTPS or file URL for the RSA public key
|
|
24
|
+
ETIQUETTE_RELEASE_PUBLIC_KEY_SHA256
|
|
25
|
+
expected SHA-256 hex for a downloaded public key
|
|
26
|
+
USAGE
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
while [ "$#" -gt 0 ]; do
|
|
30
|
+
case "$1" in
|
|
31
|
+
--version) VERSION=${2:?missing version}; shift 2 ;;
|
|
32
|
+
--base-url) BASE_URL=${2:?missing base URL}; shift 2 ;;
|
|
33
|
+
--install-root) INSTALL_ROOT=${2:?missing install root}; shift 2 ;;
|
|
34
|
+
--public-key) PUBLIC_KEY=${2:?missing public key}; shift 2 ;;
|
|
35
|
+
--public-key-url) PUBLIC_KEY_URL=${2:?missing public key URL}; shift 2 ;;
|
|
36
|
+
--public-key-sha256) PUBLIC_KEY_SHA256=${2:?missing public key SHA-256}; shift 2 ;;
|
|
37
|
+
--modify-profile) MODIFY_PROFILE=1; shift ;;
|
|
38
|
+
-h|--help) usage; exit 0 ;;
|
|
39
|
+
*) echo "install.sh: unknown argument: $1" >&2; usage >&2; exit 64 ;;
|
|
40
|
+
esac
|
|
41
|
+
done
|
|
42
|
+
|
|
43
|
+
need() {
|
|
44
|
+
if ! command -v "$1" >/dev/null 2>&1; then
|
|
45
|
+
echo "install.sh: missing required command: $1" >&2
|
|
46
|
+
exit 127
|
|
47
|
+
fi
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
need curl
|
|
51
|
+
need bun
|
|
52
|
+
need openssl
|
|
53
|
+
need shasum
|
|
54
|
+
need tar
|
|
55
|
+
|
|
56
|
+
TMPDIR_ROOT=${TMPDIR:-/tmp}
|
|
57
|
+
TMP=$(mktemp -d "$TMPDIR_ROOT/etiquette-install.XXXXXX")
|
|
58
|
+
trap 'rm -rf "$TMP"' EXIT INT TERM
|
|
59
|
+
|
|
60
|
+
if [ -n "$PUBLIC_KEY" ] && [ -n "$PUBLIC_KEY_URL" ]; then
|
|
61
|
+
echo "install.sh: use either --public-key or --public-key-url, not both" >&2
|
|
62
|
+
exit 64
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
if [ -n "$PUBLIC_KEY" ]; then
|
|
66
|
+
if [ ! -f "$PUBLIC_KEY" ]; then
|
|
67
|
+
echo "install.sh: public key path does not exist: $PUBLIC_KEY" >&2
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
elif [ -n "$PUBLIC_KEY_URL" ]; then
|
|
71
|
+
if [ -z "$PUBLIC_KEY_SHA256" ]; then
|
|
72
|
+
echo "install.sh: --public-key-url requires --public-key-sha256" >&2
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
PUBLIC_KEY="$TMP/etiquette-release.pub"
|
|
76
|
+
curl -fsSL "$PUBLIC_KEY_URL" -o "$PUBLIC_KEY"
|
|
77
|
+
ACTUAL_KEY_SHA=$(shasum -a 256 "$PUBLIC_KEY" | awk '{ print $1 }')
|
|
78
|
+
if [ "$PUBLIC_KEY_SHA256" != "$ACTUAL_KEY_SHA" ]; then
|
|
79
|
+
echo "install.sh: public key SHA-256 mismatch" >&2
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
else
|
|
83
|
+
echo "install.sh: provide --public-key, or --public-key-url with --public-key-sha256" >&2
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
RELEASE_URL="${BASE_URL%/}/$VERSION"
|
|
88
|
+
cd "$TMP"
|
|
89
|
+
curl -fsSLO "$RELEASE_URL/SHA256SUMS"
|
|
90
|
+
curl -fsSLO "$RELEASE_URL/SHA256SUMS.sig"
|
|
91
|
+
TARBALL=$(awk '/etiquette-[0-9][^ ]*\.tgz$/ { print $2; exit }' SHA256SUMS)
|
|
92
|
+
if [ -z "$TARBALL" ]; then
|
|
93
|
+
echo "install.sh: SHA256SUMS does not name an etiquette release tarball" >&2
|
|
94
|
+
exit 1
|
|
95
|
+
fi
|
|
96
|
+
curl -fsSLO "$RELEASE_URL/$TARBALL"
|
|
97
|
+
|
|
98
|
+
EXPECTED=$(awk -v file="$TARBALL" '$2 == file { print $1; exit }' SHA256SUMS)
|
|
99
|
+
ACTUAL=$(shasum -a 256 "$TARBALL" | awk '{ print $1 }')
|
|
100
|
+
if [ "$EXPECTED" != "$ACTUAL" ]; then
|
|
101
|
+
echo "install.sh: checksum mismatch for $TARBALL" >&2
|
|
102
|
+
exit 1
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
openssl dgst -sha256 -verify "$PUBLIC_KEY" -signature SHA256SUMS.sig SHA256SUMS >/dev/null
|
|
106
|
+
|
|
107
|
+
VERSION_DIR=$(basename "$TARBALL" .tgz)
|
|
108
|
+
LIB_DIR="$INSTALL_ROOT/lib/$VERSION_DIR"
|
|
109
|
+
BIN_DIR="$INSTALL_ROOT/bin"
|
|
110
|
+
mkdir -p "$LIB_DIR" "$BIN_DIR"
|
|
111
|
+
tar -xzf "$TARBALL"
|
|
112
|
+
rm -rf "$LIB_DIR"
|
|
113
|
+
mkdir -p "$LIB_DIR"
|
|
114
|
+
cp -R package/. "$LIB_DIR/"
|
|
115
|
+
if [ -f "$LIB_DIR/package.json" ]; then
|
|
116
|
+
(
|
|
117
|
+
cd "$LIB_DIR"
|
|
118
|
+
bun install --production >/dev/null
|
|
119
|
+
)
|
|
120
|
+
fi
|
|
121
|
+
ln -sfn "$LIB_DIR/bin/etiquette" "$BIN_DIR/etiquette"
|
|
122
|
+
ln -sfn "$LIB_DIR/bin/etiquette-core" "$BIN_DIR/etiquette-core"
|
|
123
|
+
|
|
124
|
+
if [ "$MODIFY_PROFILE" -eq 1 ]; then
|
|
125
|
+
PROFILE=${SHELL##*/}
|
|
126
|
+
case "$PROFILE" in
|
|
127
|
+
zsh) PROFILE_FILE="$HOME/.zshrc" ;;
|
|
128
|
+
bash) PROFILE_FILE="$HOME/.bashrc" ;;
|
|
129
|
+
*) PROFILE_FILE="$HOME/.profile" ;;
|
|
130
|
+
esac
|
|
131
|
+
LINE="export PATH=\"$BIN_DIR:\$PATH\""
|
|
132
|
+
touch "$PROFILE_FILE"
|
|
133
|
+
if ! grep -Fqx "$LINE" "$PROFILE_FILE"; then
|
|
134
|
+
printf '\n# Etiquette CLI\n%s\n' "$LINE" >> "$PROFILE_FILE"
|
|
135
|
+
fi
|
|
136
|
+
echo "install.sh: updated $PROFILE_FILE"
|
|
137
|
+
else
|
|
138
|
+
echo "install.sh: add $BIN_DIR to PATH, or rerun with --modify-profile"
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
echo "install.sh: installed etiquette into $INSTALL_ROOT"
|
|
142
|
+
echo "install.sh: docs: https://etiquette.example.com"
|
|
143
|
+
echo "install.sh: run: $BIN_DIR/etiquette doctor --project <workspace>"
|
|
144
|
+
echo "install.sh: agent skill integrations are explicit; no Claude/Codex/Gemini config was modified"
|