openplanr 1.21.2 → 1.22.0

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 (100) hide show
  1. package/dist/cli/commands/doctor.d.ts.map +1 -1
  2. package/dist/cli/commands/doctor.js +11 -1
  3. package/dist/cli/commands/doctor.js.map +1 -1
  4. package/dist/cli/commands/operate.d.ts.map +1 -1
  5. package/dist/cli/commands/operate.js +91 -2
  6. package/dist/cli/commands/operate.js.map +1 -1
  7. package/dist/services/operate/advisors.d.ts +63 -0
  8. package/dist/services/operate/advisors.d.ts.map +1 -1
  9. package/dist/services/operate/advisors.js +68 -4
  10. package/dist/services/operate/advisors.js.map +1 -1
  11. package/dist/services/operate/artifacts.d.ts +9 -3
  12. package/dist/services/operate/artifacts.d.ts.map +1 -1
  13. package/dist/services/operate/artifacts.js +126 -5
  14. package/dist/services/operate/artifacts.js.map +1 -1
  15. package/dist/services/operate/citation-resolution.d.ts +14 -0
  16. package/dist/services/operate/citation-resolution.d.ts.map +1 -1
  17. package/dist/services/operate/citation-resolution.js +9 -0
  18. package/dist/services/operate/citation-resolution.js.map +1 -1
  19. package/dist/services/operate/completion.d.ts +80 -0
  20. package/dist/services/operate/completion.d.ts.map +1 -0
  21. package/dist/services/operate/completion.js +279 -0
  22. package/dist/services/operate/completion.js.map +1 -0
  23. package/dist/services/operate/config.d.ts +7 -0
  24. package/dist/services/operate/config.d.ts.map +1 -1
  25. package/dist/services/operate/config.js +7 -0
  26. package/dist/services/operate/config.js.map +1 -1
  27. package/dist/services/operate/context-research.d.ts +43 -0
  28. package/dist/services/operate/context-research.d.ts.map +1 -1
  29. package/dist/services/operate/context-research.js +219 -1
  30. package/dist/services/operate/context-research.js.map +1 -1
  31. package/dist/services/operate/decision-brief.d.ts +90 -1
  32. package/dist/services/operate/decision-brief.d.ts.map +1 -1
  33. package/dist/services/operate/decision-brief.js +175 -1
  34. package/dist/services/operate/decision-brief.js.map +1 -1
  35. package/dist/services/operate/doctor.d.ts +58 -0
  36. package/dist/services/operate/doctor.d.ts.map +1 -1
  37. package/dist/services/operate/doctor.js +395 -21
  38. package/dist/services/operate/doctor.js.map +1 -1
  39. package/dist/services/operate/engine.d.ts +75 -2
  40. package/dist/services/operate/engine.d.ts.map +1 -1
  41. package/dist/services/operate/engine.js +504 -33
  42. package/dist/services/operate/engine.js.map +1 -1
  43. package/dist/services/operate/event-store.d.ts +22 -0
  44. package/dist/services/operate/event-store.d.ts.map +1 -1
  45. package/dist/services/operate/event-store.js +35 -0
  46. package/dist/services/operate/event-store.js.map +1 -1
  47. package/dist/services/operate/evidence-cache.d.ts.map +1 -1
  48. package/dist/services/operate/evidence-cache.js +41 -5
  49. package/dist/services/operate/evidence-cache.js.map +1 -1
  50. package/dist/services/operate/index.d.ts.map +1 -1
  51. package/dist/services/operate/index.js +98 -1
  52. package/dist/services/operate/index.js.map +1 -1
  53. package/dist/services/operate/interaction/question-engine.d.ts.map +1 -1
  54. package/dist/services/operate/interaction/question-engine.js +36 -8
  55. package/dist/services/operate/interaction/question-engine.js.map +1 -1
  56. package/dist/services/operate/interaction/question-registry.d.ts +8 -0
  57. package/dist/services/operate/interaction/question-registry.d.ts.map +1 -1
  58. package/dist/services/operate/interaction/question-registry.js +21 -2
  59. package/dist/services/operate/interaction/question-registry.js.map +1 -1
  60. package/dist/services/operate/lifecycle-driver.d.ts +309 -0
  61. package/dist/services/operate/lifecycle-driver.d.ts.map +1 -0
  62. package/dist/services/operate/lifecycle-driver.js +434 -0
  63. package/dist/services/operate/lifecycle-driver.js.map +1 -0
  64. package/dist/services/operate/maintenance.d.ts +65 -1
  65. package/dist/services/operate/maintenance.d.ts.map +1 -1
  66. package/dist/services/operate/maintenance.js +718 -24
  67. package/dist/services/operate/maintenance.js.map +1 -1
  68. package/dist/services/operate/mission-dispatch.d.ts +61 -1
  69. package/dist/services/operate/mission-dispatch.d.ts.map +1 -1
  70. package/dist/services/operate/mission-dispatch.js +78 -5
  71. package/dist/services/operate/mission-dispatch.js.map +1 -1
  72. package/dist/services/operate/profile-migration.d.ts +69 -0
  73. package/dist/services/operate/profile-migration.d.ts.map +1 -0
  74. package/dist/services/operate/profile-migration.js +462 -0
  75. package/dist/services/operate/profile-migration.js.map +1 -0
  76. package/dist/services/operate/projection-persistence.d.ts.map +1 -1
  77. package/dist/services/operate/projection-persistence.js +24 -5
  78. package/dist/services/operate/projection-persistence.js.map +1 -1
  79. package/dist/services/operate/projection.d.ts.map +1 -1
  80. package/dist/services/operate/projection.js +9 -0
  81. package/dist/services/operate/projection.js.map +1 -1
  82. package/dist/services/operate/protocol.d.ts +1 -0
  83. package/dist/services/operate/protocol.d.ts.map +1 -1
  84. package/dist/services/operate/protocol.js.map +1 -1
  85. package/dist/services/operate/scratch.d.ts +81 -0
  86. package/dist/services/operate/scratch.d.ts.map +1 -0
  87. package/dist/services/operate/scratch.js +190 -0
  88. package/dist/services/operate/scratch.js.map +1 -0
  89. package/dist/services/operate/types.d.ts +3 -2
  90. package/dist/services/operate/types.d.ts.map +1 -1
  91. package/dist/services/operate/types.js.map +1 -1
  92. package/dist/services/operate/workspace.d.ts +1 -0
  93. package/dist/services/operate/workspace.d.ts.map +1 -1
  94. package/dist/services/operate/workspace.js +2 -0
  95. package/dist/services/operate/workspace.js.map +1 -1
  96. package/dist/services/runtime-manager-service.d.ts +23 -0
  97. package/dist/services/runtime-manager-service.d.ts.map +1 -1
  98. package/dist/services/runtime-manager-service.js +30 -0
  99. package/dist/services/runtime-manager-service.js.map +1 -1
  100. package/package.json +2 -2
