@authorbot/domain 0.1.31 → 0.1.33

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/CHANGELOG.md CHANGED
@@ -9,6 +9,54 @@ Every published package shares this version. A tag builds, tests, and publishes
9
9
  all of them together, so `@authorbot/cli@0.1.15` and `@authorbot/api@0.1.15` are
10
10
  always the same commit.
11
11
 
12
+ ## 0.1.33
13
+
14
+ - **Collaboration state now stays coherent across the whole site.** Account,
15
+ chapter, annotation, reply, vote, Work, operation, and lease state share one
16
+ lazily loaded browser store. Writes update the page immediately, reconcile
17
+ against authoritative responses and events, and roll back honestly when a
18
+ request fails.
19
+ - **New Work claims can recover without persisting lease secrets.** A client
20
+ that loses an in-memory lease token can rotate it through a new
21
+ credential-bound recovery endpoint. Only the exact browser session or agent
22
+ token that made the claim can recover it, and recovery cannot renew or revive
23
+ an expired lease. Claims already live when a book upgrades have no credential
24
+ binding; release and claim them again before relying on recovery.
25
+ - **Live collaboration uses fewer requests and exposes less state.** Concurrent
26
+ reads are coalesced, event streams restart when authorization changes, and
27
+ anonymous or signed-in nonmember event polling receives only explicitly
28
+ reviewed public event types and payload fields.
29
+ - Background synchronization no longer tears down a sign-in form or editor
30
+ while someone is using it. Optimistic voting, replies, notes, drafts, and
31
+ Work actions retain focus and settle against the same shared state.
32
+ - The collaborator skill documents lost-token recovery and safe retry behavior.
33
+ No book-format migration or D1 database migration is required for this
34
+ release.
35
+
36
+ ## 0.1.32
37
+
38
+ - **Chapter navigation shows the work around each chapter.** Signed-in
39
+ collaborators now see separate, accessible counts for open suggestions,
40
+ block or range comments, whole-chapter comments, replies, and active Work on
41
+ the chapter list, current chapter, previous and next links, and Draft rows.
42
+ The counts come from one indexed database read instead of one request per
43
+ chapter.
44
+ - **Any open note can become Work with one click.** Maintainers can promote
45
+ suggestions and comments at chapter, block, or range scope without entering
46
+ a reason. Accepted cards settle into a compact green state, and Previous and
47
+ Next controls move through a chapter's notes without manual scrolling.
48
+ - **Upgrades repair their own lockfile.** `authorbot upgrade` now aligns the CLI
49
+ and API packages, refreshes `package-lock.json` with scripts disabled, checks
50
+ the resolved versions, and fails before changing the repository if npm cannot
51
+ produce a safe lockfile.
52
+ - The collaboration UI now has its first project-scoped `zustand/vanilla`
53
+ store for shared session and chapter-summary reads. Optimistic mutation and
54
+ event reconciliation remain explicitly staged as the next Phase 11
55
+ increment.
56
+ - This release includes database migration `0009_chapter_activity.sql`, which
57
+ adds indexes for the chapter activity aggregate. No book-format migration is
58
+ required.
59
+
12
60
  ## 0.1.31
13
61
 
14
62
  - **Suggestion cards take you back to the prose they reference.** Clicking a
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ export type { DecisionResult, SupportChangeOutcome, SupportChangeTransition, } f
17
17
  export { PHASE3_WORK_ITEM_STATUSES, WORK_ITEM_STATUSES, WORK_ITEM_TRANSITIONS, canTransitionWorkItem, isPhase3WorkItemStatus, transitionWorkItem, } from "./work-item-state.js";
18
18
  export type { WorkItemStatus, WorkItemTransitionDenialReason, } from "./work-item-state.js";
19
19
  export { FORCE_CREATE_RULE_VERSION, MAX_OVERRIDE_REASON_LENGTH, MIN_OVERRIDE_REASON_LENGTH, authorizeCancelWorkItem, authorizeForceCreateWorkItem, authorizeRejectSuggestion, authorizeReopenSuggestion, cancelWorkItemCommandSchema, forceCreateWorkItemCommandSchema, overrideReasonSchema, rejectSuggestionCommandSchema, reopenSuggestionCommandSchema, } from "./overrides.js";
