@etiquekit/etq 1.0.13 → 1.0.15
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 +26 -19
- package/LICENSE +3 -2
- package/NOTICE +4 -6
- package/QuickStart.md +46 -35
- package/README.md +57 -55
- package/bin/etiquette +5 -1
- package/bin/etiquette-core +5 -1
- package/docs/ARCHITECTURE.md +17 -20
- package/docs/CONCEPTS.md +5 -5
- package/docs/CORE_PROFILE.md +15 -7
- package/docs/LANE_PROVISIONING.md +2 -7
- package/docs/README.md +14 -13
- package/docs/RELEASE_SURFACE_AUDIT.md +6 -7
- package/docs/SEAT_DISCIPLINE.md +91 -55
- package/docs/SEAT_PROVISIONING.md +19 -16
- package/docs/TEAM_HANDOFF.md +21 -21
- package/docs/WORKTREE_QOL.md +0 -7
- package/docs/contracts/ledger-entry/README.md +11 -11
- package/docs/contracts/ledger-entry/ledger-entry.v0.2.md +2 -2
- package/docs/contracts/ledger-entry/ledger-entry.v0.md +8 -8
- package/lib/etiquette-core.js +313 -0
- package/lib/etiquette.js +1151 -0
- package/package.json +13 -12
- package/templates/etiquette-vanilla-v0/README.md +3 -2
- package/templates/etiquette-vanilla-v0/source/control-seat/README.md +6 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/access-assurance-check +55 -0
- package/templates/etiquette-vanilla-v0/source/control-seat/bin/seat-doctor +5 -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/validate-vanilla.sh +5 -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 +2 -3
- package/templates/seat-packs-v0/source/claude-code-seat/README.md +3 -3
- package/templates/seat-packs-v0/source/codex-seat/README.md +3 -3
- package/templates/seat-packs-v0/source/gemini-seat/README.md +3 -3
- package/templates/seat-packs-v0/source/ollama-seat/README.md +3 -3
- package/templates/seat-packs-v0/source/openrouter-seat/README.md +3 -3
- package/docs/CONCEPT_STATUS.md +0 -66
- package/packages/control/src/authority/lease.ts +0 -261
- package/packages/control/src/authority/node-delegation.ts +0 -257
- package/packages/control/src/authority/rig-conductor.ts +0 -632
- package/packages/control/src/cli/argv.ts +0 -155
- package/packages/control/src/cli/commands/console.ts +0 -200
- package/packages/control/src/cli/commands/dispatch-core.ts +0 -89
- package/packages/control/src/cli/commands/dispatch.ts +0 -279
- package/packages/control/src/cli/commands/harness.ts +0 -89
- package/packages/control/src/cli/commands/hook.ts +0 -50
- package/packages/control/src/cli/commands/ledger.ts +0 -91
- package/packages/control/src/cli/commands/local-workflow.ts +0 -4686
- package/packages/control/src/cli/commands/memory.ts +0 -445
- package/packages/control/src/cli/commands/release.ts +0 -108
- package/packages/control/src/cli/commands/rubric.ts +0 -103
- package/packages/control/src/cli/commands/seat.ts +0 -179
- package/packages/control/src/cli/commands/session.ts +0 -127
- package/packages/control/src/cli/commands/supervision.ts +0 -246
- package/packages/control/src/cli/commands/sync.ts +0 -119
- package/packages/control/src/cli/commands/workflow.ts +0 -86
- package/packages/control/src/cli/commands/workspace.ts +0 -50
- package/packages/control/src/cli/core-usage.ts +0 -34
- package/packages/control/src/cli/prompt.ts +0 -67
- package/packages/control/src/cli/supervision-deps.ts +0 -44
- package/packages/control/src/cli/usage.ts +0 -241
- package/packages/control/src/cli.ts +0 -207
- package/packages/control/src/core-cli.ts +0 -50
- package/packages/control/src/dispatch/decision.ts +0 -202
- package/packages/control/src/dispatch/projection.ts +0 -293
- package/packages/control/src/dispatch/record.ts +0 -153
- package/packages/control/src/engagement/project.ts +0 -170
- package/packages/control/src/fs.ts +0 -19
- package/packages/control/src/harness/pruning.ts +0 -406
- package/packages/control/src/hooks/dispatcher.ts +0 -117
- package/packages/control/src/hooks/outbox.ts +0 -86
- package/packages/control/src/hooks/sanitize.ts +0 -6
- package/packages/control/src/hooks/types.ts +0 -34
- package/packages/control/src/index.ts +0 -384
- package/packages/control/src/ledger/entry.ts +0 -303
- package/packages/control/src/ledger/indexer.ts +0 -542
- package/packages/control/src/memory/context.ts +0 -149
- package/packages/control/src/memory/drain-import.ts +0 -207
- package/packages/control/src/memory/indexer.ts +0 -284
- package/packages/control/src/memory/query.ts +0 -75
- package/packages/control/src/memory/sanitize.ts +0 -50
- package/packages/control/src/memory/sharded-drain-import.ts +0 -212
- package/packages/control/src/memory/status.ts +0 -211
- package/packages/control/src/memory/store-lifecycle.ts +0 -509
- package/packages/control/src/memory/store.ts +0 -284
- package/packages/control/src/memory/types.ts +0 -146
- package/packages/control/src/parity/surfaces.ts +0 -748
- package/packages/control/src/project.ts +0 -141
- package/packages/control/src/projection/local-ledger-view.ts +0 -373
- package/packages/control/src/projection/return-enforcement.ts +0 -48
- package/packages/control/src/projection/timeline-preview.ts +0 -539
- package/packages/control/src/projection/timeline.ts +0 -708
- package/packages/control/src/release/readiness.ts +0 -831
- package/packages/control/src/rubric/loader.ts +0 -326
- package/packages/control/src/rubric/promotion.ts +0 -54
- package/packages/control/src/rubric/runner.ts +0 -159
- package/packages/control/src/rubric/types.ts +0 -158
- package/packages/control/src/seat/owner-card.ts +0 -388
- package/packages/control/src/seat/readiness.ts +0 -834
- package/packages/control/src/session/runbook.ts +0 -431
- package/packages/control/src/shared/sanitize.ts +0 -49
- package/packages/control/src/supervision/action-classes.ts +0 -192
- package/packages/control/src/supervision/command-apply.ts +0 -378
- package/packages/control/src/supervision/errors.ts +0 -14
- package/packages/control/src/supervision/event-replay.ts +0 -155
- package/packages/control/src/supervision/events.ts +0 -109
- package/packages/control/src/supervision/index.ts +0 -16
- package/packages/control/src/supervision/manifest.ts +0 -127
- package/packages/control/src/supervision/paths.ts +0 -49
- package/packages/control/src/supervision/projection-adapter.ts +0 -274
- package/packages/control/src/supervision/projection.ts +0 -75
- package/packages/control/src/supervision/rebuild.ts +0 -99
- package/packages/control/src/supervision/session-open.ts +0 -131
- package/packages/control/src/supervision/session-read.ts +0 -99
- package/packages/control/src/supervision/sqlite-impl.ts +0 -71
- package/packages/control/src/supervision/sqlite.ts +0 -121
- package/packages/control/src/supervision/store-rows.ts +0 -371
- package/packages/control/src/supervision/turn-close.ts +0 -154
- package/packages/control/src/supervision/turn-open.ts +0 -284
- package/packages/control/src/sync/event-log-merge-driver.ts +0 -263
- package/packages/control/src/sync/join-plan.ts +0 -375
- package/packages/control/src/sync/outbox.ts +0 -492
- package/packages/control/src/workflow/evaluator.ts +0 -140
- package/packages/control/src/workflow/loader.ts +0 -200
- package/packages/control/src/workflow/types.ts +0 -90
- package/packages/control/src/workspace/authority.ts +0 -499
- package/packages/protocol/src/guards.ts +0 -119
- package/packages/protocol/src/huddle-board.ts +0 -198
- package/packages/protocol/src/huddle.ts +0 -295
- package/packages/protocol/src/incident.ts +0 -251
- package/packages/protocol/src/index.ts +0 -8
- package/packages/protocol/src/interfaces.ts +0 -107
- package/packages/protocol/src/packet-profile.ts +0 -195
- package/packages/protocol/src/state.ts +0 -81
- package/packages/protocol/src/types.ts +0 -434
- package/release/lineage.v0.json +0 -14
- package/scripts/release-candidate-verify.sh +0 -175
- package/scripts/release-checksum.sh +0 -25
- package/scripts/release-pack-canary.sh +0 -97
- package/scripts/release-scan.sh +0 -249
- package/scripts/release-sign.sh +0 -34
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etiquekit/etq",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"
|
|
3
|
+
"version": "1.0.15",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"description": "Thin local execution plane for Etiquette Core governance contracts.",
|
|
5
6
|
"private": false,
|
|
6
7
|
"type": "module",
|
|
7
8
|
"bin": {
|
|
@@ -15,16 +16,15 @@
|
|
|
15
16
|
},
|
|
16
17
|
"files": [
|
|
17
18
|
"LICENSE",
|
|
18
|
-
"AGENTS.md",
|
|
19
19
|
"NOTICE",
|
|
20
|
+
"AGENTS.md",
|
|
20
21
|
"QuickStart.md",
|
|
21
22
|
"README.md",
|
|
22
23
|
"bin/",
|
|
24
|
+
"lib/",
|
|
23
25
|
"docs/",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"release/lineage.v0.json",
|
|
27
|
-
"scripts/",
|
|
26
|
+
"scripts/install.sh",
|
|
27
|
+
"scripts/uninstall.sh",
|
|
28
28
|
"templates/",
|
|
29
29
|
"!docs/work/"
|
|
30
30
|
],
|
|
@@ -35,25 +35,26 @@
|
|
|
35
35
|
"core:cli": "bun packages/control/src/core-cli.ts",
|
|
36
36
|
"release:scan": "sh scripts/release-scan.sh",
|
|
37
37
|
"release:pack": "sh scripts/release-pack-canary.sh",
|
|
38
|
-
"release:candidate": "sh scripts/release-candidate-verify.sh",
|
|
39
38
|
"release:checksum": "sh scripts/release-checksum.sh",
|
|
40
|
-
"release:sign": "sh scripts/release-sign.sh"
|
|
39
|
+
"release:sign": "sh scripts/release-sign.sh",
|
|
40
|
+
"release:build": "sh scripts/release-build.sh",
|
|
41
|
+
"prepack": "sh scripts/release-build.sh"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@types/bun": "^1.2.17",
|
|
44
45
|
"typescript": "^5.7.3"
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
48
|
+
"@etiquekit/core": "0.1.0",
|
|
47
49
|
"yaml": "2.8.3",
|
|
48
50
|
"zod": "4.3.6"
|
|
49
51
|
},
|
|
50
|
-
"license": "Apache-2.0",
|
|
51
52
|
"homepage": "https://etiquekit.com",
|
|
52
53
|
"repository": {
|
|
53
54
|
"type": "git",
|
|
54
|
-
"url": "git+https://github.com/leepickdev/etq
|
|
55
|
+
"url": "git+https://github.com/leepickdev/etq.git"
|
|
55
56
|
},
|
|
56
57
|
"bugs": {
|
|
57
|
-
"url": "https://github.com/leepickdev/etq
|
|
58
|
+
"url": "https://github.com/leepickdev/etq/issues"
|
|
58
59
|
}
|
|
59
60
|
}
|
|
@@ -11,7 +11,7 @@ default_surface:
|
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
It does not create runtime seats, product repos, backplanes, hosted services, dashboards, or sample products.
|
|
14
|
-
It starts
|
|
14
|
+
It starts unauthenticated: `workspace-secure-profile.v0` is `open`, with upgrade paths for `screening-warn`, `screening-enforced`, and `enterprise-reactor`.
|
|
15
15
|
|
|
16
16
|
## Quick Start
|
|
17
17
|
|
|
@@ -23,6 +23,7 @@ sh /tmp/etiquette-start/validate-vanilla.sh
|
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
The first person who claims the stamped `control-seat` reports readiness before assigning work.
|
|
26
|
+
For restricted seats, change the secure profile, add provider-derived policy/claims, then run `sh source/control-seat/bin/access-assurance-check`.
|
|
26
27
|
|
|
27
28
|
## Local Receipt Proof
|
|
28
29
|
|
|
@@ -54,7 +55,7 @@ cannot:
|
|
|
54
55
|
- clone product repos before assignment
|
|
55
56
|
- bypass validation
|
|
56
57
|
- treat chat as evidence
|
|
57
|
-
- grant
|
|
58
|
+
- grant access from the secure profile or reactor
|
|
58
59
|
```
|
|
59
60
|
|
|
60
61
|
Provision these later only after the control seat grants them:
|
|
@@ -8,3 +8,9 @@ For local-only proof, append events with `bin/local-event` and compact them with
|
|
|
8
8
|
|
|
9
9
|
Inside a live runtime session, run `bin/session-init` after `bin/seat-init`
|
|
10
10
|
to prepare the local ledger, receipts, tasks, outbox, and session state.
|
|
11
|
+
|
|
12
|
+
Access assurance is explicit and optional. The default profile is
|
|
13
|
+
`docs/work/access/workspace-secure-profile.v0.json` with `mode: open`. Run
|
|
14
|
+
`bin/access-assurance-check` before routing restricted seats, and switch to
|
|
15
|
+
`screening-warn`, `screening-enforced`, or `enterprise-reactor` only when the
|
|
16
|
+
workspace actually needs provider-backed screening.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
5
|
+
PROFILE="$ROOT/docs/work/access/workspace-secure-profile.v0.json"
|
|
6
|
+
POLICY="$ROOT/docs/work/access/seat-access-policy.v0.json"
|
|
7
|
+
CLAIMS="$ROOT/docs/work/access/access-assurance-claims.v0.json"
|
|
8
|
+
|
|
9
|
+
json_string_field() {
|
|
10
|
+
sed -n "s/.*\"$2\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p" "$1" | head -n 1
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
json_bool_field() {
|
|
14
|
+
sed -n "s/.*\"$2\"[[:space:]]*:[[:space:]]*\\(true\\|false\\).*/\\1/p" "$1" | head -n 1
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if [ ! -f "$PROFILE" ]; then
|
|
18
|
+
echo "access-assurance: fail missing docs/work/access/workspace-secure-profile.v0.json" >&2
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
mode=$(json_string_field "$PROFILE" mode)
|
|
23
|
+
case "$mode" in
|
|
24
|
+
open|screening-warn|screening-enforced|enterprise-reactor) ;;
|
|
25
|
+
*)
|
|
26
|
+
echo "access-assurance: fail invalid mode=${mode:-missing}" >&2
|
|
27
|
+
exit 1
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
|
|
31
|
+
if [ "$mode" = "open" ]; then
|
|
32
|
+
echo "access-assurance: pass mode=open policy=not-required"
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
if [ ! -f "$POLICY" ] || [ ! -f "$CLAIMS" ]; then
|
|
37
|
+
message="access-assurance: missing policy or claims for mode=$mode"
|
|
38
|
+
if [ "$mode" = "screening-warn" ]; then
|
|
39
|
+
echo "$message"
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
echo "$message" >&2
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [ "$mode" = "enterprise-reactor" ]; then
|
|
47
|
+
tighten_only=$(json_bool_field "$PROFILE" tighten_only)
|
|
48
|
+
reactor_can_grant=$(json_bool_field "$PROFILE" reactor_can_grant_or_loosen_access)
|
|
49
|
+
if [ "$tighten_only" != "true" ] || [ "$reactor_can_grant" != "false" ]; then
|
|
50
|
+
echo "access-assurance: fail enterprise-reactor requires tighten_only=true and reactor_can_grant_or_loosen_access=false" >&2
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
echo "access-assurance: pass mode=$mode"
|
|
@@ -5,11 +5,16 @@ ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
|
5
5
|
|
|
6
6
|
test -f "$ROOT/.llm-substrate/HANDOFF.md"
|
|
7
7
|
test -f "$ROOT/docs/work/ledger/LEDGER.md"
|
|
8
|
+
test -f "$ROOT/docs/work/access/workspace-secure-profile.v0.json"
|
|
9
|
+
test -f "$ROOT/docs/work/access/ACCESS-ASSURANCE.md"
|
|
8
10
|
test -f "$ROOT/docs/work/playbacks/PLAYBACK_TEMPLATE.md"
|
|
9
11
|
test -f "$ROOT/docs/work/tasks/CONTROL-001.yaml"
|
|
10
12
|
test -d "$ROOT/docs/work/receipts"
|
|
13
|
+
test -f "$ROOT/bin/access-assurance-check"
|
|
11
14
|
test -f "$ROOT/bin/session-init"
|
|
12
15
|
test -f "$ROOT/bin/local-event"
|
|
13
16
|
test -f "$ROOT/bin/compact-local-events"
|
|
14
17
|
|
|
18
|
+
sh "$ROOT/bin/access-assurance-check" >/dev/null
|
|
19
|
+
|
|
15
20
|
echo "control-seat: ok"
|
package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/ACCESS-ASSURANCE.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Access Assurance
|
|
2
|
+
|
|
3
|
+
The vanilla control seat starts in `open` mode. That keeps Etiquette usable as a
|
|
4
|
+
local-first workflow kit without authentication, screening, hosted services, or
|
|
5
|
+
a daemon.
|
|
6
|
+
|
|
7
|
+
The workspace mode lives in `workspace-secure-profile.v0.json`.
|
|
8
|
+
|
|
9
|
+
Modes:
|
|
10
|
+
|
|
11
|
+
- `open`: no access-assurance gate is required.
|
|
12
|
+
- `screening-warn`: restricted-seat policy and claims are checked, but failures
|
|
13
|
+
warn instead of blocking.
|
|
14
|
+
- `screening-enforced`: restricted seats fail closed when policy or claims are
|
|
15
|
+
missing, expired, revoked, or not provider-backed.
|
|
16
|
+
- `enterprise-reactor`: `screening-enforced` plus an optional tighten-only
|
|
17
|
+
daemon for revocation sync, badge refresh, kill-switch writes, and outbox
|
|
18
|
+
drain.
|
|
19
|
+
|
|
20
|
+
The reactor may tighten access only. It must not grant access, authorize
|
|
21
|
+
actions, close work, merge, or rewrite the ledger.
|
|
22
|
+
|
|
23
|
+
Provider-backed secure deployments should keep raw identity material outside the
|
|
24
|
+
repo:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
Persona / Scandit / SSO -> Supabase derived claims -> local access check
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Repo-safe fields are provider refs, status, policy eligibility class, evidence
|
|
31
|
+
hash, expiry, and audit timestamps. Passport images, document photos, full
|
|
32
|
+
document numbers, ethnicity, provider secrets, and raw webhook payloads do not
|
|
33
|
+
belong in Git.
|
|
34
|
+
|
|
35
|
+
Check the mode:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
sh bin/access-assurance-check
|
|
39
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "workspace-secure-profile.v0",
|
|
3
|
+
"workspace_id": "vanilla-control-seat",
|
|
4
|
+
"mode": "open",
|
|
5
|
+
"allowed_modes": [
|
|
6
|
+
"open",
|
|
7
|
+
"screening-warn",
|
|
8
|
+
"screening-enforced",
|
|
9
|
+
"enterprise-reactor"
|
|
10
|
+
],
|
|
11
|
+
"mode_meanings": {
|
|
12
|
+
"open": "No access-assurance gate is required. Etiquette core remains local and unauthenticated.",
|
|
13
|
+
"screening-warn": "Restricted-seat claims are checked and reported, but missing or failed claims do not block local entry.",
|
|
14
|
+
"screening-enforced": "Restricted-seat claims are required before routing or entering restricted seats.",
|
|
15
|
+
"enterprise-reactor": "screening-enforced plus an optional tighten-only reactor for revocation sync, badge refresh, kill-switch writes, and outbox drain."
|
|
16
|
+
},
|
|
17
|
+
"identity_model": {
|
|
18
|
+
"authenticate": "operator_principals",
|
|
19
|
+
"assign_to": "seat_ids",
|
|
20
|
+
"authorize": "per_action_grants",
|
|
21
|
+
"workspace_role": "policy_scope",
|
|
22
|
+
"linear_role": "external_backlog_projection_only"
|
|
23
|
+
},
|
|
24
|
+
"claim_source": {
|
|
25
|
+
"kind": "none-required-for-open-mode",
|
|
26
|
+
"live_replacement": "Supabase Auth plus derived Persona and Scandit claim export",
|
|
27
|
+
"raw_pii_allowed_in_repo": false
|
|
28
|
+
},
|
|
29
|
+
"reactor": {
|
|
30
|
+
"required_for_mode": "enterprise-reactor",
|
|
31
|
+
"default_enabled": false,
|
|
32
|
+
"tighten_only": true,
|
|
33
|
+
"may_write": [
|
|
34
|
+
"kill_switch_entries",
|
|
35
|
+
"expired_assurance_markers",
|
|
36
|
+
"badge_refresh_cache",
|
|
37
|
+
"sync_outbox"
|
|
38
|
+
],
|
|
39
|
+
"must_not": [
|
|
40
|
+
"grant_access",
|
|
41
|
+
"close_work",
|
|
42
|
+
"merge",
|
|
43
|
+
"rewrite_ledger",
|
|
44
|
+
"authorize_actions"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"authority_boundary": {
|
|
48
|
+
"profile_can_authorize_work": false,
|
|
49
|
+
"profile_can_grant_seat": false,
|
|
50
|
+
"profile_can_merge_or_close": false,
|
|
51
|
+
"reactor_can_grant_or_loosen_access": false
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -7,17 +7,22 @@ test -f "$ROOT/README.md"
|
|
|
7
7
|
test -d "$ROOT/source/etiquette-kernel"
|
|
8
8
|
test -d "$ROOT/source/control-seat"
|
|
9
9
|
grep -Fq ".etiquette/events/*.ndjson" "$ROOT/source/control-seat/.gitignore"
|
|
10
|
+
grep -q '"schema": "workspace-secure-profile.v0"' "$ROOT/source/control-seat/docs/work/access/workspace-secure-profile.v0.json"
|
|
11
|
+
grep -q '"mode": "open"' "$ROOT/source/control-seat/docs/work/access/workspace-secure-profile.v0.json"
|
|
12
|
+
grep -q "enterprise-reactor" "$ROOT/source/control-seat/docs/work/access/ACCESS-ASSURANCE.md"
|
|
10
13
|
grep -q "Controlled drills require one operator approval per drill" "$ROOT/source/etiquette-kernel/contracts/playback.v0.md"
|
|
11
14
|
grep -q "batch_approval_allowed: false" "$ROOT/source/control-seat/docs/work/playbacks/PLAYBACK_TEMPLATE.md"
|
|
12
15
|
|
|
13
16
|
sh "$ROOT/source/etiquette-kernel/bin/kernel-doctor"
|
|
14
17
|
sh "$ROOT/source/control-seat/bin/seat-doctor"
|
|
18
|
+
sh "$ROOT/source/control-seat/bin/access-assurance-check" | grep -q "mode=open"
|
|
15
19
|
|
|
16
20
|
tmp_root=$(mktemp -d "${TMPDIR:-/tmp}/etiquette-vanilla-compact.XXXXXX")
|
|
17
21
|
trap 'rm -rf "$tmp_root"' EXIT
|
|
18
22
|
|
|
19
23
|
cp -R "$ROOT/source/control-seat/." "$tmp_root/control-seat/"
|
|
20
24
|
sh "$tmp_root/control-seat/bin/seat-init" --execution-seat control-seat >/dev/null
|
|
25
|
+
sh "$tmp_root/control-seat/bin/access-assurance-check" | grep -q "mode=open"
|
|
21
26
|
sh "$tmp_root/control-seat/bin/session-init" --task-id SESSION-INIT --operator local-operator >/tmp/session-init.out
|
|
22
27
|
test -f "$tmp_root/control-seat/.etiquette/state/session.json"
|
|
23
28
|
grep -q "session_opened" "$tmp_root/control-seat/docs/work/ledger/LEDGER.md"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Hosted Receiver Templates
|
|
2
|
+
|
|
3
|
+
Opt-in templates for teams that want to expose Etiquette's W1 GitHub webhook
|
|
4
|
+
receiver behind their own hosting layer.
|
|
5
|
+
|
|
6
|
+
## W1 GitHub Receiver
|
|
7
|
+
|
|
8
|
+
`w1-github-webhook-receiver.mjs` is a small Node HTTP server:
|
|
9
|
+
|
|
10
|
+
- `GET /health` returns a readiness probe.
|
|
11
|
+
- `POST /github` accepts GitHub `ping` and `push` webhook deliveries.
|
|
12
|
+
- `ping` returns `200` only after the delivery is signature-verified.
|
|
13
|
+
- `push` delegates to `etiquette notify webhook github`.
|
|
14
|
+
- raw payloads are written only to a temporary file for the CLI call, then
|
|
15
|
+
removed.
|
|
16
|
+
- emitted records stay pointer-only and authority-false.
|
|
17
|
+
|
|
18
|
+
Run it with:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
export ETIQUETTE_GITHUB_WEBHOOK_SECRET='<webhook-secret>'
|
|
22
|
+
export ETIQUETTE_CLI='etiquette'
|
|
23
|
+
node w1-github-webhook-receiver.mjs
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Optional:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
export PORT=8080
|
|
30
|
+
export ETIQUETTE_WAKE_OUT_DIR=/var/lib/etiquette/wake
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`ETIQUETTE_WAKE_OUT_DIR` stores only the verified pointer output, never the raw
|
|
34
|
+
webhook body.
|
|
35
|
+
|
|
36
|
+
## Boundary
|
|
37
|
+
|
|
38
|
+
This template does not create a public endpoint, register repository webhooks,
|
|
39
|
+
provision cloud infrastructure, start remote execution, or grant authority. Host
|
|
40
|
+
selection, webhook registration, secret rotation, and retention policy remain
|
|
41
|
+
operator decisions.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { spawnSync } from 'node:child_process';
|
|
8
|
+
|
|
9
|
+
const port = Number(process.env.PORT || '8080');
|
|
10
|
+
const etiquetteCli = process.env.ETIQUETTE_CLI || 'etiquette';
|
|
11
|
+
const secret = process.env.ETIQUETTE_GITHUB_WEBHOOK_SECRET;
|
|
12
|
+
const outDir = process.env.ETIQUETTE_WAKE_OUT_DIR || '';
|
|
13
|
+
|
|
14
|
+
if (!secret) throw new Error('ETIQUETTE_GITHUB_WEBHOOK_SECRET is required');
|
|
15
|
+
|
|
16
|
+
function readRaw(req) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const chunks = [];
|
|
19
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
20
|
+
req.on('end', () => resolve(Buffer.concat(chunks)));
|
|
21
|
+
req.on('error', reject);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function writeJson(res, status, value) {
|
|
26
|
+
res.writeHead(status, {
|
|
27
|
+
'content-type': 'application/json',
|
|
28
|
+
'cache-control': 'no-store',
|
|
29
|
+
});
|
|
30
|
+
res.end(`${JSON.stringify(value, null, 2)}\n`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function publicRecord(record) {
|
|
34
|
+
return {
|
|
35
|
+
ok: true,
|
|
36
|
+
schema: record.schema,
|
|
37
|
+
event: record.event,
|
|
38
|
+
delivery_id: record.delivery_id,
|
|
39
|
+
repository: record.repository.full_name,
|
|
40
|
+
ref: record.ref || null,
|
|
41
|
+
after: record.after || null,
|
|
42
|
+
signature_verified: record.transport.signature_verified,
|
|
43
|
+
pointers_only: record.payload_boundary.pointers_only,
|
|
44
|
+
notification_is_authority: record.authority_boundary.notification_is_authority,
|
|
45
|
+
next_action: record.next_action,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function verifyDelivery(req, event, delivery, signature) {
|
|
50
|
+
const raw = await readRaw(req);
|
|
51
|
+
const payloadPath = join(tmpdir(), `etiquette-webhook-${delivery}-${randomUUID()}.json`);
|
|
52
|
+
writeFileSync(payloadPath, raw);
|
|
53
|
+
try {
|
|
54
|
+
const result = spawnSync(etiquetteCli, [
|
|
55
|
+
'notify',
|
|
56
|
+
'webhook',
|
|
57
|
+
'github',
|
|
58
|
+
'--payload',
|
|
59
|
+
payloadPath,
|
|
60
|
+
'--delivery',
|
|
61
|
+
delivery,
|
|
62
|
+
'--event',
|
|
63
|
+
event,
|
|
64
|
+
'--signature-256',
|
|
65
|
+
signature,
|
|
66
|
+
'--json',
|
|
67
|
+
], {
|
|
68
|
+
encoding: 'utf8',
|
|
69
|
+
env: {
|
|
70
|
+
...process.env,
|
|
71
|
+
ETIQUETTE_GITHUB_WEBHOOK_SECRET: secret,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
if (result.status !== 0) {
|
|
75
|
+
return {
|
|
76
|
+
ok: false,
|
|
77
|
+
status: 401,
|
|
78
|
+
body: {
|
|
79
|
+
ok: false,
|
|
80
|
+
error: 'signature_or_payload_rejected',
|
|
81
|
+
detail: result.stderr.trim().slice(0, 200),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const record = JSON.parse(result.stdout);
|
|
86
|
+
if (outDir) {
|
|
87
|
+
mkdirSync(outDir, { recursive: true });
|
|
88
|
+
writeFileSync(join(outDir, 'latest.json'), `${JSON.stringify(record, null, 2)}\n`);
|
|
89
|
+
writeFileSync(join(outDir, `${delivery}.json`), `${JSON.stringify(record, null, 2)}\n`);
|
|
90
|
+
}
|
|
91
|
+
return { ok: true, status: 200, body: publicRecord(record) };
|
|
92
|
+
} finally {
|
|
93
|
+
rmSync(payloadPath, { force: true });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const server = createServer(async (req, res) => {
|
|
98
|
+
try {
|
|
99
|
+
if (req.method === 'GET' && req.url === '/health') {
|
|
100
|
+
writeJson(res, 200, { ok: true, authority: false });
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (req.method !== 'POST' || req.url !== '/github') {
|
|
104
|
+
writeJson(res, 404, { ok: false, error: 'not_found' });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const event = String(req.headers['x-github-event'] || '');
|
|
109
|
+
const delivery = String(req.headers['x-github-delivery'] || randomUUID());
|
|
110
|
+
const signature = String(req.headers['x-hub-signature-256'] || '');
|
|
111
|
+
if (event !== 'push' && event !== 'ping') {
|
|
112
|
+
writeJson(res, 400, { ok: false, error: 'unsupported_event', event });
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (!signature.startsWith('sha256=')) {
|
|
116
|
+
writeJson(res, 401, { ok: false, error: 'missing_signature' });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const result = await verifyDelivery(req, event, delivery, signature);
|
|
121
|
+
writeJson(res, result.status, result.body);
|
|
122
|
+
} catch (error) {
|
|
123
|
+
writeJson(res, 500, { ok: false, error: String(error?.message || error) });
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
server.listen(port, '0.0.0.0', () => {
|
|
128
|
+
console.log(`etiquette_w1_receiver: listening on ${port}`);
|
|
129
|
+
});
|
|
@@ -62,9 +62,8 @@ project head-start surfaces before pickup:
|
|
|
62
62
|
- `docs/work/manuals/SEAT_OPERATING_MANUAL.md`
|
|
63
63
|
- `docs/work/cookbooks/ADD_A_LANE.md` when routing work
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
swaps,
|
|
67
|
-
Lifecycle/readiness checks are evidence only; they do not authorize work.
|
|
65
|
+
Re-orient with `etiquette whereami` before pickup after stale context, resume,
|
|
66
|
+
runner/model/profile swaps, or workflow migration.
|
|
68
67
|
|
|
69
68
|
## Validate Catalog
|
|
70
69
|
|
|
@@ -14,6 +14,6 @@ Before pickup in the target project, read:
|
|
|
14
14
|
4. `docs/work/manuals/SEAT_OPERATING_MANUAL.md`
|
|
15
15
|
5. `docs/work/cookbooks/ADD_A_LANE.md` when routing new work
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
swaps,
|
|
19
|
-
|
|
17
|
+
Re-orient with `etiquette whereami` before pickup after stale context, resume,
|
|
18
|
+
runner/model/profile swaps, or workflow migration. Hooks and readiness are
|
|
19
|
+
evidence only; the task envelope is the work authority.
|
|
@@ -14,9 +14,9 @@ Before pickup in the target project, read:
|
|
|
14
14
|
4. `docs/work/manuals/SEAT_OPERATING_MANUAL.md`
|
|
15
15
|
5. `docs/work/cookbooks/ADD_A_LANE.md` when routing new work
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
swaps,
|
|
19
|
-
|
|
17
|
+
Re-orient with `etiquette whereami` before pickup after stale context, resume,
|
|
18
|
+
runner/model/profile swaps, or workflow migration. Hooks and readiness are
|
|
19
|
+
evidence only; the task envelope is the work authority.
|
|
20
20
|
|
|
21
21
|
For bounded, cursor-based wake checks use the portable core command
|
|
22
22
|
`etiquette notify poll --seat <id> --after-seq <n>` instead of raw `tail -F` monitors.
|
|
@@ -14,6 +14,6 @@ Before pickup in the target project, read:
|
|
|
14
14
|
4. `docs/work/manuals/SEAT_OPERATING_MANUAL.md`
|
|
15
15
|
5. `docs/work/cookbooks/ADD_A_LANE.md` when routing new work
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
swaps,
|
|
19
|
-
|
|
17
|
+
Re-orient with `etiquette whereami` before pickup after stale context, resume,
|
|
18
|
+
runner/model/profile swaps, or workflow migration. Hooks and readiness are
|
|
19
|
+
evidence only; the task envelope is the work authority.
|
|
@@ -14,6 +14,6 @@ Before pickup in the target project, read:
|
|
|
14
14
|
4. `docs/work/manuals/SEAT_OPERATING_MANUAL.md`
|
|
15
15
|
5. `docs/work/cookbooks/ADD_A_LANE.md` when routing new work
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
swaps,
|
|
19
|
-
|
|
17
|
+
Re-orient with `etiquette whereami` before pickup after stale context, resume,
|
|
18
|
+
runner/model/profile swaps, or workflow migration. Hooks and readiness are
|
|
19
|
+
evidence only; the task envelope is the work authority.
|
|
@@ -14,6 +14,6 @@ Before pickup in the target project, read:
|
|
|
14
14
|
4. `docs/work/manuals/SEAT_OPERATING_MANUAL.md`
|
|
15
15
|
5. `docs/work/cookbooks/ADD_A_LANE.md` when routing new work
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
swaps,
|
|
19
|
-
|
|
17
|
+
Re-orient with `etiquette whereami` before pickup after stale context, resume,
|
|
18
|
+
runner/model/profile swaps, or workflow migration. Hooks and readiness are
|
|
19
|
+
evidence only; the task envelope is the work authority.
|
package/docs/CONCEPT_STATUS.md
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# Concept Status Matrix
|
|
2
|
-
|
|
3
|
-
Etiquette uses a few strong workflow concepts. Some are core behavior today,
|
|
4
|
-
some belong to the optional secure plane, and some are still operating patterns
|
|
5
|
-
that need a concrete consumer before they become default workflow.
|
|
6
|
-
|
|
7
|
-
Use this page when writing portal copy, onboarding material, release notes, or
|
|
8
|
-
manager runbooks. Do not promote a concept beyond the status shown here.
|
|
9
|
-
|
|
10
|
-
## Edition Boundary
|
|
11
|
-
|
|
12
|
-
| Surface | Purpose | Authority Posture |
|
|
13
|
-
| --- | --- | --- |
|
|
14
|
-
| Etiquette Core | Repo-local coordination, task envelopes, receipts, allowed writes, read models, manuals, and canaries. | Transparent by default; authority comes from tracked task/grant records and receipts. |
|
|
15
|
-
| Etiquette Secure | Restricted-seat admission, external assurance claims, revocation, policy state, and optional tightening reactor. | Tightens standing and eligibility; it must not grant workflow authority by itself. |
|
|
16
|
-
| Hosted/portal plane | Setup passes, workspace visibility, onboarding, board/read-model display, and operational observability. | Portal RBAC authorizes portal operations only. Workflow authority stays local and grant-backed. |
|
|
17
|
-
|
|
18
|
-
## Concept Matrix
|
|
19
|
-
|
|
20
|
-
| Concept | Core Status | Secure Status | Portal Surface | Caveat |
|
|
21
|
-
| --- | --- | --- | --- | --- |
|
|
22
|
-
| Ledger | Shipped. Repo-local task records, events, and receipts carry durable workflow truth. | May receive signed or protected replication later. | Board and console render ledger-derived read models. | Git-backed truth is durable and auditable; call it cryptographic only when signing/protected append-only is actually configured. |
|
|
23
|
-
| Receipts | Shipped. Work returns must cite changed files, validation, blockers, and next owner. | May include action authorization stamps and external verifier receipts. | Evidence drawers and manager views point to receipts. | A receipt proves evidence; it does not grant, merge, close, or promote by itself. |
|
|
24
|
-
| Seats and agents | Shipped. A seat is a stable responsibility; an occupant/runtime can change. Owner cards derive accountability, diet, boundaries, review cadence, and failure modes from source contracts plus live readiness. | Secure posture is parked; seats use local readiness and explicit task routing. | Roster and owner cards show lifecycle, readiness, ownership, and posture. | Model cards, owner cards, and roster posture help routing but do not authorize work or transfer ownership. |
|
|
25
|
-
| Task envelopes | Shipped. Tasks declare owner, mode, allowed writes, forbidden writes, validation, stop conditions, and receipt expectations. | Secure admission is parked; task routing remains explicit. | Manager manuals and pickup surfaces show the envelope. | Allowed writes are a cooperative boundary unless paired with OS/container enforcement or audit gates. |
|
|
26
|
-
| Rubrics and validation | Shipped as acceptance criteria and conformance gates. | Can be bound to restricted workflows and verifier receipts. | Manager/operator docs list required validation and stop conditions. | Do not claim every runtime is hard-blocked from returning unless the specific flow enforces that gate. |
|
|
27
|
-
| Authorization | Shipped as grant-backed workflow discipline: authentication seats an actor; authorization gates consequential action. | Secure posture is parked; grant leases, kill-switch state, and action stamps remain the admission-time authority model. | Hosted pass docs and workspace authority contracts describe the boundary. | A verified occupant has standing, not blanket authority. Grants are effective only while standing is current. |
|
|
28
|
-
| Portal / management console | Core read model, docs site, screenshots, and read-only `console serve` are shipped. | Secure portal may manage policy state and revocation signals. | Console and board are read-only by default. | Portal RBAC is not workflow authority. Browser actions remain out of scope in Core. |
|
|
29
|
-
| Distribution and plugins | Core CLI, docs, templates, MCP resources/prompts, and outbox-backed proposal staging are portable. | Secure can ship as an optional add-on. | Codex and Claude Code plugins may launch workflows and portal views. | Plugins are convenience packaging, not authority. MCP proposal tools must not mutate the ledger directly. |
|
|
30
|
-
| Remote execution | Supported as evidence-first design. | Secure runtimes may require admission, revocation, and verifier identity before execution. Org-remote workspaces use session outboxes, sharded drains, candidate imports, and authority promotion gates. | Manager docs should treat remote receipts as evidence. | Start remote as witness, not worker. Remote receipts and drain imports do not authorize promotion. |
|
|
31
|
-
| Managed-agent parity | Parity map exists for agents, environments, sessions, events, tools, MCP, memory, outcomes, and scheduling. | Secure runtime admission is parked. | Docs site and portal docs may expose the map. | Compatibility is not dependency. The runner executes; Etiquette governs and records. |
|
|
32
|
-
| Architecture boundary | Core, runtime, harness, adapter, and reactor roles are documented and import-boundary tested. | Secure adds admission policy without forking doctrine. | Hosted consumes projected views without becoming authority. | New reverse imports are architectural changes, not convenience edits. |
|
|
33
|
-
| Memory | Shipped as cited context, filesystem-shaped candidate stores, SQLite FTS recall, and `memory status` capability reporting. Evidence consolidation/rollup is the memory compaction lifecycle; it is not doctrine marination. | Secure deployments may restrict what crosses org/workspace boundaries. | Docs may surface references, summaries, archive pointers, and shipped/reserved memory status. | Memory proposes; ledger authorizes. Do not claim full semantic/vector memory parity until the adapter ships. Do not rewrite shared truth through background consolidation. |
|
|
34
|
-
| Marination | Operating pattern. Use for doctrine sabbaticals: scheduled fresh-attention review of rules, errata, and proposed revisions. | Can be run under Secure as an advisory process with cited evidence. | Not yet a default portal workflow. | Deltas only. It produces proposals, not silent lane mutations. |
|
|
35
|
-
| Sabbaticals / parking | Partially reflected as `park`, `held`, and deferred dispositions. | Secure deployments may freeze standing or grants while work is parked. | Manager cadence can show parked/held work. | Do not promise automatic stash/cleanup unless the workspace implements that runbook. |
|
|
36
|
-
| Tightening reactor | Not part of default Core. | Optional off-by-default listener that writes only fail-closed signals such as revocation or kill-switch state. | Secure operations may show reactor health. | It may tighten, never loosen. If it stops, local admission still fails or proceeds from last known policy according to the configured gate. |
|
|
37
|
-
|
|
38
|
-
## Primitive Loop
|
|
39
|
-
|
|
40
|
-
Core records, validates, gates, and dispatches. Full remembers, consolidates,
|
|
41
|
-
marinates, and projects. Execution is not the gate: Core execution is the local
|
|
42
|
-
shell/worktree, Full execution is a runtime cell or managed runner, and both
|
|
43
|
-
remain authority-false until the promotion gate accepts evidence.
|
|
44
|
-
|
|
45
|
-
| Layer | Core | Full |
|
|
46
|
-
| --- | --- | --- |
|
|
47
|
-
| Record | identity, seats, task envelopes, session runbooks, ledger, receipts | memory stores, recall capsules, org/workspace projections |
|
|
48
|
-
| Reflect | rubrics, local validation, reconciliation by review | consolidation rollups, marination, drift and failure trend review |
|
|
49
|
-
| Gate | human/Git promotion gate over receipts and grants | same gate, enriched by secure admission and policy checks |
|
|
50
|
-
| Execute | local shell, local worktree, local runner | runtime cells, EKS/kind sandboxes, managed runners |
|
|
51
|
-
| Act | dispatch, receipt return, next-owner routing | hosted portal views, observability, adapter projections |
|
|
52
|
-
|
|
53
|
-
## Writing Rule
|
|
54
|
-
|
|
55
|
-
Use shipped language for shipped behavior, design language for parked behavior,
|
|
56
|
-
and edition language for Secure behavior:
|
|
57
|
-
|
|
58
|
-
```text
|
|
59
|
-
Core records, validates, gates, and dispatches.
|
|
60
|
-
Full remembers, consolidates, marinates, and projects.
|
|
61
|
-
Secure admits and revokes restricted standing.
|
|
62
|
-
Portals display and coordinate.
|
|
63
|
-
Grants authorize consequential actions.
|
|
64
|
-
Receipts prove what happened.
|
|
65
|
-
Execution returns evidence; it never mints authority.
|
|
66
|
-
```
|