forgetrail 0.4.20 → 0.5.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 (42) hide show
  1. package/CONTINUATION_PROMPT.md +5 -5
  2. package/INITIAL_PROMPT.md +15 -15
  3. package/README.md +5 -5
  4. package/TRACKING_SCHEMA.md +16 -7
  5. package/TRY_FORGETRAIL.md +3 -3
  6. package/WORKFLOW.md +50 -45
  7. package/content/AGENT_INTEGRATION_claude.md +1 -1
  8. package/content/AGENT_INTEGRATION_cursor.md +3 -3
  9. package/content/AGENT_INTEGRATION_generic.md +5 -5
  10. package/content/AGENT_INTEGRATION_grok.md +8 -8
  11. package/content/COMPANION_TOOLS.md +1 -1
  12. package/content/FORGETRAIL_LITE.md +72 -68
  13. package/content/FORGETRAIL_PROGRESS.md +3 -3
  14. package/content/GENESIS_SPEC_PROMPT.md +1 -1
  15. package/content/GENESIS_STUB.md +1 -1
  16. package/content/GREENFIELD_INTAKE.md +6 -6
  17. package/content/KICKOFF_WITHOUT_MCP.md +1 -1
  18. package/content/NEW_PROJECT_BOOTSTRAP.md +27 -27
  19. package/content/PLAN_MODE_PATTERNS.md +4 -4
  20. package/content/POST_BOOTSTRAP_USER_MESSAGE.md +1 -1
  21. package/content/SESSION_RESUME_MCP.md +7 -7
  22. package/content/companion-tools.json +1 -1
  23. package/content/cursor-rules/forgetrail-phase-status.mdc +8 -9
  24. package/content/examples/two-session-continuity.md +31 -67
  25. package/content/forgetrail-workspace-README.md +2 -2
  26. package/content/hooks/README.md +3 -3
  27. package/content/hooks/session-start.mjs +58 -63
  28. package/content/hooks/session-stop.mjs +49 -30
  29. package/content/hooks/validate-tracking-core.mjs +34 -1
  30. package/content/scripts/forgetrail-dev-launcher.mjs +12 -2
  31. package/content/skills/forgetrail/SKILL.md +21 -21
  32. package/content/skills/forgetrail/SKILL_FACTS.md +2 -2
  33. package/docs/CONTEXT_PROMPT.md +1 -1
  34. package/docs/NPM.md +8 -8
  35. package/docs/PHASE_1_BRIEF.md +7 -7
  36. package/package.json +69 -70
  37. package/scripts/forgetrail-cli.mjs +1 -1
  38. package/scripts/install-lib.mjs +1 -0
  39. package/scripts/install.mjs +6 -23
  40. package/scripts/publish-gate.mjs +6 -4
  41. package/scripts/tracking-cutover.test.mjs +109 -0
  42. package/scripts/workspace-index.mjs +9 -1
@@ -3,20 +3,17 @@
3
3
  /**
4
4
  * ForgeTrail Session Start Context Injector
5
5
  * Hook event: sessionStart (Cursor)
6
- * Injects live ForgeTrail phase status and open exit criteria into session context.
7
- * Retires static phase-status rules on hosts with hook support.
6
+ * Points the session at appledger/. A legacy workflow_tracking.json is a conflict, not the live phase.
8
7
  */
9
8
 
10
- import { readFileSync, existsSync } from "node:fs";
11
- import { resolve, join } from "node:path";
9
+ import { existsSync, readFileSync } from "node:fs";
10
+ import { join, resolve } from "node:path";
12
11
 
