borgmcp-shared 0.12.0 → 0.12.3

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.
@@ -209,6 +209,11 @@ export interface ConformanceAdmin {
209
209
  readonly isMandatory?: boolean;
210
210
  }): Promise<ConformanceRole>;
211
211
  referenceRoleFromTaxonomy(cube: ConformanceCube, role: ConformanceRole): Promise<void>;
212
+ configureMessageClassRouting(
213
+ cube: ConformanceCube,
214
+ className: string,
215
+ recipientDroneIds: readonly string[],
216
+ ): Promise<void>;
212
217
  createDrone(
213
218
  principal: ConformancePrincipal,
214
219
  cube: ConformanceCube,
@@ -1457,6 +1462,8 @@ export async function runAdapterConformance(
1457
1462
  });
1458
1463
  const firstRecipient = await environment.admin.createDrone(principal, cube, role);
1459
1464
  const secondRecipient = await environment.admin.createDrone(principal, cube, role);
1465
+ await environment.admin.configureMessageClassRouting(cube, 'conformance-review', [firstRecipient.id]);
1466
+ await environment.admin.configureMessageClassRouting(cube, 'conformance-security', [firstRecipient.id]);
1460
1467
  const postId = '00000000-0000-4000-8000-000000000313';
1461
1468
  const initialPayload = {
1462
1469
  post_id: postId,
@@ -1475,12 +1482,32 @@ export async function runAdapterConformance(
1475
1482
  const firstResult = decodeAppendLogResultEnvelope(first.body).payload;
1476
1483
  invariant(!firstResult.deduplicated, 'Initial append was reported as deduplicated.');
1477
1484
  for (const [index, vector] of APPEND_LOG_IDEMPOTENCY_CONFORMANCE.entries()) {
1478
- const payload = {
1485
+ const classRouting = vector.mutation === 'resolved_class_routing';
1486
+ const vectorPostId = classRouting
1487
+ ? '00000000-0000-4000-8000-000000000314'
1488
+ : postId;
1489
+ if (classRouting) {
1490
+ const baseline = await environment.operations.append(
1491
+ credential,
1492
+ cube,
1493
+ createProtocolEnvelope('append-idempotency-class-baseline', {
1494
+ post_id: vectorPostId,
1495
+ message: 'once',
1496
+ class: 'conformance-review',
1497
+ }),
1498
+ );
1499
+ expectStatus(baseline, 201, 'Resolved class-routing baseline');
1500
+ }
1501
+ const payload = classRouting ? {
1502
+ post_id: vectorPostId,
1503
+ message: 'once',
1504
+ class: 'conformance-security',
1505
+ } : {
1479
1506
  ...initialPayload,
1480
1507
  ...(vector.mutation === 'message' ? { message: 'changed' } : {}),
1481
1508
  ...(vector.mutation === 'visibility' ? { visibility: 'broadcast' as const } : {}),
1482
1509
  ...(vector.mutation === 'recipient_set' ? { recipientDroneIds: [secondRecipient.id] } : {}),
1483
- ...(vector.mutation === 'resolved_class_routing' ? { class: 'security', to: ['Security Auditor'] } : {}),
1510
+ ...(vector.mutation === 'ignored_request_shape' ? { class: 'security', to: ['Security Auditor'] } : {}),
1484
1511
  };
1485
1512
  const response = await environment.operations.append(
1486
1513
  vector.actor === 'same' ? credential : otherCredential,
@@ -1508,10 +1535,10 @@ export async function runAdapterConformance(
1508
1535
  );
1509
1536
  expectStatus(read, 200, 'Idempotent append read');
1510
1537
  invariant(
1511
- decodeReadLogResultEnvelope(read.body).payload.entries.length === 2,
1538
+ decodeReadLogResultEnvelope(read.body).payload.entries.length === 3,
1512
1539
  'Append collision controls persisted the wrong number of entries.',
1513
1540
  );
1514
- return { persisted_entries: 2, stable_entry: true, deduplicated: true, conflicts: 4, cross_author_created: true };
1541
+ return { persisted_entries: 3, stable_entry: true, deduplicated: true, conflicts: 4, cross_author_created: true };
1515
1542
  });
1516
1543
 
1517
1544
  const entries: Array<{ id: string; created_at: string; message: string }> = [];
@@ -108,7 +108,7 @@ export interface AppendLogRequestConformanceVector {
108
108
  export interface AppendLogIdempotencyConformanceVector {
109
109
  name: string;
110
110
  actor: 'same' | 'different';
111
- mutation: 'none' | 'message' | 'visibility' | 'recipient_set' | 'resolved_class_routing';
111
+ mutation: 'none' | 'message' | 'visibility' | 'recipient_set' | 'ignored_request_shape' | 'resolved_class_routing';
112
112
  expected: 'deduplicated' | 'POST_ID_CONFLICT' | 'created';
113
113
  }
114
114
 
@@ -118,6 +118,7 @@ export const APPEND_LOG_IDEMPOTENCY_CONFORMANCE: readonly AppendLogIdempotencyCo
118
118
  { name: 'rejects a same-author message collision', actor: 'same', mutation: 'message', expected: 'POST_ID_CONFLICT' },
119
119
  { name: 'rejects a same-author visibility collision', actor: 'same', mutation: 'visibility', expected: 'POST_ID_CONFLICT' },
120
120
  { name: 'rejects a same-author recipient-set collision', actor: 'same', mutation: 'recipient_set', expected: 'POST_ID_CONFLICT' },
121
+ { name: 'deduplicates ignored class selectors with identical resolved delivery', actor: 'same', mutation: 'ignored_request_shape', expected: 'deduplicated' },
121
122
  { name: 'rejects a same-author resolved class-routing collision', actor: 'same', mutation: 'resolved_class_routing', expected: 'POST_ID_CONFLICT' },
122
123
  { name: 'creates an independent cross-author post', actor: 'different', mutation: 'none', expected: 'created' },
123
124
  ];
@@ -13,7 +13,7 @@ import type {
13
13
  } from './types.js';
14
14
 
15
15
  export const SHARED_PACKAGE_NAME = 'borgmcp-shared' as const;
16
- export const SHARED_PACKAGE_VERSION = '0.12.0' as const;
16
+ export const SHARED_PACKAGE_VERSION = '0.12.3' as const;
17
17
  /** Maximum UTF-8 payload for each newly recorded decision text field. */
18
18
  export const DECISION_TEXT_MAX_BYTES = 512 as const;
19
19
  /** Maximum UTF-8 size of role detailed-description text and any returned section slice. */
package/src/templates.ts CHANGED
@@ -103,7 +103,8 @@ Integration and release:
103
103
  - Review approval does not itself authorize merge, deployment, publication, tagging, or release.
104
104
  - Perform those actions only when the user request or a standing delegation explicitly includes them.
105
105
  - Use the repository's protected workflow and bind every gate to the exact revision being integrated.
106
- - Never substitute, move, overwrite, or rerun an immutable release artifact without explicit recovery authority.`;
106
+ - A release tag starts the tag-restricted staging workflow automatically; npm stage approval is the sole human publication boundary.
107
+ - Before npm accepts a stage, correct a failed workflow and retry the same immutable tag. Never move, replace, or force-update the tag.`;
107
108
 
108
109
  export const GIT_OPERATIONAL_DISCIPLINE_BUILDER = `
109
110
 
@@ -200,7 +201,7 @@ const SOFTWARE_DEV_DIRECTIVE = `## Scope and coordination
200
201
  - When an outcome includes a separately published external surface, the Coordinator names one owning role or seat for its implementation. Other seats report findings or perform routed review; they do not mutate that surface.
201
202
  - Waiting is valid when no authorized action is available.
202
203
  - Merge, deploy, publish, tag, release, credential, and live-operator actions require explicit authority.
203
- - Keep cube-log signals concise. Put durable reasoning in the relevant issue, change, or existing maintained documentation only when it has an operational consumer.${SAME_REPOSITORY_WORKFLOW_DISCIPLINE}`;
204
+ - Keep cube-log signals concise. Put durable reasoning in the relevant issue, change, or existing maintained documentation only when it has an operational consumer.${SAME_REPOSITORY_WORKFLOW_DISCIPLINE}${RELEASE_CYCLE_SHAPES}`;
204
205
 
205
206
  const SOFTWARE_DEV_TAXONOMY: MessageTaxonomy = [
206
207
  {
@@ -308,6 +309,8 @@ Review:
308
309
  - Classify findings as in-scope blocker, touched-surface safety blocker, or out-of-scope finding.
309
310
  - Drop an observation when it changes no decision; do not create work merely to preserve it.
310
311
  - Reviewers provide evidence; they do not redefine the work unit. Route one due gate at a time, proportionate to the changed surface. Never pre-route a later gate.
312
+ - Require one proof per property. Mechanical, version, lock, and generated changes require exact-revision CI plus one Code Review only.
313
+ - Give a successor revision delta review. Carry unchanged green evidence without rerunning it.
311
314
  - Bind every verdict to the exact revision. Before claiming gate completion, reread the source log and verify every required verdict.
312
315
  - After two blocked rounds, stop and ask the human for the smallest next choice.
313
316
 
@@ -340,10 +343,11 @@ Implementation discipline:
340
343
  - Mark a deliberate corner-cut with a comment naming the known ceiling and the upgrade path.
341
344
 
342
345
  While working:
343
- - Post STARTING with the branch and first concrete action, then substantive PROGRESS during active work.
346
+ - Post STARTING with the branch and first concrete action. Omit PROGRESS for work expected to finish within 10 minutes; otherwise post only substantive PROGRESS during active work.
344
347
  - Do not add cleanup, broad refactors, speculative hardening, documentation programs, or follow-up issues unless assigned.
345
348
  - A discovered issue outside the slice is a finding, not permission to fix it.
346
- - Add proportionate tests for behavior you change. Run the repository checks required by the touched surface.
349
+ - Add proportionate tests for behavior you change. Run focused verification required by the touched surface, and do not rerun green CI checks merely to duplicate exact-revision evidence.
350
+ - Check documentation or a separately published site only when the changed behavior, public API, package metadata, or named user claim belongs to that surface.
347
351
 
348
352
  Handoff:
349
353
  - Verify the final diff contains only the authorized slice.