20
- export type { CancelWorkItemCommand, ForceCreateWorkItemCommand, RejectSuggestionCommand, ReopenSuggestionCommand, SuggestionOverrideDenialReason, WorkItemOverrideDenialReason, } from "./overrides.js";
20
+ export type { AnnotationPromotionDenialReason, CancelWorkItemCommand, ForceCreateWorkItemCommand, RejectSuggestionCommand, ReopenSuggestionCommand, SuggestionOverrideDenialReason, WorkItemOverrideDenialReason, } from "./overrides.js";
21
21
  export { AGENT_TOKEN_PREFIX, AGENT_TOKEN_REGEX, AGENT_TOKEN_SECRET_LENGTH, DEFAULT_TOKEN_TTL_DAYS, LAST_USED_UPDATE_INTERVAL_MS, MAX_TOKEN_TTL_DAYS, SESSION_ID_LENGTH, SESSION_ID_REGEX, SESSION_TTL_DAYS, agentTokenSchema, checkTokenActive, isAgentTokenFormat, isSessionIdFormat, parseAgentToken, resolveSessionExpiry, resolveTokenExpiry, sessionIdSchema, shouldUpdateLastUsed, toTimestamp, } from "./token.js";
22
22
  export type { AgentTokenParseFailure, AgentTokenParseResult, TokenExpiryResult, TokenInactiveReason, } from "./token.js";
23
23
  export { DEFAULT_LEASE_CONFIG, LEASE_DURATION_MS, LEASE_MAX_TOTAL_DURATION_MS, LEASE_RENEWAL_DURATION_MS, LEASE_RENEWAL_PROMPT_BEFORE_MS, checkLeaseActive, checkLeaseRenewable, checkWorkItemClaimable, isLeaseExpired, leaseConfigSchema, parseIsoDuration, renewalPromptAt, resolveLeaseExpiry, shouldExpireLease, } from "./lease.js";
@@ -4,9 +4,10 @@ import { type Decision } from "./decision.js";
4
4
  import type { Role } from "./scopes.js";
5
5
  /**
6
6
  * Maintainer overrides (Phase 3 contract section 4; design section 11.2).
7
- * All four are maintainer-only, require a recorded `reason`, and are recorded
8
- * as decisions with `override_reason`. Force-create bypasses the rule but
9
- * respects the same uniqueness key `(source_annotation_id, action_type,
7
+ * Reject, reopen, and cancel require a recorded `reason`. Phase 11 makes
8
+ * promotion a one-click action for either annotation kind, so force-create
9
+ * accepts a legacy reason but does not require one. It still bypasses the rule
10
+ * and respects the same uniqueness key `(source_annotation_id, action_type,
10
11
  * rule_version)` with `rule_version: 0`.
11
12
  */
12
13
  /** Minimum meaningful override reason length (after trimming). */
@@ -41,10 +42,11 @@ export type ReopenSuggestionCommand = z.infer<typeof reopenSuggestionCommandSche
41
42
  */
42
43
  export declare const forceCreateWorkItemCommandSchema: z.ZodObject<{
43
44
  annotationId: z.ZodString;
44
- reason: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
45
+ reason: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
45
46
  }, z.core.$strict>;
46
47
  export type ForceCreateWorkItemCommand = z.infer<typeof forceCreateWorkItemCommandSchema>;
47
48
  export type SuggestionOverrideDenialReason = "not-maintainer" | "not-a-suggestion" | "illegal-transition";
49
+ export type AnnotationPromotionDenialReason = "not-maintainer" | "illegal-transition";
48
50
  /** Reject an open suggestion (`open -> rejected`). */
