@etiquekit/etq 1.0.14 → 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.
Files changed (143) hide show
  1. package/AGENTS.md +26 -19
  2. package/LICENSE +3 -2
  3. package/NOTICE +4 -6
  4. package/QuickStart.md +46 -35
  5. package/README.md +56 -56
  6. package/bin/etiquette +5 -1
  7. package/bin/etiquette-core +5 -1
  8. package/docs/ARCHITECTURE.md +17 -20
  9. package/docs/CONCEPTS.md +5 -5
  10. package/docs/CORE_PROFILE.md +15 -7
  11. package/docs/LANE_PROVISIONING.md +2 -7
  12. package/docs/README.md +14 -13
  13. package/docs/RELEASE_SURFACE_AUDIT.md +7 -8
  14. package/docs/SEAT_DISCIPLINE.md +91 -55
  15. package/docs/SEAT_PROVISIONING.md +19 -16
  16. package/docs/TEAM_HANDOFF.md +21 -21
  17. package/docs/WORKTREE_QOL.md +0 -7
  18. package/docs/contracts/ledger-entry/README.md +11 -11
  19. package/docs/contracts/ledger-entry/ledger-entry.v0.2.md +2 -2
  20. package/docs/contracts/ledger-entry/ledger-entry.v0.md +8 -8
  21. package/lib/etiquette-core.js +313 -0
  22. package/lib/etiquette.js +1151 -0
  23. package/package.json +11 -10
  24. package/templates/etiquette-vanilla-v0/README.md +3 -2
  25. package/templates/etiquette-vanilla-v0/source/control-seat/README.md +6 -0
  26. package/templates/etiquette-vanilla-v0/source/control-seat/bin/access-assurance-check +55 -0
  27. package/templates/etiquette-vanilla-v0/source/control-seat/bin/seat-doctor +5 -0
  28. package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/ACCESS-ASSURANCE.md +39 -0
  29. package/templates/etiquette-vanilla-v0/source/control-seat/docs/work/access/workspace-secure-profile.v0.json +53 -0
  30. package/templates/etiquette-vanilla-v0/validate-vanilla.sh +5 -0
  31. package/templates/hosted-receiver/README.md +41 -0
  32. package/templates/hosted-receiver/w1-github-webhook-receiver.mjs +129 -0
  33. package/templates/seat-packs-v0/README.md +2 -3
  34. package/templates/seat-packs-v0/source/claude-code-seat/README.md +3 -3
  35. package/templates/seat-packs-v0/source/codex-seat/README.md +3 -3
  36. package/templates/seat-packs-v0/source/gemini-seat/README.md +3 -3
  37. package/templates/seat-packs-v0/source/ollama-seat/README.md +3 -3
  38. package/templates/seat-packs-v0/source/openrouter-seat/README.md +3 -3
  39. package/docs/CONCEPT_STATUS.md +0 -66
  40. package/packages/control/src/authority/lease.ts +0 -261
  41. package/packages/control/src/authority/node-delegation.ts +0 -257
  42. package/packages/control/src/authority/rig-conductor.ts +0 -632
  43. package/packages/control/src/cli/argv.ts +0 -155
  44. package/packages/control/src/cli/commands/console.ts +0 -200
  45. package/packages/control/src/cli/commands/dispatch-core.ts +0 -89
  46. package/packages/control/src/cli/commands/dispatch.ts +0 -279
  47. package/packages/control/src/cli/commands/harness.ts +0 -89
  48. package/packages/control/src/cli/commands/hook.ts +0 -50
  49. package/packages/control/src/cli/commands/ledger.ts +0 -91
  50. package/packages/control/src/cli/commands/local-workflow.ts +0 -4690
  51. package/packages/control/src/cli/commands/memory.ts +0 -445
  52. package/packages/control/src/cli/commands/release.ts +0 -108
  53. package/packages/control/src/cli/commands/rubric.ts +0 -103
  54. package/packages/control/src/cli/commands/seat.ts +0 -179
  55. package/packages/control/src/cli/commands/session.ts +0 -127
  56. package/packages/control/src/cli/commands/supervision.ts +0 -246
  57. package/packages/control/src/cli/commands/sync.ts +0 -119
  58. package/packages/control/src/cli/commands/workflow.ts +0 -86
  59. package/packages/control/src/cli/commands/workspace.ts +0 -50
  60. package/packages/control/src/cli/core-usage.ts +0 -34
  61. package/packages/control/src/cli/prompt.ts +0 -67
  62. package/packages/control/src/cli/supervision-deps.ts +0 -44
  63. package/packages/control/src/cli/usage.ts +0 -241
  64. package/packages/control/src/cli.ts +0 -207
  65. package/packages/control/src/core-cli.ts +0 -50
  66. package/packages/control/src/dispatch/decision.ts +0 -202
  67. package/packages/control/src/dispatch/projection.ts +0 -293
  68. package/packages/control/src/dispatch/record.ts +0 -153
  69. package/packages/control/src/engagement/project.ts +0 -170
  70. package/packages/control/src/fs.ts +0 -19
  71. package/packages/control/src/harness/pruning.ts +0 -406
  72. package/packages/control/src/hooks/dispatcher.ts +0 -117
  73. package/packages/control/src/hooks/outbox.ts +0 -86
  74. package/packages/control/src/hooks/sanitize.ts +0 -6
  75. package/packages/control/src/hooks/types.ts +0 -34
  76. package/packages/control/src/index.ts +0 -384
  77. package/packages/control/src/ledger/entry.ts +0 -303
  78. package/packages/control/src/ledger/indexer.ts +0 -542
  79. package/packages/control/src/memory/context.ts +0 -149
  80. package/packages/control/src/memory/drain-import.ts +0 -207
  81. package/packages/control/src/memory/indexer.ts +0 -284
  82. package/packages/control/src/memory/query.ts +0 -75
  83. package/packages/control/src/memory/sanitize.ts +0 -50
  84. package/packages/control/src/memory/sharded-drain-import.ts +0 -212
  85. package/packages/control/src/memory/status.ts +0 -211
  86. package/packages/control/src/memory/store-lifecycle.ts +0 -509
  87. package/packages/control/src/memory/store.ts +0 -284
  88. package/packages/control/src/memory/types.ts +0 -146
  89. package/packages/control/src/parity/surfaces.ts +0 -748
  90. package/packages/control/src/project.ts +0 -141
  91. package/packages/control/src/projection/local-ledger-view.ts +0 -373
  92. package/packages/control/src/projection/return-enforcement.ts +0 -48
  93. package/packages/control/src/projection/timeline-preview.ts +0 -539
  94. package/packages/control/src/projection/timeline.ts +0 -708
  95. package/packages/control/src/release/readiness.ts +0 -842
  96. package/packages/control/src/rubric/loader.ts +0 -326
  97. package/packages/control/src/rubric/promotion.ts +0 -54
  98. package/packages/control/src/rubric/runner.ts +0 -159
  99. package/packages/control/src/rubric/types.ts +0 -158
  100. package/packages/control/src/seat/owner-card.ts +0 -388
  101. package/packages/control/src/seat/readiness.ts +0 -834
  102. package/packages/control/src/session/runbook.ts +0 -431
  103. package/packages/control/src/shared/sanitize.ts +0 -49
  104. package/packages/control/src/supervision/action-classes.ts +0 -192
  105. package/packages/control/src/supervision/command-apply.ts +0 -378
  106. package/packages/control/src/supervision/errors.ts +0 -14
  107. package/packages/control/src/supervision/event-replay.ts +0 -155
  108. package/packages/control/src/supervision/events.ts +0 -109
  109. package/packages/control/src/supervision/index.ts +0 -16
  110. package/packages/control/src/supervision/manifest.ts +0 -127
  111. package/packages/control/src/supervision/paths.ts +0 -49
  112. package/packages/control/src/supervision/projection-adapter.ts +0 -274
  113. package/packages/control/src/supervision/projection.ts +0 -75
  114. package/packages/control/src/supervision/rebuild.ts +0 -99
  115. package/packages/control/src/supervision/session-open.ts +0 -131
  116. package/packages/control/src/supervision/session-read.ts +0 -99
  117. package/packages/control/src/supervision/sqlite-impl.ts +0 -71
  118. package/packages/control/src/supervision/sqlite.ts +0 -121
  119. package/packages/control/src/supervision/store-rows.ts +0 -371
  120. package/packages/control/src/supervision/turn-close.ts +0 -154
  121. package/packages/control/src/supervision/turn-open.ts +0 -284
  122. package/packages/control/src/sync/event-log-merge-driver.ts +0 -263
  123. package/packages/control/src/sync/join-plan.ts +0 -375
  124. package/packages/control/src/sync/outbox.ts +0 -492
  125. package/packages/control/src/workflow/evaluator.ts +0 -140
  126. package/packages/control/src/workflow/loader.ts +0 -200
  127. package/packages/control/src/workflow/types.ts +0 -90
  128. package/packages/control/src/workspace/authority.ts +0 -499
  129. package/packages/protocol/src/guards.ts +0 -119
  130. package/packages/protocol/src/huddle-board.ts +0 -198
  131. package/packages/protocol/src/huddle.ts +0 -295
  132. package/packages/protocol/src/incident.ts +0 -251
  133. package/packages/protocol/src/index.ts +0 -8
  134. package/packages/protocol/src/interfaces.ts +0 -107
  135. package/packages/protocol/src/packet-profile.ts +0 -195
  136. package/packages/protocol/src/state.ts +0 -81
  137. package/packages/protocol/src/types.ts +0 -434
  138. package/release/lineage.v0.json +0 -15
  139. package/scripts/release-candidate-verify.sh +0 -175
  140. package/scripts/release-checksum.sh +0 -25
  141. package/scripts/release-pack-canary.sh +0 -97
  142. package/scripts/release-scan.sh +0 -249
  143. package/scripts/release-sign.sh +0 -34
