@etiquekit/etq 1.0.12 → 1.0.14

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.
Files changed (149) hide show
  1. package/AGENTS.md +19 -26
  2. package/LICENSE +2 -3
  3. package/NOTICE +6 -4
  4. package/QuickStart.md +35 -47
  5. package/README.md +54 -54
  6. package/bin/etiquette +1 -5
  7. package/bin/etiquette-core +1 -5
  8. package/docs/ARCHITECTURE.md +5 -5
  9. package/docs/CODEX_CLIENT_COMPATIBILITY.md +1 -1
  10. package/docs/CONCEPTS.md +7 -23
  11. package/docs/CONCEPT_STATUS.md +66 -0
  12. package/docs/CORE_PROFILE.md +3 -5
  13. package/docs/LANE_PROVISIONING.md +7 -2
  14. package/docs/README.md +4 -4
  15. package/docs/RELEASE_SURFACE_AUDIT.md +8 -7
  16. package/docs/SEAT_DISCIPLINE.md +55 -91
  17. package/docs/SEAT_PROVISIONING.md +19 -22
  18. package/docs/TEAM_HANDOFF.md +21 -21
  19. package/docs/WORKTREE_QOL.md +7 -6
  20. package/docs/contracts/ledger-entry/README.md +11 -11
  21. package/docs/contracts/ledger-entry/ledger-entry.v0.2.md +3 -3
  22. package/docs/contracts/ledger-entry/ledger-entry.v0.md +8 -8
  23. package/package.json +9 -9
  24. package/packages/control/src/authority/lease.ts +261 -0
  25. package/packages/control/src/authority/node-delegation.ts +257 -0
  26. package/packages/control/src/authority/rig-conductor.ts +632 -0
  27. package/packages/control/src/cli/argv.ts +155 -0
  28. package/packages/control/src/cli/commands/console.ts +200 -0
  29. package/packages/control/src/cli/commands/dispatch-core.ts +89 -0
  30. package/packages/control/src/cli/commands/dispatch.ts +279 -0
  31. package/packages/control/src/cli/commands/harness.ts +89 -0
  32. package/packages/control/src/cli/commands/hook.ts +50 -0
  33. package/packages/control/src/cli/commands/ledger.ts +91 -0
  34. package/packages/control/src/cli/commands/local-workflow.ts +4690 -0
  35. package/packages/control/src/cli/commands/memory.ts +445 -0
  36. package/packages/control/src/cli/commands/release.ts +108 -0
  37. package/packages/control/src/cli/commands/rubric.ts +103 -0
  38. package/packages/control/src/cli/commands/seat.ts +179 -0
  39. package/packages/control/src/cli/commands/session.ts +127 -0
  40. package/packages/control/src/cli/commands/supervision.ts +246 -0
  41. package/packages/control/src/cli/commands/sync.ts +119 -0
  42. package/packages/control/src/cli/commands/workflow.ts +86 -0
  43. package/packages/control/src/cli/commands/workspace.ts +50 -0
  44. package/packages/control/src/cli/core-usage.ts +34 -0
  45. package/packages/control/src/cli/prompt.ts +67 -0
  46. package/packages/control/src/cli/supervision-deps.ts +44 -0
  47. package/packages/control/src/cli/usage.ts +241 -0
  48. package/packages/control/src/cli.ts +207 -0
  49. package/packages/control/src/core-cli.ts +50 -0
  50. package/packages/control/src/dispatch/decision.ts +202 -0
  51. package/packages/control/src/dispatch/projection.ts +293 -0
  52. package/packages/control/src/dispatch/record.ts +153 -0
  53. package/packages/control/src/engagement/project.ts +170 -0
  54. package/packages/control/src/fs.ts +19 -0
  55. package/packages/control/src/harness/pruning.ts +406 -0
  56. package/packages/control/src/hooks/dispatcher.ts +117 -0
  57. package/packages/control/src/hooks/outbox.ts +86 -0
  58. package/packages/control/src/hooks/sanitize.ts +6 -0
  59. package/packages/control/src/hooks/types.ts +34 -0
  60. package/packages/control/src/index.ts +384 -0
  61. package/packages/control/src/ledger/entry.ts +303 -0
  62. package/packages/control/src/ledger/indexer.ts +542 -0
  63. package/packages/control/src/memory/context.ts +149 -0
  64. package/packages/control/src/memory/drain-import.ts +207 -0
  65. package/packages/control/src/memory/indexer.ts +284 -0
  66. package/packages/control/src/memory/query.ts +75 -0
  67. package/packages/control/src/memory/sanitize.ts +50 -0
  68. package/packages/control/src/memory/sharded-drain-import.ts +212 -0
  69. package/packages/control/src/memory/status.ts +211 -0
  70. package/packages/control/src/memory/store-lifecycle.ts +509 -0
  71. package/packages/control/src/memory/store.ts +284 -0
  72. package/packages/control/src/memory/types.ts +146 -0
  73. package/packages/control/src/parity/surfaces.ts +748 -0
  74. package/packages/control/src/project.ts +141 -0
  75. package/packages/control/src/projection/local-ledger-view.ts +373 -0
  76. package/packages/control/src/projection/return-enforcement.ts +48 -0
  77. package/packages/control/src/projection/timeline-preview.ts +539 -0
  78. package/packages/control/src/projection/timeline.ts +708 -0
  79. package/packages/control/src/release/readiness.ts +842 -0
  80. package/packages/control/src/rubric/loader.ts +326 -0
  81. package/packages/control/src/rubric/promotion.ts +54 -0
  82. package/packages/control/src/rubric/runner.ts +159 -0
  83. package/packages/control/src/rubric/types.ts +158 -0
  84. package/packages/control/src/seat/owner-card.ts +388 -0
  85. package/packages/control/src/seat/readiness.ts +834 -0
  86. package/packages/control/src/session/runbook.ts +431 -0
  87. package/packages/control/src/shared/sanitize.ts +49 -0
  88. package/packages/control/src/supervision/action-classes.ts +192 -0
  89. package/packages/control/src/supervision/command-apply.ts +378 -0
  90. package/packages/control/src/supervision/errors.ts +14 -0
  91. package/packages/control/src/supervision/event-replay.ts +155 -0
  92. package/packages/control/src/supervision/events.ts +109 -0
  93. package/packages/control/src/supervision/index.ts +16 -0
  94. package/packages/control/src/supervision/manifest.ts +127 -0
  95. package/packages/control/src/supervision/paths.ts +49 -0
  96. package/packages/control/src/supervision/projection-adapter.ts +274 -0
  97. package/packages/control/src/supervision/projection.ts +75 -0
  98. package/packages/control/src/supervision/rebuild.ts +99 -0
  99. package/packages/control/src/supervision/session-open.ts +131 -0
  100. package/packages/control/src/supervision/session-read.ts +99 -0
  101. package/packages/control/src/supervision/sqlite-impl.ts +71 -0
  102. package/packages/control/src/supervision/sqlite.ts +121 -0
  103. package/packages/control/src/supervision/store-rows.ts +371 -0
  104. package/packages/control/src/supervision/turn-close.ts +154 -0
  105. package/packages/control/src/supervision/turn-open.ts +284 -0
  106. package/packages/control/src/sync/event-log-merge-driver.ts +263 -0
  107. package/packages/control/src/sync/join-plan.ts +375 -0
  108. package/packages/control/src/sync/outbox.ts +492 -0
  109. package/packages/control/src/workflow/evaluator.ts +140 -0
  110. package/packages/control/src/workflow/loader.ts +200 -0
  111. package/packages/control/src/workflow/types.ts +90 -0
  112. package/packages/control/src/workspace/authority.ts +499 -0
  113. package/packages/protocol/src/guards.ts +119 -0
  114. package/packages/protocol/src/huddle-board.ts +198 -0
  115. package/packages/protocol/src/huddle.ts +295 -0
  116. package/packages/protocol/src/incident.ts +251 -0
  117. package/packages/protocol/src/index.ts +8 -0
  118. package/packages/protocol/src/interfaces.ts +107 -0
  119. package/packages/protocol/src/packet-profile.ts +195 -0
  120. package/packages/protocol/src/state.ts +81 -0
  121. package/packages/protocol/src/types.ts +434 -0
  122. package/release/lineage.v0.json +15 -0
  123. package/scripts/release-candidate-verify.sh +175 -0
  124. package/scripts/release-checksum.sh +25 -0
  125. package/scripts/release-pack-canary.sh +97 -0
  126. package/scripts/release-scan.sh +249 -0
  127. package/scripts/release-sign.sh +34 -0
  128. package/templates/etiquette-vanilla-v0/README.md +2 -3
  129. package/templates/etiquette-vanilla-v0/source/control-seat/README.md +0 -6
  130. package/templates/etiquette-vanilla-v0/source/control-seat/bin/seat-doctor +0 -5
  131. package/templates/etiquette-vanilla-v0/validate-vanilla.sh +0 -5
  132. package/templates/seat-packs-v0/README.md +3 -2
  133. package/templates/seat-packs-v0/source/claude-code-seat/README.md +3 -29
  134. package/templates/seat-packs-v0/source/codex-seat/README.md +3 -17
  135. package/templates/seat-packs-v0/source/gemini-seat/README.md +3 -23
  136. package/templates/seat-packs-v0/source/ollama-seat/README.md +3 -3
  137. package/templates/seat-packs-v0/source/openrouter-seat/README.md +3 -3
  138. package/docs/AGENT_SPAWNING.md +0 -78
  139. package/docs/INTEGRATION_UI.md +0 -215
  140. package/docs/OPERATOR_PLAYBOOK.md +0 -77
  141. package/docs/TAG_ROUTE.md +0 -95
  142. package/lib/etiquette-core.js +0 -315
  143. package/lib/etiquette.js +0 -1160
  144. package/templates/DISPATCH_PREMISES.md +0 -39
  145. package/templates/etiquette-vanilla-v0/source/control-seat/bin/access-assurance-check +0 -55
  146. package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/ACCESS-ASSURANCE.md +0 -39
  147. package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/workspace-secure-profile.v0.json +0 -53
  148. package/templates/hosted-receiver/README.md +0 -41
  149. package/templates/hosted-receiver/w1-github-webhook-receiver.mjs +0 -129