49
51
  export declare function authorizeRejectSuggestion(input: {
50
52
  actorRole: Role;
@@ -64,7 +66,7 @@ export declare function authorizeCancelWorkItem(input: {
64
66
  workItemStatus: WorkItemStatus;
65
67
  }): Decision<WorkItemOverrideDenialReason>;
66
68
  /**
67
- * Force-create a work item for an open suggestion, bypassing the rule. The
69
+ * Promote any open annotation to a work item, bypassing the rule. The
68
70
  * annotation must still be able to make the `open -> work_item_created`
69
71
  * transition; uniqueness (one item per annotation/action/rule-version) is the
70
72
  * DB constraint's job.
@@ -73,5 +75,5 @@ export declare function authorizeForceCreateWorkItem(input: {
73
75
  actorRole: Role;
74
76
  annotationKind: AnnotationKind;
75
77
  annotationStatus: AnnotationStatus;
76
- }): Decision<SuggestionOverrideDenialReason>;
78
+ }): Decision<AnnotationPromotionDenialReason>;
77
79
  //# sourceMappingURL=overrides.d.ts.map
package/dist/overrides.js CHANGED
@@ -5,9 +5,10 @@ import { ALLOWED, denied } from "./decision.js";
5
5
  import { transitionWorkItem } from "./work-item-state.js";
6
6
  /**
7
7
  * Maintainer overrides (Phase 3 contract section 4; design section 11.2).
8
- * All four are maintainer-only, require a recorded `reason`, and are recorded
9
- * as decisions with `override_reason`. Force-create bypasses the rule but
10
- * respects the same uniqueness key `(source_annotation_id, action_type,
8
+ * Reject, reopen, and cancel require a recorded `reason`. Phase 11 makes
9
+ * promotion a one-click action for either annotation kind, so force-create
10
+ * accepts a legacy reason but does not require one. It still bypasses the rule
11
+ * and respects the same uniqueness key `(source_annotation_id, action_type,
11
12
  * rule_version)` with `rule_version: 0`.
12
13
  */
13
14
  /** Minimum meaningful override reason length (after trimming). */
@@ -43,7 +44,7 @@ export const reopenSuggestionCommandSchema = z.strictObject({
43
44
  */
44
45
  export const forceCreateWorkItemCommandSchema = z.strictObject({
45
46
  annotationId: uuidv7Schema,
46
- reason: overrideReasonSchema,
47
+ reason: overrideReasonSchema.optional(),
47
48
  });
48
49
  function requireMaintainer(actorRole) {
49
50
  if (actorRole !== "maintainer") {
@@ -91,7 +92,7 @@ export function authorizeCancelWorkItem(input) {
91
92
  return transitionWorkItem(input.workItemStatus, "cancelled");
92
93
  }
93
94
  /**
94
- * Force-create a work item for an open suggestion, bypassing the rule. The
95
+ * Promote any open annotation to a work item, bypassing the rule. The
95
96
  * annotation must still be able to make the `open -> work_item_created`
96
97
  * transition; uniqueness (one item per annotation/action/rule-version) is the
97
98
  * DB constraint's job.
@@ -100,11 +101,8 @@ export function authorizeForceCreateWorkItem(input) {
100
101
  const maintainer = requireMaintainer(input.actorRole);
101
102
  if (!maintainer.allowed)
102
103
  return maintainer;
103
- const suggestion = requireSuggestion(input.annotationKind);
104
- if (!suggestion.allowed)
105
- return suggestion;
106
104
  if (!canTransitionAnnotation(input.annotationStatus, "work_item_created")) {
107
- return denied("illegal-transition", `a suggestion with status "${input.annotationStatus}" cannot receive a work item (only "open")`);
105
+ return denied("illegal-transition", `an annotation with status "${input.annotationStatus}" cannot receive a work item (only "open")`);
108
106
  }
109
107
  return ALLOWED;
110
108
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@authorbot/domain",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Pure domain logic for Authorbot: role/scope authorization, annotation and Git-operation state machines, command validators, and token/session value rules (Phase 2 contract section 3)",
5
5
  "keywords": [
6
6
  "authorbot",
@@ -40,7 +40,7 @@
40
40
  ],
41
41
  "dependencies": {
42
42
  "zod": "^4.0.0",
43
- "@authorbot/schemas": "0.1.31"
43
+ "@authorbot/schemas": "0.1.33"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^22.0.0",