13
- function findTrackingFile(startDir) {
12
+ function walkUp(startDir, found) {
14
13
  let curr = resolve(startDir || process.cwd());
15
14
  for (let i = 0; i < 6; i++) {
16
- const candidate1 = join(curr, ".forgetrail", "workflow_tracking.json");
17
- if (existsSync(candidate1)) return candidate1;
18
- const candidate2 = join(curr, "workflow_tracking.json");
19
- if (existsSync(candidate2)) return candidate2;
15
+ const hit = found(curr);
16
+ if (hit) return hit;
20
17
  const parent = resolve(curr, "..");
21
18
  if (parent === curr) break;
22
19
  curr = parent;
@@ -24,70 +21,68 @@ function findTrackingFile(startDir) {
24
21
  return null;
25
22
  }
26
23
 
27
- function main() {
28
- const trackingPath = findTrackingFile(process.cwd());
29
-
30
- if (!trackingPath) {
31
- console.log(JSON.stringify({}));
32
- return;
33
- }
34
-
35
- try {
36
- const tracking = JSON.parse(readFileSync(trackingPath, "utf-8"));
37
- const projectName = tracking.project?.name || "App";
38
- const phase = tracking.currentPhase || "1";
39
- const isLite = tracking.schemaVersion === "lite-1";
24
+ function findLedger(startDir) {
25
+ return walkUp(startDir, (dir) => {
26
+ const manifest = join(dir, "appledger", "manifest.yaml");
27
+ if (existsSync(manifest)) return dir;
28
+ return null;
29
+ });
30
+ }
40
31
 
41
- let remaining = [];
42
- if (isLite) {
43
- const phaseObj = tracking.phases?.[String(phase)];
44
- if (phaseObj?.exitCriteria) {
45
- remaining = Object.entries(phaseObj.exitCriteria)
46
- .filter(([_, met]) => !met)
47
- .map(([flag]) => flag);
48
- }
49
- } else {
50
- const phaseObj = tracking.phases?.[phase];
51
- if (Array.isArray(phaseObj?.exitCriteriaRemaining)) {
52
- remaining = phaseObj.exitCriteriaRemaining;
53
- }
54
- }
32
+ function findProjectTracking(startDir) {
33
+ return walkUp(startDir, (dir) => {
34
+ const candidate = join(dir, ".forgetrail", "workflow_tracking.json");
35
+ if (existsSync(candidate)) return candidate;
36
+ const rootStarter = join(dir, "workflow_tracking.json");
37
+ const methodology = existsSync(join(dir, "WORKFLOW.md")) && existsSync(join(dir, "content"));
38
+ if (existsSync(rootStarter) && !methodology) return rootStarter;
39
+ return null;
40
+ });
41
+ }
55
42
 
56
- let lastLeftOff = "";
57
- if (Array.isArray(tracking.sessions) && tracking.sessions.length > 0) {
58
- const lastSession = tracking.sessions[tracking.sessions.length - 1];
59
- lastLeftOff = lastSession.leftOff || lastSession.notes || "";
60
- }
43
+ function isPointer(data) {
44
+ return data?.status === "pointer" && typeof data.record === "string" && data.record.replaceAll("\\", "/").includes("appledger");
45
+ }
61
46
 
62
- const lines = [
63
- `=== ForgeTrail Context (${projectName}) ===`,
64
- `Current Phase: ${phase} (${isLite ? "Lite schema" : "MCP schema"})`,
65
- ];
47
+ function main() {
48
+ const ledgerRoot = findLedger(process.cwd());
49
+ const trackingPath = findProjectTracking(process.cwd());
50
+ const lines = [];
66
51
 
67
- if (lastLeftOff) {
68
- lines.push(`Last Session Left Off: ${lastLeftOff}`);
69
- }
52
+ if (ledgerRoot) {
53
+ lines.push("=== ForgeTrail Context ===");
54
+ lines.push("Project record: appledger/");
55
+ lines.push("Read appledger/profiles/forgetrail.yaml for the current phase.");
56
+ lines.push("Read the latest session record for left_off and next_steps.");
57
+ lines.push("Do not update workflow_tracking.json.");
58
+ }
70
59
 
71
- if (remaining.length > 0) {
72
- lines.push("Open Exit Criteria for Current Phase:");
73
- for (const item of remaining.slice(0, 5)) {
74
- lines.push(` - ${item}`);
75
- }
76
- if (remaining.length > 5) {
77
- lines.push(` ...and ${remaining.length - 5} more`);
60
+ if (trackingPath) {
61
+ try {
62
+ const tracking = JSON.parse(readFileSync(trackingPath, "utf-8"));
63
+ if (isPointer(tracking)) {
64
+ if (!ledgerRoot) {
65
+ lines.push("=== ForgeTrail Context ===");
66
+ lines.push("workflow_tracking.json is a pointer to appledger/. Do not write decisions, sessions, or phase status there.");
67
+ }
68
+ } else {
69
+ lines.push("=== Legacy tracking conflict ===");
70
+ lines.push("workflow_tracking.json is not the system of record.");
71
+ lines.push("Do not add decisions, sessions, or phase status to it.");
72
+ lines.push("Run `appledger migrate preview`, then apply once, and write only in appledger/.");
78
73
  }
74
+ } catch {
75
+ lines.push("workflow_tracking.json could not be read. Do not recreate it. Use appledger/.");
79
76
  }
77
+ }
80
78
 
81
- lines.push("========================================");
82
-
83
- console.log(
84
- JSON.stringify({
85
- additional_context: lines.join("\n"),
86
- })
87
- );
88
- } catch {
79
+ if (lines.length === 0) {
89
80
  console.log(JSON.stringify({}));
81
+ return;
90
82
  }
83
+
84
+ lines.push("========================================");
85
+ console.log(JSON.stringify({ additional_context: lines.join("\n") }));
91
86
  }
92
87
 
93
88
  main();
@@ -3,19 +3,17 @@
3
3
  /**
4
4
  * ForgeTrail Session Stop Check
5
5
  * Hook event: stop (Cursor)
6
- * Prompts a reminder if a session concluded without updating sessions[] in tracking.
6
+ * Reminds the agent to update the AppLedger session, not a tracking JSON file.
7
7
  */
8
8
 
9
- import { readFileSync, existsSync } from "node:fs";
10
- import { resolve, join } from "node:path";
9
+ import { existsSync, readFileSync } from "node:fs";
10
+ import { join, resolve } from "node:path";
11
11
 
12
- function findTrackingFile(startDir) {
12
+ function walkUp(startDir, found) {
13
13
  let curr = resolve(startDir || process.cwd());
14
14
  for (let i = 0; i < 6; i++) {
15
- const candidate1 = join(curr, ".forgetrail", "workflow_tracking.json");
16
- if (existsSync(candidate1)) return candidate1;
17
- const candidate2 = join(curr, "workflow_tracking.json");
18
- if (existsSync(candidate2)) return candidate2;
15
+ const hit = found(curr);
16
+ if (hit) return hit;
19
17
  const parent = resolve(curr, "..");
20
18
  if (parent === curr) break;
21
19
  curr = parent;
@@ -23,32 +21,53 @@ function findTrackingFile(startDir) {
23
21
  return null;
24
22
  }
25
23
 
24
+ function findLedger(startDir) {
25
+ return walkUp(startDir, (dir) => (existsSync(join(dir, "appledger", "manifest.yaml")) ? dir : null));
26
+ }
27
+
28
+ function findProjectTracking(startDir) {
29
+ return walkUp(startDir, (dir) => {
30
+ const candidate = join(dir, ".forgetrail", "workflow_tracking.json");
31
+ if (existsSync(candidate)) return candidate;
32
+ return null;
33
+ });
34
+ }
35
+
36
+ function isPointer(data) {
37
+ return data?.status === "pointer" && typeof data.record === "string" && data.record.replaceAll("\\", "/").includes("appledger");
38
+ }
39
+
26
40
  function main() {
27
- const trackingPath = findTrackingFile(process.cwd());
28
- if (!trackingPath) {
29
- console.log(JSON.stringify({}));
41
+ const ledgerRoot = findLedger(process.cwd());
42
+ const trackingPath = findProjectTracking(process.cwd());
43
+ let legacy = false;
44
+ if (trackingPath) {
45
+ try {
46
+ legacy = !isPointer(JSON.parse(readFileSync(trackingPath, "utf-8")));
47
+ } catch {
48
+ legacy = true;
49
+ }
50
+ }
51
+
52
+ if (legacy) {
53
+ console.log(
54
+ JSON.stringify({
55
+ followup_message:
56
+ "ForgeTrail reminder: workflow_tracking.json is a legacy file. Do not append sessions to it. Run `appledger migrate preview`, then apply, and record this session in appledger/.",
57
+ })
58
+ );
30
59
  return;
31
60
  }
32
61
 
33
- try {
34
- const tracking = JSON.parse(readFileSync(trackingPath, "utf-8"));
35
- const sessions = tracking.sessions;
36
-
37
- const today = new Date().toISOString().slice(0, 10);
38
- const hasTodaySession =
39
- Array.isArray(sessions) &&
40
- sessions.some((s) => s.date === today || (s.timestamp && s.timestamp.startsWith(today)));
41
-
42
- if (!hasTodaySession) {
43
- console.log(
44
- JSON.stringify({
45
- followup_message:
46
- "ForgeTrail Reminder: Update .forgetrail/workflow_tracking.json (sessions[], decisions[], gotchas[]) with what was accomplished before ending.",
47
- })
48
- );
49
- return;
50
- }
51
- } catch {}
62
+ if (ledgerRoot) {
63
+ console.log(
64
+ JSON.stringify({
65
+ followup_message:
66
+ "ForgeTrail reminder: update the appledger session record (what was accomplished, left_off, next_steps) before ending. Do not write workflow_tracking.json.",
67
+ })
68
+ );
69
+ return;
70
+ }
52
71
 
53
72
  console.log(JSON.stringify({}));
54
73
  }
@@ -41,6 +41,26 @@ function isLiteSchema(data) {
41
41
  return data && data.schemaVersion === "lite-1";
42
42
  }
43
43
 
44
+ const LEGACY_TRACKING_ISSUE =
45
+ "Legacy writable tracking is not the system of record. Do not add decisions, sessions, or phase status to this file. Run `appledger migrate preview`, then apply once, and write only in appledger/.";
46
+
47
+ const POINTER_WARNING =
48
+ "This file is a pointer to appledger/. Do not add decisions, sessions, or phase status here.";
49
+
50
+ function isPointer(data) {
51
+ return data.status === "pointer" && typeof data.record === "string" && data.record.replaceAll("\\", "/").includes("appledger");
52
+ }
53
+
54
+ function isLegacyTracking(data) {
55
+ return (
56
+ "currentPhase" in data ||
57
+ "phases" in data ||
58
+ "decisions" in data ||
59
+ "sessions" in data ||
60
+ "schemaVersion" in data
61
+ );
62
+ }
63
+
44
64
  export function validateTrackingData(data) {
45
65
  const issues = [];
46
66
  const warnings = [];
@@ -50,6 +70,15 @@ export function validateTrackingData(data) {
50
70
  return { issues, warnings };
51
71
  }
52
72
 
73
+ if (isPointer(data)) {
74
+ warnings.push(POINTER_WARNING);
75
+ return { issues, warnings };
76
+ }
77
+
78
+ if (isLegacyTracking(data)) {
79
+ issues.push(LEGACY_TRACKING_ISSUE);
80
+ }
81
+
53
82
  const project = data.project;
54
83
  if (!project || typeof project !== "object") {
55
84
  issues.push("Missing top-level project object.");
@@ -214,7 +243,11 @@ export function formatValidationResult(result) {
214
243
  const { issues, warnings } = result;
215
244
 
216
245
  if (issues.length === 0 && warnings.length === 0) {
217
- return "Tracking file looks structurally healthy.";
246
+ return "No workflow_tracking.json is required. Project state lives in appledger/.";
247
+ }
248
+
249
+ if (issues.length === 0 && warnings.every((item) => item.includes("pointer"))) {
250
+ return "Pointer accepted. Project state lives in appledger/.\n\n" + warnings.map((item) => `- ${item}`).join("\n");
218
251
  }
219
252
 
220
253
  const parts = [];
@@ -143,9 +143,19 @@ async function cmdRun() {
143
143
 
144
144
  function renderProgress() {
145
145
  if (!existsSync(trackingPath)) {
146
- return { text: "No .forgetrail/workflow_tracking.json yet — agent bootstrap not finished.", md: null };
146
+ return {
147
+ text: "No workflow_tracking.json. Phase state belongs in appledger/profiles/forgetrail.yaml.",
148
+ md: null,
149
+ };
147
150
  }
148
151
  const t = JSON.parse(readFileSync(trackingPath, "utf8"));
152
+ const record = typeof t.record === "string" ? t.record.replaceAll("\\", "/") : "";
153
+ if (t.status === "pointer" && record.includes("appledger")) {
154
+ return {
155
+ text: "workflow_tracking.json is a pointer to appledger/. Read appledger/profiles/forgetrail.yaml.",
156
+ md: null,
157
+ };
158
+ }
149
159
  const phase = t.currentPhase ?? "?";
150
160
  const phaseId = String(phase);
151
161
  const phaseBlock = t.phases?.[phaseId];
@@ -168,7 +178,7 @@ function renderProgress() {
168
178
  const md = [
169
179
  "# ForgeTrail progress",
170
180
  "",
171
- "_Human-readable snapshot. Source of truth: `.forgetrail/workflow_tracking.json`._",
181
+ "_Human-readable snapshot read from a legacy workflow_tracking.json. After migrate, the source of truth is `appledger/profiles/forgetrail.yaml`._",
172
182
  "",
173
183
  `**Current phase:** ${label} (\`${phaseId}\`) — **${status}**`,
174
184
  "",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: forgetrail
3
- description: "Enforce the ForgeTrail 7-phase lifecycle (Plan → Build → Stabilize → Iterate → Refine → Align → Harden), maintain .forgetrail/workflow_tracking.json as the system of record, pause at explicit phase transitions for user approval, prefer native plan modes when available, and use subagents for parallel audits/research where the host agent supports it. Activate for any non-trivial full-stack app development. Follow progressive documentation rules and propagate lessons back."
3
+ description: "Enforce the ForgeTrail 7-phase lifecycle (Plan → Build → Stabilize → Iterate → Refine → Align → Harden), maintain appledger/ as the system of record, pause at explicit phase transitions for user approval, prefer native plan modes when available, and use subagents for parallel audits/research where the host agent supports it. Do not write workflow_tracking.json. Activate for any non-trivial full-stack app development. Follow progressive documentation rules and propagate lessons back."
4
4
  user-invocable: true
5
5
  argument-hint: "kickoff new project | resume session | Phase 4 feature work | run black-hat audit | stabilize current issues"
6
6
  allowed-tools: "read_file, search_replace, run_terminal_command, todo_write, spawn_subagent, getPhaseGuidance, getCompanionSuggestions, runAudit, searchLessons, validateTracking, suggestSubagentDecomposition, getTemplate, getNewProjectKickoff, getResumeSessionInstructions"
@@ -21,27 +21,28 @@ You are operating under the ForgeTrail methodology. Your primary job is to give
21
21
  - 6. Align (map to brand/strategy)
22
22
  - 7. Harden (security, perf, docs, production readiness)
23
23
 
24
- Phases 4 and 5 commonly alternate. Update `currentPhase` and exit criteria in tracking.
24
+ Phases 4 and 5 commonly alternate. Update `current_phase_instance` and criteria in `appledger/profiles/forgetrail.yaml`. Do not write `workflow_tracking.json`.
25
25
 
26
26
  2. **At the start of every session or major turn**:
27
- - Read `.forgetrail/workflow_tracking.json` (create `.forgetrail/` if missing).
27
+ - Read `appledger/profiles/forgetrail.yaml` and the latest session record.
28
28
  - Read `CONTEXT_PROMPT.md` and `TODO.md` if they exist.
29
29
  - Call `getPhaseGuidance` for the current phase if needed.
30
- - Summarize current phase, exit criteria met/remaining, and recent decisions to the user briefly.
30
+ - Summarize current phase, pending criteria, and recent decisions to the user briefly.
31
+ - If `workflow_tracking.json` exists and is not a pointer, do not edit it. Run `appledger migrate preview`, then apply.
31
32
 
32
33
  3. **Pause at phase transitions**:
33
34
  - When you believe exit criteria for the current phase are met, explicitly tell the user: "I think we have completed Phase X because [reasons]. The remaining exit criteria are [list]. Ready to move to Phase Y?"
34
- - Wait for explicit user approval before advancing `currentPhase` in tracking.
35
+ - Wait for explicit user approval before changing `current_phase_instance`.
35
36
 
36
- 4. **Maintain the tracking file** (`.forgetrail/workflow_tracking.json`):
37
- - Log every major decision with rationale and alternatives_considered.
38
- - Move items from `exitCriteriaRemaining` to `exitCriteriaMet`.
39
- - Add to `gotchas[]` immediately when something surprising or painful happens.
40
- - Append session notes at natural breaks.
41
- - Use the schema from `getTrackingSchema`.
37
+ 4. **Maintain `appledger/`**:
38
+ - Log every major decision as a decision record with rationale.
39
+ - Mark a criterion `met` only when an evidence ref exists.
40
+ - Add a lesson or question record when something surprising or painful happens.
41
+ - Update the session record at natural breaks.
42
+ - Do not create or update `workflow_tracking.json`.
42
43
 
43
44
  5. **Use native agent capabilities**:
44
- - If the agent supports a native plan mode (e.g. Grok `/plan`), use it for Phase 1. On approval, export the plan into `docs/PHASE_1_BRIEF.md` (via `getTemplate`) + `decisions[]`.
45
+ - If the agent supports a native plan mode (e.g. Grok `/plan`), use it for Phase 1. On approval, export the plan into `docs/PHASE_1_BRIEF.md` (via `getTemplate`) and decision records in `appledger/`. Do not write `workflow_tracking.json`.
45
46
  - When the host supports `spawn_subagent`, use `suggestSubagentDecomposition` (or reason directly) to run audits, research, and reviews in parallel with appropriate `capability_mode`, `isolation`, and personas. Synthesize results in the parent thread and update tracking/docs.
46
47
  - Prefer `read-only` or `execute` modes for subagents doing analysis.
47
48
 
@@ -68,18 +69,17 @@ You are operating under the ForgeTrail methodology. Your primary job is to give
68
69
  ## Phase Transition Protocol
69
70
 
70
71
  When ready to advance:
71
- - Confirm all exit criteria.
72
- - Update tracking.
73
- - Ask user: "Ready to move to Phase X?"
74
- - Only after confirmation, update `currentPhase` and start the next phase's playbook.
72
+ - Confirm the phase criteria that have evidence.
73
+ - Ask the user: "Ready to move to Phase X?"
74
+ - Only after confirmation, update the phase status in `appledger/profiles/forgetrail.yaml` and the session record. Do not write `workflow_tracking.json`.
75
75
 
76
76
  ## For New Projects (Greenfield)
77
77
 
78
- Prefer calling `getNewProjectKickoff` (or `kickoffGreenfield`) at the very beginning. Write the returned `.forgetrail/workflow_tracking.json`, optional Cursor rules, and follow the post-bootstrap instructions exactly. Then start with Phase 1.
78
+ Prefer calling `getNewProjectKickoff` (or `kickoffGreenfield`) at the very beginning. When `appledger` is installed, run `appledger init` as that bundle describes. Do not write `workflow_tracking.json`. Write optional Cursor rules, and follow the post-bootstrap instructions exactly. Then start with Phase 1.
79
79
 
80
80
  ## For Resuming
81
81
 
82
- Call `getResumeSessionInstructions` (or read tracking + CONTEXT_PROMPT) and continue from the current phase.
82
+ Call `getResumeSessionInstructions` (or read `appledger/profiles/forgetrail.yaml`, the latest session, and CONTEXT_PROMPT) and continue from the current phase.
83
83
 
84
84
  ## Key Tools to Use Proactively
85
85
 
@@ -88,10 +88,10 @@ Call `getResumeSessionInstructions` (or read tracking + CONTEXT_PROMPT) and cont
88
88
  - `getTemplate({name: "..."})` — for PHASE_1_BRIEF, CONTEXT_PROMPT, audits, etc. Use mode "shell" for clean structure.
89
89
  - `runAudit`, `searchLessons`, `getAntiPatterns`
90
90
  - `suggestSubagentDecomposition` (when subagents available)
91
- - `validateTracking` (to keep the state file healthy)
92
- - `ingestPlanArtifact` (after native plan mode approval — map plan → PHASE_1_BRIEF + decisions[])
91
+ - `validateTracking` (classify a legacy `workflow_tracking.json`; a missing file is expected)
92
+ - `ingestPlanArtifact` (after native plan mode approval — map plan → PHASE_1_BRIEF + decision records)
93
93
  - `todo_write` — mirror open exit criteria and next actions.
94
94
 
95
- Always keep the user in the loop on phase progress and major decisions. The tracking file + CONTEXT_PROMPT are the source of truth across sessions, not chat history.
95
+ Always keep the user in the loop on phase progress and major decisions. `appledger/` plus CONTEXT_PROMPT are the source of truth across sessions, not chat history.
96
96
 
97
97
  This skill makes you a much more reliable long-term build partner. Use it.
@@ -6,7 +6,7 @@ version: "0.3.0"
6
6
  status: active
7
7
  license: Apache-2.0
8
8
  kind: cursor-skill
9
- purpose: "Enforce the ForgeTrail 7-phase lifecycle and maintain .forgetrail/workflow_tracking.json as the system of record"
9
+ purpose: "Enforce the ForgeTrail 7-phase lifecycle and maintain appledger/ as the system of record"
10
10
  homepage: https://forgetrail.dev
11
11
  repository: https://github.com/Catalyst-Forge-LLC/forgetrail
12
12
  provenance:
@@ -54,7 +54,7 @@ credits:
54
54
 
55
55
  ## Purpose
56
56
 
57
- Enforce the ForgeTrail 7-phase lifecycle and maintain .forgetrail/workflow_tracking.json as the system of record
57
+ Enforce the ForgeTrail 7-phase lifecycle and maintain appledger/ as the system of record
58
58
 
59
59
  ## Provenance
60
60
 
@@ -24,7 +24,7 @@ _If the project used ForgeTrail Phase 1 properly, **`docs/PHASE_1_BRIEF.md`** ex
24
24
  | §10 Out of scope v1 | **Key Architectural Decisions** or short note under **Recent Changes** |
25
25
  | §11 First feature batch | Seed **`TODO.md`** |
26
26
 
27
- **After merge:** Keep **`PHASE_1_BRIEF.md`** in `docs/` as a dated audit trail **or** replace its body with one line: `Merged into CONTEXT_PROMPT.md on [date]. Source preserved in git history.` Do **not** delete corresponding entries in **`.forgetrail/workflow_tracking.json` → `decisions[]`.**
27
+ **After merge:** Keep **`PHASE_1_BRIEF.md`** in `docs/` as a dated audit trail **or** replace its body with one line: `Merged into CONTEXT_PROMPT.md on [date]. Source preserved in git history.` Do **not** delete the corresponding decision records in **`appledger/`**.
28
28
 
29
29
  ---
30
30
 
package/docs/NPM.md CHANGED
@@ -8,14 +8,14 @@ You run `pnpm publish`. The gate does not log in or publish.
8
8
 
9
9
  Two public unscoped packages:
10
10
 
11
- | Package | Version | From | What it is |
12
- | --- | --- | --- | --- |
13
- | [`forgetrail`](https://www.npmjs.com/package/forgetrail) | 0.3.0 | repo root | CLI + Lite + templates. `npx forgetrail install --lite` |
14
- | [`forgetrail-mcp`](https://www.npmjs.com/package/forgetrail-mcp) | 0.2.2 | `mcp-server/` | MCP bin. `npx -y forgetrail-mcp` |
11
+ | Package | This tree | On npm until you publish | From | What it is |
12
+ | --- | --- | --- | --- | --- |
13
+ | [`forgetrail`](https://www.npmjs.com/package/forgetrail) | 0.5.0 | 0.4.20 | repo root | CLI + Lite + templates. `pnpm dlx forgetrail install --lite` |
14
+ | [`forgetrail-mcp`](https://www.npmjs.com/package/forgetrail-mcp) | 0.4.0 | 0.3.10 | `mcp-server/` | MCP bin. `pnpm dlx forgetrail-mcp` |
15
15
 
16
16
  These are **installer and MCP channels**, not a library. App repos should not add `forgetrail` to `dependencies`.
17
17
 
18
- `pnpm run pack:check` already passed on this tree (2026-08-20). Root dry-run packed `forgetrail@0.3.0` (98 files, no `site/` or `specs/`).
18
+ `0.5.0` stops installing `workflow_tracking.json`. `0.4.0` tells kickoff to run `appledger init`. The registry copies above do not include that cutover. `pnpm run pack:check` is the gate. It does not publish.
19
19
 
20
20
  ---
21
21
 
@@ -59,11 +59,11 @@ The `Debugger listening` line on MCP `prepack` is Cursor attaching to a one-line
59
59
 
60
60
  ```bash
61
61
  # Prefer pnpm dlx. npm 12 `npx forgetrail --help` on Windows failed to spawn the bin.
62
- pnpm dlx forgetrail@0.3.0 --help
63
- pnpm dlx forgetrail@0.3.0 install --lite --dry-run
62
+ pnpm dlx forgetrail@0.5.0 --help
63
+ pnpm dlx forgetrail@0.5.0 install --lite --dry-run
64
64
 
65
65
  # MCP starts; needs content via FORGETRAIL_ROOT or a sibling forgetrail install
66
- pnpm dlx forgetrail-mcp@0.2.2
66
+ pnpm dlx forgetrail-mcp@0.4.0
67
67
  ```
68
68
 
69
69
  Optional Cursor MCP (content from a `forgetrail` install, or set the path):
@@ -1,10 +1,10 @@
1
1
  # [App Name] — Phase 1 architecture brief
2
2
 
3
- _Structured capture of planning and architecture **before** code scaffolding. Goal: Phase 2 (or a new agent/session) can start from this file + `.forgetrail/workflow_tracking.json` without re-reading the whole Phase 1 chat._
3
+ _Structured capture of planning and architecture **before** code scaffolding. Goal: Phase 2 (or a new agent/session) can start from this file plus `appledger/` without re-reading the whole Phase 1 chat._
4
4
 
5
5
  **Status:** `[draft | locked]`
6
6
  **Last updated:** `[ISO date]`
7
- **Phase 1 exit:** Do not mark Phase 1 complete in `.forgetrail/workflow_tracking.json` until this brief is **locked** and major commitments are in `decisions[]`.
7
+ **Phase 1 exit:** Do not mark the `plan` phase complete in `appledger/profiles/forgetrail.yaml` until this brief is **locked** and major commitments are decision records. Do not write `workflow_tracking.json`.
8
8
 
9
9
  ---
10
10
 
@@ -13,7 +13,7 @@ _Structured capture of planning and architecture **before** code scaffolding. Go
13
13
  **What we are building (2–4 sentences):**
14
14
 
15
15
 
16
- **Project archetype:** `[product | internal-tool | one-shot]` _(WORKFLOW.md §1d — non-`product` archetypes prune later-phase exit criteria in the tracking file; log the pruning in `decisions[]`)_
16
+ **Project archetype:** `[product | internal-tool | one-shot]` _(WORKFLOW.md §1d — non-`product` archetypes prune later-phase criteria in `appledger/profiles/forgetrail.yaml`; record the pruning as a decision.)_
17
17
 
18
18
  **What “done” looks like for v1 (measurable where possible):**
19
19
 
@@ -115,7 +115,7 @@ _What could blow schedule or architecture — honest list._
115
115
 
116
116
  ## 8. Architectural decisions (numbered)
117
117
 
118
- _Each decision should include **WHY** and what was rejected. **Also** add each major commitment to `.forgetrail/workflow_tracking.json` → `decisions[]` (id, timestamp, phase, decision, rationale, alternatives_considered)._
118
+ _Each decision should include **WHY** and what was rejected. **Also** add each major commitment as a decision record in `appledger/` (choice, rationale, alternatives)._
119
119
 
120
120
  **D1.**
121
121
 
@@ -158,7 +158,7 @@ _Ordered list of what to build after the spine runs — aligns with initial `TOD
158
158
 
159
159
  - [ ] User has confirmed stack, folder shape, data sketch, hero flow, and v1 boundaries
160
160
  - [ ] This brief is **locked** (no `[draft]` ambiguity) or remaining items are only in §9 Open questions
161
- - [ ] `.forgetrail/workflow_tracking.json` updated: `decisions[]` for each major D#; `phases["1-architecture"]` notes summarize sign-off
162
- - [ ] Phase 2 opener will read **this file** + `.forgetrail/workflow_tracking.json` first
161
+ - [ ] `appledger/` updated: a decision record for each major D#, and the session records the sign-off. Do not write `workflow_tracking.json`.
162
+ - [ ] Phase 2 opener will read **this file**, `appledger/profiles/forgetrail.yaml`, and the latest session record first
163
163
 
164
- > 💡 **Lesson learned:** Treat the brief and `decisions[]` as a pair: JSON is great for machine-structured history; the brief is great for the next human or agent to read in one pass. Duplicated rationale is OK — drift between them is not. After Phase 2 starts, **merge** this content into `CONTEXT_PROMPT.md` per the mapping in that template’s “Handoff from Phase 1” section.
164
+ > 💡 **Lesson learned:** Treat the brief and the decision records as a pair. The brief is what the next human or agent reads in one pass. Duplicated rationale is OK — drift between them is not. After Phase 2 starts, **merge** this content into `CONTEXT_PROMPT.md` per the mapping in that template’s “Handoff from Phase 1” section.