@skillcap/gdh 0.23.0 → 0.24.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.
- package/INSTALL-BUNDLE.json +1 -1
- package/RELEASE-SPAN-UPDATE-CONTRACTS.json +64 -0
- package/node_modules/@gdh/adapters/dist/authoring-hook-render.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/authoring-hook-render.js +2 -1
- package/node_modules/@gdh/adapters/dist/authoring-hook-render.js.map +1 -1
- package/node_modules/@gdh/adapters/dist/claude-statusline-render.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/claude-statusline-render.js +2 -1
- package/node_modules/@gdh/adapters/dist/claude-statusline-render.js.map +1 -1
- package/node_modules/@gdh/adapters/dist/claude-update-hook-render.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/claude-update-hook-render.js +2 -1
- package/node_modules/@gdh/adapters/dist/claude-update-hook-render.js.map +1 -1
- package/node_modules/@gdh/adapters/dist/claude-update-worker-render.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/claude-update-worker-render.js +2 -1
- package/node_modules/@gdh/adapters/dist/claude-update-worker-render.js.map +1 -1
- package/node_modules/@gdh/adapters/dist/deferred-actions-advisory.d.ts +71 -0
- package/node_modules/@gdh/adapters/dist/deferred-actions-advisory.d.ts.map +1 -0
- package/node_modules/@gdh/adapters/dist/deferred-actions-advisory.js +89 -0
- package/node_modules/@gdh/adapters/dist/deferred-actions-advisory.js.map +1 -0
- package/node_modules/@gdh/adapters/dist/durable-backup.d.ts +209 -0
- package/node_modules/@gdh/adapters/dist/durable-backup.d.ts.map +1 -0
- package/node_modules/@gdh/adapters/dist/durable-backup.js +346 -0
- package/node_modules/@gdh/adapters/dist/durable-backup.js.map +1 -0
- package/node_modules/@gdh/adapters/dist/index.d.ts +10 -1
- package/node_modules/@gdh/adapters/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/index.js +24 -2
- package/node_modules/@gdh/adapters/dist/index.js.map +1 -1
- package/node_modules/@gdh/adapters/dist/inventory-sweep.d.ts +53 -0
- package/node_modules/@gdh/adapters/dist/inventory-sweep.d.ts.map +1 -0
- package/node_modules/@gdh/adapters/dist/inventory-sweep.js +98 -0
- package/node_modules/@gdh/adapters/dist/inventory-sweep.js.map +1 -0
- package/node_modules/@gdh/adapters/dist/process-orchestration.d.ts +223 -0
- package/node_modules/@gdh/adapters/dist/process-orchestration.d.ts.map +1 -0
- package/node_modules/@gdh/adapters/dist/process-orchestration.js +368 -0
- package/node_modules/@gdh/adapters/dist/process-orchestration.js.map +1 -0
- package/node_modules/@gdh/adapters/dist/self-update-mechanics.d.ts +157 -14
- package/node_modules/@gdh/adapters/dist/self-update-mechanics.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/self-update-mechanics.js +570 -89
- package/node_modules/@gdh/adapters/dist/self-update-mechanics.js.map +1 -1
- package/node_modules/@gdh/adapters/dist/skill-rendering.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/skill-rendering.js +25 -0
- package/node_modules/@gdh/adapters/dist/skill-rendering.js.map +1 -1
- package/node_modules/@gdh/adapters/package.json +8 -8
- package/node_modules/@gdh/authoring/package.json +2 -2
- package/node_modules/@gdh/cli/dist/index.d.ts +9 -0
- package/node_modules/@gdh/cli/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/cli/dist/index.js +244 -2
- package/node_modules/@gdh/cli/dist/index.js.map +1 -1
- package/node_modules/@gdh/cli/dist/migrate.d.ts +152 -1
- package/node_modules/@gdh/cli/dist/migrate.d.ts.map +1 -1
- package/node_modules/@gdh/cli/dist/migrate.js +290 -6
- package/node_modules/@gdh/cli/dist/migrate.js.map +1 -1
- package/node_modules/@gdh/cli/dist/self-update.d.ts +14 -0
- package/node_modules/@gdh/cli/dist/self-update.d.ts.map +1 -1
- package/node_modules/@gdh/cli/dist/self-update.js +197 -15
- package/node_modules/@gdh/cli/dist/self-update.js.map +1 -1
- package/node_modules/@gdh/cli/package.json +10 -10
- package/node_modules/@gdh/core/dist/index.d.ts +97 -5
- package/node_modules/@gdh/core/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/core/dist/index.js +23 -5
- package/node_modules/@gdh/core/dist/index.js.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/entries/s2c2_to_s2c3_rules_schema_v2_to_v3.d.ts +3 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s2c2_to_s2c3_rules_schema_v2_to_v3.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s2c2_to_s2c3_rules_schema_v2_to_v3.js +247 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s2c2_to_s2c3_rules_schema_v2_to_v3.js.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s3c8_to_s3c9_register_runtime_bridge_autoload.d.ts +3 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s3c8_to_s3c9_register_runtime_bridge_autoload.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s3c8_to_s3c9_register_runtime_bridge_autoload.js +152 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s3c8_to_s3c9_register_runtime_bridge_autoload.js.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/envelope-output-validator.d.ts +3 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/envelope-output-validator.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/envelope-output-validator.js +67 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/envelope-output-validator.js.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/index.d.ts +37 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/index.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/index.js +60 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/index.js.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/types.d.ts +121 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/types.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/types.js +2 -0
- package/node_modules/@gdh/core/dist/migrations/envelopes/types.js.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/golden-harness.d.ts +40 -0
- package/node_modules/@gdh/core/dist/migrations/golden-harness.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/golden-harness.js +71 -0
- package/node_modules/@gdh/core/dist/migrations/golden-harness.js.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.d.ts +322 -0
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.js +384 -0
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.js.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/probes.d.ts +58 -0
- package/node_modules/@gdh/core/dist/migrations/probes.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/probes.js +112 -0
- package/node_modules/@gdh/core/dist/migrations/probes.js.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/registry.d.ts +205 -0
- package/node_modules/@gdh/core/dist/migrations/registry.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/registry.js +214 -0
- package/node_modules/@gdh/core/dist/migrations/registry.js.map +1 -0
- package/node_modules/@gdh/core/dist/state/atomic-write.d.ts +19 -0
- package/node_modules/@gdh/core/dist/state/atomic-write.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/state/atomic-write.js +34 -0
- package/node_modules/@gdh/core/dist/state/atomic-write.js.map +1 -0
- package/node_modules/@gdh/core/dist/state/migration-state.d.ts +135 -0
- package/node_modules/@gdh/core/dist/state/migration-state.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/state/migration-state.js +186 -0
- package/node_modules/@gdh/core/dist/state/migration-state.js.map +1 -0
- package/node_modules/@gdh/core/dist/state/processes-snapshot.d.ts +72 -0
- package/node_modules/@gdh/core/dist/state/processes-snapshot.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/state/processes-snapshot.js +113 -0
- package/node_modules/@gdh/core/dist/state/processes-snapshot.js.map +1 -0
- package/node_modules/@gdh/core/dist/state/render-inventory.d.ts +54 -0
- package/node_modules/@gdh/core/dist/state/render-inventory.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/state/render-inventory.js +77 -0
- package/node_modules/@gdh/core/dist/state/render-inventory.js.map +1 -0
- package/node_modules/@gdh/core/package.json +1 -1
- package/node_modules/@gdh/docs/dist/agent-contract.d.ts.map +1 -1
- package/node_modules/@gdh/docs/dist/agent-contract.js +2 -1
- package/node_modules/@gdh/docs/dist/agent-contract.js.map +1 -1
- package/node_modules/@gdh/docs/dist/guidance.d.ts.map +1 -1
- package/node_modules/@gdh/docs/dist/guidance.js +3 -1
- package/node_modules/@gdh/docs/dist/guidance.js.map +1 -1
- package/node_modules/@gdh/docs/package.json +2 -2
- package/node_modules/@gdh/mcp/package.json +8 -8
- package/node_modules/@gdh/observability/package.json +2 -2
- package/node_modules/@gdh/runtime/dist/bridge-surface.js +63 -2
- package/node_modules/@gdh/runtime/dist/bridge-surface.js.map +1 -1
- package/node_modules/@gdh/runtime/package.json +2 -2
- package/node_modules/@gdh/scan/package.json +3 -3
- package/node_modules/@gdh/verify/package.json +7 -7
- package/package.json +11 -11
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { GdhManagedSurfaceClass } from "./managed-surface-classes.js";
|
|
2
|
+
import type { GdhMigrationEnvelope } from "./envelopes/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Schema/agentContract pair that identifies a migration boundary.
|
|
5
|
+
* D-02: pair drives chain resolution; package version is presentation only.
|
|
6
|
+
*/
|
|
7
|
+
export interface GdhMigrationVersionPair {
|
|
8
|
+
readonly schema: number;
|
|
9
|
+
readonly agentContract: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Result of a per-entry verify probe (D-05).
|
|
13
|
+
* Distinct from STA-03 deferred-action probes (those live in migration.json).
|
|
14
|
+
*/
|
|
15
|
+
export type GdhMigrationEntryVerifyResult = {
|
|
16
|
+
readonly ok: true;
|
|
17
|
+
} | {
|
|
18
|
+
readonly ok: false;
|
|
19
|
+
readonly reason: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* GDH migration registry entry (REG-01 / D-01).
|
|
23
|
+
*
|
|
24
|
+
* Each entry covers a single schema/agentContract pair transition.
|
|
25
|
+
* Append-only; no removal of historic entries within the supported range.
|
|
26
|
+
*
|
|
27
|
+
* The `transform` signature is filesystem-first per the walk-test consumer shape
|
|
28
|
+
* at tests/integration/migration-chain.test.ts:244-253. Per-entry golden tests
|
|
29
|
+
* adapt this to the file-map shape via runMigrationGolden.
|
|
30
|
+
*/
|
|
31
|
+
export interface GdhMigrationEntry {
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly from: GdhMigrationVersionPair;
|
|
34
|
+
readonly to: GdhMigrationVersionPair;
|
|
35
|
+
readonly classesTouched: readonly GdhManagedSurfaceClass[];
|
|
36
|
+
readonly transform: (targetPath: string) => Promise<void>;
|
|
37
|
+
readonly verify: (targetPath: string) => Promise<GdhMigrationEntryVerifyResult>;
|
|
38
|
+
/** Optional reference to a Phase 73 subagent envelope. Unused in Phase 72 (D-25). */
|
|
39
|
+
readonly envelope_ref?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Per-release supplementary cleanup paths declared by this entry —
|
|
42
|
+
* workspace-relative POSIX paths the inventory sweep should delete in
|
|
43
|
+
* addition to set-diff orphans.
|
|
44
|
+
*
|
|
45
|
+
* Use sparingly: orphans normally come from manifest set-diff (the new
|
|
46
|
+
* render set vs the prior render-inventory.paths). This field is for
|
|
47
|
+
* targets OUTSIDE the rendered surface — e.g., orphaned MCP processes
|
|
48
|
+
* captured at registry-entry resolution time, or class-1 file drops the
|
|
49
|
+
* inventory-set-diff cannot derive.
|
|
50
|
+
*
|
|
51
|
+
* Validated by `isWorkspaceRelativePath` at sweep time (T-72-03-01); any
|
|
52
|
+
* candidate failing the check is skipped with a structured warning, never
|
|
53
|
+
* deleted. Per 72-CONTEXT.md "specifics" section.
|
|
54
|
+
*/
|
|
55
|
+
readonly supplementaryDeletions?: readonly string[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Validates a path is workspace-relative POSIX.
|
|
59
|
+
*
|
|
60
|
+
* Rejects:
|
|
61
|
+
* - empty string
|
|
62
|
+
* - absolute paths (starts with "/")
|
|
63
|
+
* - paths containing ".." segments
|
|
64
|
+
* - paths containing "" segments (double-slash)
|
|
65
|
+
* - paths containing null bytes
|
|
66
|
+
*
|
|
67
|
+
* Used to gate `supplementaryDeletions` and inventory-sweep delete targets
|
|
68
|
+
* against path traversal (T-72-03-01). Any candidate failing this check
|
|
69
|
+
* MUST be skipped by the sweep with a `path_traversal_blocked` reason.
|
|
70
|
+
*/
|
|
71
|
+
export declare function isWorkspaceRelativePath(candidate: string): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Central migration registry (REG-01 / D-01).
|
|
74
|
+
*
|
|
75
|
+
* Ordered ascending by `from` pair (schema, then agentContract).
|
|
76
|
+
* Append-only across phases.
|
|
77
|
+
*
|
|
78
|
+
* D-09 (clarified by Phase 72 Plan 02 audit, see
|
|
79
|
+
* .planning/phases/72-migration-workflow-internals-registry-inventory-durable-back/72-02-AUDIT.md):
|
|
80
|
+
* the registry contains one entry per real class-2/3 schema/agent-contract
|
|
81
|
+
* bump in the supported version range. Bumps that produce no class-2/3
|
|
82
|
+
* work — i.e., the bump's user-visible effect is fully covered by
|
|
83
|
+
* deterministic class-1 re-render — are owned by
|
|
84
|
+
* `installSupportedAgentAdapters` re-bake at D-10 step 7 and are NOT
|
|
85
|
+
* represented in the registry. Adding identity-only entries for such
|
|
86
|
+
* bumps is the rejected "no-op identity entry" pattern: it would create
|
|
87
|
+
* a transform with no work and a verify probe with no shape to assert,
|
|
88
|
+
* masking real drift the chain matrix is meant to catch. Rollup
|
|
89
|
+
* mega-entries are also rejected (loses chain composition fidelity).
|
|
90
|
+
*
|
|
91
|
+
* Phase 72 Plan 02 populates this array with one entry
|
|
92
|
+
* (`entry_s2c2_to_s2c3_rules_schema`); the other three v0.18→HEAD bumps
|
|
93
|
+
* (s2c3→s2c6, s2c6→s2c7, s3c7→s3c8) are class-1-only per the audit and
|
|
94
|
+
* are intentionally absent.
|
|
95
|
+
*/
|
|
96
|
+
export declare const MIGRATION_REGISTRY_ENTRIES: readonly [GdhMigrationEntry, GdhMigrationEntry];
|
|
97
|
+
/**
|
|
98
|
+
* Result of applyMigrationChain (D-06).
|
|
99
|
+
*
|
|
100
|
+
* Discriminated union following the project pattern in self-update-mechanics.ts.
|
|
101
|
+
*
|
|
102
|
+
* **Externalized rollback contract (WR-05).** This function does NOT roll back
|
|
103
|
+
* partial transform output on `verify_failed` or `transform_threw`. The
|
|
104
|
+
* `transform` step writes to disk BEFORE its own `verify` runs (and before the
|
|
105
|
+
* next entry's transform). When verify rejects, those writes persist on disk
|
|
106
|
+
* unchanged; the failed entry's intended-but-rejected state is also already
|
|
107
|
+
* partially or fully on disk on `transform_threw`. The `partialWriteOccurred`
|
|
108
|
+
* field on both failure variants is a typed reminder that the caller MUST
|
|
109
|
+
* either (a) restore from a durable backup taken before the chain ran (the
|
|
110
|
+
* pattern used by `bumpAndRebakePin`'s D-10 step 8a), or (b) accept the
|
|
111
|
+
* partial mutation. Standalone callers that consume `applyMigrationChain`
|
|
112
|
+
* without a durable backup MUST treat `partialWriteOccurred: true` as a
|
|
113
|
+
* cleanup obligation; ignoring it leaves the workspace in a half-applied
|
|
114
|
+
* state that the next chain run may verify-pass against (entries are
|
|
115
|
+
* idempotent) but which violates the all-or-nothing guarantee operators
|
|
116
|
+
* expect from migration tooling.
|
|
117
|
+
*/
|
|
118
|
+
export type GdhApplyMigrationChainResult = {
|
|
119
|
+
readonly state: "applied";
|
|
120
|
+
readonly applied: readonly string[];
|
|
121
|
+
} | {
|
|
122
|
+
readonly state: "noop";
|
|
123
|
+
readonly applied: readonly string[];
|
|
124
|
+
} | {
|
|
125
|
+
readonly state: "verify_failed";
|
|
126
|
+
readonly failedEntryId: string;
|
|
127
|
+
readonly reason: string;
|
|
128
|
+
readonly applied: readonly string[];
|
|
129
|
+
/**
|
|
130
|
+
* WR-05: Always `true` on this variant — the failed entry's `transform`
|
|
131
|
+
* ran to completion before `verify` rejected, so its intended output is
|
|
132
|
+
* already on disk. Caller must restore from durable backup or accept
|
|
133
|
+
* the partial write.
|
|
134
|
+
*/
|
|
135
|
+
readonly partialWriteOccurred: true;
|
|
136
|
+
} | {
|
|
137
|
+
readonly state: "transform_threw";
|
|
138
|
+
readonly failedEntryId: string;
|
|
139
|
+
readonly error: string;
|
|
140
|
+
readonly applied: readonly string[];
|
|
141
|
+
/**
|
|
142
|
+
* WR-05 / Phase 73: `true` when the entry's `transform` threw mid-execution
|
|
143
|
+
* (existing Phase 72 path) — an indeterminate amount of its intended output
|
|
144
|
+
* may already be on disk; caller must restore from durable backup or accept
|
|
145
|
+
* the partial write. `false` for Phase 73 synthetic envelope-resolution
|
|
146
|
+
* failures (`envelope_not_found`) where the gate trips BEFORE transform
|
|
147
|
+
* runs and nothing is on disk — bumpAndRebakePin still rolls back from the
|
|
148
|
+
* durable backup, but no partial chain output requires cleanup.
|
|
149
|
+
*/
|
|
150
|
+
readonly partialWriteOccurred: boolean;
|
|
151
|
+
} | {
|
|
152
|
+
/** Phase 73 D-09: chain paused on an unresolved envelope_ref. */
|
|
153
|
+
readonly state: "needs_envelope";
|
|
154
|
+
readonly envelopeRef: string;
|
|
155
|
+
readonly envelope: GdhMigrationEnvelope;
|
|
156
|
+
readonly fromPair: GdhMigrationVersionPair;
|
|
157
|
+
readonly toPair: GdhMigrationVersionPair;
|
|
158
|
+
/** Entries already applied in this chain run before the pause. */
|
|
159
|
+
readonly applied: readonly string[];
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* applyMigrationChain — filter entries whose `from` >= fromPair AND `to` <= toPair,
|
|
163
|
+
* iterate in registry order, run transform then verify, halt on first failure.
|
|
164
|
+
*
|
|
165
|
+
* **Phase 73 envelope gate (D-09 / D-10).** When an entry declares
|
|
166
|
+
* `envelope_ref` (Phase 73), this function pauses BEFORE running its transform
|
|
167
|
+
* and returns a `needs_envelope` result so the calling agent can run the
|
|
168
|
+
* envelope (subagent or inline per D-05/D-06). On the resume run, if a
|
|
169
|
+
* recorded slot exists in `migration.json.envelopes[<envelope_ref>]` whose
|
|
170
|
+
* `(envelope_ref, from_pin, to_pin)` triple matches the current chain step
|
|
171
|
+
* (per `envelopePinContext`), the entry is treated as advanced (Phase 73
|
|
172
|
+
* records evidence only — Pitfall 7) and the chain continues. Stale slot
|
|
173
|
+
* (pin mismatch) → re-emit `needs_envelope`. Missing/unresolved envelope file
|
|
174
|
+
* → synthetic `transform_threw` with `envelope_not_found:` reason. Phase 72
|
|
175
|
+
* mechanical entries (envelope_ref undefined) skip this gate entirely.
|
|
176
|
+
*
|
|
177
|
+
* **Externalized rollback contract (WR-05).** This function does NOT roll back
|
|
178
|
+
* partial transform output. On `verify_failed`, the failed entry's transform
|
|
179
|
+
* ran to completion (writing to disk) before verify rejected. On
|
|
180
|
+
* `transform_threw`, an indeterminate amount of the failed entry's output may
|
|
181
|
+
* be on disk. In both cases the result carries `partialWriteOccurred: true`
|
|
182
|
+
* so callers cannot silently ignore the cleanup obligation. The integrated
|
|
183
|
+
* `bumpAndRebakePin` orchestrator restores from the durable backup at
|
|
184
|
+
* `.gdh-state/backup/` per Plan 72-08 D-10 step 8a. Standalone callers (the
|
|
185
|
+
* chain matrix walk-test, future direct invocations) that lack a durable
|
|
186
|
+
* backup MUST either implement an equivalent rollback or accept the partial
|
|
187
|
+
* mutation.
|
|
188
|
+
*
|
|
189
|
+
* The `entries` parameter exists for testability; production callers omit it
|
|
190
|
+
* and the default `MIGRATION_REGISTRY_ENTRIES` is used.
|
|
191
|
+
*/
|
|
192
|
+
export declare function applyMigrationChain(targetPath: string, fromPair: GdhMigrationVersionPair, toPair: GdhMigrationVersionPair, entries?: readonly GdhMigrationEntry[],
|
|
193
|
+
/**
|
|
194
|
+
* Phase 73 (Plan 73-03): optional pin pair for D-10 envelope staleness
|
|
195
|
+
* comparison. When omitted (Phase 72 callers, the chain matrix walk-test),
|
|
196
|
+
* envelope-bearing entries are unreachable in the Phase 72 registry — the
|
|
197
|
+
* function still type-checks, but the envelope gate cannot validate
|
|
198
|
+
* `from_pin`/`to_pin` and fails closed (re-emits the envelope). Production
|
|
199
|
+
* callers (`bumpAndRebakePin` in Plan 73-04) always pass this argument.
|
|
200
|
+
*/
|
|
201
|
+
envelopePinContext?: {
|
|
202
|
+
readonly fromPin: string;
|
|
203
|
+
readonly toPin: string;
|
|
204
|
+
}): Promise<GdhApplyMigrationChainResult>;
|
|
205
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/migrations/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { entry_s2c2_to_s2c3 } from "./entries/s2c2_to_s2c3_rules_schema_v2_to_v3.js";
|
|
2
|
+
import { entry_s3c8_to_s3c9 } from "./entries/s3c8_to_s3c9_register_runtime_bridge_autoload.js";
|
|
3
|
+
import { resolveEnvelopeBySlug } from "./envelopes/index.js";
|
|
4
|
+
import { readMigrationState } from "../state/migration-state.js";
|
|
5
|
+
/**
|
|
6
|
+
* Validates a path is workspace-relative POSIX.
|
|
7
|
+
*
|
|
8
|
+
* Rejects:
|
|
9
|
+
* - empty string
|
|
10
|
+
* - absolute paths (starts with "/")
|
|
11
|
+
* - paths containing ".." segments
|
|
12
|
+
* - paths containing "" segments (double-slash)
|
|
13
|
+
* - paths containing null bytes
|
|
14
|
+
*
|
|
15
|
+
* Used to gate `supplementaryDeletions` and inventory-sweep delete targets
|
|
16
|
+
* against path traversal (T-72-03-01). Any candidate failing this check
|
|
17
|
+
* MUST be skipped by the sweep with a `path_traversal_blocked` reason.
|
|
18
|
+
*/
|
|
19
|
+
export function isWorkspaceRelativePath(candidate) {
|
|
20
|
+
if (typeof candidate !== "string" || candidate.length === 0)
|
|
21
|
+
return false;
|
|
22
|
+
if (candidate.startsWith("/"))
|
|
23
|
+
return false;
|
|
24
|
+
if (candidate.includes("\0"))
|
|
25
|
+
return false;
|
|
26
|
+
const segments = candidate.split("/");
|
|
27
|
+
return !segments.some((s) => s === ".." || s === "");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Central migration registry (REG-01 / D-01).
|
|
31
|
+
*
|
|
32
|
+
* Ordered ascending by `from` pair (schema, then agentContract).
|
|
33
|
+
* Append-only across phases.
|
|
34
|
+
*
|
|
35
|
+
* D-09 (clarified by Phase 72 Plan 02 audit, see
|
|
36
|
+
* .planning/phases/72-migration-workflow-internals-registry-inventory-durable-back/72-02-AUDIT.md):
|
|
37
|
+
* the registry contains one entry per real class-2/3 schema/agent-contract
|
|
38
|
+
* bump in the supported version range. Bumps that produce no class-2/3
|
|
39
|
+
* work — i.e., the bump's user-visible effect is fully covered by
|
|
40
|
+
* deterministic class-1 re-render — are owned by
|
|
41
|
+
* `installSupportedAgentAdapters` re-bake at D-10 step 7 and are NOT
|
|
42
|
+
* represented in the registry. Adding identity-only entries for such
|
|
43
|
+
* bumps is the rejected "no-op identity entry" pattern: it would create
|
|
44
|
+
* a transform with no work and a verify probe with no shape to assert,
|
|
45
|
+
* masking real drift the chain matrix is meant to catch. Rollup
|
|
46
|
+
* mega-entries are also rejected (loses chain composition fidelity).
|
|
47
|
+
*
|
|
48
|
+
* Phase 72 Plan 02 populates this array with one entry
|
|
49
|
+
* (`entry_s2c2_to_s2c3_rules_schema`); the other three v0.18→HEAD bumps
|
|
50
|
+
* (s2c3→s2c6, s2c6→s2c7, s3c7→s3c8) are class-1-only per the audit and
|
|
51
|
+
* are intentionally absent.
|
|
52
|
+
*/
|
|
53
|
+
export const MIGRATION_REGISTRY_ENTRIES = [
|
|
54
|
+
entry_s2c2_to_s2c3,
|
|
55
|
+
entry_s3c8_to_s3c9,
|
|
56
|
+
];
|
|
57
|
+
/**
|
|
58
|
+
* Pair comparator: returns negative if a < b, zero if equal, positive if a > b.
|
|
59
|
+
* Schema is the major axis; agentContract is the minor axis.
|
|
60
|
+
*/
|
|
61
|
+
function comparePair(a, b) {
|
|
62
|
+
if (a.schema !== b.schema)
|
|
63
|
+
return a.schema - b.schema;
|
|
64
|
+
return a.agentContract - b.agentContract;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* D-10 staleness check (Phase 73). A recorded envelope slot is valid only when
|
|
68
|
+
* BOTH the slot's `from_pin` and `to_pin` match the chain step's bump pair.
|
|
69
|
+
* The slot is keyed by `envelope_ref` at the call site (the caller looks it up
|
|
70
|
+
* in `state.envelopes[entry.envelope_ref]`); this helper validates the
|
|
71
|
+
* remaining two axes of the (envelope_ref, from_pin, to_pin) triple.
|
|
72
|
+
*
|
|
73
|
+
* Pitfall 1 — defense in depth: the explicit pin-pair comparison is what
|
|
74
|
+
* stops a hand-edited `migration.json` slot whose pin pair targets a
|
|
75
|
+
* different chain step from silently advancing the current step.
|
|
76
|
+
*/
|
|
77
|
+
function isEnvelopeRecordValid(slot, expected) {
|
|
78
|
+
return slot.from_pin === expected.from_pin && slot.to_pin === expected.to_pin;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* applyMigrationChain — filter entries whose `from` >= fromPair AND `to` <= toPair,
|
|
82
|
+
* iterate in registry order, run transform then verify, halt on first failure.
|
|
83
|
+
*
|
|
84
|
+
* **Phase 73 envelope gate (D-09 / D-10).** When an entry declares
|
|
85
|
+
* `envelope_ref` (Phase 73), this function pauses BEFORE running its transform
|
|
86
|
+
* and returns a `needs_envelope` result so the calling agent can run the
|
|
87
|
+
* envelope (subagent or inline per D-05/D-06). On the resume run, if a
|
|
88
|
+
* recorded slot exists in `migration.json.envelopes[<envelope_ref>]` whose
|
|
89
|
+
* `(envelope_ref, from_pin, to_pin)` triple matches the current chain step
|
|
90
|
+
* (per `envelopePinContext`), the entry is treated as advanced (Phase 73
|
|
91
|
+
* records evidence only — Pitfall 7) and the chain continues. Stale slot
|
|
92
|
+
* (pin mismatch) → re-emit `needs_envelope`. Missing/unresolved envelope file
|
|
93
|
+
* → synthetic `transform_threw` with `envelope_not_found:` reason. Phase 72
|
|
94
|
+
* mechanical entries (envelope_ref undefined) skip this gate entirely.
|
|
95
|
+
*
|
|
96
|
+
* **Externalized rollback contract (WR-05).** This function does NOT roll back
|
|
97
|
+
* partial transform output. On `verify_failed`, the failed entry's transform
|
|
98
|
+
* ran to completion (writing to disk) before verify rejected. On
|
|
99
|
+
* `transform_threw`, an indeterminate amount of the failed entry's output may
|
|
100
|
+
* be on disk. In both cases the result carries `partialWriteOccurred: true`
|
|
101
|
+
* so callers cannot silently ignore the cleanup obligation. The integrated
|
|
102
|
+
* `bumpAndRebakePin` orchestrator restores from the durable backup at
|
|
103
|
+
* `.gdh-state/backup/` per Plan 72-08 D-10 step 8a. Standalone callers (the
|
|
104
|
+
* chain matrix walk-test, future direct invocations) that lack a durable
|
|
105
|
+
* backup MUST either implement an equivalent rollback or accept the partial
|
|
106
|
+
* mutation.
|
|
107
|
+
*
|
|
108
|
+
* The `entries` parameter exists for testability; production callers omit it
|
|
109
|
+
* and the default `MIGRATION_REGISTRY_ENTRIES` is used.
|
|
110
|
+
*/
|
|
111
|
+
export async function applyMigrationChain(targetPath, fromPair, toPair, entries = MIGRATION_REGISTRY_ENTRIES,
|
|
112
|
+
/**
|
|
113
|
+
* Phase 73 (Plan 73-03): optional pin pair for D-10 envelope staleness
|
|
114
|
+
* comparison. When omitted (Phase 72 callers, the chain matrix walk-test),
|
|
115
|
+
* envelope-bearing entries are unreachable in the Phase 72 registry — the
|
|
116
|
+
* function still type-checks, but the envelope gate cannot validate
|
|
117
|
+
* `from_pin`/`to_pin` and fails closed (re-emits the envelope). Production
|
|
118
|
+
* callers (`bumpAndRebakePin` in Plan 73-04) always pass this argument.
|
|
119
|
+
*/
|
|
120
|
+
envelopePinContext) {
|
|
121
|
+
const inRange = entries.filter((entry) => comparePair(entry.from, fromPair) >= 0 &&
|
|
122
|
+
comparePair(entry.to, toPair) <= 0);
|
|
123
|
+
const applied = [];
|
|
124
|
+
for (const entry of inRange) {
|
|
125
|
+
// ── Phase 73 envelope gate (D-09 / Pitfall 3 ordering invariant) ──
|
|
126
|
+
// MUST run BEFORE entry.transform: an unresolved envelope must not
|
|
127
|
+
// mutate disk. Phase 72 mechanical entries (envelope_ref undefined)
|
|
128
|
+
// skip this branch entirely.
|
|
129
|
+
if (entry.envelope_ref !== undefined) {
|
|
130
|
+
const envelope = resolveEnvelopeBySlug(entry.envelope_ref);
|
|
131
|
+
if (envelope === null) {
|
|
132
|
+
// Author bug: entry declares envelope_ref but no envelope file is
|
|
133
|
+
// registered in ENVELOPE_REGISTRY. Surface as transform_threw with
|
|
134
|
+
// the synthetic `envelope_not_found` reason so the existing rollback
|
|
135
|
+
// path applies (durable backup is intact at the bumpAndRebakePin
|
|
136
|
+
// layer); partialWriteOccurred=false because nothing was written.
|
|
137
|
+
return {
|
|
138
|
+
state: "transform_threw",
|
|
139
|
+
failedEntryId: entry.id,
|
|
140
|
+
error: `envelope_not_found: entry ${entry.id} declares envelope_ref="${entry.envelope_ref}" but no envelope file is registered`,
|
|
141
|
+
applied,
|
|
142
|
+
partialWriteOccurred: false,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const state = await readMigrationState(targetPath);
|
|
146
|
+
const recorded = state?.envelopes?.[entry.envelope_ref] ?? null;
|
|
147
|
+
const triple = envelopePinContext !== undefined
|
|
148
|
+
? {
|
|
149
|
+
envelope_ref: entry.envelope_ref,
|
|
150
|
+
from_pin: envelopePinContext.fromPin,
|
|
151
|
+
to_pin: envelopePinContext.toPin,
|
|
152
|
+
}
|
|
153
|
+
: null;
|
|
154
|
+
const valid = recorded !== null &&
|
|
155
|
+
triple !== null &&
|
|
156
|
+
isEnvelopeRecordValid(recorded, triple) &&
|
|
157
|
+
// WR-01: only `output_contract.state === "apply"` advances the chain.
|
|
158
|
+
// `abort` and `needs_clarification` are recorded as evidence (Pitfall 7
|
|
159
|
+
// — record-only) but MUST NOT advance the chain past the entry, which
|
|
160
|
+
// would silently claim success for an envelope the agent declined or
|
|
161
|
+
// could not resolve. Re-emit needs_envelope so the operator can either
|
|
162
|
+
// re-record the envelope (after collecting clarification) or run
|
|
163
|
+
// `gdh migration clear-envelope <slug>` and re-attempt.
|
|
164
|
+
recorded.output_contract.state === "apply";
|
|
165
|
+
if (!valid) {
|
|
166
|
+
return {
|
|
167
|
+
state: "needs_envelope",
|
|
168
|
+
envelopeRef: entry.envelope_ref,
|
|
169
|
+
envelope,
|
|
170
|
+
fromPair: entry.from,
|
|
171
|
+
toPair: entry.to,
|
|
172
|
+
applied,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// Recorded result is valid for this triple AND output_contract.state is
|
|
176
|
+
// "apply". Phase 73 records evidence ONLY (Pitfall 7); the apply-consumer
|
|
177
|
+
// that mutates disk based on output_contract.changes is out of scope for
|
|
178
|
+
// v1.18 because no Phase 72 entry has envelope_ref set. Mark the entry
|
|
179
|
+
// as advanced and continue.
|
|
180
|
+
applied.push(entry.id);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
// ── existing Phase 72 transform → verify path (unchanged) ──
|
|
184
|
+
try {
|
|
185
|
+
await entry.transform(targetPath);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
return {
|
|
189
|
+
state: "transform_threw",
|
|
190
|
+
failedEntryId: entry.id,
|
|
191
|
+
error: error instanceof Error ? error.message : String(error),
|
|
192
|
+
applied,
|
|
193
|
+
// WR-05: transform threw mid-execution; partial output may be on disk.
|
|
194
|
+
partialWriteOccurred: true,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const verifyResult = await entry.verify(targetPath);
|
|
198
|
+
if (!verifyResult.ok) {
|
|
199
|
+
return {
|
|
200
|
+
state: "verify_failed",
|
|
201
|
+
failedEntryId: entry.id,
|
|
202
|
+
reason: verifyResult.reason,
|
|
203
|
+
applied,
|
|
204
|
+
// WR-05: transform completed before verify rejected; output is on disk.
|
|
205
|
+
partialWriteOccurred: true,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
applied.push(entry.id);
|
|
209
|
+
}
|
|
210
|
+
return inRange.length === 0
|
|
211
|
+
? { state: "noop", applied: [] }
|
|
212
|
+
: { state: "applied", applied };
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/migrations/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,4DAA4D,CAAC;AAEhG,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAwDjE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1E,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,kBAAkB;IAClB,kBAAkB;CAC6B,CAAC;AAkElD;;;GAGG;AACH,SAAS,WAAW,CAClB,CAA0B,EAC1B,CAA0B;IAE1B,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtD,OAAO,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,qBAAqB,CAC5B,IAA8B,EAC9B,QAAoE;IAEpE,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAAkB,EAClB,QAAiC,EACjC,MAA+B,EAC/B,UAAwC,0BAA0B;AAClE;;;;;;;GAOG;AACH,kBAAyE;IAEzE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAC5B,CAAC,KAAK,EAAE,EAAE,CACR,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;QACtC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CACrC,CAAC;IACF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,qEAAqE;QACrE,mEAAmE;QACnE,oEAAoE;QACpE,6BAA6B;QAC7B,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC3D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,kEAAkE;gBAClE,mEAAmE;gBACnE,qEAAqE;gBACrE,iEAAiE;gBACjE,kEAAkE;gBAClE,OAAO;oBACL,KAAK,EAAE,iBAAiB;oBACxB,aAAa,EAAE,KAAK,CAAC,EAAE;oBACvB,KAAK,EAAE,6BAA6B,KAAK,CAAC,EAAE,2BAA2B,KAAK,CAAC,YAAY,sCAAsC;oBAC/H,OAAO;oBACP,oBAAoB,EAAE,KAAK;iBAC5B,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,QAAQ,GAAG,KAAK,EAAE,SAAS,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC;YAChE,MAAM,MAAM,GACV,kBAAkB,KAAK,SAAS;gBAC9B,CAAC,CAAC;oBACE,YAAY,EAAE,KAAK,CAAC,YAAY;oBAChC,QAAQ,EAAE,kBAAkB,CAAC,OAAO;oBACpC,MAAM,EAAE,kBAAkB,CAAC,KAAK;iBACjC;gBACH,CAAC,CAAC,IAAI,CAAC;YACX,MAAM,KAAK,GACT,QAAQ,KAAK,IAAI;gBACjB,MAAM,KAAK,IAAI;gBACf,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC;gBACvC,sEAAsE;gBACtE,wEAAwE;gBACxE,sEAAsE;gBACtE,qEAAqE;gBACrE,uEAAuE;gBACvE,iEAAiE;gBACjE,wDAAwD;gBACxD,QAAQ,CAAC,eAAe,CAAC,KAAK,KAAK,OAAO,CAAC;YAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO;oBACL,KAAK,EAAE,gBAAgB;oBACvB,WAAW,EAAE,KAAK,CAAC,YAAY;oBAC/B,QAAQ;oBACR,QAAQ,EAAE,KAAK,CAAC,IAAI;oBACpB,MAAM,EAAE,KAAK,CAAC,EAAE;oBAChB,OAAO;iBACR,CAAC;YACJ,CAAC;YACD,wEAAwE;YACxE,0EAA0E;YAC1E,yEAAyE;YACzE,uEAAuE;YACvE,4BAA4B;YAC5B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QAED,8DAA8D;QAC9D,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,KAAK,EAAE,iBAAiB;gBACxB,aAAa,EAAE,KAAK,CAAC,EAAE;gBACvB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC7D,OAAO;gBACP,uEAAuE;gBACvE,oBAAoB,EAAE,IAAI;aAC3B,CAAC;QACJ,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;YACrB,OAAO;gBACL,KAAK,EAAE,eAAe;gBACtB,aAAa,EAAE,KAAK,CAAC,EAAE;gBACvB,MAAM,EAAE,YAAY,CAAC,MAAM;gBAC3B,OAAO;gBACP,wEAAwE;gBACxE,oBAAoB,EAAE,IAAI;aAC3B,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC;QACzB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAChC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic write via temp-file + POSIX rename. POSIX rename is atomic on the
|
|
3
|
+
* same filesystem, which `.gdh-state/` placement guarantees. The temp file
|
|
4
|
+
* lives in the same directory as the destination so the rename is local.
|
|
5
|
+
*
|
|
6
|
+
* Source pattern: packages/runtime/src/bridge-broker.ts:721-733. Extracted
|
|
7
|
+
* here so plans 04 (backup manifest), 05 (migration-state), and 06
|
|
8
|
+
* (processes-snapshot) can reuse a single implementation instead of
|
|
9
|
+
* copy-pasting the helper into each writer.
|
|
10
|
+
*
|
|
11
|
+
* Failure semantics: on any failure during writeFile/rename, the temp file
|
|
12
|
+
* is removed (best-effort) and the original error rethrown. The destination
|
|
13
|
+
* file is never left in a half-written state — either the new content is
|
|
14
|
+
* fully visible at the destination path, or the destination is unchanged.
|
|
15
|
+
*/
|
|
16
|
+
export declare function writeFileAtomic(filePath: string, content: string, options?: {
|
|
17
|
+
readonly mode?: number;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=atomic-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.d.ts","sourceRoot":"","sources":["../../src/state/atomic-write.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* Atomic write via temp-file + POSIX rename. POSIX rename is atomic on the
|
|
6
|
+
* same filesystem, which `.gdh-state/` placement guarantees. The temp file
|
|
7
|
+
* lives in the same directory as the destination so the rename is local.
|
|
8
|
+
*
|
|
9
|
+
* Source pattern: packages/runtime/src/bridge-broker.ts:721-733. Extracted
|
|
10
|
+
* here so plans 04 (backup manifest), 05 (migration-state), and 06
|
|
11
|
+
* (processes-snapshot) can reuse a single implementation instead of
|
|
12
|
+
* copy-pasting the helper into each writer.
|
|
13
|
+
*
|
|
14
|
+
* Failure semantics: on any failure during writeFile/rename, the temp file
|
|
15
|
+
* is removed (best-effort) and the original error rethrown. The destination
|
|
16
|
+
* file is never left in a half-written state — either the new content is
|
|
17
|
+
* fully visible at the destination path, or the destination is unchanged.
|
|
18
|
+
*/
|
|
19
|
+
export async function writeFileAtomic(filePath, content, options = {}) {
|
|
20
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
21
|
+
const tempPath = path.join(path.dirname(filePath), `.${path.basename(filePath)}.${randomUUID()}.tmp`);
|
|
22
|
+
try {
|
|
23
|
+
await fs.writeFile(tempPath, content, { mode: options.mode });
|
|
24
|
+
if (options.mode !== undefined) {
|
|
25
|
+
await fs.chmod(tempPath, options.mode).catch(() => { });
|
|
26
|
+
}
|
|
27
|
+
await fs.rename(tempPath, filePath);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
await fs.rm(tempPath, { force: true }).catch(() => { });
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=atomic-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.js","sourceRoot":"","sources":["../../src/state/atomic-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,OAAe,EACf,UAAsC,EAAE;IAExC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,UAAU,EAAE,MAAM,CAClD,CAAC;IACF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { GdhMigrationEnvelopeOutput } from "../migrations/envelopes/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Path of the GDH migration-state envelope (D-12 / D-15 / D-16).
|
|
4
|
+
*
|
|
5
|
+
* Holds the post-rebake `last_applied_at` provenance and a typed
|
|
6
|
+
* `deferred_actions` list. Closed-kind `verify.kind` enum + structured
|
|
7
|
+
* `verify.payload` (no shell strings) eliminates the shell-injection
|
|
8
|
+
* surface called out in T-72-05-01.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MIGRATION_STATE_RELATIVE_PATH = ".gdh-state/migration.json";
|
|
11
|
+
/**
|
|
12
|
+
* Closed enumeration of probe statuses (D-12).
|
|
13
|
+
*
|
|
14
|
+
* - `pending`: probe ran but the deferred condition is not yet observed
|
|
15
|
+
* (host harness has not reloaded skill metadata, process not yet running).
|
|
16
|
+
* - `clean`: deferred condition observed; the action is satisfied.
|
|
17
|
+
* - `stale`: probe could not be run cleanly (unknown verify.kind, malformed
|
|
18
|
+
* payload, host threw). Treated as not-clean by the advisory gate.
|
|
19
|
+
*/
|
|
20
|
+
export type GdhDeferredActionStatus = "pending" | "clean" | "stale";
|
|
21
|
+
/**
|
|
22
|
+
* Closed enumeration of verify dispatch kinds (D-12 / D-27).
|
|
23
|
+
*
|
|
24
|
+
* Adding a new kind requires showing GDH cannot perform the action with a
|
|
25
|
+
* precise file edit or process call (D-27 — bounded out-of-band action list).
|
|
26
|
+
*/
|
|
27
|
+
export type GdhDeferredActionVerifyKind = "agent_skill_metadata_reload" | "process_restart";
|
|
28
|
+
/**
|
|
29
|
+
* Verify descriptor (D-12). `kind` selects the dispatch arm; `payload` carries
|
|
30
|
+
* the per-kind structured data the probe runner needs. There is no
|
|
31
|
+
* `verify_command` shell string — that field intentionally does NOT exist
|
|
32
|
+
* (T-72-05-01 mitigation).
|
|
33
|
+
*/
|
|
34
|
+
export interface GdhDeferredActionVerify {
|
|
35
|
+
readonly kind: GdhDeferredActionVerifyKind;
|
|
36
|
+
readonly payload: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
export interface GdhDeferredAction {
|
|
39
|
+
readonly id: string;
|
|
40
|
+
readonly description: string;
|
|
41
|
+
readonly verify: GdhDeferredActionVerify;
|
|
42
|
+
readonly status: GdhDeferredActionStatus;
|
|
43
|
+
/** Optional ISO timestamp of last probe run; informational only. */
|
|
44
|
+
readonly last_checked_at?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface GdhMigrationStateAppliedAt {
|
|
47
|
+
readonly package: string;
|
|
48
|
+
readonly schema: number;
|
|
49
|
+
readonly agentContract: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* One recorded-result attempt history entry (D-08). Same shape as a slot, minus
|
|
53
|
+
* the `attempts` field (history doesn't recurse).
|
|
54
|
+
*/
|
|
55
|
+
export interface GdhMigrationEnvelopeAttempt {
|
|
56
|
+
readonly recorded_at: string;
|
|
57
|
+
readonly from_pin: string;
|
|
58
|
+
readonly to_pin: string;
|
|
59
|
+
readonly output_contract: GdhMigrationEnvelopeOutput;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Per-envelope-ref slot (D-08). One current slot per envelope; re-runs of
|
|
63
|
+
* `gdh migration record-envelope-result` append the prior slot's outer fields
|
|
64
|
+
* onto this slot's `attempts[]`.
|
|
65
|
+
*/
|
|
66
|
+
export interface GdhMigrationEnvelopeSlot {
|
|
67
|
+
readonly recorded_at: string;
|
|
68
|
+
readonly from_pin: string;
|
|
69
|
+
readonly to_pin: string;
|
|
70
|
+
readonly output_contract: GdhMigrationEnvelopeOutput;
|
|
71
|
+
readonly attempts: readonly GdhMigrationEnvelopeAttempt[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* In-flight resume marker (D-11). Set atomically at the applyMigrationChain
|
|
75
|
+
* pause point (alongside the durable backup); cleared atomically when the
|
|
76
|
+
* chain advances past that envelope on resume. Mirrors Phase 72's receipt-
|
|
77
|
+
* before-cleanup discipline for processes-snapshot.json — the marker is the
|
|
78
|
+
* resume substrate, distinct from the migration.json success receipt.
|
|
79
|
+
*/
|
|
80
|
+
export interface GdhPendingEnvelopeResumeMarker {
|
|
81
|
+
readonly envelope_ref: string;
|
|
82
|
+
readonly from_pin: string;
|
|
83
|
+
readonly to_pin: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Migration-state envelope (D-12).
|
|
87
|
+
*
|
|
88
|
+
* `migration_version` is `1` and locked; future shape changes require a new
|
|
89
|
+
* version number and a degraded-fallback path on read.
|
|
90
|
+
*/
|
|
91
|
+
export interface GdhMigrationState {
|
|
92
|
+
readonly migration_version: 1;
|
|
93
|
+
readonly last_applied_at: GdhMigrationStateAppliedAt;
|
|
94
|
+
readonly deferred_actions: readonly GdhDeferredAction[];
|
|
95
|
+
/**
|
|
96
|
+
* D-08 — per-envelope-ref recorded-result evidence. Optional for backward
|
|
97
|
+
* read-compat: Phase 72-written migration.json files omit this field, and
|
|
98
|
+
* the schema guard treats `undefined` as "no recorded results."
|
|
99
|
+
*/
|
|
100
|
+
readonly envelopes?: Readonly<Record<string, GdhMigrationEnvelopeSlot>>;
|
|
101
|
+
/**
|
|
102
|
+
* D-11 — in-flight resume marker. Set when applyMigrationChain pauses on an
|
|
103
|
+
* unresolved envelope_ref; cleared when bumpAndRebakePin advances past that
|
|
104
|
+
* envelope on resume. Optional for back-compat: absence reads as "no pending
|
|
105
|
+
* envelope."
|
|
106
|
+
*/
|
|
107
|
+
readonly pending_envelope_resume?: GdhPendingEnvelopeResumeMarker;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Read the migration-state envelope if present.
|
|
111
|
+
*
|
|
112
|
+
* Returns null when missing, parse-failed, or schema-invalid (T-72-05-04
|
|
113
|
+
* mitigation: degraded fallback prevents corrupted manifest from crashing
|
|
114
|
+
* status). Caller treats null as "no prior state" and the advisory gate
|
|
115
|
+
* keeps `deferredActions: []` with `backupAdvisory: null`.
|
|
116
|
+
*/
|
|
117
|
+
export declare function readMigrationState(targetPath: string): Promise<GdhMigrationState | null>;
|
|
118
|
+
/**
|
|
119
|
+
* Write the migration-state envelope atomically (D-15).
|
|
120
|
+
*
|
|
121
|
+
* Uses {@link writeFileAtomic} (temp-file + POSIX rename) so the destination
|
|
122
|
+
* is either the previous state or the new state — never half-written content
|
|
123
|
+
* if the process is interrupted between writeFile and rename.
|
|
124
|
+
*/
|
|
125
|
+
export declare function writeMigrationState(targetPath: string, state: GdhMigrationState): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Idempotent first-run bootstrap (D-16).
|
|
128
|
+
*
|
|
129
|
+
* Returns the existing state when present; otherwise returns a fresh empty
|
|
130
|
+
* envelope using `defaultLastAppliedAt`. Never throws — corrupted state files
|
|
131
|
+
* degrade to a fresh empty envelope so the caller can re-establish provenance
|
|
132
|
+
* at the next rebake.
|
|
133
|
+
*/
|
|
134
|
+
export declare function bootstrapMigrationStateOrEmpty(targetPath: string, defaultLastAppliedAt: GdhMigrationStateAppliedAt): Promise<GdhMigrationState>;
|
|
135
|
+
//# sourceMappingURL=migration-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-state.d.ts","sourceRoot":"","sources":["../../src/state/migration-state.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAEnF;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,8BAA8B,CAAC;AAEzE;;;;;;;;GAQG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GACnC,6BAA6B,GAC7B,iBAAiB,CAAC;AAEtB;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC,oEAAoE;IACpE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,0BAA0B,CAAC;CACtD;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,0BAA0B,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,SAAS,2BAA2B,EAAE,CAAC;CAC3D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC9B,QAAQ,CAAC,eAAe,EAAE,0BAA0B,CAAC;IACrD,QAAQ,CAAC,gBAAgB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACxD;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC;IACxE;;;;;OAKG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,8BAA8B,CAAC;CACnE;AAmHD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAYnC;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;;;;;GAOG;AACH,wBAAsB,8BAA8B,CAClD,UAAU,EAAE,MAAM,EAClB,oBAAoB,EAAE,0BAA0B,GAC/C,OAAO,CAAC,iBAAiB,CAAC,CAQ5B"}
|