@elevasis/sdk 1.21.0 → 1.22.1

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 (160) hide show
  1. package/dist/cli.cjs +1239 -173
  2. package/dist/index.d.ts +1752 -464
  3. package/dist/index.js +3477 -143
  4. package/dist/node/index.d.ts +1 -0
  5. package/dist/node/index.js +19 -1
  6. package/dist/test-utils/index.d.ts +1188 -127
  7. package/dist/test-utils/index.js +3359 -152
  8. package/dist/worker/index.js +3148 -80
  9. package/package.json +2 -2
  10. package/reference/claude-config/hooks/post-edit-validate.mjs +98 -98
  11. package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +188 -188
  12. package/reference/claude-config/hooks/tool-failure-recovery.mjs +73 -73
  13. package/reference/claude-config/registries/graph-skills.json +4 -4
  14. package/reference/claude-config/registries/knowledge-flags.json +0 -2
  15. package/reference/claude-config/rules/active-change-index.md +80 -80
  16. package/reference/claude-config/rules/agent-start-here.md +277 -277
  17. package/reference/claude-config/rules/deployment.md +57 -57
  18. package/reference/claude-config/rules/error-handling.md +56 -56
  19. package/reference/claude-config/rules/execution.md +40 -40
  20. package/reference/claude-config/rules/frontend.md +4 -4
  21. package/reference/claude-config/rules/observability.md +31 -31
  22. package/reference/claude-config/rules/operations.md +29 -17
  23. package/reference/claude-config/rules/organization-model.md +113 -81
  24. package/reference/claude-config/rules/organization-os.md +115 -113
  25. package/reference/claude-config/rules/package-taxonomy.md +33 -33
  26. package/reference/claude-config/rules/platform.md +42 -42
  27. package/reference/claude-config/rules/shared-types.md +49 -46
  28. package/reference/claude-config/rules/task-tracking.md +47 -47
  29. package/reference/claude-config/rules/ui.md +200 -200
  30. package/reference/claude-config/rules/vibe.md +235 -235
  31. package/reference/claude-config/scripts/statusline-command.js +18 -18
  32. package/reference/claude-config/settings.json +34 -34
  33. package/reference/claude-config/skills/deploy/{SKILL.md → skill.md} +156 -156
  34. package/reference/claude-config/skills/dsp/SKILL.md +66 -66
  35. package/reference/claude-config/skills/elevasis/SKILL.md +235 -235
  36. package/reference/claude-config/skills/explore/SKILL.md +6 -6
  37. package/reference/claude-config/skills/git-sync/SKILL.md +126 -126
  38. package/reference/claude-config/skills/knowledge/SKILL.md +314 -299
  39. package/reference/claude-config/skills/knowledge/operations/codify-level-a.md +100 -100
  40. package/reference/claude-config/skills/knowledge/operations/codify-level-b.md +159 -159
  41. package/reference/claude-config/skills/knowledge/operations/customers.md +109 -109
  42. package/reference/claude-config/skills/knowledge/operations/features.md +76 -76
  43. package/reference/claude-config/skills/knowledge/operations/goals.md +118 -118
  44. package/reference/claude-config/skills/knowledge/operations/identity.md +93 -93
  45. package/reference/claude-config/skills/knowledge/operations/labels.md +94 -94
  46. package/reference/claude-config/skills/knowledge/operations/offerings.md +109 -109
  47. package/reference/claude-config/skills/knowledge/operations/roles.md +99 -99
  48. package/reference/claude-config/skills/knowledge/operations/techStack.md +30 -30
  49. package/reference/claude-config/skills/project/SKILL.md +1088 -1088
  50. package/reference/claude-config/skills/run-ui/SKILL.md +73 -73
  51. package/reference/claude-config/skills/save/SKILL.md +3 -3
  52. package/reference/claude-config/skills/setup/SKILL.md +275 -275
  53. package/reference/claude-config/skills/status/SKILL.md +59 -59
  54. package/reference/claude-config/skills/submit-request/SKILL.md +180 -180
  55. package/reference/claude-config/skills/sync/SKILL.md +47 -47
  56. package/reference/claude-config/skills/tutorial/SKILL.md +259 -259
  57. package/reference/claude-config/skills/tutorial/progress-template.md +74 -74
  58. package/reference/claude-config/skills/tutorial/technical.md +1303 -1303
  59. package/reference/claude-config/skills/tutorial/vibe-coder.md +890 -890
  60. package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +27 -27
  61. package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +30 -30
  62. package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +73 -73
  63. package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +86 -86
  64. package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +55 -55
  65. package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +97 -97
  66. package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +112 -112
  67. package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +93 -93
  68. package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +58 -58
  69. package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +56 -56
  70. package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +71 -71
  71. package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
  72. package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +59 -59
  73. package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +42 -42
  74. package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +60 -60
  75. package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +37 -37
  76. package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +34 -34
  77. package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +38 -38
  78. package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +32 -32
  79. package/reference/claude-config/sync-notes/2026-05-09-command-system.md +33 -33
  80. package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +69 -69
  81. package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +30 -30
  82. package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +45 -0
  83. package/reference/claude-config/sync-notes/README.md +43 -43
  84. package/reference/cli.mdx +808 -808
  85. package/reference/concepts.mdx +146 -146
  86. package/reference/deployment/api.mdx +297 -297
  87. package/reference/deployment/command-center.mdx +209 -209
  88. package/reference/deployment/index.mdx +195 -195
  89. package/reference/deployment/provided-features.mdx +107 -107
  90. package/reference/deployment/ui-execution.mdx +250 -250
  91. package/reference/examples/organization-model.ts +171 -84
  92. package/reference/framework/agent.mdx +156 -156
  93. package/reference/framework/index.mdx +195 -195
  94. package/reference/framework/interaction-guidance.mdx +182 -182
  95. package/reference/framework/memory.mdx +326 -326
  96. package/reference/framework/project-structure.mdx +282 -282
  97. package/reference/framework/tutorial-system.mdx +135 -135
  98. package/reference/getting-started.mdx +142 -142
  99. package/reference/index.mdx +106 -106
  100. package/reference/packages/core/src/README.md +14 -14
  101. package/reference/packages/core/src/business/README.md +2 -2
  102. package/reference/packages/core/src/knowledge/README.md +32 -32
  103. package/reference/packages/core/src/organization-model/README.md +149 -149
  104. package/reference/packages/core/src/test-utils/README.md +37 -37
  105. package/reference/packages/ui/src/api/README.md +18 -18
  106. package/reference/packages/ui/src/app/README.md +24 -24
  107. package/reference/packages/ui/src/auth/README.md +18 -18
  108. package/reference/packages/ui/src/components/README.md +24 -24
  109. package/reference/packages/ui/src/execution/README.md +16 -16
  110. package/reference/packages/ui/src/features/README.md +28 -28
  111. package/reference/packages/ui/src/graph/README.md +16 -16
  112. package/reference/packages/ui/src/hooks/README.md +23 -23
  113. package/reference/packages/ui/src/initialization/README.md +19 -19
  114. package/reference/packages/ui/src/knowledge/README.md +31 -31
  115. package/reference/packages/ui/src/organization/README.md +18 -18
  116. package/reference/packages/ui/src/profile/README.md +19 -19
  117. package/reference/packages/ui/src/provider/README.md +32 -32
  118. package/reference/packages/ui/src/router/README.md +18 -18
  119. package/reference/packages/ui/src/sse/README.md +13 -13
  120. package/reference/packages/ui/src/test-utils/README.md +7 -7
  121. package/reference/packages/ui/src/theme/README.md +23 -23
  122. package/reference/packages/ui/src/theme/presets/README.md +19 -19
  123. package/reference/packages/ui/src/types/README.md +16 -16
  124. package/reference/packages/ui/src/utils/README.md +18 -18
  125. package/reference/packages/ui/src/zustand/README.md +18 -18
  126. package/reference/platform-tools/adapters-integration.mdx +301 -301
  127. package/reference/platform-tools/adapters-platform.mdx +553 -553
  128. package/reference/platform-tools/index.mdx +217 -217
  129. package/reference/platform-tools/type-safety.mdx +82 -82
  130. package/reference/resources/index.mdx +349 -349
  131. package/reference/resources/patterns.mdx +449 -449
  132. package/reference/resources/types.mdx +116 -116
  133. package/reference/roadmap.mdx +165 -165
  134. package/reference/runtime.mdx +173 -173
  135. package/reference/scaffold/core/organization-graph.mdx +110 -90
  136. package/reference/scaffold/core/organization-model.mdx +225 -213
  137. package/reference/scaffold/index.mdx +67 -67
  138. package/reference/scaffold/operations/propagation-pipeline.md +77 -77
  139. package/reference/scaffold/operations/scaffold-maintenance.md +12 -12
  140. package/reference/scaffold/operations/workflow-recipes.md +138 -138
  141. package/reference/scaffold/recipes/add-a-feature.md +307 -85
  142. package/reference/scaffold/recipes/add-a-resource.md +137 -103
  143. package/reference/scaffold/recipes/customize-knowledge-browser.md +5 -5
  144. package/reference/scaffold/recipes/customize-organization-model.md +275 -138
  145. package/reference/scaffold/recipes/extend-a-base-entity.md +8 -8
  146. package/reference/scaffold/recipes/extend-crm.md +3 -3
  147. package/reference/scaffold/recipes/extend-lead-gen.md +394 -394
  148. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +118 -118
  149. package/reference/scaffold/recipes/index.md +46 -46
  150. package/reference/scaffold/recipes/query-the-knowledge-graph.md +197 -170
  151. package/reference/scaffold/reference/contracts.md +2136 -2093
  152. package/reference/scaffold/reference/glossary.md +76 -76
  153. package/reference/scaffold/ui/composition-extensibility.mdx +233 -233
  154. package/reference/scaffold/ui/customization.md +243 -243
  155. package/reference/scaffold/ui/feature-flags-and-gating.md +46 -46
  156. package/reference/scaffold/ui/feature-shell.mdx +72 -72
  157. package/reference/scaffold/ui/recipes.md +221 -214
  158. package/reference/spine/spine-primer.md +96 -96
  159. package/reference/templates/index.mdx +47 -47
  160. package/reference/troubleshooting.mdx +223 -223