@@ -0,0 +1,69 @@
1
+ import { type OperatingProfile } from './types.js';
2
+ export interface LegacyProfileFieldConversion {
3
+ field: string;
4
+ detail: string;
5
+ }
6
+ export interface LegacyProfileUnsupportedField {
7
+ field: string;
8
+ reason: string;
9
+ }
10
+ export interface LegacyProfileClassification {
11
+ /** The concrete migrated profile — only fields the current schema accepts. */
12
+ migratedProfile: Record<string, unknown>;
13
+ /** The recognized profile id, when the legacy file named a valid one. */
14
+ id: OperatingProfile['id'] | null;
15
+ /** Fields carried through unchanged. */
16
+ preserved: string[];
17
+ /** Fields whose value was normalized to satisfy the current schema. */
18
+ converted: LegacyProfileFieldConversion[];
19
+ /** Fields the current profile schema cannot carry, reported explicitly. */
20
+ unsupported: LegacyProfileUnsupportedField[];
21
+ }
22
+ export interface OperatingProfileMigrationInspection {
23
+ present: boolean;
24
+ sourcePath: string;
25
+ sourceDigest: `sha256:${string}` | null;
26
+ migrationId: string | null;
27
+ migratedProfile: Record<string, unknown> | null;
28
+ id: OperatingProfile['id'] | null;
29
+ preserved: string[];
30
+ converted: LegacyProfileFieldConversion[];
31
+ unsupported: LegacyProfileUnsupportedField[];
32
+ /** True when applying the migration would rewrite the profile file. */
33
+ changed: boolean;
34
+ }
35
+ export interface OperatingProfileMigrationResult {
36
+ present: boolean;
37
+ applied: boolean;
38
+ alreadyApplied: boolean;
39
+ migrationId: string | null;
40
+ backupPath: string | null;
41
+ sourceDigest: `sha256:${string}` | null;
42
+ preserved: string[];
43
+ converted: LegacyProfileFieldConversion[];
44
+ unsupported: LegacyProfileUnsupportedField[];
45
+ }
46
+ /**
47
+ * Classify a parsed legacy operating-profile object against the current schema.
48
+ * Pure and total: it never reads the filesystem and never throws on arbitrary
49
+ * JSON, so both guided init (detect-don't-ask) and the migration command can rely
50
+ * on the same field-level verdicts.
51
+ */
52
+ export declare function classifyLegacyOperatingProfile(record: Record<string, unknown>): LegacyProfileClassification;
53
+ /**
54
+ * Compare a parsed legacy profile against a parsed operating-config, returning the
55
+ * sorted names of the fields that differ. Only fields present on the profile are
56
+ * compared. Used by the doctor profile/config-drift diagnostic. Pure and total.
57
+ */
58
+ export declare function compareLegacyProfileToOperatingConfig(profile: Record<string, unknown>, config: Record<string, unknown>): string[];
59
+ export declare function inspectOperatingProfileMigration(input: {
60
+ projectRoot: string;
61
+ localRoot?: string;
62
+ }): Promise<OperatingProfileMigrationInspection>;
63
+ export declare function applyOperatingProfileMigration(input: {
64
+ projectRoot: string;
65
+ confirmed: boolean;
66
+ localRoot?: string;
67
+ now?: string;
68
+ }): Promise<OperatingProfileMigrationResult>;
69
+ //# sourceMappingURL=profile-migration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-migration.d.ts","sourceRoot":"","sources":["../../../src/services/operate/profile-migration.ts"],"names":[],"mappings":"AAUA,OAAO,EAAyC,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA6D1F,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,2BAA2B;IAC1C,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,yEAAyE;IACzE,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClC,wCAAwC;IACxC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,uEAAuE;IACvE,SAAS,EAAE,4BAA4B,EAAE,CAAC;IAC1C,2EAA2E;IAC3E,WAAW,EAAE,6BAA6B,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,mCAAmC;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,UAAU,MAAM,EAAE,GAAG,IAAI,CAAC;IACxC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChD,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,4BAA4B,EAAE,CAAC;IAC1C,WAAW,EAAE,6BAA6B,EAAE,CAAC;IAC7C,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,UAAU,MAAM,EAAE,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,4BAA4B,EAAE,CAAC;IAC1C,WAAW,EAAE,6BAA6B,EAAE,CAAC;CAC9C;AAWD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,2BAA2B,CAgI7B;AAqBD;;;;GAIG;AACH,wBAAgB,qCAAqC,CACnD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,EAAE,CAyBV;AAyDD,wBAAsB,gCAAgC,CAAC,KAAK,EAAE;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,mCAAmC,CAAC,CA6B/C;AAgED,wBAAsB,8BAA8B,CAAC,KAAK,EAAE;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,+BAA+B,CAAC,CA6H3C"}
@@ -0,0 +1,462 @@
1
+ import { mkdir, open, readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { canonicalDigest, canonicalize, sha256Digest } from './canonical.js';
4
+ import { FROZEN_OPERATING_BUDGETS, FROZEN_OPERATING_PROVIDERS, operatingProjectKey, } from './config.js';
5
+ import { applyJournalTransaction, prepareJournalTransaction } from './journal.js';
6
+ import { withOperatingLock } from './lock-service.js';
7
+ import { OperateError } from './types.js';
8
+ import { resolveOperatingPaths } from './workspace.js';
9
+ /**
10
+ * FR10 / T-009 — migrate a stale `.planr/operate-profile.json` into a form the
11
+ * current CLI accepts. This is deliberately a DIFFERENT feature from
12
+ * `legacy-import-service.ts` (which imports legacy PLAN-era board data — findings,
13
+ * decisions, gaps, routes, outcomes — into the event store). Here the subject is
14
+ * the operating profile file itself: guided init used to suggest a profile whose
15
+ * `enabledProviders`/`budgets` the same CLI then rejects. This module classifies
16
+ * each field against the live schema, converts what is compatible, drops what the
17
+ * profile schema cannot carry (reporting it explicitly), keeps role selection,
18
+ * sources, budgets, caps, and author intent where supported, backs up the exact
19
+ * pre-migration bytes before mutating, and is idempotent.
20
+ */
21
+ const LEGACY_PROFILE_RELATIVE_PATH = '.planr/operate-profile.json';
22
+ const MAX_PROFILE_FILE_BYTES = 64 * 1024;
23
+ /** The profile file carries no event-chain state, so its journal write is anchored
24
+ * to the genesis head rather than the live event store — it stays fully decoupled
25
+ * from board state and works whether or not the board is initialized. */
26
+ const GENESIS_EVENT_HEAD = { sequence: 0, hash: null };
27
+ const KNOWN_PROFILE_IDS = new Set([
28
+ 'saas',
29
+ 'product',
30
+ 'engineering',
31
+ 'custom',
32
+ ]);
33
+ /** The six operating roles a profile may select (mirrors config.ts's ALL_ROLES,
34
+ * which is module-private there — doctor.ts keeps its own copy the same way). */
35
+ const KNOWN_OPERATING_ROLES = new Set([
36
+ 'strategy-finance',
37
+ 'technology-risk',
38
+ 'product-activation',
39
+ 'growth-market',
40
+ 'operations-customer',
41
+ 'chair',
42
+ ]);
43
+ const CAP_MAXIMA = {
44
+ surfacedFindings: 50,
45
+ newSpecs: 12,
46
+ openDecisions: 20,
47
+ agentArtifacts: 20,
48
+ };
49
+ /** Fields the current operating-profile schema recognizes at the top level. Any
50
+ * other key is reported as unsupported so nothing is silently discarded. */
51
+ const KNOWN_LEGACY_PROFILE_KEYS = new Set([
52
+ 'id',
53
+ 'title',
54
+ 'description',
55
+ 'enabledRoles',
56
+ 'caps',
57
+ 'enabledProviders',
58
+ 'budgets',
59
+ ]);
60
+ function plainObject(value) {
61
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
62
+ }
63
+ function normalizedStringSet(value) {
64
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string'))
65
+ return null;
66
+ return [...new Set(value.map((entry) => entry.trim()).filter(Boolean))].sort();
67
+ }
68
+ /**
69
+ * Classify a parsed legacy operating-profile object against the current schema.
70
+ * Pure and total: it never reads the filesystem and never throws on arbitrary
71
+ * JSON, so both guided init (detect-don't-ask) and the migration command can rely
72
+ * on the same field-level verdicts.
73
+ */
74
+ export function classifyLegacyOperatingProfile(record) {
75
+ const migratedProfile = {};
76
+ const preserved = [];
77
+ const converted = [];
78
+ const unsupported = [];
79
+ let id = null;
80
+ if (record.id !== undefined) {
81
+ if (typeof record.id === 'string' &&
82
+ KNOWN_PROFILE_IDS.has(record.id)) {
83
+ id = record.id;
84
+ migratedProfile.id = id;
85
+ preserved.push('id');
86
+ }
87
+ else {
88
+ unsupported.push({
89
+ field: 'id',
90
+ reason: `names an unknown operating profile \`${String(record.id)}\``,
91
+ });
92
+ }
93
+ }
94
+ for (const key of ['title', 'description']) {
95
+ const value = record[key];
96
+ if (value === undefined)
97
+ continue;
98
+ if (typeof value === 'string' && value.trim().length > 0 && value.length <= 1024) {
99
+ migratedProfile[key] = value.trim();
100
+ preserved.push(key);
101
+ }
102
+ else {
103
+ unsupported.push({ field: key, reason: `${key} is not a bounded non-empty string` });
104
+ }
105
+ }
106
+ if (record.enabledRoles !== undefined) {
107
+ const roles = Array.isArray(record.enabledRoles) ? record.enabledRoles : [];
108
+ const stringRoles = roles.filter((role) => typeof role === 'string');
109
+ const unique = [...new Set(stringRoles.map((role) => role.trim()).filter(Boolean))];
110
+ const recognized = unique.filter((role) => KNOWN_OPERATING_ROLES.has(role));
111
+ const dropped = unique.filter((role) => !KNOWN_OPERATING_ROLES.has(role));
112
+ const malformed = !Array.isArray(record.enabledRoles) || stringRoles.length !== roles.length;
113
+ if (recognized.length === 0) {
114
+ unsupported.push({
115
+ field: 'enabledRoles',
116
+ reason: 'names no recognized operating role',
117
+ });
118
+ }
119
+ else if (dropped.length > 0 || malformed) {
120
+ migratedProfile.enabledRoles = recognized;
121
+ converted.push({
122
+ field: 'enabledRoles',
123
+ detail: dropped.length > 0
124
+ ? `dropped unrecognized role(s): ${dropped.join(', ')}`
125
+ : 'dropped malformed role entries',
126
+ });
127
+ }
128
+ else {
129
+ migratedProfile.enabledRoles = recognized;
130
+ preserved.push('enabledRoles');
131
+ }
132
+ }
133
+ if (record.caps !== undefined) {
134
+ const caps = classifyCaps(record.caps);
135
+ if (caps.ok) {
136
+ migratedProfile.caps = caps.caps;
137
+ preserved.push('caps');
138
+ }
139
+ else {
140
+ unsupported.push({ field: 'caps', reason: caps.reason });
141
+ }
142
+ }
143
+ // Providers ("sources") and budgets are fixed by the engine and are not carried
144
+ // on the profile schema, so they are always dropped from the migrated file. A
145
+ // value matching the fixed shape is a safe conversion; anything else is reported
146
+ // as unsupported so the operator sees exactly what the CLI would not reuse.
147
+ if (record.enabledProviders !== undefined) {
148
+ const providers = normalizedStringSet(record.enabledProviders);
149
+ const frozen = [...FROZEN_OPERATING_PROVIDERS].sort();
150
+ if (providers &&
151
+ providers.length === frozen.length &&
152
+ providers.every((p, i) => p === frozen[i])) {
153
+ converted.push({
154
+ field: 'enabledProviders',
155
+ detail: `folded into the fixed providers (${frozen.join(', ')})`,
156
+ });
157
+ }
158
+ else {
159
+ const unknownProviders = (providers ?? []).filter((provider) => !FROZEN_OPERATING_PROVIDERS.includes(provider));
160
+ unsupported.push({
161
+ field: 'enabledProviders',
162
+ reason: unknownProviders.length > 0
163
+ ? `includes provider(s) the operating configuration does not accept: ${unknownProviders.join(', ')}`
164
+ : `differs from the fixed providers (${frozen.join(', ')}) and will not be reused as-is`,
165
+ });
166
+ }
167
+ }
168
+ if (record.budgets !== undefined) {
169
+ if (canonicalize(record.budgets) === canonicalize(FROZEN_OPERATING_BUDGETS)) {
170
+ converted.push({ field: 'budgets', detail: 'matches the fixed operating budgets' });
171
+ }
172
+ else {
173
+ unsupported.push({
174
+ field: 'budgets',
175
+ reason: 'differs from the fixed operating budgets and will not be reused as-is',
176
+ });
177
+ }
178
+ }
179
+ for (const key of Object.keys(record)) {
180
+ if (!KNOWN_LEGACY_PROFILE_KEYS.has(key)) {
181
+ unsupported.push({
182
+ field: key,
183
+ reason: 'is not part of the current operating profile schema',
184
+ });
185
+ }
186
+ }
187
+ return {
188
+ migratedProfile,
189
+ id,
190
+ preserved: preserved.sort(),
191
+ converted: converted.sort((a, b) => a.field.localeCompare(b.field)),
192
+ unsupported: unsupported.sort((a, b) => a.field.localeCompare(b.field)),
193
+ };
194
+ }
195
+ function classifyCaps(value) {
196
+ if (!plainObject(value))
197
+ return { ok: false, reason: 'caps must be a JSON object' };
198
+ const unknown = Object.keys(value).filter((key) => !(key in CAP_MAXIMA));
199
+ if (unknown.length > 0) {
200
+ return { ok: false, reason: `caps has unsupported field(s): ${unknown.join(', ')}` };
201
+ }
202
+ const caps = {};
203
+ for (const [key, entry] of Object.entries(value)) {
204
+ const maximum = CAP_MAXIMA[key];
205
+ if (!Number.isInteger(entry) || entry < 1 || entry > maximum) {
206
+ return { ok: false, reason: `caps.${key} is outside the supported 1-${maximum} range` };
207
+ }
208
+ caps[key] = entry;
209
+ }
210
+ return { ok: true, caps };
211
+ }
212
+ /**
213
+ * Compare a parsed legacy profile against a parsed operating-config, returning the
214
+ * sorted names of the fields that differ. Only fields present on the profile are
215
+ * compared. Used by the doctor profile/config-drift diagnostic. Pure and total.
216
+ */
217
+ export function compareLegacyProfileToOperatingConfig(profile, config) {
218
+ const drift = [];
219
+ if ('id' in profile && String(profile.id) !== String(config.profile))
220
+ drift.push('id');
221
+ if ('enabledRoles' in profile && !sameStringSet(profile.enabledRoles, config.enabledRoles)) {
222
+ drift.push('enabledRoles');
223
+ }
224
+ if ('caps' in profile &&
225
+ canonicalize(profile.caps ?? null) !== canonicalize(config.caps ?? null)) {
226
+ drift.push('caps');
227
+ }
228
+ if ('enabledProviders' in profile &&
229
+ !sameStringSet(profile.enabledProviders, config.enabledProviders)) {
230
+ drift.push('enabledProviders');
231
+ }
232
+ if ('budgets' in profile &&
233
+ canonicalize(profile.budgets ?? null) !== canonicalize(config.budgets ?? null)) {
234
+ drift.push('budgets');
235
+ }
236
+ return drift.sort();
237
+ }
238
+ function sameStringSet(left, right) {
239
+ const a = normalizedStringSet(left);
240
+ const b = normalizedStringSet(right);
241
+ if (a === null || b === null)
242
+ return canonicalize(left ?? null) === canonicalize(right ?? null);
243
+ return a.length === b.length && a.every((entry, index) => entry === b[index]);
244
+ }
245
+ async function readLegacyProfileFile(projectRoot) {
246
+ const target = path.join(projectRoot, '.planr', 'operate-profile.json');
247
+ const buffer = await readFile(target).catch((error) => {
248
+ if (error.code === 'ENOENT')
249
+ return null;
250
+ throw error;
251
+ });
252
+ if (buffer === null)
253
+ return null;
254
+ if (buffer.byteLength > MAX_PROFILE_FILE_BYTES) {
255
+ throw new OperateError('E_OPERATE_INPUT_TOO_LARGE', `${LEGACY_PROFILE_RELATIVE_PATH} exceeds the ${MAX_PROFILE_FILE_BYTES}-byte limit.`);
256
+ }
257
+ const raw = buffer.toString('utf8');
258
+ let parsed;
259
+ try {
260
+ parsed = JSON.parse(raw);
261
+ }
262
+ catch {
263
+ throw new OperateError('E_OPERATE_CONFIG_INVALID', `${LEGACY_PROFILE_RELATIVE_PATH} is not valid JSON.`);
264
+ }
265
+ if (!plainObject(parsed)) {
266
+ throw new OperateError('E_OPERATE_CONFIG_INVALID', `${LEGACY_PROFILE_RELATIVE_PATH} must be a JSON object.`);
267
+ }
268
+ return { raw, buffer, record: parsed, digest: sha256Digest(buffer) };
269
+ }
270
+ function profileMigrationId(sourceDigest) {
271
+ return `PMIG-${sourceDigest.slice('sha256:'.length, 'sha256:'.length + 24)}`;
272
+ }
273
+ /** A field is "changed" when applying would strip or rewrite it. */
274
+ function migrationChanges(classification) {
275
+ return classification.converted.length > 0 || classification.unsupported.length > 0;
276
+ }
277
+ export async function inspectOperatingProfileMigration(input) {
278
+ const file = await readLegacyProfileFile(input.projectRoot);
279
+ if (file === null) {
280
+ return {
281
+ present: false,
282
+ sourcePath: LEGACY_PROFILE_RELATIVE_PATH,
283
+ sourceDigest: null,
284
+ migrationId: null,
285
+ migratedProfile: null,
286
+ id: null,
287
+ preserved: [],
288
+ converted: [],
289
+ unsupported: [],
290
+ changed: false,
291
+ };
292
+ }
293
+ const classification = classifyLegacyOperatingProfile(file.record);
294
+ return {
295
+ present: true,
296
+ sourcePath: LEGACY_PROFILE_RELATIVE_PATH,
297
+ sourceDigest: file.digest,
298
+ migrationId: profileMigrationId(file.digest),
299
+ migratedProfile: classification.migratedProfile,
300
+ id: classification.id,
301
+ preserved: classification.preserved,
302
+ converted: classification.converted,
303
+ unsupported: classification.unsupported,
304
+ changed: migrationChanges(classification),
305
+ };
306
+ }
307
+ /** Write bytes at mode 0600, failing closed on any tampering. Re-writing the same
308
+ * bytes is a safe no-op so a resumed apply reuses the exact prior backup. */
309
+ async function writePrivateBytes(target, bytes) {
310
+ await mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
311
+ try {
312
+ const handle = await open(target, 'wx', 0o600);
313
+ try {
314
+ await handle.writeFile(bytes);
315
+ await handle.sync();
316
+ }
317
+ finally {
318
+ await handle.close();
319
+ }
320
+ }
321
+ catch (error) {
322
+ if (error.code !== 'EEXIST')
323
+ throw error;
324
+ const existing = await readFile(target);
325
+ if (sha256Digest(existing) !== sha256Digest(bytes)) {
326
+ throw new OperateError('E_OPERATE_MIGRATION_CONFLICT', `Operating profile backup changed unexpectedly: ${path.basename(target)}`);
327
+ }
328
+ }
329
+ }
330
+ async function writeExactBackup(input) {
331
+ const root = path.join(resolveOperatingPaths(input.projectRoot, { localRoot: input.localRoot }).localRoot, 'profile-migration-backups', input.migrationId);
332
+ const backupFile = path.join(root, 'operate-profile.json');
333
+ await writePrivateBytes(backupFile, input.sourceBytes);
334
+ const manifest = {
335
+ implementation: 'openplanr-operate-profile-backup',
336
+ version: '1.0.0',
337
+ migrationId: input.migrationId,
338
+ sourcePath: LEGACY_PROFILE_RELATIVE_PATH,
339
+ sourceDigest: input.sourceDigest,
340
+ backupFile: 'operate-profile.json',
341
+ };
342
+ await writePrivateBytes(path.join(root, 'manifest.json'), Buffer.from(`${canonicalize(manifest)}\n`));
343
+ return backupFile;
344
+ }
345
+ export async function applyOperatingProfileMigration(input) {
346
+ const preview = await inspectOperatingProfileMigration(input);
347
+ if (!preview.present) {
348
+ return {
349
+ present: false,
350
+ applied: false,
351
+ alreadyApplied: false,
352
+ migrationId: null,
353
+ backupPath: null,
354
+ sourceDigest: null,
355
+ preserved: [],
356
+ converted: [],
357
+ unsupported: [],
358
+ };
359
+ }
360
+ if (!preview.changed) {
361
+ // Idempotent: the profile already carries only supported fields, so a second
362
+ // apply (or an apply of an already-clean profile) reports already-applied and
363
+ // makes no further change.
364
+ return {
365
+ present: true,
366
+ applied: false,
367
+ alreadyApplied: true,
368
+ migrationId: preview.migrationId,
369
+ backupPath: null,
370
+ sourceDigest: preview.sourceDigest,
371
+ preserved: preview.preserved,
372
+ converted: preview.converted,
373
+ unsupported: preview.unsupported,
374
+ };
375
+ }
376
+ if (!input.confirmed) {
377
+ throw new OperateError('E_OPERATE_AUTHORITY_REQUIRED', 'Operating profile migration requires explicit confirmation of its preview.', { preview });
378
+ }
379
+ return withOperatingLock(input.projectRoot, {
380
+ projectKey: operatingProjectKey(input.projectRoot),
381
+ name: 'profile-migration',
382
+ expectedEventHead: GENESIS_EVENT_HEAD,
383
+ currentEventHead: GENESIS_EVENT_HEAD,
384
+ localRoot: input.localRoot,
385
+ }, async () => {
386
+ const file = await readLegacyProfileFile(input.projectRoot);
387
+ if (file === null) {
388
+ return {
389
+ present: false,
390
+ applied: false,
391
+ alreadyApplied: false,
392
+ migrationId: null,
393
+ backupPath: null,
394
+ sourceDigest: null,
395
+ preserved: [],
396
+ converted: [],
397
+ unsupported: [],
398
+ };
399
+ }
400
+ const classification = classifyLegacyOperatingProfile(file.record);
401
+ const migrationId = profileMigrationId(file.digest);
402
+ if (!migrationChanges(classification)) {
403
+ return {
404
+ present: true,
405
+ applied: false,
406
+ alreadyApplied: true,
407
+ migrationId,
408
+ backupPath: null,
409
+ sourceDigest: file.digest,
410
+ preserved: classification.preserved,
411
+ converted: classification.converted,
412
+ unsupported: classification.unsupported,
413
+ };
414
+ }
415
+ // Exact pre-migration backup BEFORE any mutation.
416
+ const backupPath = await writeExactBackup({
417
+ projectRoot: input.projectRoot,
418
+ localRoot: input.localRoot,
419
+ migrationId,
420
+ sourceBytes: file.buffer,
421
+ sourceDigest: file.digest,
422
+ });
423
+ // Transactional, fsynced rewrite of the profile file (journal keeps a
424
+ // before-image and rolls back on any failure). Anchored to the genesis head
425
+ // because the profile is not part of the event chain.
426
+ const desired = `${canonicalize(classification.migratedProfile)}\n`;
427
+ const prepared = await prepareJournalTransaction(input.projectRoot, {
428
+ transactionId: `TXN-${migrationId}-apply`,
429
+ writes: [
430
+ {
431
+ relativePath: LEGACY_PROFILE_RELATIVE_PATH,
432
+ operation: 'replace',
433
+ content: desired,
434
+ mode: '0644',
435
+ },
436
+ ],
437
+ eventHead: GENESIS_EVENT_HEAD,
438
+ previewDigest: canonicalDigest({
439
+ migrationId,
440
+ sourceDigest: file.digest,
441
+ target: classification.migratedProfile,
442
+ }),
443
+ localRoot: input.localRoot,
444
+ now: input.now,
445
+ });
446
+ await applyJournalTransaction(input.projectRoot, prepared, {
447
+ currentEventHead: GENESIS_EVENT_HEAD,
448
+ });
449
+ return {
450
+ present: true,
451
+ applied: true,
452
+ alreadyApplied: false,
453
+ migrationId,
454
+ backupPath,
455
+ sourceDigest: file.digest,
456
+ preserved: classification.preserved,
457
+ converted: classification.converted,
458
+ unsupported: classification.unsupported,
459
+ };
460
+ });
461
+ }
462
+ //# sourceMappingURL=profile-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-migration.js","sourceRoot":"","sources":["../../../src/services/operate/profile-migration.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"projection-persistence.d.ts","sourceRoot":"","sources":["../../../src/services/operate/projection-persistence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"projection-persistence.d.ts","sourceRoot":"","sources":["../../../src/services/operate/projection-persistence.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAgB,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAsDxF,MAAM,MAAM,8BAA8B,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAE5E,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,8BAA8B,CAAC;IACvC,cAAc,EAAE,UAAU,MAAM,EAAE,CAAC;IACnC,YAAY,EAAE,UAAU,MAAM,EAAE,GAAG,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,UAAU,MAAM,EAAE,CAAC;IAChC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,aAAa,EAAE,UAAU,MAAM,EAAE,CAAC;IAClC,KAAK,EAAE,uBAAuB,EAAE,CAAC;IACjC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,wBAAwB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,gCAAiC,SAAQ,0BAA0B;IAClF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAoRD;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACvC;AAuCD;;;;;;;;GAQG;AACH,wBAAsB,+BAA+B,CAAC,KAAK,EAAE;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC,CAqFnD;AA6FD,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,cAAc,EACrB,aAAa,GAAE,WAAW,CAAC,MAAM,EAAE,0BAA0B,CAAa,GACzE,uBAAuB,EAAE,CA8B3B;AAkED,wBAAsB,+BAA+B,CAAC,KAAK,EAAE;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;CACtE,GAAG,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAWtC;AAED,wBAAsB,iCAAiC,CAAC,KAAK,EAAE;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB;AAED,wBAAsB,qCAAqC,CAAC,KAAK,EAAE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAiEtC;AAED,wBAAsB,2BAA2B,CAAC,KAAK,EAAE;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACzD,GAAG,OAAO,CAAC,gCAAgC,CAAC,CA6B5C;AAED,eAAO,MAAM,0BAA0B;;;;;;;;;CAY7B,CAAC"}
@@ -289,7 +289,15 @@ function renderAgenticActionsMarkdown(cycleId, reports) {
289
289
  */
290
290
  export async function readOperatingRichCycleArtifacts(input) {
291
291
  const artifacts = new Map();
292
- const cycles = input.state.cycles.filter((cycle) => cycle.state === 'reviewable' || cycle.state === 'closed');
292
+ // FR4 (SPEC-005): a still-advising (or consolidating/blocked) cycle materializes
293
+ // its readable artifacts too, so every validated lens is inspectable BEFORE
294
+ // Chair finalizes — not only once the cycle reaches `reviewable`. An in-flight
295
+ // cycle is only included once it actually has committed advisor results (guarded
296
+ // below on `evaluatedRoleIds`), so the pre-record advising handoff still writes
297
+ // no empty cycle directory.
298
+ const TERMINAL_CYCLE_STATES = new Set(['reviewable', 'closed']);
299
+ const cycles = input.state.cycles.filter((cycle) => TERMINAL_CYCLE_STATES.has(cycle.state) ||
300
+ ['advising', 'consolidating', 'blocked'].includes(cycle.state));
293
301
  if (cycles.length === 0)
294
302
  return artifacts;
295
303
  const { readOperatingReport, markdownLens, markdownCompleteRegisters } = await import('./reports.js');
@@ -314,6 +322,16 @@ export async function readOperatingRichCycleArtifacts(input) {
314
322
  ? cycleDrafts.map((draft) => `- **${draft.draftId}** [${draft.status} · ${draft.artifactKind}] \`${draft.path}\``)
315
323
  : ['- No citation-qualified provisional drafts were materialized.']),
316
324
  ].join('\n');
325
+ const evaluatedRoleIds = new Set(report.reports
326
+ .filter((entry) => entry.outcome !== 'not_evaluated')
327
+ .map((entry) => entry.roleId));
328
+ // An in-flight cycle earns a persisted artifact only once at least one lens
329
+ // has actually recorded (FR4); before that, its report is entirely
330
+ // not-evaluated and would write an empty cycle directory. A reviewable/closed
331
+ // cycle always materializes, exactly as before.
332
+ if (!TERMINAL_CYCLE_STATES.has(cycle.state) && evaluatedRoleIds.size === 0) {
333
+ continue;
334
+ }
317
335
  artifacts.set(cycle.id, {
318
336
  // FR8: the persisted `report.md` is self-contained — the concise brief +
319
337
  // lens reports + integrity section, then the complete uncapped registers.
@@ -332,9 +350,7 @@ export async function readOperatingRichCycleArtifacts(input) {
332
350
  })}\n`,
333
351
  actionsMarkdown: `${renderAgenticActionsMarkdown(cycle.id, report.reports)}\n\n${draftSection}`,
334
352
  boardByRole: new Map(report.reports.map((entry) => [entry.roleId, markdownLens(entry)])),
335
- evaluatedRoleIds: new Set(report.reports
336
- .filter((entry) => entry.outcome !== 'not_evaluated')
337
- .map((entry) => entry.roleId)),
353
+ evaluatedRoleIds,
338
354
  });
339
355
  }
340
356
  catch {
@@ -354,7 +370,10 @@ function markdownProjectionSpecs(state, richArtifacts) {
354
370
  managedContent: projection.render(state),
355
371
  }));
356
372
  const cycleArtifacts = [...state.cycles]
357
- .filter((cycle) => cycle.state === 'reviewable' || cycle.state === 'closed')
373
+ // FR4 (SPEC-005): a reviewable/closed cycle always materializes; an in-flight
374
+ // cycle materializes once it has a rich artifact (i.e. at least one lens has
375
+ // recorded), so partial validated progress is on disk before Chair runs.
376
+ .filter((cycle) => cycle.state === 'reviewable' || cycle.state === 'closed' || richArtifacts.has(cycle.id))
358
377
  .sort((left, right) => left.id.localeCompare(right.id))
359
378
  .flatMap((cycle) => {
360
379
  const rich = richArtifacts.get(cycle.id);