@warpgogol/forge 0.24.0 → 0.26.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 (60) hide show
  1. package/AGENTS.md +14 -2
  2. package/dist/os/adr/adr.module.d.ts.map +1 -1
  3. package/dist/os/adr/adr.module.js +31 -0
  4. package/dist/os/adr/adr.module.js.map +1 -1
  5. package/dist/os/adr/handlers/archive.d.ts.map +1 -1
  6. package/dist/os/adr/handlers/archive.js +26 -0
  7. package/dist/os/adr/handlers/archive.js.map +1 -1
  8. package/dist/os/adr/handlers/implement-stamp.d.ts +4 -0
  9. package/dist/os/adr/handlers/implement-stamp.d.ts.map +1 -0
  10. package/dist/os/adr/handlers/implement-stamp.js +258 -0
  11. package/dist/os/adr/handlers/implement-stamp.js.map +1 -0
  12. package/dist/os/adr/handlers/validate.js +1 -1
  13. package/dist/os/adr/handlers/validate.js.map +1 -1
  14. package/dist/os/adr/types.d.ts +16 -0
  15. package/dist/os/adr/types.d.ts.map +1 -1
  16. package/dist/os/adr/types.js +1 -0
  17. package/dist/os/adr/types.js.map +1 -1
  18. package/dist/os/audit/handlers/archive.d.ts.map +1 -1
  19. package/dist/os/audit/handlers/archive.js +34 -0
  20. package/dist/os/audit/handlers/archive.js.map +1 -1
  21. package/dist/os/core/core.module.d.ts.map +1 -1
  22. package/dist/os/core/core.module.js +55 -0
  23. package/dist/os/core/core.module.js.map +1 -1
  24. package/dist/os/core/handlers/pinned-check.d.ts +39 -0
  25. package/dist/os/core/handlers/pinned-check.d.ts.map +1 -0
  26. package/dist/os/core/handlers/pinned-check.js +135 -0
  27. package/dist/os/core/handlers/pinned-check.js.map +1 -0
  28. package/dist/os/core/handlers/pinned-init.d.ts +19 -0
  29. package/dist/os/core/handlers/pinned-init.d.ts.map +1 -0
  30. package/dist/os/core/handlers/pinned-init.js +282 -0
  31. package/dist/os/core/handlers/pinned-init.js.map +1 -0
  32. package/dist/os/core/handlers/pinned-types.d.ts +29 -0
  33. package/dist/os/core/handlers/pinned-types.d.ts.map +1 -0
  34. package/dist/os/core/handlers/pinned-types.js +16 -0
  35. package/dist/os/core/handlers/pinned-types.js.map +1 -0
  36. package/dist/os/core/handlers/pinned-validate.d.ts +4 -0
  37. package/dist/os/core/handlers/pinned-validate.d.ts.map +1 -0
  38. package/dist/os/core/handlers/pinned-validate.js +228 -0
  39. package/dist/os/core/handlers/pinned-validate.js.map +1 -0
  40. package/dist/os/mission/handlers/archive.d.ts.map +1 -1
  41. package/dist/os/mission/handlers/archive.js +34 -0
  42. package/dist/os/mission/handlers/archive.js.map +1 -1
  43. package/dist/os/plan/handlers/archive.d.ts.map +1 -1
  44. package/dist/os/plan/handlers/archive.js +34 -0
  45. package/dist/os/plan/handlers/archive.js.map +1 -1
  46. package/dist/os/rfc/acceptance.d.ts.map +1 -1
  47. package/dist/os/rfc/acceptance.js +20 -2
  48. package/dist/os/rfc/acceptance.js.map +1 -1
  49. package/dist/os/rfc/handlers/archive.d.ts.map +1 -1
  50. package/dist/os/rfc/handlers/archive.js +26 -0
  51. package/dist/os/rfc/handlers/archive.js.map +1 -1
  52. package/dist/os/session/handlers/archive.d.ts.map +1 -1
  53. package/dist/os/session/handlers/archive.js +26 -0
  54. package/dist/os/session/handlers/archive.js.map +1 -1
  55. package/package.json +1 -1
  56. package/skills/_shared/fo-pipeline-conventions.md +22 -0
  57. package/skills/fo/fo-fix/SKILL.md +3 -1
  58. package/skills/fo/fo-idea-implement/SKILL.md +15 -9
  59. package/skills/fo/fo-idea-plan/SKILL.md +2 -2
  60. package/skills/fo/fo-review/SKILL.md +1 -0
