@warpgogol/forge 0.28.0 → 1.0.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 (83) hide show
  1. package/AGENTS.md +16 -0
  2. package/README.md +4 -4
  3. package/README.uk.md +4 -4
  4. package/dist/os/core/core.module.d.ts.map +1 -1
  5. package/dist/os/core/core.module.js +34 -0
  6. package/dist/os/core/core.module.js.map +1 -1
  7. package/dist/os/core/handlers/workspace-deps.js +3 -3
  8. package/dist/os/core/handlers/workspace-deps.js.map +1 -1
  9. package/dist/os/program/discovery.d.ts +61 -0
  10. package/dist/os/program/discovery.d.ts.map +1 -0
  11. package/dist/os/program/discovery.js +236 -0
  12. package/dist/os/program/discovery.js.map +1 -0
  13. package/dist/os/program/handlers/complete.d.ts +12 -0
  14. package/dist/os/program/handlers/complete.d.ts.map +1 -0
  15. package/dist/os/program/handlers/complete.js +344 -0
  16. package/dist/os/program/handlers/complete.js.map +1 -0
  17. package/dist/os/program/handlers/lease.d.ts +13 -0
  18. package/dist/os/program/handlers/lease.d.ts.map +1 -0
  19. package/dist/os/program/handlers/lease.js +322 -0
  20. package/dist/os/program/handlers/lease.js.map +1 -0
  21. package/dist/os/program/handlers/seal.d.ts +12 -0
  22. package/dist/os/program/handlers/seal.d.ts.map +1 -0
  23. package/dist/os/program/handlers/seal.js +265 -0
  24. package/dist/os/program/handlers/seal.js.map +1 -0
  25. package/dist/os/program/handlers/validate.d.ts +14 -0
  26. package/dist/os/program/handlers/validate.d.ts.map +1 -0
  27. package/dist/os/program/handlers/validate.js +164 -0
  28. package/dist/os/program/handlers/validate.js.map +1 -0
  29. package/dist/os/program/lease.d.ts +39 -0
  30. package/dist/os/program/lease.d.ts.map +1 -0
  31. package/dist/os/program/lease.js +129 -0
  32. package/dist/os/program/lease.js.map +1 -0
  33. package/dist/os/program/program.module.d.ts +3 -0
  34. package/dist/os/program/program.module.d.ts.map +1 -0
  35. package/dist/os/program/program.module.js +201 -0
  36. package/dist/os/program/program.module.js.map +1 -0
  37. package/dist/os/program/schemas.d.ts +225 -0
  38. package/dist/os/program/schemas.d.ts.map +1 -0
  39. package/dist/os/program/schemas.js +174 -0
  40. package/dist/os/program/schemas.js.map +1 -0
  41. package/dist/os/program/state.d.ts +38 -0
  42. package/dist/os/program/state.d.ts.map +1 -0
  43. package/dist/os/program/state.js +189 -0
  44. package/dist/os/program/state.js.map +1 -0
  45. package/dist/os/rfc/handlers/archive.d.ts +1 -0
  46. package/dist/os/rfc/handlers/archive.d.ts.map +1 -1
  47. package/dist/os/rfc/handlers/archive.js +54 -0
  48. package/dist/os/rfc/handlers/archive.js.map +1 -1
  49. package/dist/os/rfc/handlers/validate-rules.js +2 -2
  50. package/dist/os/rfc/handlers/validate-rules.js.map +1 -1
  51. package/dist/os/werkstatt/handlers/schema.js +2 -2
  52. package/dist/src/index.d.ts +1 -0
  53. package/dist/src/index.d.ts.map +1 -1
  54. package/dist/src/index.js +1 -0
  55. package/dist/src/index.js.map +1 -1
  56. package/dist/src/onboarding/invariant-engine.d.ts.map +1 -1
  57. package/dist/src/onboarding/invariant-engine.js +61 -1
  58. package/dist/src/onboarding/invariant-engine.js.map +1 -1
  59. package/dist/src/profiles/profile-schema.d.ts +7 -1
  60. package/dist/src/profiles/profile-schema.d.ts.map +1 -1
  61. package/dist/src/profiles/profile-schema.js +3 -0
  62. package/dist/src/profiles/profile-schema.js.map +1 -1
  63. package/dist/src/profiles/stack-profile.d.ts +2 -0
  64. package/dist/src/profiles/stack-profile.d.ts.map +1 -1
  65. package/dist/src/utils/fs.js +2 -2
  66. package/dist/src/utils/fs.js.map +1 -1
  67. package/dist/src/utils/string-utils.js +1 -1
  68. package/dist/src/validators/port-validate.js +1 -1
  69. package/dist/src/validators/port-validate.js.map +1 -1
  70. package/package.json +19 -15
  71. package/profiles/astro-typescript-turborepo.yaml +1 -1
  72. package/profiles/editframe.yaml +2 -2
  73. package/profiles/forge-shell.yaml +1 -1
  74. package/profiles/godot-csharp.yaml +388 -0
  75. package/profiles/phaser-turborepo.yaml +1 -1
  76. package/skills/fo/ef-onboard/SKILL.md +1 -1
  77. package/skills/fo/fo-idea/SKILL.md +2 -2
  78. package/skills/fo/fo-idea-implement/SKILL.md +1 -1
  79. package/skills/fo/fo-step-commit/SKILL.md +7 -5
  80. package/skills/shared/grilling/learned-principles.archive.md +212 -0
  81. package/skills/shared/grilling/learned-principles.md +0 -13
  82. package/skills/shared/grilling/qa-log.md +624 -0
  83. package/skills/shared/knowledge/learned-principles.md +99 -0