@@ -1,434 +0,0 @@
1
- export const SLICE_STATES = [
2
- 'draft',
3
- 'planned',
4
- 'split',
5
- 'assigned',
6
- 'in_progress',
7
- 'integration',
8
- 'validated',
9
- 'closed',
10
- ] as const;
11
-
12
- export const TASK_STATES = [
13
- 'incoming',
14
- 'claimed',
15
- 'in_progress',
16
- 'evidence_ready',
17
- 'accepted',
18
- 'countered',
19
- 'blocked',
20
- 'resolved',
21
- ] as const;
22
-
23
- export const PACKET_STATES = ['PROPOSED', 'ACCEPTED', 'LOCKED', 'PROVISIONED'] as const;
24
- export const SCRUTINY_STATES = ['OPEN', 'IN_PROGRESS', 'BLOCKED', 'DEFERRED', 'RESOLVED', 'VERIFIED', 'WONT_FIX'] as const;
25
- export const SCRUTINY_KINDS = ['issue', 'feature', 'feature_set', 'readiness_gate', 'dependency', 'risk', 'research', 'decision', 'migration', 'cleanup'] as const;
26
- export const CORE_SURFACES = ['backend', 'bff', 'android', 'ios', 'integration'] as const;
27
- export const ACTOR_KINDS = ['owner', 'worker', 'secretary', 'integrator', 'reviewer'] as const;
28
-
29
- export type SliceState = (typeof SLICE_STATES)[number];
30
- export type TaskState = (typeof TASK_STATES)[number];
31
- export type PacketState = (typeof PACKET_STATES)[number];
32
- export type ScrutinyState = (typeof SCRUTINY_STATES)[number];
33
- export type ScrutinyKind = (typeof SCRUTINY_KINDS)[number];
34
- export type CoreSurface = (typeof CORE_SURFACES)[number];
35
- export type Surface = string;
36
- export type ActorKind = (typeof ACTOR_KINDS)[number];
37
-
38
- export interface Actor {
39
- actorId: string;
40
- kind: ActorKind;
41
- displayName: string;
42
- }
43
-
44
- export interface Dependency {
45
- taskId: string;
46
- kind: 'blocked-by' | 'depends-on';
47
- }
48
-
49
- export interface StateTransition {
50
- state: string;
51
- actorId: string;
52
- at: string;
53
- note?: string;
54
- }
55
-
56
- export interface EvidenceItem {
57
- kind: 'report' | 'receipt' | 'sample' | 'artifact' | 'note';
58
- path: string;
59
- summary: string;
60
- }
61
-
62
- export interface EvidenceBundle {
63
- bundleId: string;
64
- taskId: string;
65
- status: 'pending' | 'ready' | 'accepted';
66
- items: EvidenceItem[];
67
- }
68
-
69
- export interface Verdict {
70
- verdictId: string;
71
- sliceId: string;
72
- taskId?: string;
73
- outcome: 'accepted' | 'countered' | 'blocked' | 'completed';
74
- by: string;
75
- at: string;
76
- note?: string;
77
- }
78
-
79
- export interface WorkBounds {
80
- repoRoots: string[];
81
- ownedPaths: string[];
82
- forbiddenPaths: string[];
83
- checks: string[];
84
- evidenceFiles: string[];
85
- }
86
-
87
- export interface SliceTask {
88
- taskId: string;
89
- surface: Surface;
90
- title: string;
91
- summary: string;
92
- scrutinyId: string;
93
- state: TaskState;
94
- packetId?: string;
95
- worktreePath?: string;
96
- branchName?: string;
97
- owner?: string;
98
- workerRole?: string;
99
- bounds: WorkBounds;
100
- dependencies: Dependency[];
101
- transitions: StateTransition[];
102
- }
103
-
104
- export interface Slice {
105
- schemaVersion: 'discipline-slice.v1';
106
- sliceId: string;
107
- projectId: string;
108
- title: string;
109
- objective: string;
110
- scrutinyId: string;
111
- state: SliceState;
112
- repoRoots: string[];
113
- handshakeStorePath: string;
114
- tasks: SliceTask[];
115
- transitions: StateTransition[];
116
- createdAt: string;
117
- updatedAt: string;
118
- }
119
-
120
- export interface SurfaceDefaults {
121
- owner: string;
122
- workerRole: string;
123
- repoRoots: string[];
124
- ownedPaths: string[];
125
- forbiddenPaths: string[];
126
- checks: string[];
127
- evidenceFiles: string[];
128
- worktreeTemplate: string;
129
- }
130
-
131
- export interface SliceTaskBlueprint {
132
- title: string;
133
- summary: string;
134
- repoRoots?: string[];
135
- ownedPaths?: string[];
136
- forbiddenPaths?: string[];
137
- checks?: string[];
138
- evidenceFiles?: string[];
139
- worktreePath?: string;
140
- workerRole?: string;
141
- owner?: string;
142
- dependencies?: Dependency[];
143
- }
144
-
145
- export interface SliceBlueprint {
146
- title: string;
147
- objective: string;
148
- scrutinyId: string;
149
- repoRoots?: string[];
150
- tasks: Record<string, SliceTaskBlueprint>;
151
- }
152
-
153
- export type WorkerScripts = Record<string, string>;
154
-
155
- export interface ProjectManifest {
156
- schemaVersion: 'discipline-project.v1';
157
- projectId: string;
158
- title: string;
159
- projectRoot: string;
160
- handshakeStorePath: string;
161
- logixRepoRoot?: string;
162
- scrutinyWorkflowPath: string;
163
- defaultWorktreeRoot: string;
164
- workerScripts: WorkerScripts;
165
- surfaces: Record<string, SurfaceDefaults>;
166
- slices: Record<string, SliceBlueprint>;
167
- }
168
-
169
- export interface TaskPacketSpec {
170
- packetId: string;
171
- sliceId: string;
172
- task: SliceTask;
173
- project: ProjectManifest;
174
- }
175
-
176
- export interface TaskLedgerRecord {
177
- task_id: string;
178
- status: 'incoming' | 'pending' | 'resolved';
179
- source: string;
180
- packet_id: string;
181
- action: string;
182
- actor: string;
183
- created_at: string;
184
- ingested_at: string;
185
- claimed_by: string | null;
186
- claimed_at: string | null;
187
- resolved_by: string | null;
188
- resolved_at: string | null;
189
- resolution_note: string | null;
190
- summary: string;
191
- chat_text: string;
192
- }
193
-
194
- export interface SliceStatusSnapshot {
195
- sliceId: string;
196
- sliceState: SliceState;
197
- scrutinyState: ScrutinyState;
198
- packetStates: Record<PacketState, number>;
199
- taskStates: Record<TaskState, number>;
200
- unresolvedTasks: string[];
201
- readyToClose: boolean;
202
- blockers: string[];
203
- }
204
-
205
- export interface SecretaryAction {
206
- level: 'info' | 'action' | 'blocked';
207
- taskId?: string;
208
- surface?: string;
209
- summary: string;
210
- }
211
-
212
- export interface SecretarySummary {
213
- sliceId: string;
214
- actions: SecretaryAction[];
215
- }
216
-
217
- // ============================================================================
218
- // Supervision (Phase 1)
219
- // Authority: etiquette/internal/docs/supervision/PHASE1.md
220
- // Doctrine: llm-substrate/governance/shared-live-supervision.md
221
- // ============================================================================
222
-
223
- export const SESSION_STATUSES = [
224
- 'running',
225
- 'paused',
226
- 'blocked',
227
- 'awaiting_human',
228
- 'closed',
229
- ] as const;
230
- export type SessionStatus = (typeof SESSION_STATUSES)[number];
231
-
232
- export const TURN_STATUSES = ['open', 'closed'] as const;
233
- export type TurnStatus = (typeof TURN_STATUSES)[number];
234
-
235
- export const TURN_RESULTS = [
236
- 'done',
237
- 'blocked',
238
- 'handed_off',
239
- 'stopped',
240
- 'timed_out',
241
- ] as const;
242
- export type TurnResult = (typeof TURN_RESULTS)[number];
243
-
244
- export const SUPERVISION_COMMANDS = [
245
- 'status',
246
- 'pause',
247
- 'resume',
248
- 'stop',
249
- 'approve_next_turn',
250
- 'redirect_owner',
251
- 'request_summary',
252
- 'mark_blocked',
253
- 'escalate_to_human',
254
- ] as const;
255
- export type SupervisionCommand = (typeof SUPERVISION_COMMANDS)[number];
256
-
257
- export const COMMAND_STATUSES = [
258
- 'queued',
259
- 'applied',
260
- 'rejected',
261
- 'expired',
262
- ] as const;
263
- export type CommandStatus = (typeof COMMAND_STATUSES)[number];
264
-
265
- export const ACTION_CLASSES = [
266
- 'coordination_only',
267
- 'read_only_local',
268
- 'bounded_verification',
269
- 'bounded_product_mutation',
270
- 'human_only',
271
- ] as const;
272
- export type ActionClass = (typeof ACTION_CLASSES)[number];
273
-
274
- export const ALLOWED_COMMAND_IDS = [
275
- 'inspect_repo',
276
- 'run_verify',
277
- 'write_projection',
278
- 'append_evidence',
279
- 'write_product_files',
280
- 'launch_runtime_target',
281
- ] as const;
282
- export type AllowedCommandId = (typeof ALLOWED_COMMAND_IDS)[number];
283
-
284
- export const PROJECTION_POLICIES = [
285
- 'on_state_change',
286
- 'on_command_only',
287
- ] as const;
288
- export type ProjectionPolicy = (typeof PROJECTION_POLICIES)[number];
289
-
290
- export const SUPERVISION_EVENT_TYPES = [
291
- 'session.opened',
292
- 'session.status_changed',
293
- 'session.next_owner_changed',
294
- 'turn.opened',
295
- 'turn.closed',
296
- 'command.queued',
297
- 'command.applied',
298
- 'command.rejected',
299
- 'projection.rendered',
300
- 'rebuild.completed',
301
- ] as const;
302
- export type SupervisionEventType = (typeof SUPERVISION_EVENT_TYPES)[number];
303
-
304
- export const RUNTIME_KINDS = [
305
- 'codex',
306
- 'claude-code',
307
- 'human-mobile',
308
- 'human-desktop',
309
- 'other',
310
- ] as const;
311
- export type RuntimeKind = (typeof RUNTIME_KINDS)[number];
312
-
313
- export type SupervisionAudience =
314
- | 'all'
315
- | 'lead'
316
- | 'responder'
317
- | 'escalation_owner'
318
- | `seat:${string}`;
319
-
320
- export interface SupervisionSession {
321
- sessionId: string;
322
- campaignRoot: string;
323
- topic: string;
324
- objective: string;
325
- status: SessionStatus;
326
- leadSeat: string;
327
- responderSeat: string;
328
- escalationOwner: string;
329
- timeCapMinutes: number;
330
- turnCap: number;
331
- currentTurnId: string | null;
332
- nextOwnerHint: string | null;
333
- approvedNextTurnJson: string | null;
334
- lastBlockerJson: string | null;
335
- sourceRefs: string[];
336
- createdAt: string;
337
- updatedAt: string;
338
- }
339
-
340
- export interface SupervisionTurn {
341
- turnId: string;
342
- sessionId: string;
343
- sequenceNo: number;
344
- status: TurnStatus;
345
- ownerSeat: string;
346
- allowedActionClass: ActionClass;
347
- maxDurationMinutes: number;
348
- allowedCommands: AllowedCommandId[];
349
- repoRoots: string[];
350
- ownedPaths: string[];
351
- forbiddenPaths: string[];
352
- verifyCommands: string[];
353
- requiresHumanApproval: boolean;
354
- projectionPolicy: ProjectionPolicy;
355
- startedAt: string;
356
- endedAt: string | null;
357
- result: TurnResult | null;
358
- summary: string | null;
359
- evidenceRefs: string[];
360
- }
361
-
362
- export interface SupervisionCommandRecord {
363
- commandId: string;
364
- sessionId: string;
365
- turnId: string | null;
366
- issuedBy: string;
367
- command: SupervisionCommand;
368
- payloadJson: string;
369
- status: CommandStatus;
370
- issuedAt: string;
371
- appliedAt: string | null;
372
- rejectionReason: string | null;
373
- }
374
-
375
- export interface SupervisionEvent {
376
- eventId: string;
377
- sessionId: string;
378
- turnId: string | null;
379
- commandId: string | null;
380
- eventType: SupervisionEventType;
381
- actor: string;
382
- audience: SupervisionAudience;
383
- at: string;
384
- payload: unknown;
385
- }
386
-
387
- export interface SeatCapabilityManifest {
388
- schemaVersion: 'discipline-supervision-seat-capabilities.v1';
389
- seatId: string;
390
- displayName: string;
391
- runtimeKind: RuntimeKind;
392
- canReadHandshake: boolean;
393
- canWriteHandshake: boolean;
394
- canReadProductRepo: boolean;
395
- canRunBuilds: boolean;
396
- canWriteProductRepo: boolean;
397
- canLaunchRuntimeTargets: boolean;
398
- canAcceptMobileSteering: boolean;
399
- allowedActionClasses: ActionClass[];
400
- defaultRequiresHumanApprovalForProductMutation: boolean;
401
- updatedAt: string;
402
- }
403
-
404
- export interface SupervisionProjection {
405
- sessionId: string;
406
- renderedAt: string;
407
- sessionSnapshot: SupervisionSession;
408
- currentTurn: SupervisionTurn | null;
409
- pendingCommands: SupervisionCommandRecord[];
410
- }
411
-
412
- export interface ApprovedNextTurnPayload {
413
- ownerSeat: string;
414
- allowedActionClass: ActionClass;
415
- maxDurationMinutes: number;
416
- allowedCommands: AllowedCommandId[];
417
- repoRoots: string[];
418
- ownedPaths: string[];
419
- forbiddenPaths: string[];
420
- verifyCommands: string[];
421
- requiresHumanApproval: boolean;
422
- projectionPolicy: ProjectionPolicy;
423
- issuedBy: string;
424
- issuedAt: string;
425
- expiresAt: string | null;
426
- }
427
-
428
- export interface BlockerPayload {
429
- reason: string;
430
- raisedBy: string;
431
- raisedAt: string;
432
- escalationOwner: string;
433
- evidenceRefs: string[];
434
- }
@@ -1,15 +0,0 @@
1
- {
2
- "schema": "etq-release-lineage.v0",
3
- "package_name": "@etiquekit/etq",
4
- "candidate_version": "1.0.14",
5
- "distribution_mode": "bun-typescript-source",
6
- "source_repository": "git+https://github.com/leepickdev/etq-devkit.git",
7
- "distribution_repository": "git+https://github.com/leepickdev/etq.git",
8
- "source_base_commit": "b2384dc782548ce0d712da3bd33e108d977adb44",
9
- "registry_floor": "1.0.13",
10
- "required_bins": [
11
- "etq",
12
- "etiquette",
13
- "etiquette-core"
14
- ]
15
- }
@@ -1,175 +0,0 @@
1
- #!/bin/sh
2
- # Prove the reviewed package tarball from an isolated install. Never publishes.
3
- set -eu
4
-
5
- ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
6
- TMPDIR_ROOT=${TMPDIR:-/tmp}
7
- TMP=$(mktemp -d "$TMPDIR_ROOT/etq-release-candidate.XXXXXX")
8
- trap 'rm -rf "$TMP"' EXIT INT TERM
9
-
10
- LINEAGE="$ROOT/release/lineage.v0.json"
11
- PACKAGE_NAME=$(node -e 'const m=require(process.argv[1]); process.stdout.write(m.package_name)' "$LINEAGE")
12
- VERSION=$(node -e 'const m=require(process.argv[1]); process.stdout.write(m.candidate_version)' "$LINEAGE")
13
-
14
- cd "$ROOT"
15
-
16
- if [ -n "$(git status --porcelain)" ]; then
17
- echo "release-candidate: worktree must be clean" >&2
18
- exit 1
19
- fi
20
-
21
- bun packages/control/src/cli.ts release readiness --project . --fail-on-blocked >/dev/null
22
-
23
- REGISTRY_VERSION=$(npm view "$PACKAGE_NAME" version --json | node -e 'let d=""; process.stdin.on("data",c=>d+=c).on("end",()=>process.stdout.write(JSON.parse(d)))')
24
- node -e '
25
- const parse = value => {
26
- const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(value);
27
- if (!match) throw new Error(`invalid GA version: ${value}`);
28
- return match.slice(1).map(Number);
29
- };
30
- const candidate = parse(process.argv[1]);
31
- const current = parse(process.argv[2]);
32
- for (let i = 0; i < 3; i += 1) {
33
- if (candidate[i] > current[i]) process.exit(0);
34
- if (candidate[i] < current[i]) process.exit(1);
35
- }
36
- process.exit(1);
37
- ' "$VERSION" "$REGISTRY_VERSION" || {
38
- echo "release-candidate: $VERSION is not newer than registry $REGISTRY_VERSION" >&2
39
- exit 1
40
- }
41
-
42
- TAG_MATCH=$(git ls-remote --tags origin "refs/tags/v$VERSION" "refs/tags/v$VERSION^{}")
43
- if [ -n "$TAG_MATCH" ]; then
44
- echo "release-candidate: remote tag v$VERSION already exists" >&2
45
- exit 1
46
- fi
47
-
48
- PACK_DIR="$TMP/pack"
49
- PREFIX="$TMP/prefix"
50
- SCRATCH="$TMP/scratch"
51
- mkdir -p "$PACK_DIR" "$PREFIX" "$SCRATCH"
52
-
53
- npm pack --pack-destination "$PACK_DIR" >/dev/null
54
- TGZ=$(find "$PACK_DIR" -maxdepth 1 -name '*.tgz' -type f -print | sort | sed -n '1p')
55
- if [ -z "$TGZ" ]; then
56
- echo "release-candidate: npm pack produced no tarball" >&2
57
- exit 1
58
- fi
59
-
60
- tar -tzf "$TGZ" > "$TMP/files.txt"
61
- grep -Fxq 'package/release/lineage.v0.json' "$TMP/files.txt"
62
- grep -Fxq 'package/packages/control/src/cli.ts' "$TMP/files.txt"
63
- grep -Fxq 'package/packages/protocol/src/index.ts' "$TMP/files.txt"
64
- if grep -Eq '^package/lib/' "$TMP/files.txt"; then
65
- echo "release-candidate: compiled lib output contradicts source-shipping mode" >&2
66
- exit 1
67
- fi
68
-
69
- tar -xzOf "$TGZ" package/package.json | node -e '
70
- let d="";
71
- process.stdin.on("data", c => d += c).on("end", () => {
72
- const p = JSON.parse(d);
73
- const expectedName = process.argv[1];
74
- const expectedVersion = process.argv[2];
75
- if (p.name !== expectedName || p.version !== expectedVersion) process.exit(1);
76
- for (const name of ["etq", "etiquette", "etiquette-core"]) {
77
- if (!p.bin || typeof p.bin[name] !== "string") process.exit(1);
78
- }
79
- if (p.prepack || (p.scripts && (p.scripts.prepack || p.scripts["release:build"]))) process.exit(1);
80
- });
81
- ' "$PACKAGE_NAME" "$VERSION"
82
-
83
- npm install --prefix "$PREFIX" --ignore-scripts --no-audit --no-fund "$TGZ" >/dev/null
84
- ETQ_BIN="$PREFIX/node_modules/.bin/etq"
85
- ETIQUETTE_BIN="$PREFIX/node_modules/.bin/etiquette"
86
- CORE_BIN="$PREFIX/node_modules/.bin/etiquette-core"
87
- for binary in "$ETQ_BIN" "$ETIQUETTE_BIN" "$CORE_BIN"; do
88
- if [ ! -x "$binary" ]; then
89
- echo "release-candidate: installed binary missing: $binary" >&2
90
- exit 1
91
- fi
92
- done
93
-
94
- REAL_ETQ=$(node -e 'process.stdout.write(require("fs").realpathSync(process.argv[1]))' "$ETQ_BIN")
95
- REAL_PREFIX=$(node -e 'process.stdout.write(require("fs").realpathSync(process.argv[1]))' "$PREFIX")
96
- case "$REAL_ETQ" in
97
- "$REAL_PREFIX"/*) ;;
98
- *) echo "release-candidate: etq resolved outside isolated prefix" >&2; exit 1 ;;
99
- esac
100
-
101
- EXPECTED="etiquette $VERSION ($PACKAGE_NAME)"
102
- [ "$($ETQ_BIN --version)" = "$EXPECTED" ]
103
- [ "$($ETIQUETTE_BIN version)" = "$EXPECTED" ]
104
-
105
- PROFILE="$SCRATCH/profile.yaml"
106
- DRAFT="$SCRATCH/candidate-review.md"
107
- cat > "$PROFILE" <<'YAML'
108
- schema: packet-profile.v0
109
- format: markdown-frontmatter
110
- filename:
111
- pattern: "{{created_at}}-{{kind}}"
112
- extension: .md
113
- frontmatter:
114
- fields:
115
- - key: kind
116
- required: true
117
- - key: work_id
118
- required: true
119
- - key: author
120
- required: true
121
- - key: recipient
122
- required: true
123
- - key: created_at
124
- required: true
125
- - key: changes_state
126
- default: false
127
- title:
128
- derive: "{{work_id}} {{kind}}"
129
- sections:
130
- - key: summary
131
- heading: Summary
132
- required: true
133
- - key: evidence
134
- heading: Evidence
135
- required: true
136
- - key: next_step
137
- heading: Next Step
138
- required: true
139
- YAML
140
-
141
- (cd "$SCRATCH" && "$ETQ_BIN" post \
142
- --profile "$PROFILE" \
143
- --draft \
144
- --out "$DRAFT" \
145
- --kind review-return \
146
- --work-id RELEASE-CANDIDATE \
147
- --author candidate-seat \
148
- --recipient review-seat \
149
- --summary 'Candidate package installed from the reviewed tarball.' \
150
- --evidence 'Exact package identity and isolated executable provenance passed.' \
151
- --next-step 'Run the consumer lint bridge.' \
152
- --at '2026-07-13T14:00:00.000Z' >/dev/null)
153
-
154
- [ -f "$DRAFT" ]
155
- [ ! -e "$SCRATCH/.etiquette" ]
156
- grep -Fq 'changes_state: false' "$DRAFT"
157
-
158
- mkdir -p "$ROOT/dist"
159
- TARGET="$ROOT/dist/$(basename "$TGZ")"
160
- cp "$TGZ" "$TARGET"
161
- (cd "$ROOT/dist" && shasum -a 256 "$(basename "$TARGET")" > SHA256SUMS)
162
- rm -f \
163
- "$ROOT/dist/SHA256SUMS.sig" \
164
- "$ROOT/dist/SHA256SUMS.hmac" \
165
- "$ROOT/dist/SIGNATURE_MANIFEST.txt" \
166
- "$ROOT/dist/SIGNATURE_REQUIRED.txt"
167
- SHA256=$(shasum -a 256 "$TARGET" | awk '{print $1}')
168
- printf 'release-candidate: ok\n'
169
- printf 'package: %s@%s\n' "$PACKAGE_NAME" "$VERSION"
170
- printf 'registry_floor_observed: %s\n' "$REGISTRY_VERSION"
171
- printf 'tarball: %s\n' "$TARGET"
172
- printf 'checksums: %s\n' "$ROOT/dist/SHA256SUMS"
173
- printf 'sha256: %s\n' "$SHA256"
174
- printf 'installed_etq: %s\n' "$REAL_ETQ"
175
- printf 'draft: %s\n' "$DRAFT"
@@ -1,25 +0,0 @@
1
- #!/bin/sh
2
- # Create a fresh npm tarball and checksum manifest under ignored dist/.
3
- set -eu
4
-
5
- ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
6
- TMPDIR_ROOT=${TMPDIR:-/tmp}
7
- TMP=$(mktemp -d "$TMPDIR_ROOT/etiquette-release-checksum.XXXXXX")
8
- trap 'rm -rf "$TMP"' EXIT INT TERM
9
-
10
- cd "$ROOT"
11
- sh scripts/release-pack-canary.sh >/dev/null
12
- mkdir -p dist
13
- npm pack --pack-destination "$TMP" >/dev/null
14
-
15
- TGZ=$(find "$TMP" -maxdepth 1 -name '*.tgz' -print | sort | sed -n '1p')
16
- if [ -z "$TGZ" ]; then
17
- echo "release-checksum: npm pack did not produce a tarball" >&2
18
- exit 1
19
- fi
20
-
21
- TARGET="dist/$(basename "$TGZ")"
22
- cp "$TGZ" "$TARGET"
23
- (cd dist && shasum -a 256 "$(basename "$TARGET")" > SHA256SUMS)
24
-
25
- echo "release-checksum: wrote $TARGET and dist/SHA256SUMS"