@@ -0,0 +1,200 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { extname } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import { assertSharedMemoryScopeId, assertSharedMemoryText } from '../shared/sanitize';
5
+ import {
6
+ GRANTORS,
7
+ STRATEGY_POLICIES,
8
+ WORKFLOW_DISPATCH_MODES,
9
+ WORKFLOW_MODE_TYPES,
10
+ WORKFLOW_RISK_LEVELS,
11
+ type Grantor,
12
+ type StrategyPolicy,
13
+ type WorkflowCheckEnvelope,
14
+ type WorkflowDispatchMode,
15
+ type WorkflowMode,
16
+ type WorkflowModeType,
17
+ type WorkflowRiskLevel,
18
+ } from './types';
19
+
20
+ type JsonRecord = Record<string, unknown>;
21
+
22
+ function isRecord(value: unknown): value is JsonRecord {
23
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
24
+ }
25
+
26
+ async function readStructured(path: string): Promise<unknown> {
27
+ const raw = await readFile(path, 'utf-8');
28
+ if (extname(path).toLowerCase() === '.json') {
29
+ return JSON.parse(raw) as unknown;
30
+ }
31
+ return parseYaml(raw) as unknown;
32
+ }
33
+
34
+ function asRecord(value: unknown, name: string): JsonRecord {
35
+ if (!isRecord(value)) throw new Error(`${name} must be an object`);
36
+ return value;
37
+ }
38
+
39
+ function asString(record: JsonRecord, key: string): string {
40
+ const value = record[key];
41
+ if (typeof value !== 'string' || value.trim().length === 0) {
42
+ throw new Error(`${key} must be a non-empty string`);
43
+ }
44
+ return value;
45
+ }
46
+
47
+ function asNullableString(record: JsonRecord, key: string): string | null {
48
+ const value = record[key];
49
+ if (value === null || value === undefined) return null;
50
+ if (typeof value !== 'string' || value.trim().length === 0) {
51
+ throw new Error(`${key} must be null or a non-empty string`);
52
+ }
53
+ return value;
54
+ }
55
+
56
+ function asStringArray(record: JsonRecord, key: string): string[] {
57
+ const value = record[key];
58
+ if (!Array.isArray(value) || value.some((item) => typeof item !== 'string')) {
59
+ throw new Error(`${key} must be a string array`);
60
+ }
61
+ return value as string[];
62
+ }
63
+
64
+ function asBoolean(record: JsonRecord, key: string): boolean {
65
+ const value = record[key];
66
+ if (typeof value !== 'boolean') throw new Error(`${key} must be a boolean`);
67
+ return value;
68
+ }
69
+
70
+ function asNumber(record: JsonRecord, key: string): number {
71
+ const value = record[key];
72
+ if (typeof value !== 'number' || !Number.isInteger(value) || value < 0) {
73
+ throw new Error(`${key} must be a non-negative integer`);
74
+ }
75
+ return value;
76
+ }
77
+
78
+ function asEnum<T extends readonly string[]>(values: T, raw: unknown, key: string): T[number] {
79
+ if (typeof raw !== 'string' || !(values as readonly string[]).includes(raw)) {
80
+ throw new Error(`${key} must be one of: ${values.join(', ')}`);
81
+ }
82
+ return raw as T[number];
83
+ }
84
+
85
+ function assertSemverish(value: string, key: string): void {
86
+ if (!/^\d+\.\d+\.\d+(?:[-+][A-Za-z0-9_.-]+)?$/.test(value)) {
87
+ throw new Error(`${key} must be semver-like (x.y.z)`);
88
+ }
89
+ }
90
+
91
+ function assertSafeTextOrNull(value: string | null, key: string): void {
92
+ if (value !== null) assertSharedMemoryText(value, key);
93
+ }
94
+
95
+ function validateModeInvariants(mode: WorkflowMode): void {
96
+ if (mode.authority_status !== 'policy_preset_only') {
97
+ throw new Error('authority_status must be policy_preset_only');
98
+ }
99
+ if (mode.grant.advisory_consensus_can_authorize !== false) {
100
+ throw new Error('grant.advisory_consensus_can_authorize must be false');
101
+ }
102
+ if (mode.drafting.min_reviewers > 0 && !mode.drafting.requires_review) {
103
+ throw new Error('drafting.min_reviewers requires drafting.requires_review');
104
+ }
105
+ if (mode.mode_type === 'mixed' && mode.execution.dispatch === 'immediate') {
106
+ throw new Error('mixed mode must not dispatch immediate before a grant hinge');
107
+ }
108
+ if (mode.mode_type === 'expedient' && !mode.proof.receipt_required) {
109
+ throw new Error('expedient mode must require receipt proof');
110
+ }
111
+ if (mode.mode_type === 'expedient' && !mode.proof.validation_required) {
112
+ throw new Error('expedient mode must require validation evidence');
113
+ }
114
+ }
115
+
116
+ export function parseWorkflowMode(value: unknown): WorkflowMode {
117
+ const record = asRecord(value, 'workflow_mode');
118
+ const drafting = asRecord(record.drafting, 'drafting');
119
+ const grant = asRecord(record.grant, 'grant');
120
+ const execution = asRecord(record.execution, 'execution');
121
+ const proof = asRecord(record.proof, 'proof');
122
+ const audit = asRecord(record.audit, 'audit');
123
+
124
+ const mode: WorkflowMode = {
125
+ mode_id: asString(record, 'mode_id'),
126
+ mode_version: asString(record, 'mode_version'),
127
+ mode_type: asEnum(WORKFLOW_MODE_TYPES, record.mode_type, 'mode_type') as WorkflowModeType,
128
+ drafting: {
129
+ surface: asString(drafting, 'surface'),
130
+ requires_review: asBoolean(drafting, 'requires_review'),
131
+ min_reviewers: asNumber(drafting, 'min_reviewers'),
132
+ amendment_rounds_allowed: asBoolean(drafting, 'amendment_rounds_allowed'),
133
+ adversarial_review_required: asBoolean(drafting, 'adversarial_review_required'),
134
+ compact_reason_required: asBoolean(drafting, 'compact_reason_required'),
135
+ },
136
+ grant: {
137
+ required: asBoolean(grant, 'required'),
138
+ preauthorization_allowed: asBoolean(grant, 'preauthorization_allowed'),
139
+ granted_by: asEnum(GRANTORS, grant.granted_by, 'granted_by') as Grantor,
140
+ advisory_consensus_can_authorize: asBoolean(grant, 'advisory_consensus_can_authorize') as false,
141
+ },
142
+ execution: {
143
+ surface: asString(execution, 'surface'),
144
+ dispatch: asEnum(WORKFLOW_DISPATCH_MODES, execution.dispatch, 'dispatch') as WorkflowDispatchMode,
145
+ strategy_policy: asEnum(STRATEGY_POLICIES, execution.strategy_policy, 'strategy_policy') as StrategyPolicy,
146
+ rubric_required: asBoolean(execution, 'rubric_required'),
147
+ },
148
+ proof: {
149
+ receipt_required: asBoolean(proof, 'receipt_required'),
150
+ validation_required: asBoolean(proof, 'validation_required'),
151
+ closeout_requires_receipt: asBoolean(proof, 'closeout_requires_receipt'),
152
+ },
153
+ audit: {
154
+ event_log_required: asBoolean(audit, 'event_log_required'),
155
+ dissent_capture_required: asBoolean(audit, 'dissent_capture_required'),
156
+ },
157
+ authority_status: asEnum(['policy_preset_only'] as const, record.authority_status, 'authority_status'),
158
+ };
159
+
160
+ assertSharedMemoryScopeId(mode.mode_id, 'mode_id');
161
+ assertSemverish(mode.mode_version, 'mode_version');
162
+ assertSharedMemoryScopeId(mode.drafting.surface, 'drafting.surface');
163
+ assertSharedMemoryScopeId(mode.execution.surface, 'execution.surface');
164
+ validateModeInvariants(mode);
165
+ return mode;
166
+ }
167
+
168
+ export async function loadWorkflowMode(path: string): Promise<WorkflowMode> {
169
+ return parseWorkflowMode(await readStructured(path));
170
+ }
171
+
172
+ export function parseWorkflowEnvelope(value: unknown): WorkflowCheckEnvelope {
173
+ const record = asRecord(value, 'workflow_check_envelope');
174
+ const envelope: WorkflowCheckEnvelope = {
175
+ task_ref: asString(record, 'task_ref'),
176
+ workflow_mode_ref: asString(record, 'workflow_mode_ref'),
177
+ requested_mode_type: asEnum(WORKFLOW_MODE_TYPES, record.requested_mode_type, 'requested_mode_type') as WorkflowModeType,
178
+ mutates_state: asBoolean(record, 'mutates_state'),
179
+ grant_ref: asNullableString(record, 'grant_ref'),
180
+ consensus_ref: asNullableString(record, 'consensus_ref'),
181
+ receipt_ref: asNullableString(record, 'receipt_ref'),
182
+ validation_refs: asStringArray(record, 'validation_refs'),
183
+ bounded: asBoolean(record, 'bounded'),
184
+ preauthorized: asBoolean(record, 'preauthorized'),
185
+ advisory_consensus_claims_authority: asBoolean(record, 'advisory_consensus_claims_authority'),
186
+ risk: asEnum(WORKFLOW_RISK_LEVELS, record.risk, 'risk') as WorkflowRiskLevel,
187
+ };
188
+
189
+ assertSharedMemoryText(envelope.task_ref, 'task_ref');
190
+ assertSharedMemoryText(envelope.workflow_mode_ref, 'workflow_mode_ref');
191
+ assertSafeTextOrNull(envelope.grant_ref, 'grant_ref');
192
+ assertSafeTextOrNull(envelope.consensus_ref, 'consensus_ref');
193
+ assertSafeTextOrNull(envelope.receipt_ref, 'receipt_ref');
194
+ for (const ref of envelope.validation_refs) assertSharedMemoryText(ref, 'validation_refs[]');
195
+ return envelope;
196
+ }
197
+
198
+ export async function loadWorkflowEnvelope(path: string): Promise<WorkflowCheckEnvelope> {
199
+ return parseWorkflowEnvelope(await readStructured(path));
200
+ }
@@ -0,0 +1,90 @@
1
+ export const WORKFLOW_MODE_TYPES = ['deliberative', 'expedient', 'mixed'] as const;
2
+ export type WorkflowModeType = typeof WORKFLOW_MODE_TYPES[number];
3
+
4
+ export const WORKFLOW_DISPATCH_MODES = ['manual', 'immediate', 'immediate_after_grant'] as const;
5
+ export type WorkflowDispatchMode = typeof WORKFLOW_DISPATCH_MODES[number];
6
+
7
+ export const STRATEGY_POLICIES = ['executor_selected', 'suggested', 'required'] as const;
8
+ export type StrategyPolicy = typeof STRATEGY_POLICIES[number];
9
+
10
+ export const GRANTORS = ['operator_principal', 'delegated_control_seat'] as const;
11
+ export type Grantor = typeof GRANTORS[number];
12
+
13
+ export const WORKFLOW_RISK_LEVELS = ['low', 'medium', 'high'] as const;
14
+ export type WorkflowRiskLevel = typeof WORKFLOW_RISK_LEVELS[number];
15
+
16
+ export const WORKFLOW_RECOMMENDATIONS = ['pass', 'warn', 'block'] as const;
17
+ export type WorkflowRecommendation = typeof WORKFLOW_RECOMMENDATIONS[number];
18
+
19
+ export interface WorkflowMode {
20
+ mode_id: string;
21
+ mode_version: string;
22
+ mode_type: WorkflowModeType;
23
+ drafting: {
24
+ surface: string;
25
+ requires_review: boolean;
26
+ min_reviewers: number;
27
+ amendment_rounds_allowed: boolean;
28
+ adversarial_review_required: boolean;
29
+ compact_reason_required: boolean;
30
+ };
31
+ grant: {
32
+ required: boolean;
33
+ preauthorization_allowed: boolean;
34
+ granted_by: Grantor;
35
+ advisory_consensus_can_authorize: false;
36
+ };
37
+ execution: {
38
+ surface: string;
39
+ dispatch: WorkflowDispatchMode;
40
+ strategy_policy: StrategyPolicy;
41
+ rubric_required: boolean;
42
+ };
43
+ proof: {
44
+ receipt_required: boolean;
45
+ validation_required: boolean;
46
+ closeout_requires_receipt: boolean;
47
+ };
48
+ audit: {
49
+ event_log_required: boolean;
50
+ dissent_capture_required: boolean;
51
+ };
52
+ authority_status: 'policy_preset_only';
53
+ }
54
+
55
+ export interface WorkflowCheckEnvelope {
56
+ task_ref: string;
57
+ workflow_mode_ref: string;
58
+ requested_mode_type: WorkflowModeType;
59
+ mutates_state: boolean;
60
+ grant_ref: string | null;
61
+ consensus_ref: string | null;
62
+ receipt_ref: string | null;
63
+ validation_refs: string[];
64
+ bounded: boolean;
65
+ preauthorized: boolean;
66
+ advisory_consensus_claims_authority: boolean;
67
+ risk: WorkflowRiskLevel;
68
+ }
69
+
70
+ export interface WorkflowCheckResult {
71
+ schema: 'workflow-check-receipt.v0';
72
+ task_ref: string;
73
+ mode_id: string;
74
+ mode_type: WorkflowModeType;
75
+ recommendation: WorkflowRecommendation;
76
+ missing: string[];
77
+ warnings: string[];
78
+ checks: Array<{
79
+ check_id: string;
80
+ status: WorkflowRecommendation;
81
+ summary: string;
82
+ }>;
83
+ authority_boundary: {
84
+ can_authorize: false;
85
+ can_attach_grant: false;
86
+ consensus_can_authorize: false;
87
+ mode_is_engine: false;
88
+ requires_grant: boolean;
89
+ };
90
+ }