@@ -0,0 +1,164 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Command handler for program.packet.validate — read-only validation
4
+ of a program packet against schema, source hashes, branch/head, and state
5
+ machine rules (RFC-0856).</purpose>
6
+ <non-goals>
7
+ <item>Do not mutate files — validate is read-only.</item>
8
+ <item>Do not import from @warpgogol/* — forge must remain dependency-free.</item>
9
+ </non-goals>
10
+ </MODULE_CONTRACT>
11
+ <CHANGE_SUMMARY>
12
+ <item>RFC-0856: initial validate command handler.</item>
13
+ </CHANGE_SUMMARY>
14
+ */
15
+ import { discoverProgram, findPacketEntry, resolvePacketPath, parsePacketFile, verifyNormativeSources, gitBranch, gitHead, gitIsClean, } from "../discovery.js";
16
+ import { findActiveLeases, isLeaseStale } from "../lease.js";
17
+ import { validateSealTransition } from "../state.js";
18
+ export async function runValidate(input, context) {
19
+ const program = input.flags.program;
20
+ const packetId = input.flags.packet;
21
+ const phase = input.flags.phase ?? "draft";
22
+ if (!program || !packetId) {
23
+ return {
24
+ data: {
25
+ command: "program.packet.validate",
26
+ status: "fail",
27
+ program: program ?? "<missing>",
28
+ packetId: packetId ?? "<missing>",
29
+ phase,
30
+ branch: "",
31
+ head: "",
32
+ violations: [
33
+ {
34
+ rule: "PROGRAM-PACKET-01",
35
+ message: "both --program and --packet are required",
36
+ },
37
+ ],
38
+ },
39
+ exitCode: 1,
40
+ summary: "program.packet.validate: missing required flags",
41
+ };
42
+ }
43
+ const { workspaceRoot } = context;
44
+ // Discover program
45
+ let programLocation;
46
+ try {
47
+ programLocation = discoverProgram(workspaceRoot, program);
48
+ }
49
+ catch (err) {
50
+ return failResult(program, packetId, phase, [
51
+ {
52
+ rule: "PROGRAM-PACKET-01",
53
+ message: String(err.message),
54
+ },
55
+ ]);
56
+ }
57
+ if (!programLocation) {
58
+ return failResult(program, packetId, phase, [
59
+ {
60
+ rule: "PROGRAM-PACKET-01",
61
+ message: `program ${program} not found in docs/plans/`,
62
+ },
63
+ ]);
64
+ }
65
+ const { manifest, programDir } = programLocation;
66
+ // Find packet entry
67
+ const entry = findPacketEntry(manifest, packetId);
68
+ if (!entry) {
69
+ return failResult(program, packetId, phase, [
70
+ {
71
+ rule: "PROGRAM-PACKET-01",
72
+ message: `packet ${packetId} not found in program manifest`,
73
+ },
74
+ ]);
75
+ }
76
+ // Parse packet file
77
+ let packet;
78
+ try {
79
+ packet = parsePacketFile(resolvePacketPath(programDir, entry));
80
+ }
81
+ catch (err) {
82
+ return failResult(program, packetId, phase, [
83
+ {
84
+ rule: "PROGRAM-PACKET-01",
85
+ message: String(err.message),
86
+ },
87
+ ]);
88
+ }
89
+ const violations = [];
90
+ // Verify normative source hashes
91
+ const hashViolations = verifyNormativeSources(workspaceRoot, packet);
92
+ for (const v of hashViolations) {
93
+ violations.push({
94
+ rule: "PROGRAM-PACKET-07",
95
+ path: v.path,
96
+ message: `normative source hash mismatch: expected ${v.expected}, got ${v.actual}`,
97
+ });
98
+ }
99
+ // Check git state
100
+ let branch = "";
101
+ let head = "";
102
+ try {
103
+ branch = gitBranch(workspaceRoot);
104
+ head = gitHead(workspaceRoot);
105
+ }
106
+ catch {
107
+ violations.push({
108
+ rule: "PROGRAM-PACKET-02",
109
+ message: "failed to read git state",
110
+ });
111
+ }
112
+ // Check for active leases
113
+ const activeLeases = findActiveLeases(workspaceRoot, program);
114
+ const hasActiveLease = activeLeases.some((l) => l.packetId === packetId && !isLeaseStale(l.lease));
115
+ // Validate seal transition (covers most validation rules)
116
+ let isClean = false;
117
+ try {
118
+ isClean = gitIsClean(workspaceRoot);
119
+ }
120
+ catch {
121
+ // ignore
122
+ }
123
+ const sealViolations = validateSealTransition(manifest, entry, packet, {
124
+ branch,
125
+ head,
126
+ isClean,
127
+ hasActiveLease,
128
+ });
129
+ violations.push(...sealViolations);
130
+ const status = violations.length === 0 ? "pass" : "fail";
131
+ return {
132
+ data: {
133
+ command: "program.packet.validate",
134
+ status,
135
+ program,
136
+ packetId,
137
+ phase,
138
+ branch,
139
+ head,
140
+ violations,
141
+ },
142
+ exitCode: status === "pass" ? 0 : 1,
143
+ summary: status === "pass"
144
+ ? `program.packet.validate: ${packetId} passed (${phase})`
145
+ : `program.packet.validate: ${packetId} failed with ${violations.length} violation(s)`,
146
+ };
147
+ }
148
+ function failResult(program, packetId, phase, violations) {
149
+ return {
150
+ data: {
151
+ command: "program.packet.validate",
152
+ status: "fail",
153
+ program,
154
+ packetId,
155
+ phase,
156
+ branch: "",
157
+ head: "",
158
+ violations,
159
+ },
160
+ exitCode: 1,
161
+ summary: `program.packet.validate: ${packetId} failed with ${violations.length} violation(s)`,
162
+ };
163
+ }
164
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../os/program/handlers/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type ProgramPacketLease } from "./schemas.ts";
2
+ export declare function leaseDir(workspaceRoot: string, program: string): string;
3
+ export declare function leasePath(workspaceRoot: string, program: string, packetId: string): string;
4
+ /**
5
+ * Generate a random opaque lease token (32 bytes hex).
6
+ */
7
+ export declare function generateLeaseToken(): string;
8
+ /**
9
+ * Hash a lease token for storage. Only the hash is persisted.
10
+ */
11
+ export declare function hashLeaseToken(token: string): string;
12
+ /**
13
+ * Read a lease file. Returns null if no lease exists.
14
+ */
15
+ export declare function readLease(workspaceRoot: string, program: string, packetId: string): ProgramPacketLease | null;
16
+ /**
17
+ * Write a lease file atomically.
18
+ */
19
+ export declare function writeLease(workspaceRoot: string, program: string, lease: ProgramPacketLease): void;
20
+ /**
21
+ * Delete a lease file.
22
+ */
23
+ export declare function deleteLease(workspaceRoot: string, program: string, packetId: string): void;
24
+ /**
25
+ * Check if any active lease exists for a program (any packet).
26
+ */
27
+ export declare function findActiveLeases(workspaceRoot: string, program: string): Array<{
28
+ packetId: string;
29
+ lease: ProgramPacketLease;
30
+ }>;
31
+ /**
32
+ * Check if a lease is stale (heartbeat exceeded timeout).
33
+ */
34
+ export declare function isLeaseStale(lease: ProgramPacketLease, now?: Date): boolean;
35
+ /**
36
+ * Update heartbeat timestamp on an existing lease.
37
+ */
38
+ export declare function updateHeartbeat(workspaceRoot: string, program: string, packetId: string, now?: Date): ProgramPacketLease;
39
+ //# sourceMappingURL=lease.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease.d.ts","sourceRoot":"","sources":["../../../os/program/lease.ts"],"names":[],"mappings":"AAkBA,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAMjF,wBAAgB,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,wBAAgB,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1F;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAMD;;GAEG;AACH,wBAAgB,SAAS,CACvB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,kBAAkB,GAAG,IAAI,CAW3B;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,kBAAkB,GACxB,IAAI,CAMN;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAK1F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,GACd,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAmBxD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAKvF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,IAAiB,GACrB,kBAAkB,CAWpB"}
@@ -0,0 +1,129 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Untracked lease management for program packets. Lease files live
4
+ under .forge/program-leases/<program>/ and contain only the token hash.
5
+ Raw tokens are never persisted to disk.</purpose>
6
+ <non-goals>
7
+ <item>Do not store raw lease tokens — only the SHA-256 hash.</item>
8
+ <item>Do not import from @warpgogol/* — forge must remain dependency-free.</item>
9
+ </non-goals>
10
+ </MODULE_CONTRACT>
11
+ <CHANGE_SUMMARY>
12
+ <item>RFC-0856: initial lease management.</item>
13
+ </CHANGE_SUMMARY>
14
+ */
15
+ import fs from "node:fs";
16
+ import path from "node:path";
17
+ import { createHash, randomBytes } from "node:crypto";
18
+ import { programPacketLeaseSchema } from "./schemas.js";
19
+ // ---------------------------------------------------------------------------
20
+ // Lease directory
21
+ // ---------------------------------------------------------------------------
22
+ export function leaseDir(workspaceRoot, program) {
23
+ return path.join(workspaceRoot, ".forge", "program-leases", program);
24
+ }
25
+ export function leasePath(workspaceRoot, program, packetId) {
26
+ return path.join(leaseDir(workspaceRoot, program), `${packetId}.json`);
27
+ }
28
+ // ---------------------------------------------------------------------------
29
+ // Token utilities
30
+ // ---------------------------------------------------------------------------
31
+ /**
32
+ * Generate a random opaque lease token (32 bytes hex).
33
+ */
34
+ export function generateLeaseToken() {
35
+ return randomBytes(32).toString("hex");
36
+ }
37
+ /**
38
+ * Hash a lease token for storage. Only the hash is persisted.
39
+ */
40
+ export function hashLeaseToken(token) {
41
+ return createHash("sha256").update(token).digest("hex");
42
+ }
43
+ // ---------------------------------------------------------------------------
44
+ // Lease CRUD (untracked files)
45
+ // ---------------------------------------------------------------------------
46
+ /**
47
+ * Read a lease file. Returns null if no lease exists.
48
+ */
49
+ export function readLease(workspaceRoot, program, packetId) {
50
+ const p = leasePath(workspaceRoot, program, packetId);
51
+ if (!fs.existsSync(p))
52
+ return null;
53
+ const raw = fs.readFileSync(p, "utf8");
54
+ const parsed = JSON.parse(raw);
55
+ const result = programPacketLeaseSchema.safeParse(parsed);
56
+ if (!result.success) {
57
+ throw new Error(`PROGRAM-PACKET-01: malformed lease at ${p}: ${result.error.message}`);
58
+ }
59
+ return result.data;
60
+ }
61
+ /**
62
+ * Write a lease file atomically.
63
+ */
64
+ export function writeLease(workspaceRoot, program, lease) {
65
+ const dir = leaseDir(workspaceRoot, program);
66
+ fs.mkdirSync(dir, { recursive: true });
67
+ const p = leasePath(workspaceRoot, program, lease.packetId);
68
+ const content = JSON.stringify(lease, null, 2) + "\n";
69
+ fs.writeFileSync(p, content);
70
+ }
71
+ /**
72
+ * Delete a lease file.
73
+ */
74
+ export function deleteLease(workspaceRoot, program, packetId) {
75
+ const p = leasePath(workspaceRoot, program, packetId);
76
+ if (fs.existsSync(p)) {
77
+ fs.unlinkSync(p);
78
+ }
79
+ }
80
+ /**
81
+ * Check if any active lease exists for a program (any packet).
82
+ */
83
+ export function findActiveLeases(workspaceRoot, program) {
84
+ const dir = leaseDir(workspaceRoot, program);
85
+ if (!fs.existsSync(dir))
86
+ return [];
87
+ const results = [];
88
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
89
+ if (!entry.isFile() || !entry.name.endsWith(".json"))
90
+ continue;
91
+ const p = path.join(dir, entry.name);
92
+ const raw = fs.readFileSync(p, "utf8");
93
+ const parsed = JSON.parse(raw);
94
+ const result = programPacketLeaseSchema.safeParse(parsed);
95
+ if (result.success) {
96
+ results.push({
97
+ packetId: result.data.packetId,
98
+ lease: result.data,
99
+ });
100
+ }
101
+ }
102
+ return results;
103
+ }
104
+ /**
105
+ * Check if a lease is stale (heartbeat exceeded timeout).
106
+ */
107
+ export function isLeaseStale(lease, now = new Date()) {
108
+ const heartbeatMs = Date.parse(lease.heartbeatAt);
109
+ if (Number.isNaN(heartbeatMs))
110
+ return true;
111
+ const elapsed = now.getTime() - heartbeatMs;
112
+ return elapsed > lease.timeoutSeconds * 1000;
113
+ }
114
+ /**
115
+ * Update heartbeat timestamp on an existing lease.
116
+ */
117
+ export function updateHeartbeat(workspaceRoot, program, packetId, now = new Date()) {
118
+ const existing = readLease(workspaceRoot, program, packetId);
119
+ if (!existing) {
120
+ throw new Error(`PROGRAM-PACKET-05: no lease found for ${packetId}`);
121
+ }
122
+ const updated = {
123
+ ...existing,
124
+ heartbeatAt: now.toISOString(),
125
+ };
126
+ writeLease(workspaceRoot, program, updated);
127
+ return updated;
128
+ }
129
+ //# sourceMappingURL=lease.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease.js","sourceRoot":"","sources":["../../../os/program/lease.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ForgeModule } from "../../src/forge-module.ts";
2
+ export declare const forgeProgramModule: ForgeModule;
3
+ //# sourceMappingURL=program.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.module.d.ts","sourceRoot":"","sources":["../../../os/program/program.module.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,eAAO,MAAM,kBAAkB,EAAE,WAoMhC,CAAC"}
@@ -0,0 +1,201 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Register the program packet control plane commands with the forge
4
+ kernel registry (RFC-0856).</purpose>
5
+ <non-goals>
6
+ <item>Do not implement command logic here — handlers live in handlers/*.ts.</item>
7
+ </non-goals>
8
+ </MODULE_CONTRACT>
9
+ <CHANGE_SUMMARY>
10
+ <item>RFC-0856: initial program module registration.</item>
11
+ </CHANGE_SUMMARY>
12
+ */
13
+ export const forgeProgramModule = {
14
+ name: "forge-program",
15
+ version: "0.1.0",
16
+ async register(registry) {
17
+ const { runValidate } = await import("./handlers/validate.js");
18
+ const { runSeal } = await import("./handlers/seal.js");
19
+ const { runLease } = await import("./handlers/lease.js");
20
+ const { runComplete } = await import("./handlers/complete.js");
21
+ registry.registerCommand({
22
+ name: "program.packet.validate",
23
+ description: "Validate a program packet against schema, source hashes, branch/head, " +
24
+ "and state machine rules. Read-only. " +
25
+ "Usage: program.packet.validate --program=RFC-XXXX --packet=NNN-foo --phase=draft --json",
26
+ scope: "workspace",
27
+ supportsAllSites: false,
28
+ flags: {
29
+ program: {
30
+ kind: "string",
31
+ required: true,
32
+ description: "Program RFC id (e.g. RFC-0855).",
33
+ },
34
+ packet: {
35
+ kind: "string",
36
+ required: true,
37
+ description: "Packet id (e.g. 010-node-24).",
38
+ },
39
+ phase: {
40
+ kind: "string",
41
+ description: "Validation phase: draft, sealed, active, or completion.",
42
+ },
43
+ json: {
44
+ kind: "boolean",
45
+ description: "Machine-readable JSON output.",
46
+ },
47
+ },
48
+ reads: ["docs/plans/**/program.yaml", "docs/plans/**/*.md"],
49
+ cacheable: false,
50
+ execute: runValidate,
51
+ });
52
+ registry.registerCommand({
53
+ name: "program.packet.seal",
54
+ description: "Steward finalizes a packet against the predecessor's completion commit, " +
55
+ "updates packet state from draft to sealed, and records the seal in the " +
56
+ "program manifest. Does not commit — use ecosystem.commit after. " +
57
+ "Usage: program.packet.seal --program=RFC-XXXX --packet=NNN-foo " +
58
+ "--steward=human:id --idempotency-key=<key> --json",
59
+ scope: "workspace",
60
+ supportsAllSites: false,
61
+ mutatesState: true,
62
+ flags: {
63
+ program: {
64
+ kind: "string",
65
+ required: true,
66
+ description: "Program RFC id.",
67
+ },
68
+ packet: {
69
+ kind: "string",
70
+ required: true,
71
+ description: "Packet id to seal.",
72
+ },
73
+ steward: {
74
+ kind: "string",
75
+ required: true,
76
+ description: "Steward actor id (human:<id> or agent:<id>).",
77
+ },
78
+ "idempotency-key": {
79
+ kind: "string",
80
+ description: "Idempotency key for retry-safe sealing.",
81
+ },
82
+ json: {
83
+ kind: "boolean",
84
+ description: "Machine-readable JSON output.",
85
+ },
86
+ },
87
+ writes: ["docs/plans/**/program.yaml", "docs/plans/**/*.md"],
88
+ reads: ["docs/plans/**/program.yaml", "docs/plans/**/*.md"],
89
+ cacheable: false,
90
+ execute: runSeal,
91
+ });
92
+ registry.registerCommand({
93
+ name: "program.packet.lease",
94
+ description: "Manage the exclusive local executor lease for a sealed packet. " +
95
+ "Actions: start, heartbeat, release, recover. " +
96
+ "Raw lease tokens are never persisted — only the SHA-256 hash. " +
97
+ "Usage: program.packet.lease --program=RFC-XXXX --packet=NNN-foo " +
98
+ "--action=start --executor=agent:id --json",
99
+ scope: "workspace",
100
+ supportsAllSites: false,
101
+ flags: {
102
+ program: {
103
+ kind: "string",
104
+ required: true,
105
+ description: "Program RFC id.",
106
+ },
107
+ packet: {
108
+ kind: "string",
109
+ required: true,
110
+ description: "Packet id.",
111
+ },
112
+ action: {
113
+ kind: "string",
114
+ required: true,
115
+ description: "Lease action: start, heartbeat, release, or recover.",
116
+ },
117
+ executor: {
118
+ kind: "string",
119
+ description: "Executor actor id (required for --action=start).",
120
+ },
121
+ steward: {
122
+ kind: "string",
123
+ description: "Steward actor id (required for --action=recover).",
124
+ },
125
+ "lease-token": {
126
+ kind: "string",
127
+ description: "Opaque lease token (required for heartbeat and release).",
128
+ },
129
+ reason: {
130
+ kind: "string",
131
+ description: "Recovery reason (required for --action=recover).",
132
+ },
133
+ json: {
134
+ kind: "boolean",
135
+ description: "Machine-readable JSON output.",
136
+ },
137
+ },
138
+ writes: [".forge/program-leases/**"],
139
+ reads: ["docs/plans/**/program.yaml", "docs/plans/**/*.md"],
140
+ cacheable: false,
141
+ execute: runLease,
142
+ });
143
+ registry.registerCommand({
144
+ name: "program.packet.complete",
145
+ description: "Steward validates the implementation range, writes the completion report, " +
146
+ "and updates the program manifest. Supports --bootstrap for packet 000. " +
147
+ "Does not commit — use ecosystem.commit after. " +
148
+ "Usage: program.packet.complete --program=RFC-XXXX --packet=NNN-foo " +
149
+ "--steward=human:id --lease-token=<token> --implementation-head=<sha> --json",
150
+ scope: "workspace",
151
+ supportsAllSites: false,
152
+ mutatesState: true,
153
+ flags: {
154
+ program: {
155
+ kind: "string",
156
+ required: true,
157
+ description: "Program RFC id.",
158
+ },
159
+ packet: {
160
+ kind: "string",
161
+ required: true,
162
+ description: "Packet id to complete.",
163
+ },
164
+ steward: {
165
+ kind: "string",
166
+ required: true,
167
+ description: "Steward actor id (must differ from executor).",
168
+ },
169
+ "lease-token": {
170
+ kind: "string",
171
+ description: "Lease token (required for non-bootstrap).",
172
+ },
173
+ "implementation-head": {
174
+ kind: "string",
175
+ description: "SHA of the implementation head commit (required for non-bootstrap).",
176
+ },
177
+ "idempotency-key": {
178
+ kind: "string",
179
+ description: "Idempotency key for retry-safe completion.",
180
+ },
181
+ bootstrap: {
182
+ kind: "boolean",
183
+ description: "Bootstrap completion (packet 000 only).",
184
+ },
185
+ "seal-commit": {
186
+ kind: "string",
187
+ description: "Seal commit SHA (required for --bootstrap).",
188
+ },
189
+ json: {
190
+ kind: "boolean",
191
+ description: "Machine-readable JSON output.",
192
+ },
193
+ },
194
+ writes: ["docs/plans/**/completions/**", "docs/plans/**/program.yaml"],
195
+ reads: ["docs/plans/**/program.yaml", "docs/plans/**/*.md"],
196
+ cacheable: false,
197
+ execute: runComplete,
198
+ });
199
+ },
200
+ };
201
+ //# sourceMappingURL=program.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.module.js","sourceRoot":"","sources":["../../../os/program/program.module.ts"],"names":[],"mappings":"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"}