@@ -1,97 +1,97 @@
1
- # CRM HITL Action Layer Cutover
2
-
3
- ## Why this note exists
4
-
5
- The Elevasis platform completed an atomic cutover of `acq_deals` from the legacy `cached_stage` + `proposal_status` model to the canonical `pipeline_key` / `stage_key` / `state_key` runtime fields. The release train that ships this cutover bumps `@elevasis/core`, `@elevasis/ui`, and `@elevasis/sdk` together, and rewires server-side lifecycle to flow through a single `transitionItem()` boundary in the API.
6
-
7
- Concretely, this train introduces:
8
-
9
- - a flat `ActivityEventSchema` discriminated union on `@elevasis/core/business/acquisition` (replaces the older `DealActivityEntry` shape; activity rows now use fields like `stageBefore`, `stageAfter`, `stateBefore`, `stateAfter`, `taskId`, `timestamp`)
10
- - a pure `deriveActions(deal)` helper on `@elevasis/core/business/acquisition` (UI/API action derivation from current deal state)
11
- - new typed CRM hooks on `@elevasis/ui` (`useTransitionItem`, refreshed `useSyncDealStage`, kanban + deal-drawer wiring)
12
- - canonical `transitionItem(dealId, organizationId, pipelineKey, stageKey, stateKey?, reason?, expectedUpdatedAt?)` as the single lifecycle mutation; server-side it appends activity, supersedes open command-queue rows, and closes incompatible tasks atomically
13
- - a `command_queue`-backed HITL transport supersession lifecycle resolved by `resolveDealCommandQueue` (called inside `transitionItem`)
14
-
15
- Derived projects that read or write `acq_deals` directly, render the CRM kanban from `@elevasis/ui`, or import acquisition types from `@elevasis/core` will pick up these contract changes when they upgrade through this train.
16
-
17
- ## Applies to
18
-
19
- All template-derived projects that:
20
-
21
- - consume `@elevasis/core/business/acquisition` types (`Deal`, `ActivityEvent`, action types) or import `deriveActions`
22
- - render the CRM kanban / deal drawer surfaces from `@elevasis/ui`
23
- - have a project-local `acq_deals` table that mirrors the platform schema
24
- - author workflows under `operations/src/sales/crm/**` that call `acqDb.transitionItem(...)` (or formerly called `syncDealStage` / direct stage writes)
25
- - read `activity_log` rows on deals and pattern-match on event shape
26
-
27
- Operations-only projects with no CRM surface and no `acq_deals` table can ignore this train.
28
-
29
- ## Required actions
30
-
31
- 1. Pull template changes with `/git-sync` so the refreshed CRM hook + drawer/kanban consumers are available.
32
-
33
- 2. After the release train is published, update package versions in the project:
34
-
35
- ```bash
36
- pnpm up @elevasis/core @elevasis/ui @elevasis/sdk --latest
37
- ```
38
-
39
- 3. If your project has a project-local `acq_deals` table, run a matching atomic cutover migration. The reference SQL that drove the monorepo cutover (preflight, outlier cleanup, atomic cutover, postflight) is no longer checked into the repo -- recover it from git history under `apps/docs/content/docs/in-progress/active-development/sdk-changes/org-model/_sql/` (deleted 2026-04-27 alongside the completed task doc) if you need a starting point.
40
-
41
- The cutover is single-shot, not dual-write. Backfill `pipeline_key` / `stage_key` from `cached_stage` and drop the legacy columns in the same transaction. There is no mid-flight rollback path; fix-forward only. Confirm prod deal volume is small enough to accept that tradeoff before applying.
42
-
43
- 4. Replace any direct stage writes with `acqDb.transitionItem(...)`:
44
- - workflow code that previously called `syncDealStage`, `updateDeal({ cached_stage: ... })`, or wrote `proposal_status` directly must now route through `transitionItem`
45
- - the API server injects `organizationId` from execution context — never pass `organizationId` from worker payload
46
- - the platform-side method appends `ActivityEventSchema`-shaped events; do NOT also write activity rows from the workflow side
47
-
48
- 5. If you read `activity_log` and pattern-match by `type`, update consumers to the flat schema:
49
-
50
- ```ts
51
- // Stage change
52
- { type: 'stage_change', timestamp, stageBefore, stageAfter, reason? }
53
-
54
- // State change
55
- { type: 'state_change', timestamp, stateBefore, stateAfter, reason? }
56
-
57
- // Task created
58
- { type: 'task_created', timestamp, taskId }
59
-
60
- // Approval resolved (written by resolveDealCommandQueue)
61
- { type: 'approval_resolved', timestamp, ... }
62
- ```
63
-
64
- The legacy `{ type, title, payload, occurredAt }` envelope is gone.
65
-
66
- 6. If your project deploys SDK resources, redeploy `operations` after the package upgrades so workers pick up the new typed adapter surface and ToolMap entries:
67
-
68
- ```bash
69
- pnpm -C operations exec elevasis-sdk deploy --prod
70
- ```
71
-
72
- ## Verification
73
-
74
- Run from the project root after package updates and any DB migration:
75
-
76
- ```bash
77
- pnpm -C ui check-types
78
- pnpm -C ui build
79
- pnpm -C operations check-types
80
- pnpm -C operations exec elevasis-sdk check
81
- ```
82
-
83
- Then exercise the CRM surface:
84
-
85
- - open the deal kanban — drag a deal between stages; confirm the activity log shows a flat `stage_change` event with `stageBefore` / `stageAfter`
86
- - open a deal drawer — confirm available actions render from `deriveActions(deal)` and not from a stored `available_actions` array
87
- - if you have a HITL approval surface, confirm that completing or superseding an approval lands an `approval_resolved` activity event before any subsequent state change
88
-
89
- If a workflow that historically wrote stage updates throws Zod errors against `ActivityEventSchema`, it is still on the legacy envelope — fix-forward by routing it through `acqDb.transitionItem(...)`.
90
-
91
- ## Not handled by /git-sync
92
-
93
- - `/git-sync` does not publish or upgrade `@elevasis/core`, `@elevasis/ui`, or `@elevasis/sdk`.
94
- - `/git-sync` does not run the project-local `acq_deals` cutover migration. The DB cutover is atomic and irreversible — only the project owner can authorize it.
95
- - `/git-sync` does not redeploy the project's `operations` bundle to dev or prod.
96
- - `/git-sync` does not rewrite project-owned workflow code that bypasses `transitionItem` to write stage / state directly.
97
- - `/git-sync` does not reconcile project-owned `activity_log` consumers that still pattern-match on the legacy `DealActivityEntry` envelope.
1
+ # CRM HITL Action Layer Cutover
2
+
3
+ ## Why this note exists
4
+
5
+ The Elevasis platform completed an atomic cutover of `acq_deals` from the legacy `cached_stage` + `proposal_status` model to the canonical `pipeline_key` / `stage_key` / `state_key` runtime fields. The release train that ships this cutover bumps `@elevasis/core`, `@elevasis/ui`, and `@elevasis/sdk` together, and rewires server-side lifecycle to flow through a single `transitionItem()` boundary in the API.
6
+
7
+ Concretely, this train introduces:
8
+
9
+ - a flat `ActivityEventSchema` discriminated union on `@elevasis/core/business/acquisition` (replaces the older `DealActivityEntry` shape; activity rows now use fields like `stageBefore`, `stageAfter`, `stateBefore`, `stateAfter`, `taskId`, `timestamp`)
10
+ - a pure `deriveActions(deal)` helper on `@elevasis/core/business/acquisition` (UI/API action derivation from current deal state)
11
+ - new typed CRM hooks on `@elevasis/ui` (`useTransitionItem`, refreshed `useSyncDealStage`, kanban + deal-drawer wiring)
12
+ - canonical `transitionItem(dealId, organizationId, pipelineKey, stageKey, stateKey?, reason?, expectedUpdatedAt?)` as the single lifecycle mutation; server-side it appends activity, supersedes open command-queue rows, and closes incompatible tasks atomically
13
+ - a `command_queue`-backed HITL transport supersession lifecycle resolved by `resolveDealCommandQueue` (called inside `transitionItem`)
14
+
15
+ Derived projects that read or write `acq_deals` directly, render the CRM kanban from `@elevasis/ui`, or import acquisition types from `@elevasis/core` will pick up these contract changes when they upgrade through this train.
16
+
17
+ ## Applies to
18
+
19
+ All template-derived projects that:
20
+
21
+ - consume `@elevasis/core/business/acquisition` types (`Deal`, `ActivityEvent`, action types) or import `deriveActions`
22
+ - render the CRM kanban / deal drawer surfaces from `@elevasis/ui`
23
+ - have a project-local `acq_deals` table that mirrors the platform schema
24
+ - author workflows under `operations/src/sales/crm/**` that call `acqDb.transitionItem(...)` (or formerly called `syncDealStage` / direct stage writes)
25
+ - read `activity_log` rows on deals and pattern-match on event shape
26
+
27
+ Operations-only projects with no CRM surface and no `acq_deals` table can ignore this train.
28
+
29
+ ## Required actions
30
+
31
+ 1. Pull template changes with `/git-sync` so the refreshed CRM hook + drawer/kanban consumers are available.
32
+
33
+ 2. After the release train is published, update package versions in the project:
34
+
35
+ ```bash
36
+ pnpm up @elevasis/core @elevasis/ui @elevasis/sdk --latest
37
+ ```
38
+
39
+ 3. If your project has a project-local `acq_deals` table, run a matching atomic cutover migration. The reference SQL that drove the monorepo cutover (preflight, outlier cleanup, atomic cutover, postflight) is no longer checked into the repo -- recover it from git history under `apps/docs/content/docs/in-progress/active-development/sdk-changes/org-model/_sql/` (deleted 2026-04-27 alongside the completed task doc) if you need a starting point.
40
+
41
+ The cutover is single-shot, not dual-write. Backfill `pipeline_key` / `stage_key` from `cached_stage` and drop the legacy columns in the same transaction. There is no mid-flight rollback path; fix-forward only. Confirm prod deal volume is small enough to accept that tradeoff before applying.
42
+
43
+ 4. Replace any direct stage writes with `acqDb.transitionItem(...)`:
44
+ - workflow code that previously called `syncDealStage`, `updateDeal({ cached_stage: ... })`, or wrote `proposal_status` directly must now route through `transitionItem`
45
+ - the API server injects `organizationId` from execution context — never pass `organizationId` from worker payload
46
+ - the platform-side method appends `ActivityEventSchema`-shaped events; do NOT also write activity rows from the workflow side
47
+
48
+ 5. If you read `activity_log` and pattern-match by `type`, update consumers to the flat schema:
49
+
50
+ ```ts
51
+ // Stage change
52
+ { type: 'stage_change', timestamp, stageBefore, stageAfter, reason? }
53
+
54
+ // State change
55
+ { type: 'state_change', timestamp, stateBefore, stateAfter, reason? }
56
+
57
+ // Task created
58
+ { type: 'task_created', timestamp, taskId }
59
+
60
+ // Approval resolved (written by resolveDealCommandQueue)
61
+ { type: 'approval_resolved', timestamp, ... }
62
+ ```
63
+
64
+ The legacy `{ type, title, payload, occurredAt }` envelope is gone.
65
+
66
+ 6. If your project deploys SDK resources, redeploy `operations` after the package upgrades so workers pick up the new typed adapter surface and ToolMap entries:
67
+
68
+ ```bash
69
+ pnpm -C operations exec elevasis-sdk deploy --prod
70
+ ```
71
+
72
+ ## Verification
73
+
74
+ Run from the project root after package updates and any DB migration:
75
+
76
+ ```bash
77
+ pnpm -C ui check-types
78
+ pnpm -C ui build
79
+ pnpm -C operations check-types
80
+ pnpm -C operations exec elevasis-sdk check
81
+ ```
82
+
83
+ Then exercise the CRM surface:
84
+
85
+ - open the deal kanban — drag a deal between stages; confirm the activity log shows a flat `stage_change` event with `stageBefore` / `stageAfter`
86
+ - open a deal drawer — confirm available actions render from `deriveActions(deal)` and not from a stored `available_actions` array
87
+ - if you have a HITL approval surface, confirm that completing or superseding an approval lands an `approval_resolved` activity event before any subsequent state change
88
+
89
+ If a workflow that historically wrote stage updates throws Zod errors against `ActivityEventSchema`, it is still on the legacy envelope — fix-forward by routing it through `acqDb.transitionItem(...)`.
90
+
91
+ ## Not handled by /git-sync
92
+
93
+ - `/git-sync` does not publish or upgrade `@elevasis/core`, `@elevasis/ui`, or `@elevasis/sdk`.
94
+ - `/git-sync` does not run the project-local `acq_deals` cutover migration. The DB cutover is atomic and irreversible — only the project owner can authorize it.
95
+ - `/git-sync` does not redeploy the project's `operations` bundle to dev or prod.
96
+ - `/git-sync` does not rewrite project-owned workflow code that bypasses `transitionItem` to write stage / state directly.
97
+ - `/git-sync` does not reconcile project-owned `activity_log` consumers that still pattern-match on the legacy `DealActivityEntry` envelope.
@@ -1,112 +1,112 @@
1
- # Lead-Gen Substrate Train (Tracks A + B + C)
2
-
3
- > **PARTIAL SUPERSEDE — 2026-04-29.** Track A's `acq_touchpoints` table and all `recordTouchpoint` / `listDealTouchpoints` helpers were removed end-to-end on 2026-04-28/29. Replacement substrate for outreach event audit is `acq_deals.activity_log` (JSONB) appended via `acqDb.recordDealActivity`. Replacement substrate for thread context (Instantly thread UUIDs) is the same `activity_log` — `reply_received` entries now carry thread fields in their payload. Ignore every touchpoint-flavored instruction in this note (table creation, hooks, UI tabs, writers, verification). The `acq_artifacts` table and ICP rubric columns from Track A remain valid. Track B + Track C non-touchpoint content remains valid.
4
-
5
- ## Why this note exists
6
-
7
- This release train ships the Lead-Gen Substrate Generalization across three coordinated tracks:
8
-
9
- - **Track A — Additive Primitives.** New `acq_artifacts` (versioned content: audit PDFs, email drafts, etc.) and `acq_touchpoints` (append-only outreach event log) tables, plus ICP rubric columns (`qualification_score numeric`, `qualification_signals jsonb`, `qualification_rubric_key text`) on `acq_companies` and `acq_contacts`. Purely additive schema — no column drops on these entities.
10
- - **Track B — Stateful Trait Generalization.** The `(pipeline_key, stage_key, state_key, activity_log)` quartet from the CRM HITL deal cutover is now applied to `acq_lists`, `acq_list_members`, and `acq_list_companies`. Legacy `acq_lists.status`, `acq_list_*.stage`, and `acq_list_*.stage_updated_at` columns are dropped. `acq_companies` and `acq_contacts` are explicitly **excluded** (batch-ETL pattern, not state-machine).
11
- - **Track C — Campaign Creator UI.** `@elevasis/ui` ships a hooks layer (`useArtifacts`, `useCreateArtifact`, `useTouchpoints`, `useListMembers`, `useListMember`, `useTransitionList`, `useTransitionListMember`, `useTransitionListCompany`, `useDeriveActions`) plus upgraded `LeadGenListsPage` and `LeadGenListDetailPage` (5-tab layout: Overview / Members / Activity / Artifacts / Touchpoints) and a `ListMemberDrawer` deep-linkable via `?member=<id>&memberKind=<contact|company>`.
12
-
13
- Concretely, this train introduces:
14
-
15
- - a `Stateful` interface + `StatefulSchema` Zod object + generic `TransitionItem<T,TEvent>` / `DeriveActions<T,TAction>` type aliases at `@elevasis/core/business/acquisition/stateful`
16
- - three `StatefulPipelineDefinition` constants on `@elevasis/core/organization-model` — `ACQ_LISTS_LEAD_GEN_PIPELINE` (single stage `lifecycle` with five states: draft / enriching / launched / closing / archived), `ACQ_LIST_MEMBERS_LEAD_GEN_PIPELINE`, `ACQ_LIST_COMPANIES_LEAD_GEN_PIPELINE` — plus `findPipeline()` helper and `LEAD_GEN_PIPELINE_DEFINITIONS` map
17
- - API routes `GET/POST /acquisition/artifacts`, `GET /acquisition/touchpoints`, `GET /acquisition/lists/:listId/members`, `GET /acquisition/list-members/:memberId`, `PATCH /acquisition/lists/:listId/transition`, `PATCH /acquisition/list-members/:memberId/transition`, `PATCH /acquisition/list-companies/:listCompanyId/transition`
18
- - new flat columns on `acq_artifacts` / `acq_touchpoints` / `acq_lists` / `acq_list_members` / `acq_list_companies` and ICP rubric columns on `acq_companies` / `acq_contacts`
19
-
20
- ## Applies to
21
-
22
- All template-derived projects that:
23
-
24
- - consume `@elevasis/core/business/acquisition` types or import the `Stateful` trait / `LEAD_GEN_PIPELINE_DEFINITIONS`
25
- - render the lead-gen lists / list-detail / Campaign Creator surfaces from `@elevasis/ui/features/lead-gen`
26
- - have a project-local `acq_*` schema that mirrors the platform tables (artifacts, touchpoints, lists, list-members, list-companies)
27
- - author workflows under `operations/src/sales/{outreach,prospecting,qualification}/**` that read or write the `acq_lists` / `acq_list_members` / `acq_list_companies` lifecycle columns, or that produce email drafts / audit content / outreach events
28
- - read `acq_companies.qualification_score` / `qualification_signals` / `qualification_rubric_key`, or the parallel columns on `acq_contacts`
29
-
30
- Operations-only projects with no lead-gen surface and no `acq_*` tables can ignore this train.
31
-
32
- ## Required actions
33
-
34
- 1. Pull template changes with `/git-sync` so the refreshed lead-gen hook surface, `LeadGenListsPage` upgrades, and `ListMemberDrawer` deep-link wiring are available.
35
-
36
- 2. After the release train is published, update package versions in the project:
37
-
38
- ```bash
39
- pnpm up @elevasis/core @elevasis/ui @elevasis/sdk --latest
40
- ```
41
-
42
- 3. If your project has project-local `acq_*` tables, run additive + cutover migrations:
43
- - **Additive (Track A — safe to apply standalone):** `acq_artifacts` and `acq_touchpoints` table creation (canonical 3-policy RLS — `Platform admins have full access to <table>` / `Org members with acquisition.manage can manage <table>` / `Org members can view <table>`). ICP columns added to `acq_companies` and `acq_contacts` (`qualification_score numeric`, `qualification_signals jsonb`, `qualification_rubric_key text`, all nullable).
44
- - **Stateful trait (Track B — atomic cutover, not dual-write):** add `pipeline_key text NOT NULL`, `stage_key text NOT NULL`, `state_key text NOT NULL`, `activity_log jsonb NOT NULL DEFAULT '[]'` to `acq_lists` / `acq_list_members` / `acq_list_companies`; drop `acq_lists.status`, `acq_list_members.{stage,stage_updated_at}`, `acq_list_companies.{stage,stage_updated_at}` in the same transaction.
45
- - **Backfill values used in the platform cutover:** `acq_lists` -> `pipeline_key='lead-gen'`, `stage_key='lifecycle'`, `state_key=coalesce(status,'draft')`. `acq_list_members` and `acq_list_companies` -> `pipeline_key='lead-gen'`, `stage_key='outreach'`, `state_key=coalesce(stage,'pending')` (preserves `personalized` / `verified` / `discovered` / `qualified` / `populated` / `extracted` vocabularies losslessly).
46
- - The cutover is single-shot. Confirm prod row counts on these tables are small enough to accept fix-forward semantics before applying.
47
-
48
- 4. Replace any direct lifecycle writes on lists / list-members / list-companies with the new transition surface:
49
- - workflow code that previously wrote `acq_lists.status`, `acq_list_members.stage`, or `acq_list_companies.stage` directly must now route through `acqDb.transitionList(...)` / `transitionListMember(...)` / `transitionListCompany(...)`
50
- - the API server injects `organizationId` from execution context — never pass `organizationId` from worker payload
51
- - the platform-side methods append `ActivityEventSchema`-shaped events to `activity_log`; do NOT also write activity rows from the workflow side
52
-
53
- 5. Replace `enrichmentData.pipeline.{auditDoc, touchpointCount, lastReply}` writers with `acq_artifacts` / `acq_touchpoints` writes:
54
- - audit PDFs / email drafts / proposals -> `acq_artifacts(kind='audit'|'email_draft'|'proposal', owner_kind='company'|'contact'|'list'|'list_member', version=N, content=<jsonb>, source_execution_id=<execution>)`
55
- - outreach events -> `acq_touchpoints(direction='outbound'|'inbound', channel='email'|'linkedin'|'sms', kind='initial'|'followup'|'reply'|'nudge', occurred_at=<ts>, payload=<jsonb>, artifact_id=<linked draft>, source_execution_id=<execution>)`
56
- - `pipeline_status.pipelineStatus` text enum on `acq_companies` is **untouched** (out of trait scope per Decision B1) — that JSONB key remains canonical for company-level state
57
-
58
- 6. Adopt the qualification rubric columns:
59
- - LLM qualifiers should write `acq_companies.qualification_score` / `qualification_signals` (jsonb shape: `{ status: 'complete' | 'pending' | ..., result?: ..., reason?: ..., completedAt?: ... }`) and stop writing `pipeline_status.qualification`
60
- - readers (e.g. `fetch-companies` filters in email-discovery / company-qualification workflows) should use `qualificationSignals?.status === 'complete'` instead of `pipeline_status.qualification?.status`
61
- - `qualification_rubric_key` is a free-form text key today; an Org OS rubric registry may land in a later train without a schema change
62
-
63
- 7. If you read `activity_log` rows on lists / list-members / list-companies and pattern-match by `type`, mirror the flat schema already used for `acq_deals`:
64
-
65
- ```ts
66
- { type: 'state_change', timestamp, stateBefore, stateAfter, reason? }
67
- { type: 'stage_change', timestamp, stageBefore, stageAfter, reason? }
68
- { type: 'task_created', timestamp, taskId }
69
- ```
70
-
71
- 8. If you ship lead-gen UI from `@elevasis/ui/features/lead-gen`, the `lists.tsx` and `list-detail.tsx` pages now expect:
72
- - `state_key` badge column resolved via `findPipeline('acq.list')` from `LEAD_GEN_PIPELINE_DEFINITIONS`
73
- - ICP rubric column reading `list.config.qualification.qualificationRubricKey` (em-dash when absent)
74
- - `stateKeyFilter` Select chip in the FilterBar (options sourced from `ACQ_LISTS_LEAD_GEN_PIPELINE.stages[0].states`)
75
- - 5-tab detail layout (Overview / Members / Activity / Artifacts / Touchpoints) plus action toolbar fed by `useDeriveActions(list)`
76
- - Row-click navigation on the Members tab via `window.history.pushState`, with `useSearch({ strict: false })` reading `?member=<id>&memberKind=<contact|company>` to drive `ListMemberDrawer`
77
- - For the `?member=` deep-link to be typed, add `validateSearch` to the project's `routes/lead-gen/lists.$listId.tsx` route file (optional; the drawer reads search params untyped via `strict: false`)
78
-
79
- 9. Redeploy `operations` after the package upgrades so workers pick up the new typed adapter surface, the artifact/touchpoint writers, and the qualification column writes:
80
-
81
- ```bash
82
- pnpm -C operations exec elevasis-sdk deploy --prod
83
- ```
84
-
85
- ## Verification
86
-
87
- Run from the project root after package updates and any DB migration:
88
-
89
- ```bash
90
- pnpm -C ui check-types
91
- pnpm -C ui build
92
- pnpm -C operations check-types
93
- pnpm -C operations exec elevasis-sdk check
94
- ```
95
-
96
- Then exercise the lead-gen surface:
97
-
98
- - open the lists page — confirm the new state-key badge column renders, the ICP rubric column shows either the rubric key or an em-dash, and the FilterBar exposes a state-key Select chip
99
- - open a list detail — confirm the 5-tab layout (Overview / Members / Activity / Artifacts / Touchpoints), the state-machine progression badge in the Overview tab, and that the Action toolbar in `PageTitleCaption` renders the actions returned by `useDeriveActions(list)`
100
- - click a member row — confirm the drawer opens, the URL gains `?member=<id>&memberKind=<contact|company>`, the activity / touchpoints / artifacts tabs render, and `onClose` clears both params
101
- - after the operations redeploy, run a campaign through the qualification + email-discovery workflows; confirm new rows in `acq_artifacts`, new rows in `acq_touchpoints`, and non-null `qualification_score` / `qualification_signals` on the affected `acq_companies` rows
102
-
103
- If a workflow that historically wrote `acq_lists.status` / `acq_list_*.stage` throws Zod errors against `StatefulSchema` or fails on missing `state_key`, route it through `acqDb.transitionList(...)` / `transitionListMember(...)` / `transitionListCompany(...)`.
104
-
105
- ## Not handled by /git-sync
106
-
107
- - `/git-sync` does not publish or upgrade `@elevasis/core`, `@elevasis/ui`, or `@elevasis/sdk`.
108
- - `/git-sync` does not run the project-local `acq_artifacts` / `acq_touchpoints` table creation, ICP-column additions, or the Stateful-trait cutover on `acq_lists` / `acq_list_members` / `acq_list_companies`. Each of those is owner-authorized and atomic.
109
- - `/git-sync` does not redeploy the project's `operations` bundle to dev or prod.
110
- - `/git-sync` does not rewrite project-owned workflow code that bypasses `transitionList` / `transitionListMember` / `transitionListCompany` to write list / member / company stage directly.
111
- - `/git-sync` does not retire project-local `enrichmentData.pipeline.{auditDoc, touchpointCount, lastReply}` writers — those must be migrated to `acq_artifacts` + `acq_touchpoints` by the project owner.
112
- - `/git-sync` does not migrate workflow qualifiers off `pipeline_status.qualification` onto `qualification_score` / `qualification_signals` / `qualification_rubric_key`.
1
+ # Lead-Gen Substrate Train (Tracks A + B + C)
2
+
3
+ > **PARTIAL SUPERSEDE — 2026-04-29.** Track A's `acq_touchpoints` table and all `recordTouchpoint` / `listDealTouchpoints` helpers were removed end-to-end on 2026-04-28/29. Replacement substrate for outreach event audit is `acq_deals.activity_log` (JSONB) appended via `acqDb.recordDealActivity`. Replacement substrate for thread context (Instantly thread UUIDs) is the same `activity_log` — `reply_received` entries now carry thread fields in their payload. Ignore every touchpoint-flavored instruction in this note (table creation, hooks, UI tabs, writers, verification). The `acq_artifacts` table and ICP rubric columns from Track A remain valid. Track B + Track C non-touchpoint content remains valid.
4
+
5
+ ## Why this note exists
6
+
7
+ This release train ships the Lead-Gen Substrate Generalization across three coordinated tracks:
8
+
9
+ - **Track A — Additive Primitives.** New `acq_artifacts` (versioned content: audit PDFs, email drafts, etc.) and `acq_touchpoints` (append-only outreach event log) tables, plus ICP rubric columns (`qualification_score numeric`, `qualification_signals jsonb`, `qualification_rubric_key text`) on `acq_companies` and `acq_contacts`. Purely additive schema — no column drops on these entities.
10
+ - **Track B — Stateful Trait Generalization.** The `(pipeline_key, stage_key, state_key, activity_log)` quartet from the CRM HITL deal cutover is now applied to `acq_lists`, `acq_list_members`, and `acq_list_companies`. Legacy `acq_lists.status`, `acq_list_*.stage`, and `acq_list_*.stage_updated_at` columns are dropped. `acq_companies` and `acq_contacts` are explicitly **excluded** (batch-ETL pattern, not state-machine).
11
+ - **Track C — Campaign Creator UI.** `@elevasis/ui` ships a hooks layer (`useArtifacts`, `useCreateArtifact`, `useTouchpoints`, `useListMembers`, `useListMember`, `useTransitionList`, `useTransitionListMember`, `useTransitionListCompany`, `useDeriveActions`) plus upgraded `LeadGenListsPage` and `LeadGenListDetailPage` (5-tab layout: Overview / Members / Activity / Artifacts / Touchpoints) and a `ListMemberDrawer` deep-linkable via `?member=<id>&memberKind=<contact|company>`.
12
+
13
+ Concretely, this train introduces:
14
+
15
+ - a `Stateful` interface + `StatefulSchema` Zod object + generic `TransitionItem<T,TEvent>` / `DeriveActions<T,TAction>` type aliases at `@elevasis/core/business/acquisition/stateful`
16
+ - three `StatefulPipelineDefinition` constants on `@elevasis/core/organization-model` — `ACQ_LISTS_LEAD_GEN_PIPELINE` (single stage `lifecycle` with five states: draft / enriching / launched / closing / archived), `ACQ_LIST_MEMBERS_LEAD_GEN_PIPELINE`, `ACQ_LIST_COMPANIES_LEAD_GEN_PIPELINE` — plus `findPipeline()` helper and `LEAD_GEN_PIPELINE_DEFINITIONS` map
17
+ - API routes `GET/POST /acquisition/artifacts`, `GET /acquisition/touchpoints`, `GET /acquisition/lists/:listId/members`, `GET /acquisition/list-members/:memberId`, `PATCH /acquisition/lists/:listId/transition`, `PATCH /acquisition/list-members/:memberId/transition`, `PATCH /acquisition/list-companies/:listCompanyId/transition`
18
+ - new flat columns on `acq_artifacts` / `acq_touchpoints` / `acq_lists` / `acq_list_members` / `acq_list_companies` and ICP rubric columns on `acq_companies` / `acq_contacts`
19
+
20
+ ## Applies to
21
+
22
+ All template-derived projects that:
23
+
24
+ - consume `@elevasis/core/business/acquisition` types or import the `Stateful` trait / `LEAD_GEN_PIPELINE_DEFINITIONS`
25
+ - render the lead-gen lists / list-detail / Campaign Creator surfaces from `@elevasis/ui/features/lead-gen`
26
+ - have a project-local `acq_*` schema that mirrors the platform tables (artifacts, touchpoints, lists, list-members, list-companies)
27
+ - author workflows under `operations/src/sales/{outreach,prospecting,qualification}/**` that read or write the `acq_lists` / `acq_list_members` / `acq_list_companies` lifecycle columns, or that produce email drafts / audit content / outreach events
28
+ - read `acq_companies.qualification_score` / `qualification_signals` / `qualification_rubric_key`, or the parallel columns on `acq_contacts`
29
+
30
+ Operations-only projects with no lead-gen surface and no `acq_*` tables can ignore this train.
31
+
32
+ ## Required actions
33
+
34
+ 1. Pull template changes with `/git-sync` so the refreshed lead-gen hook surface, `LeadGenListsPage` upgrades, and `ListMemberDrawer` deep-link wiring are available.
35
+
36
+ 2. After the release train is published, update package versions in the project:
37
+
38
+ ```bash
39
+ pnpm up @elevasis/core @elevasis/ui @elevasis/sdk --latest
40
+ ```
41
+
42
+ 3. If your project has project-local `acq_*` tables, run additive + cutover migrations:
43
+ - **Additive (Track A — safe to apply standalone):** `acq_artifacts` and `acq_touchpoints` table creation (canonical 3-policy RLS — `Platform admins have full access to <table>` / `Org members with acquisition.manage can manage <table>` / `Org members can view <table>`). ICP columns added to `acq_companies` and `acq_contacts` (`qualification_score numeric`, `qualification_signals jsonb`, `qualification_rubric_key text`, all nullable).
44
+ - **Stateful trait (Track B — atomic cutover, not dual-write):** add `pipeline_key text NOT NULL`, `stage_key text NOT NULL`, `state_key text NOT NULL`, `activity_log jsonb NOT NULL DEFAULT '[]'` to `acq_lists` / `acq_list_members` / `acq_list_companies`; drop `acq_lists.status`, `acq_list_members.{stage,stage_updated_at}`, `acq_list_companies.{stage,stage_updated_at}` in the same transaction.
45
+ - **Backfill values used in the platform cutover:** `acq_lists` -> `pipeline_key='lead-gen'`, `stage_key='lifecycle'`, `state_key=coalesce(status,'draft')`. `acq_list_members` and `acq_list_companies` -> `pipeline_key='lead-gen'`, `stage_key='outreach'`, `state_key=coalesce(stage,'pending')` (preserves `personalized` / `verified` / `discovered` / `qualified` / `populated` / `extracted` vocabularies losslessly).
46
+ - The cutover is single-shot. Confirm prod row counts on these tables are small enough to accept fix-forward semantics before applying.
47
+
48
+ 4. Replace any direct lifecycle writes on lists / list-members / list-companies with the new transition surface:
49
+ - workflow code that previously wrote `acq_lists.status`, `acq_list_members.stage`, or `acq_list_companies.stage` directly must now route through `acqDb.transitionList(...)` / `transitionListMember(...)` / `transitionListCompany(...)`
50
+ - the API server injects `organizationId` from execution context — never pass `organizationId` from worker payload
51
+ - the platform-side methods append `ActivityEventSchema`-shaped events to `activity_log`; do NOT also write activity rows from the workflow side
52
+
53
+ 5. Replace `enrichmentData.pipeline.{auditDoc, touchpointCount, lastReply}` writers with `acq_artifacts` / `acq_touchpoints` writes:
54
+ - audit PDFs / email drafts / proposals -> `acq_artifacts(kind='audit'|'email_draft'|'proposal', owner_kind='company'|'contact'|'list'|'list_member', version=N, content=<jsonb>, source_execution_id=<execution>)`
55
+ - outreach events -> `acq_touchpoints(direction='outbound'|'inbound', channel='email'|'linkedin'|'sms', kind='initial'|'followup'|'reply'|'nudge', occurred_at=<ts>, payload=<jsonb>, artifact_id=<linked draft>, source_execution_id=<execution>)`
56
+ - `pipeline_status.pipelineStatus` text enum on `acq_companies` is **untouched** (out of trait scope per Decision B1) — that JSONB key remains canonical for company-level state
57
+
58
+ 6. Adopt the qualification rubric columns:
59
+ - LLM qualifiers should write `acq_companies.qualification_score` / `qualification_signals` (jsonb shape: `{ status: 'complete' | 'pending' | ..., result?: ..., reason?: ..., completedAt?: ... }`) and stop writing `pipeline_status.qualification`
60
+ - readers (e.g. `fetch-companies` filters in email-discovery / company-qualification workflows) should use `qualificationSignals?.status === 'complete'` instead of `pipeline_status.qualification?.status`
61
+ - `qualification_rubric_key` is a free-form text key today; an Org OS rubric registry may land in a later train without a schema change
62
+
63
+ 7. If you read `activity_log` rows on lists / list-members / list-companies and pattern-match by `type`, mirror the flat schema already used for `acq_deals`:
64
+
65
+ ```ts
66
+ { type: 'state_change', timestamp, stateBefore, stateAfter, reason? }
67
+ { type: 'stage_change', timestamp, stageBefore, stageAfter, reason? }
68
+ { type: 'task_created', timestamp, taskId }
69
+ ```
70
+
71
+ 8. If you ship lead-gen UI from `@elevasis/ui/features/lead-gen`, the `lists.tsx` and `list-detail.tsx` pages now expect:
72
+ - `state_key` badge column resolved via `findPipeline('acq.list')` from `LEAD_GEN_PIPELINE_DEFINITIONS`
73
+ - ICP rubric column reading `list.config.qualification.qualificationRubricKey` (em-dash when absent)
74
+ - `stateKeyFilter` Select chip in the FilterBar (options sourced from `ACQ_LISTS_LEAD_GEN_PIPELINE.stages[0].states`)
75
+ - 5-tab detail layout (Overview / Members / Activity / Artifacts / Touchpoints) plus action toolbar fed by `useDeriveActions(list)`
76
+ - Row-click navigation on the Members tab via `window.history.pushState`, with `useSearch({ strict: false })` reading `?member=<id>&memberKind=<contact|company>` to drive `ListMemberDrawer`
77
+ - For the `?member=` deep-link to be typed, add `validateSearch` to the project's `routes/lead-gen/lists.$listId.tsx` route file (optional; the drawer reads search params untyped via `strict: false`)
78
+
79
+ 9. Redeploy `operations` after the package upgrades so workers pick up the new typed adapter surface, the artifact/touchpoint writers, and the qualification column writes:
80
+
81
+ ```bash
82
+ pnpm -C operations exec elevasis-sdk deploy --prod
83
+ ```
84
+
85
+ ## Verification
86
+
87
+ Run from the project root after package updates and any DB migration:
88
+
89
+ ```bash
90
+ pnpm -C ui check-types
91
+ pnpm -C ui build
92
+ pnpm -C operations check-types
93
+ pnpm -C operations exec elevasis-sdk check
94
+ ```
95
+
96
+ Then exercise the lead-gen surface:
97
+
98
+ - open the lists page — confirm the new state-key badge column renders, the ICP rubric column shows either the rubric key or an em-dash, and the FilterBar exposes a state-key Select chip
99
+ - open a list detail — confirm the 5-tab layout (Overview / Members / Activity / Artifacts / Touchpoints), the state-machine progression badge in the Overview tab, and that the Action toolbar in `PageTitleCaption` renders the actions returned by `useDeriveActions(list)`
100
+ - click a member row — confirm the drawer opens, the URL gains `?member=<id>&memberKind=<contact|company>`, the activity / touchpoints / artifacts tabs render, and `onClose` clears both params
101
+ - after the operations redeploy, run a campaign through the qualification + email-discovery workflows; confirm new rows in `acq_artifacts`, new rows in `acq_touchpoints`, and non-null `qualification_score` / `qualification_signals` on the affected `acq_companies` rows
102
+
103
+ If a workflow that historically wrote `acq_lists.status` / `acq_list_*.stage` throws Zod errors against `StatefulSchema` or fails on missing `state_key`, route it through `acqDb.transitionList(...)` / `transitionListMember(...)` / `transitionListCompany(...)`.
104
+
105
+ ## Not handled by /git-sync
106
+
107
+ - `/git-sync` does not publish or upgrade `@elevasis/core`, `@elevasis/ui`, or `@elevasis/sdk`.
108
+ - `/git-sync` does not run the project-local `acq_artifacts` / `acq_touchpoints` table creation, ICP-column additions, or the Stateful-trait cutover on `acq_lists` / `acq_list_members` / `acq_list_companies`. Each of those is owner-authorized and atomic.
109
+ - `/git-sync` does not redeploy the project's `operations` bundle to dev or prod.
110
+ - `/git-sync` does not rewrite project-owned workflow code that bypasses `transitionList` / `transitionListMember` / `transitionListCompany` to write list / member / company stage directly.
111
+ - `/git-sync` does not retire project-local `enrichmentData.pipeline.{auditDoc, touchpointCount, lastReply}` writers — those must be migrated to `acq_artifacts` + `acq_touchpoints` by the project owner.
112
+ - `/git-sync` does not migrate workflow qualifiers off `pipeline_status.qualification` onto `qualification_score` / `qualification_signals` / `qualification_rubric_key`.