@@ -0,0 +1,282 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>forge pinned.init — creates .forge/pinned.yaml with default foundation
4
+ entries, installs pre-commit hook, adds audit log to .gitignore, and optionally
5
+ generates CI workflow. Idempotent: re-running merges defaults with existing entries.</purpose>
6
+ <non-goals>
7
+ <item>Does not validate the manifest — use pinned.validate.</item>
8
+ <item>Does not enforce protection on archive commands — that is pinned-check.ts.</item>
9
+ </non-goals>
10
+ </MODULE_CONTRACT>
11
+ <CHANGE_SUMMARY>
12
+ <item>RFC-0733: initial pinned.init handler with manifest creation, hook installation, gitignore update, and CI workflow generation.</item>
13
+ </CHANGE_SUMMARY>
14
+ */
15
+ import fs from "node:fs/promises";
16
+ import path from "node:path";
17
+ import { stringify as stringifyYaml } from "yaml";
18
+ import { writeFileIfChanged } from "../../../src/utils/fs-idempotent.js";
19
+ import { PINNED_MANIFEST_PATH, loadPinnedManifest } from "./pinned-check.js";
20
+ const PRE_COMMIT_HOOK_MARKER = "# forge:pinned-check";
21
+ const AUDIT_LOG_REL_PATH = ".forge/pinned-audit.log";
22
+ /**
23
+ * Default pinned entries for a forge-consuming repository.
24
+ * These are re-added by pinned.init if missing from an existing manifest.
25
+ */
26
+ export const DEFAULT_PINNED_ENTRIES = [
27
+ {
28
+ path: ".forge/pinned.yaml",
29
+ mode: "freeze",
30
+ reason: "Self-protection — manifest must not be tampered with",
31
+ },
32
+ {
33
+ path: "docs/rfcs/rfc-0000-template.md",
34
+ mode: "freeze",
35
+ reason: "RFC template — required for rfc.create",
36
+ },
37
+ {
38
+ path: "docs/adrs/adr-0000-template.md",
39
+ mode: "freeze",
40
+ reason: "ADR template — required for adr.create",
41
+ },
42
+ {
43
+ path: "docs/audits/audit-0000-template.md",
44
+ mode: "freeze",
45
+ reason: "Audit template — required for audit creation",
46
+ },
47
+ {
48
+ path: "docs/plans/plan-0000-template.md",
49
+ mode: "freeze",
50
+ reason: "Plan template — required for plan creation",
51
+ },
52
+ {
53
+ path: "docs/architecture-dna.md",
54
+ mode: "freeze",
55
+ reason: "Architecture DNA invariants — foundational governance document",
56
+ },
57
+ {
58
+ path: "forge.yaml",
59
+ mode: "protect",
60
+ reason: "Forge configuration — required for all forge commands",
61
+ },
62
+ {
63
+ path: "package.json",
64
+ mode: "protect",
65
+ reason: "Root package.json — workspace manifest",
66
+ },
67
+ {
68
+ path: "pnpm-workspace.yaml",
69
+ mode: "protect",
70
+ reason: "Workspace definition",
71
+ },
72
+ {
73
+ path: "AGENTS.md",
74
+ mode: "protect",
75
+ reason: "Agent rules manifest",
76
+ },
77
+ {
78
+ path: "PREFERENCES.md",
79
+ mode: "protect",
80
+ reason: "Operator preferences",
81
+ },
82
+ {
83
+ path: "docs/rfcs/",
84
+ mode: "protect",
85
+ reason: "RFC directory — structural foundation",
86
+ },
87
+ {
88
+ path: "docs/adrs/",
89
+ mode: "protect",
90
+ reason: "ADR directory — structural foundation",
91
+ },
92
+ {
93
+ path: "docs/audits/",
94
+ mode: "protect",
95
+ reason: "Audit directory — structural foundation",
96
+ },
97
+ {
98
+ path: "docs/plans/",
99
+ mode: "protect",
100
+ reason: "Plan directory — structural foundation",
101
+ },
102
+ {
103
+ path: "docs/sessions/",
104
+ mode: "protect",
105
+ reason: "Session directory — structural foundation",
106
+ },
107
+ {
108
+ path: "docs/explorations/",
109
+ mode: "protect",
110
+ reason: "Exploration directory — structural foundation",
111
+ },
112
+ {
113
+ path: "docs/specs/",
114
+ mode: "protect",
115
+ reason: "Spec snapshots — immutable vendored content",
116
+ },
117
+ {
118
+ path: "missions/",
119
+ mode: "protect",
120
+ reason: "Missions directory — structural foundation",
121
+ },
122
+ ];
123
+ const PRE_COMMIT_HOOK_SCRIPT = `#!/bin/sh
124
+ ${PRE_COMMIT_HOOK_MARKER}
125
+ # Installed by forge pinned.init — do not remove this marker block.
126
+ # Pinned-files protection: blocks commits that delete/move/modify pinned files.
127
+ forge pinned.validate || exit 1
128
+ `;
129
+ const CI_WORKFLOW_TEMPLATE = `name: pinned-files
130
+ on: [push, pull_request]
131
+ jobs:
132
+ validate:
133
+ runs-on: ubuntu-latest
134
+ steps:
135
+ - uses: actions/checkout@v4
136
+ with:
137
+ fetch-depth: 2
138
+ - run: npm install -g @warpgogol/forge
139
+ - run: forge pinned.validate --mode ci --json
140
+ `;
141
+ /**
142
+ * Merge default entries with existing manifest entries.
143
+ * - Re-adds missing default entries (forge expects them).
144
+ * - Never overwrites or removes custom entries.
145
+ */
146
+ function mergeManifest(existing, defaults) {
147
+ if (!existing) {
148
+ return { pinned: [...defaults] };
149
+ }
150
+ const existingPaths = new Set(existing.pinned.map((e) => e.path));
151
+ const merged = [...existing.pinned];
152
+ for (const def of defaults) {
153
+ if (!existingPaths.has(def.path)) {
154
+ merged.push(def);
155
+ }
156
+ }
157
+ return { pinned: merged };
158
+ }
159
+ /**
160
+ * Install or merge the pre-commit hook.
161
+ * If a hook exists, appends the forge check with a marker for idempotent re-installation.
162
+ */
163
+ async function installPreCommitHook(repoRoot) {
164
+ const hookPath = path.join(repoRoot, ".git", "hooks", "pre-commit");
165
+ let existingContent;
166
+ try {
167
+ existingContent = await fs.readFile(hookPath, "utf8");
168
+ }
169
+ catch {
170
+ // No existing hook — create new
171
+ await fs.mkdir(path.dirname(hookPath), { recursive: true });
172
+ await writeFileIfChanged(hookPath, PRE_COMMIT_HOOK_SCRIPT);
173
+ await fs.chmod(hookPath, 0o755);
174
+ return "created";
175
+ }
176
+ // Check if forge hook is already present
177
+ if (existingContent.includes(PRE_COMMIT_HOOK_MARKER)) {
178
+ return "unchanged";
179
+ }
180
+ // Append forge hook to existing hook
181
+ const mergedContent = existingContent + "\n" + PRE_COMMIT_HOOK_SCRIPT;
182
+ await writeFileIfChanged(hookPath, mergedContent);
183
+ await fs.chmod(hookPath, 0o755);
184
+ return "updated";
185
+ }
186
+ /**
187
+ * Add .forge/pinned-audit.log to .gitignore (or append to existing).
188
+ */
189
+ async function addToGitignore(repoRoot) {
190
+ const gitignorePath = path.join(repoRoot, ".gitignore");
191
+ const entry = AUDIT_LOG_REL_PATH;
192
+ let existingContent;
193
+ try {
194
+ existingContent = await fs.readFile(gitignorePath, "utf8");
195
+ }
196
+ catch {
197
+ // No .gitignore — create new
198
+ await writeFileIfChanged(gitignorePath, entry + "\n");
199
+ return "created";
200
+ }
201
+ // Check if entry already exists
202
+ const lines = existingContent.split("\n");
203
+ if (lines.some((l) => l.trim() === entry)) {
204
+ return "unchanged";
205
+ }
206
+ // Append entry
207
+ const mergedContent = existingContent.trimEnd() + "\n" + entry + "\n";
208
+ await writeFileIfChanged(gitignorePath, mergedContent);
209
+ return "updated";
210
+ }
211
+ /**
212
+ * Generate CI workflow file.
213
+ */
214
+ async function generateCiWorkflow(repoRoot) {
215
+ const workflowPath = path.join(repoRoot, ".github", "workflows", "pinned-check.yml");
216
+ await fs.mkdir(path.dirname(workflowPath), { recursive: true });
217
+ await writeFileIfChanged(workflowPath, CI_WORKFLOW_TEMPLATE);
218
+ return "created";
219
+ }
220
+ export async function runPinnedInit(input, context) {
221
+ const { workspaceRoot, logger, outputFormat } = context;
222
+ const ci = input.flags["ci"] === true;
223
+ // Load existing manifest (if any)
224
+ let existingManifest = null;
225
+ try {
226
+ existingManifest = await loadPinnedManifest(workspaceRoot);
227
+ }
228
+ catch {
229
+ // Malformed manifest — will be overwritten with defaults
230
+ existingManifest = null;
231
+ }
232
+ // Merge with defaults
233
+ const merged = mergeManifest(existingManifest, DEFAULT_PINNED_ENTRIES);
234
+ // Determine action
235
+ const manifestAction = existingManifest === null
236
+ ? "created"
237
+ : merged.pinned.length > existingManifest.pinned.length
238
+ ? "merged"
239
+ : "unchanged";
240
+ // Write manifest
241
+ const manifestFullPath = path.join(workspaceRoot, PINNED_MANIFEST_PATH);
242
+ await fs.mkdir(path.dirname(manifestFullPath), { recursive: true });
243
+ const manifestContent = stringifyYaml(merged);
244
+ await writeFileIfChanged(manifestFullPath, manifestContent);
245
+ // Install pre-commit hook
246
+ const hookAction = await installPreCommitHook(workspaceRoot);
247
+ // Add to .gitignore
248
+ const gitignoreAction = await addToGitignore(workspaceRoot);
249
+ // Optional CI workflow
250
+ let ciWorkflowAction = "skipped";
251
+ if (ci) {
252
+ ciWorkflowAction = await generateCiWorkflow(workspaceRoot);
253
+ }
254
+ const result = {
255
+ command: "pinned.init",
256
+ status: "ok",
257
+ manifestPath: PINNED_MANIFEST_PATH,
258
+ manifestAction,
259
+ entriesCount: merged.pinned.length,
260
+ hookAction,
261
+ gitignoreAction,
262
+ ciWorkflowAction,
263
+ };
264
+ if (outputFormat === "pretty") {
265
+ logger.success(`pinned.init: manifest ${manifestAction} (${merged.pinned.length} entries), hook ${hookAction}, gitignore ${gitignoreAction}` +
266
+ (ci ? `, CI workflow ${ciWorkflowAction}` : ""));
267
+ }
268
+ return {
269
+ data: result,
270
+ summary: `Manifest ${manifestAction} with ${merged.pinned.length} entries, hook ${hookAction}, gitignore ${gitignoreAction}`,
271
+ nextSteps: [
272
+ {
273
+ action: "Commit .forge/pinned.yaml and .gitignore changes",
274
+ kind: "required",
275
+ },
276
+ ...(ci
277
+ ? [{ action: "Commit .github/workflows/pinned-check.yml", kind: "required" }]
278
+ : []),
279
+ ],
280
+ };
281
+ }
282
+ //# sourceMappingURL=pinned-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pinned-init.js","sourceRoot":"","sources":["../../../../os/core/handlers/pinned-init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type PinnedMode = "protect" | "freeze";
2
+ export type PinnedOperation = "delete" | "move" | "modify";
3
+ export interface PinnedEntry {
4
+ path: string;
5
+ mode: PinnedMode;
6
+ reason: string;
7
+ }
8
+ export interface PinnedManifest {
9
+ pinned: PinnedEntry[];
10
+ }
11
+ export interface PinnedViolation {
12
+ path: string;
13
+ mode: PinnedMode;
14
+ operation: PinnedOperation;
15
+ reason: string;
16
+ }
17
+ export type PinnedValidateMode = "staged" | "ci";
18
+ export interface PinnedValidateOptions {
19
+ allowPinnedOverride?: string[];
20
+ mode?: PinnedValidateMode;
21
+ json?: boolean;
22
+ }
23
+ export interface PinnedValidateResult {
24
+ command: "pinned.validate";
25
+ status: "pass" | "fail";
26
+ violations: PinnedViolation[];
27
+ overrides: string[];
28
+ }
29
+ //# sourceMappingURL=pinned-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pinned-types.d.ts","sourceRoot":"","sources":["../../../../os/core/handlers/pinned-types.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,IAAI,CAAC;AAEjD,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB"}
@@ -0,0 +1,16 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>TypeScript contracts for the forge pinned-files protection system (RFC-0733).
4
+ Defines the manifest, entry, violation, and result types used by pinned.init,
5
+ pinned.validate, and the shared pre-check utility.</purpose>
6
+ <non-goals>
7
+ <item>Does not implement validation logic — use pinned-check.ts and pinned-validate.ts.</item>
8
+ <item>Does not implement manifest creation — use pinned-init.ts.</item>
9
+ </non-goals>
10
+ </MODULE_CONTRACT>
11
+ <CHANGE_SUMMARY>
12
+ <item>RFC-0733: initial pinned-files type contracts — PinnedEntry, PinnedManifest, PinnedViolation, PinnedValidateOptions, PinnedValidateResult.</item>
13
+ </CHANGE_SUMMARY>
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=pinned-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pinned-types.js","sourceRoot":"","sources":["../../../../os/core/handlers/pinned-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;EAaE"}
@@ -0,0 +1,4 @@
1
+ import type { ForgeCommandInput, ForgeCommandResult, ForgeRuntimeContext } from "../../../src/types.ts";
2
+ import type { PinnedValidateResult } from "./pinned-types.ts";
3
+ export declare function runPinnedValidate(input: ForgeCommandInput, context: ForgeRuntimeContext): Promise<ForgeCommandResult<PinnedValidateResult>>;
4
+ //# sourceMappingURL=pinned-validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pinned-validate.d.ts","sourceRoot":"","sources":["../../../../os/core/handlers/pinned-validate.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,KAAK,EAGV,oBAAoB,EAErB,MAAM,mBAAmB,CAAC;AAiG3B,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,CAAC,CAwJnD"}
@@ -0,0 +1,228 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>forge pinned.validate — checks the working tree against .forge/pinned.yaml.
4
+ Scans git diff (staged or last-commit) for delete/move/modify operations on
5
+ pinned files. Supports --allow-pinned-override for audited escape hatch,
6
+ --json for structured output, and --mode ci for CI integration.</purpose>
7
+ <non-goals>
8
+ <item>Does not create or modify the manifest — use pinned.init.</item>
9
+ <item>Does not install hooks or CI workflows — use pinned.init.</item>
10
+ <item>Does not block archive commands — that is the pre-check utility in pinned-check.ts.</item>
11
+ </non-goals>
12
+ </MODULE_CONTRACT>
13
+ <CHANGE_SUMMARY>
14
+ <item>RFC-0733: initial pinned.validate handler with staged/ci modes, override, audit log, manifest integrity check.</item>
15
+ </CHANGE_SUMMARY>
16
+ */
17
+ import fs from "node:fs/promises";
18
+ import { exec } from "node:child_process";
19
+ import { promisify } from "node:util";
20
+ import path from "node:path";
21
+ import { loadPinnedManifest, isPinned, PINNED_MANIFEST_PATH, PinnedManifestMalformedError, } from "./pinned-check.js";
22
+ const execAsync = promisify(exec);
23
+ const AUDIT_LOG_PATH = path.join(".forge", "pinned-audit.log");
24
+ /**
25
+ * Parse git diff --name-status output into file entries with operation types.
26
+ * Git status codes:
27
+ * D = deleted, R = renamed (move), M = modified, A = added, C = copied
28
+ * Format: "R100\tdocs/old.md\tdocs/new.md" or "D\tdocs/file.md"
29
+ */
30
+ function parseGitNameStatus(output) {
31
+ const entries = [];
32
+ const lines = output.trim().split("\n").filter(Boolean);
33
+ for (const line of lines) {
34
+ const parts = line.split("\t");
35
+ if (parts.length < 2)
36
+ continue;
37
+ const statusCode = parts[0] ?? "";
38
+ const oldPath = parts[1] ?? "";
39
+ const newPath = parts[2] ?? oldPath;
40
+ if (statusCode.startsWith("D")) {
41
+ entries.push({ relPath: oldPath, operation: "delete" });
42
+ }
43
+ else if (statusCode.startsWith("R") || statusCode.startsWith("C")) {
44
+ entries.push({ relPath: oldPath, operation: "move" });
45
+ if (newPath !== oldPath) {
46
+ entries.push({ relPath: newPath, operation: "move" });
47
+ }
48
+ }
49
+ else if (statusCode.startsWith("M")) {
50
+ entries.push({ relPath: oldPath, operation: "modify" });
51
+ }
52
+ }
53
+ return entries;
54
+ }
55
+ /**
56
+ * Check manifest integrity by comparing current manifest against the last-committed version.
57
+ * If entries have been removed, return a tampered violation.
58
+ */
59
+ async function checkManifestIntegrity(repoRoot, manifest) {
60
+ try {
61
+ const { stdout } = await execAsync(`git show HEAD:${PINNED_MANIFEST_PATH}`, { cwd: repoRoot, encoding: "utf8" });
62
+ // Parse the committed manifest to compare entry paths
63
+ const { parse: parseYaml } = await import("yaml");
64
+ const committedParsed = parseYaml(stdout);
65
+ if (!committedParsed || !Array.isArray(committedParsed["pinned"])) {
66
+ return null;
67
+ }
68
+ const committedEntries = committedParsed["pinned"]
69
+ .map((e) => String(e["path"] ?? ""));
70
+ const currentPaths = new Set(manifest.pinned.map((e) => e.path));
71
+ for (const committedPath of committedEntries) {
72
+ if (!currentPaths.has(committedPath)) {
73
+ return {
74
+ path: PINNED_MANIFEST_PATH,
75
+ mode: "freeze",
76
+ operation: "modify",
77
+ reason: `PINNED_MANIFEST_TAMPERED: entry "${committedPath}" was removed from the manifest`,
78
+ };
79
+ }
80
+ }
81
+ }
82
+ catch {
83
+ // No committed manifest — nothing to compare against. This is normal for new repos.
84
+ }
85
+ return null;
86
+ }
87
+ /**
88
+ * Append an override event to the audit log. Uses fs.appendFile for atomic per-line writes.
89
+ */
90
+ async function appendAuditLog(repoRoot, entry) {
91
+ const logPath = path.join(repoRoot, AUDIT_LOG_PATH);
92
+ const line = JSON.stringify(entry) + "\n";
93
+ await fs.appendFile(logPath, line, "utf8");
94
+ }
95
+ export async function runPinnedValidate(input, context) {
96
+ const { workspaceRoot, logger, outputFormat } = context;
97
+ const mode = input.flags["mode"] ?? "staged";
98
+ const json = input.flags["json"] === true || outputFormat === "json";
99
+ const overrideRaw = input.flags["allow-pinned-override"];
100
+ const overrides = overrideRaw
101
+ ? Array.isArray(overrideRaw)
102
+ ? overrideRaw
103
+ : [overrideRaw]
104
+ : [];
105
+ // Load manifest
106
+ let manifest;
107
+ try {
108
+ manifest = await loadPinnedManifest(workspaceRoot);
109
+ }
110
+ catch (err) {
111
+ if (err instanceof PinnedManifestMalformedError) {
112
+ return {
113
+ data: {
114
+ command: "pinned.validate",
115
+ status: "fail",
116
+ violations: [],
117
+ overrides: [],
118
+ },
119
+ exitCode: 2,
120
+ summary: `Error: ${err.message}`,
121
+ };
122
+ }
123
+ throw err;
124
+ }
125
+ if (!manifest) {
126
+ const msg = "No .forge/pinned.yaml found — pinned-files protection inactive.";
127
+ if (!json) {
128
+ logger.info(msg);
129
+ }
130
+ return {
131
+ data: {
132
+ command: "pinned.validate",
133
+ status: "pass",
134
+ violations: [],
135
+ overrides: [],
136
+ },
137
+ summary: msg,
138
+ };
139
+ }
140
+ // Get git diff
141
+ let diffOutput;
142
+ try {
143
+ if (mode === "ci") {
144
+ const { stdout } = await execAsync("git diff --name-status HEAD~1 HEAD", { cwd: workspaceRoot, encoding: "utf8" });
145
+ diffOutput = stdout;
146
+ }
147
+ else {
148
+ const { stdout } = await execAsync("git diff --cached --name-status", { cwd: workspaceRoot, encoding: "utf8" });
149
+ diffOutput = stdout;
150
+ }
151
+ }
152
+ catch {
153
+ diffOutput = "";
154
+ }
155
+ const changedFiles = parseGitNameStatus(diffOutput);
156
+ // Check each changed file against the manifest
157
+ const allViolations = [];
158
+ for (const { relPath, operation } of changedFiles) {
159
+ const entry = isPinned(manifest, relPath);
160
+ if (entry) {
161
+ // For protect mode, only delete and move are violations — modify is allowed
162
+ if (entry.mode === "protect" && operation === "modify") {
163
+ continue;
164
+ }
165
+ allViolations.push({
166
+ path: relPath,
167
+ mode: entry.mode,
168
+ operation,
169
+ reason: entry.reason,
170
+ });
171
+ }
172
+ }
173
+ // Check manifest integrity (tamper detection)
174
+ const tamperViolation = await checkManifestIntegrity(workspaceRoot, manifest);
175
+ if (tamperViolation) {
176
+ allViolations.push(tamperViolation);
177
+ }
178
+ // Filter out overridden violations
179
+ const overrideSet = new Set(overrides);
180
+ const remainingViolations = [];
181
+ const appliedOverrides = [];
182
+ for (const v of allViolations) {
183
+ if (overrideSet.has(v.path)) {
184
+ appliedOverrides.push(v.path);
185
+ // Log to audit file
186
+ await appendAuditLog(workspaceRoot, {
187
+ timestamp: new Date().toISOString(),
188
+ path: v.path,
189
+ mode: v.mode,
190
+ reason: v.reason,
191
+ });
192
+ }
193
+ else {
194
+ remainingViolations.push(v);
195
+ }
196
+ }
197
+ const status = remainingViolations.length > 0 ? "fail" : "pass";
198
+ const result = {
199
+ command: "pinned.validate",
200
+ status,
201
+ violations: remainingViolations,
202
+ overrides: appliedOverrides,
203
+ };
204
+ if (!json) {
205
+ if (status === "pass") {
206
+ if (appliedOverrides.length > 0) {
207
+ logger.success(`pinned.validate: passed with ${appliedOverrides.length} override(s) (logged to audit)`);
208
+ }
209
+ else {
210
+ logger.success("pinned.validate: no violations");
211
+ }
212
+ }
213
+ else {
214
+ logger.error(`pinned.validate: ${remainingViolations.length} violation(s) found`);
215
+ for (const v of remainingViolations) {
216
+ logger.error(` ${v.operation}: ${v.path} (mode: ${v.mode}) — ${v.reason}`);
217
+ }
218
+ }
219
+ }
220
+ return {
221
+ data: result,
222
+ exitCode: status === "pass" ? 0 : 1,
223
+ summary: status === "pass"
224
+ ? `No violations${appliedOverrides.length > 0 ? ` (${appliedOverrides.length} override(s) applied)` : ""}`
225
+ : `${remainingViolations.length} violation(s) found`,
226
+ };
227
+ }
228
+ //# sourceMappingURL=pinned-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pinned-validate.js","sourceRoot":"","sources":["../../../../os/core/handlers/pinned-validate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../../os/mission/handlers/archive.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAML,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAiErB,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,CAAC,CA2LnD"}
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../../os/mission/handlers/archive.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAML,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAkErB,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,CAAC,CA6NnD"}