ace-pack 0.1.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.
@@ -0,0 +1,158 @@
1
+ export const DEFAULT_THRESHOLDS = {
2
+ large: {
3
+ minDiffLines: 300,
4
+ minFiles: 8,
5
+ },
6
+ small: {
7
+ maxDiffLines: 80,
8
+ maxFiles: 2,
9
+ },
10
+ }
11
+
12
+ export const UNIVERSAL_HIGH_RISK_PATHS = [
13
+ { label: 'agent instructions', pattern: 'AGENTS.md', tier: 'large' },
14
+ { label: 'agent instructions', pattern: 'CLAUDE.md', tier: 'large' },
15
+ { label: 'agent memory workflow', pattern: '.ai/**', tier: 'large' },
16
+ { label: 'CI workflow', pattern: '.github/workflows/**', tier: 'large' },
17
+ { label: 'CI workflow', pattern: '.gitlab-ci.yml', tier: 'large' },
18
+ { label: 'deployment configuration', pattern: 'Dockerfile', tier: 'large' },
19
+ { label: 'deployment configuration', pattern: 'docker-compose*', tier: 'large' },
20
+ { label: 'deployment configuration', pattern: 'compose.y*ml', tier: 'large' },
21
+ { label: 'automation scripts', pattern: 'scripts/**', tier: 'large' },
22
+ { label: 'request middleware', pattern: '**/middleware.*', tier: 'large' },
23
+ { label: 'database migration', pattern: '**/migrations/**', tier: 'large' },
24
+ { label: 'secret handling', pattern: '**/*secret*', tier: 'large' },
25
+ { label: 'token handling', pattern: '**/*token*', tier: 'large' },
26
+ { label: 'token or crypto handling', pattern: '**/*crypto*', tier: 'large' },
27
+ { label: 'authentication', pattern: '**/*auth*', tier: 'large' },
28
+ ]
29
+
30
+ export const UNIVERSAL_HIGH_RISK_KEYWORDS = [
31
+ { keyword: 'auth', label: 'authentication', tier: 'large' },
32
+ { keyword: 'authentication', label: 'authentication', tier: 'large' },
33
+ { keyword: 'permission', label: 'permissions', tier: 'large' },
34
+ { keyword: 'permissions', label: 'permissions', tier: 'large' },
35
+ { keyword: 'secret', label: 'secret handling', tier: 'large' },
36
+ { keyword: 'secrets', label: 'secret handling', tier: 'large' },
37
+ { keyword: 'credential', label: 'credential handling', tier: 'large' },
38
+ { keyword: 'credentials', label: 'credential handling', tier: 'large' },
39
+ { keyword: 'password', label: 'password handling', tier: 'large' },
40
+ { keyword: 'passwords', label: 'password handling', tier: 'large' },
41
+ { keyword: 'token', label: 'token handling', tier: 'large' },
42
+ { keyword: 'tokens', label: 'token handling', tier: 'large' },
43
+ { keyword: 'crypto', label: 'token or crypto handling', tier: 'large' },
44
+ { keyword: 'migration', label: 'database migration', tier: 'large' },
45
+ { keyword: 'migrations', label: 'database migration', tier: 'large' },
46
+ { keyword: 'environment', label: 'environment isolation', tier: 'large' },
47
+ { keyword: 'production', label: 'production safety', tier: 'large' },
48
+ { keyword: 'deploy', label: 'deployment', tier: 'large' },
49
+ { keyword: 'delete', label: 'destructive operation', tier: 'standard' },
50
+ { keyword: 'destroy', label: 'destructive operation', tier: 'standard' },
51
+ ]
52
+
53
+ const NEXT_TRPC_DRIZZLE_PATHS = [
54
+ { label: 'auth package', pattern: 'packages/auth/**', tier: 'large' },
55
+ { label: 'database schema', pattern: 'packages/db/src/schema/**', tier: 'large' },
56
+ { label: 'database migration', pattern: 'packages/db/migrations/**', tier: 'large' },
57
+ { label: 'database migration', pattern: 'packages/db/drizzle/**', tier: 'large' },
58
+ { label: 'tRPC router', pattern: 'packages/api/src/routers/**', tier: 'large' },
59
+ { label: 'Next.js middleware', pattern: 'middleware.ts', tier: 'large' },
60
+ { label: 'Next.js middleware', pattern: '**/middleware.ts', tier: 'large' },
61
+ { label: 'tenant isolation', pattern: '**/*tenant*', tier: 'large' },
62
+ ]
63
+
64
+ const NEXT_TRPC_DRIZZLE_KEYWORDS = [
65
+ { keyword: 'tenant', label: 'tenant isolation', tier: 'large' },
66
+ { keyword: 'tenancy', label: 'tenant isolation', tier: 'large' },
67
+ ]
68
+
69
+ export const PROJECT_PRESETS = {
70
+ 'next-trpc-drizzle-saas': {
71
+ description: 'Next.js + tRPC + Drizzle SaaS monorepo risk profile.',
72
+ highRiskKeywords: dedupeKeywordRules([
73
+ ...UNIVERSAL_HIGH_RISK_KEYWORDS,
74
+ ...NEXT_TRPC_DRIZZLE_KEYWORDS,
75
+ ]),
76
+ highRiskPaths: dedupePathRules([...UNIVERSAL_HIGH_RISK_PATHS, ...NEXT_TRPC_DRIZZLE_PATHS]),
77
+ id: 'next-trpc-drizzle-saas',
78
+ name: 'Next/tRPC/Drizzle SaaS',
79
+ },
80
+ }
81
+
82
+ export const NEUTRAL_MEMORY_CONFIG = buildMemoryConfig({
83
+ highRiskKeywords: UNIVERSAL_HIGH_RISK_KEYWORDS,
84
+ highRiskPaths: UNIVERSAL_HIGH_RISK_PATHS,
85
+ profile: {
86
+ note: 'Run pnpm ace:onboard to profile this repository and apply project-specific risk rules.',
87
+ status: 'unprofiled',
88
+ },
89
+ })
90
+
91
+ export function getProjectPreset(id) {
92
+ return PROJECT_PRESETS[id] ?? null
93
+ }
94
+
95
+ export function buildPresetMemoryConfig(id, profile = {}) {
96
+ const preset = getProjectPreset(id)
97
+
98
+ if (!preset) {
99
+ throw new Error(`Unknown ACE project preset: ${id}`)
100
+ }
101
+
102
+ return buildMemoryConfig({
103
+ highRiskKeywords: preset.highRiskKeywords,
104
+ highRiskPaths: preset.highRiskPaths,
105
+ profile: {
106
+ preset: id,
107
+ status: 'profiled',
108
+ ...profile,
109
+ },
110
+ })
111
+ }
112
+
113
+ export function buildMemoryConfig({ highRiskKeywords, highRiskPaths, profile }) {
114
+ return {
115
+ _name: 'ACE (Agentic Context Engine) Configuration',
116
+ _profile: profile,
117
+ highRiskKeywords: dedupeKeywordRules(highRiskKeywords),
118
+ highRiskPaths: dedupePathRules(highRiskPaths),
119
+ thresholds: DEFAULT_THRESHOLDS,
120
+ version: 1,
121
+ }
122
+ }
123
+
124
+ export function dedupePathRules(rules) {
125
+ const seen = new Set()
126
+ const result = []
127
+
128
+ for (const rule of rules) {
129
+ const key = `${rule.pattern}:${rule.tier}:${rule.label}`
130
+
131
+ if (seen.has(key)) {
132
+ continue
133
+ }
134
+
135
+ seen.add(key)
136
+ result.push(rule)
137
+ }
138
+
139
+ return result
140
+ }
141
+
142
+ export function dedupeKeywordRules(rules) {
143
+ const seen = new Set()
144
+ const result = []
145
+
146
+ for (const rule of rules) {
147
+ const key = `${rule.keyword}:${rule.tier}:${rule.label}`
148
+
149
+ if (seen.has(key)) {
150
+ continue
151
+ }
152
+
153
+ seen.add(key)
154
+ result.push(rule)
155
+ }
156
+
157
+ return result
158
+ }
@@ -0,0 +1,40 @@
1
+ export const productRoadmapTemplate = `# Product Roadmap
2
+
3
+ Use this file as the project-agnostic business context source for ACE.
4
+ Keep entries concise and update it only when business goals, completed epics,
5
+ or planned features materially change.
6
+
7
+ ## Business Goals
8
+ - [Describe the active product/business goals]
9
+
10
+ ## Completed Epics
11
+ - [Record completed epics with short outcome notes]
12
+
13
+ ## Planned Features
14
+ - [Record planned features or roadmap bets]
15
+
16
+ ## Open Product Questions
17
+ - [Record unresolved business or scope questions]
18
+ `
19
+
20
+ export const techDocsTemplate = `# Technical Docs
21
+
22
+ Use this file as the project-agnostic technical context source for ACE.
23
+ Keep it high-signal so browser-based AI architects can understand the system
24
+ without reading large implementation files.
25
+
26
+ ## Architecture
27
+ - [Summarize the current system architecture and key boundaries]
28
+
29
+ ## Data Model / DB Schema
30
+ - [Summarize durable schema concepts, migrations, and data ownership]
31
+
32
+ ## Auth, RBAC, and Security
33
+ - [Summarize auth flow, role boundaries, permissions, and token handling]
34
+
35
+ ## External APIs and Integrations
36
+ - [Summarize external systems, APIs, sync jobs, and failure modes]
37
+
38
+ ## DevOps and Quality Gates
39
+ - [Summarize setup, deployment, validation, and operational constraints]
40
+ `
@@ -0,0 +1,141 @@
1
+ import path from 'node:path'
2
+
3
+ import {
4
+ AGENTS_WORKFLOW_END_MARKER,
5
+ AGENTS_WORKFLOW_HEADER,
6
+ AGENTS_WORKFLOW_MARKER,
7
+ AI_FILE_SPECS,
8
+ CLAUDE_REQUIRED_SNIPPETS,
9
+ agentsWorkflowSection,
10
+ claudeTemplate,
11
+ } from './agent-memory-templates.mjs'
12
+ import { readTextIfExists, writeTextFile } from './ai-memory-utils.mjs'
13
+
14
+ export {
15
+ AGENTS_WORKFLOW_END_MARKER,
16
+ AGENTS_WORKFLOW_HEADER,
17
+ AGENTS_WORKFLOW_MARKER,
18
+ AI_FILE_SPECS,
19
+ CLAUDE_REQUIRED_SNIPPETS,
20
+ }
21
+
22
+ async function ensureFile(filePath, content) {
23
+ const existingContent = await readTextIfExists(filePath)
24
+
25
+ if (existingContent !== null) {
26
+ return false
27
+ }
28
+
29
+ await writeTextFile(filePath, content)
30
+ return true
31
+ }
32
+
33
+ async function ensureAgentsWorkflow(filePath) {
34
+ const currentContent = await readTextIfExists(filePath)
35
+
36
+ if (currentContent === null) {
37
+ throw new Error(`Missing AGENTS.md at ${filePath}`)
38
+ }
39
+
40
+ if (currentContent.includes(AGENTS_WORKFLOW_MARKER)) {
41
+ if (!currentContent.includes(AGENTS_WORKFLOW_HEADER)) {
42
+ const upgradedContent = replaceMarkedSection(currentContent, agentsWorkflowSection)
43
+
44
+ if (upgradedContent !== currentContent) {
45
+ await writeTextFile(filePath, upgradedContent)
46
+ return true
47
+ }
48
+ }
49
+
50
+ return false
51
+ }
52
+
53
+ const nextContent = `${currentContent.trimEnd()}\n\n${agentsWorkflowSection}`
54
+ await writeTextFile(filePath, nextContent)
55
+ return true
56
+ }
57
+
58
+ function replaceMarkedSection(content, replacement) {
59
+ const startIndex = content.indexOf(AGENTS_WORKFLOW_MARKER)
60
+ const endIndex = content.indexOf(AGENTS_WORKFLOW_END_MARKER, startIndex)
61
+
62
+ if (startIndex === -1 || endIndex === -1) {
63
+ return content
64
+ }
65
+
66
+ const afterEndIndex = endIndex + AGENTS_WORKFLOW_END_MARKER.length
67
+
68
+ return `${content.slice(0, startIndex)}${replacement}${content.slice(afterEndIndex)}`
69
+ }
70
+
71
+ export async function ensureAgentMemory(rootDir) {
72
+ const createdFiles = []
73
+ const updatedFiles = []
74
+ const agentsPath = path.join(rootDir, 'AGENTS.md')
75
+ const claudePath = path.join(rootDir, 'CLAUDE.md')
76
+
77
+ if (await ensureAgentsWorkflow(agentsPath)) {
78
+ updatedFiles.push('AGENTS.md')
79
+ }
80
+
81
+ if (await ensureFile(claudePath, claudeTemplate)) {
82
+ createdFiles.push('CLAUDE.md')
83
+ }
84
+
85
+ for (const fileSpec of AI_FILE_SPECS) {
86
+ const absolutePath = path.join(rootDir, fileSpec.path)
87
+
88
+ if (await ensureFile(absolutePath, fileSpec.template)) {
89
+ createdFiles.push(fileSpec.path)
90
+ }
91
+ }
92
+
93
+ return {
94
+ createdFiles,
95
+ updatedFiles,
96
+ }
97
+ }
98
+
99
+ export async function validateAgentMemory(rootDir) {
100
+ const issues = []
101
+ const agentsPath = path.join(rootDir, 'AGENTS.md')
102
+ const claudePath = path.join(rootDir, 'CLAUDE.md')
103
+ const agentsContent = await readTextIfExists(agentsPath)
104
+ const claudeContent = await readTextIfExists(claudePath)
105
+
106
+ if (agentsContent === null) {
107
+ issues.push('Missing AGENTS.md')
108
+ } else if (!agentsContent.includes(AGENTS_WORKFLOW_MARKER)) {
109
+ issues.push(`AGENTS.md is missing the ${AGENTS_WORKFLOW_HEADER} section`)
110
+ } else if (!agentsContent.includes(AGENTS_WORKFLOW_HEADER)) {
111
+ issues.push(`AGENTS.md is missing the ${AGENTS_WORKFLOW_HEADER} section`)
112
+ }
113
+
114
+ if (claudeContent === null) {
115
+ issues.push('Missing CLAUDE.md')
116
+ } else {
117
+ for (const snippet of CLAUDE_REQUIRED_SNIPPETS) {
118
+ if (!claudeContent.includes(snippet)) {
119
+ issues.push(`CLAUDE.md is missing required content: ${snippet}`)
120
+ }
121
+ }
122
+ }
123
+
124
+ for (const fileSpec of AI_FILE_SPECS) {
125
+ const absolutePath = path.join(rootDir, fileSpec.path)
126
+ const content = await readTextIfExists(absolutePath)
127
+
128
+ if (content === null) {
129
+ issues.push(`Missing ${fileSpec.path}`)
130
+ continue
131
+ }
132
+
133
+ for (const snippet of fileSpec.requiredSnippets) {
134
+ if (!content.includes(snippet)) {
135
+ issues.push(`${fileSpec.path} is missing required content: ${snippet}`)
136
+ }
137
+ }
138
+ }
139
+
140
+ return issues
141
+ }
@@ -0,0 +1,350 @@
1
+ import { NEUTRAL_MEMORY_CONFIG } from './ace-project-presets.mjs'
2
+ import { productRoadmapTemplate, techDocsTemplate } from './ace-universal-doc-templates.mjs'
3
+
4
+ export const AGENTS_WORKFLOW_HEADER = '## ACE (Agentic Context Engine) Workflow'
5
+ export const AGENTS_WORKFLOW_MARKER = '<!-- agent-memory-workflow:start -->'
6
+ export const AGENTS_WORKFLOW_END_MARKER = '<!-- agent-memory-workflow:end -->'
7
+ export const CLAUDE_REQUIRED_SNIPPETS = ['AGENTS.md', '.ai/current-task.md']
8
+
9
+ export const memoryConfigTemplate = JSON.stringify(NEUTRAL_MEMORY_CONFIG, null, 2)
10
+
11
+ export const currentTaskTemplate = `# Current Task
12
+
13
+ ## Feature Name
14
+ [Set the active feature or task name]
15
+
16
+ ## Lifecycle
17
+ Status: active
18
+ Version: v1
19
+ Task Tier: standard
20
+ Design Review Required: no
21
+ Started: [YYYY-MM-DD HH:mm]
22
+ Ready For Archive: no
23
+
24
+ ## Goal
25
+ [Describe what is being built or changed]
26
+
27
+ ## Business Value / Product Alignment
28
+ [Explain in 1-2 sentences why this matters to users or the business]
29
+
30
+ ## Technical Approach
31
+ Option 1:
32
+ - [Describe one viable approach and tradeoffs]
33
+
34
+ Option 2:
35
+ - [Describe another viable approach and tradeoffs]
36
+
37
+ Chosen Approach:
38
+ - [Explain why the selected approach best fits security, flexibility, architecture, and business value]
39
+
40
+ ## Current Status
41
+ - [ ] Step 1
42
+ - [ ] Step 2
43
+ - [ ] Step 3
44
+
45
+ ## Affected Areas
46
+ - [List the apps, packages, or files in scope]
47
+
48
+ ## Constraints
49
+ - [List must-not-break rules or important boundaries]
50
+
51
+ ## Acceptance Criteria
52
+ - [Describe the expected final behavior]
53
+
54
+ ## Completion Checklist
55
+ - [ ] Goal completed
56
+ - [ ] Acceptance criteria met
57
+ - [ ] Tests/checks passed
58
+ - [ ] \`.ai/session-handoff.md\` updated
59
+ - [ ] \`.ai/changed-files.md\` updated
60
+ - [ ] \`.ai/work-log.md\` updated
61
+ - [ ] \`pnpm ace:validate\` passed
62
+ - [ ] \`.ai/reflection-log.md\` updated if the task exposed friction or repeated mistakes
63
+ - [ ] \`.ai/decisions.md\` updated if needed
64
+ - [ ] \`.ai/tech-docs.md\` updated if architecture or technical state changed
65
+ - [ ] \`.ai/product-roadmap.md\` updated if business or roadmap state changed
66
+ - [ ] Final snapshot archived to \`.ai/archive/tasks/\` for large tasks
67
+ - [ ] Next version/task defined if work continues
68
+ `
69
+
70
+ export const handoffTemplate = `# Session Handoff
71
+
72
+ ## Last Update
73
+ [YYYY-MM-DD HH:mm]
74
+
75
+ ## What Was Done
76
+ - [Summarize the latest completed work]
77
+
78
+ ## Current State
79
+ - [Describe the current project or feature state]
80
+
81
+ ## Quality Review
82
+ Product Alignment:
83
+ - [Confirm the work still serves the stated business value]
84
+
85
+ Architecture:
86
+ - [Note the pattern used and why it fits the repo]
87
+
88
+ Security:
89
+ - [Note relevant auth, RBAC, tenancy, token, or data exposure risks]
90
+
91
+ Code Quality:
92
+ - [Note file size, duplication, strict typing, and test coverage risks]
93
+
94
+ ## Next Steps
95
+ - [List the next concrete steps]
96
+
97
+ ## Known Issues
98
+ - [List known gaps, risks, or blockers]
99
+
100
+ ## Verification
101
+ - [List checks that passed or could not be run]
102
+
103
+ ## Notes
104
+ - [Add any extra context another agent will need]
105
+ `
106
+
107
+ export const decisionsTemplate = `# Decisions
108
+
109
+ ## [YYYY-MM-DD HH:mm]
110
+
111
+ Decision:
112
+ - [Document the durable decision]
113
+
114
+ Reason:
115
+ - [Explain why it was made]
116
+
117
+ Impact:
118
+ - [Explain what this changes]
119
+ `
120
+
121
+ export const changedFilesTemplate = `# Changed Files
122
+
123
+ [path/to/file]
124
+ - [Short reason for the change]
125
+ `
126
+
127
+ export const workLogTemplate = `# Work Log
128
+
129
+ ## [YYYY-MM-DD HH:mm]
130
+
131
+ - [Append short session summaries here]
132
+ `
133
+
134
+ export const reflectionLogTemplate = `# Reflection Log
135
+
136
+ Use this file for short, actionable agent-process reflections. Do not log every
137
+ minor task; record repeated tool friction, unclear prompts, poor assumptions,
138
+ or workflow improvements worth carrying into future sessions.
139
+
140
+ ## Unresolved
141
+
142
+ ### [YYYY-MM-DD HH:mm] [Short issue title]
143
+ Status: unresolved
144
+ - Stuck Point: [Where the agent got stuck]
145
+ - Likely Cause: [Tooling, prompt, missing context, or process issue]
146
+ - Proposed Improvement: [Concrete change to try next time]
147
+
148
+ ## Resolved
149
+ `
150
+
151
+ export const claudeTemplate = `# CLAUDE.md
152
+
153
+ ## Repository Rules
154
+
155
+ \`AGENTS.md\` is the authoritative source for repository constraints, stack
156
+ choices, architecture rules, and quality gates. Read it first in every session.
157
+
158
+ ## Startup Workflow
159
+
160
+ After reading \`AGENTS.md\`, read:
161
+
162
+ 1. \`.ai/report-brief.md\` if available for compact context.
163
+ 2. \`.ai/current-task.md\`
164
+ 3. \`.ai/session-handoff.md\`
165
+ 4. \`.ai/decisions.md\`
166
+ 5. \`.ai/changed-files.md\`
167
+ 6. Recent unresolved entries in \`.ai/reflection-log.md\`
168
+
169
+ Read \`.ai/work-log.md\` only when you need additional history for the current
170
+ task.
171
+
172
+ ## Working Rules
173
+
174
+ - Prefer minimal diffs over rewrites.
175
+ - Preserve existing TypeScript, UI, and API contracts unless the task says
176
+ otherwise.
177
+ - Use \`pnpm ace:classify\` to select the adaptive task tier.
178
+ - Run \`pnpm ace:onboard\` after fresh installation in an unfamiliar project
179
+ before trusting project-specific risk rules.
180
+ - For large or high-risk standard tasks, complete \`.ai/current-task.md\`
181
+ Business Value and Technical Approach before writing code.
182
+ - Treat \`.ai/*\` as the current source of task context and handoff state.
183
+ - Use \`YYYY-MM-DD HH:mm\` timestamps in \`.ai/session-handoff.md\`,
184
+ \`.ai/work-log.md\`, \`.ai/reflection-log.md\`, and \`.ai/decisions.md\`.
185
+
186
+ ## End-of-Task Routine
187
+
188
+ Run \`pnpm ace:validate\`, fix failures, then run \`pnpm ace:finish\` after
189
+ updating the relevant \`.ai/*\` files. The finish script validates the
190
+ required closeout depth for the detected task tier and generates the
191
+ appropriate reports.
192
+ `
193
+
194
+ export const agentsWorkflowSection = `<!-- agent-memory-workflow:start -->
195
+ ## ACE (Agentic Context Engine) Workflow
196
+
197
+ ACE is the local automation framework for managing AI context, code quality,
198
+ and decision history. Use this workflow on top of the repo rules above;
199
+ \`AGENTS.md\` remains the authoritative source for stack, architecture, and
200
+ quality constraints.
201
+
202
+ Before starting work:
203
+
204
+ 1. Read \`AGENTS.md\` first.
205
+ 2. If available, read \`.ai/report-brief.md\` first for a compact summary,
206
+ including recent unresolved reflections.
207
+ 3. Treat \`.ai/*\` as authoritative and read \`.ai/current-task.md\`,
208
+ \`.ai/session-handoff.md\`, \`.ai/decisions.md\`, and
209
+ \`.ai/changed-files.md\` when you need detail or verification.
210
+ 4. Run \`pnpm ace:classify\` before implementation to identify whether the
211
+ task is small, standard, or large.
212
+ 5. If this is a newly installed or unknown project and \`.ai/memory-config.json\`
213
+ is still marked \`unprofiled\`, run \`pnpm ace:onboard\` and apply an
214
+ approved profile before implementation.
215
+ 6. For large tasks, and standard tasks with high-risk signals, complete the
216
+ \`.ai/current-task.md\` Business Value and Technical Approach sections before
217
+ writing code. Compare at least two viable patterns and choose explicitly.
218
+ 7. Read \`.ai/work-log.md\` only when you need extra historical context.
219
+ 8. If the memory files are missing, run \`pnpm ace:init\`.
220
+
221
+ Legacy commands such as \`pnpm ai:task:classify\`, \`pnpm ai:task:finish\`,
222
+ and \`pnpm agent-memory:init\` remain supported for compatibility.
223
+
224
+ While working:
225
+
226
+ - Prefer minimal, safe diffs that preserve existing UI and API contracts.
227
+ - Do not rewrite large components or architecture unless the task requires it.
228
+ - Keep \`.ai/current-task.md\` aligned with the active task when scope changes.
229
+ - Keep project-specific tier and risk rules in \`.ai/memory-config.json\`, the
230
+ canonical ACE config, not inside the scripts, so the toolset remains
231
+ portable.
232
+ - Use \`pnpm ace:onboard\` to generate \`.ai/project-profile.md\` and
233
+ recommended project-specific risk rules when ACE is installed into an
234
+ unfamiliar repo.
235
+ - When updating \`.ai/session-handoff.md\`, \`.ai/work-log.md\`,
236
+ \`.ai/reflection-log.md\`, or \`.ai/decisions.md\`, use timestamps in
237
+ \`YYYY-MM-DD HH:mm\` format.
238
+ - Keep \`.ai/current-task.md\`, \`.ai/session-handoff.md\`,
239
+ \`.ai/reflection-log.md\`, and \`.ai/changed-files.md\` compact.
240
+ - Archive only \`.ai/work-log.md\`, \`.ai/reflection-log.md\`, and
241
+ \`.ai/decisions.md\` into \`.ai/archive/\` when they grow past the documented
242
+ thresholds.
243
+ - Use \`.ai/current-task.md\` lifecycle fields for task/version transitions.
244
+ When a large task version is complete, mark its completion checklist and let
245
+ \`pnpm ace:finish\` archive a final snapshot.
246
+
247
+ After completing a task:
248
+
249
+ 1. Update the authoritative \`.ai/*\` files directly or through
250
+ \`ai:update:*\` helpers.
251
+ 2. Run \`pnpm ace:validate\` and fix any mechanical quality gate failures.
252
+ 3. Run \`pnpm ace:finish\` to validate the adaptive closeout and generate
253
+ reports.
254
+ 4. Small tasks need compact handoff, changed-files, work-log, and brief report.
255
+ 5. Standard tasks also need product, architecture, security, and code-quality
256
+ review notes.
257
+ 6. Large tasks also need design review, reflection entry when useful, archive
258
+ snapshot, full report, and a review of \`.ai/tech-docs.md\` or
259
+ \`.ai/product-roadmap.md\` when technical or business state changed.
260
+ <!-- agent-memory-workflow:end -->
261
+ `
262
+
263
+ export const AI_FILE_SPECS = [
264
+ {
265
+ path: '.ai/memory-config.json',
266
+ requiredSnippets: [
267
+ '"_name": "ACE (Agentic Context Engine) Configuration"',
268
+ '"version": 1',
269
+ '"thresholds"',
270
+ '"highRiskPaths"',
271
+ ],
272
+ template: memoryConfigTemplate,
273
+ },
274
+ {
275
+ path: '.ai/current-task.md',
276
+ requiredSnippets: [
277
+ '# Current Task',
278
+ '## Lifecycle',
279
+ 'Task Tier:',
280
+ 'Design Review Required:',
281
+ '## Goal',
282
+ '## Business Value / Product Alignment',
283
+ '## Technical Approach',
284
+ '## Acceptance Criteria',
285
+ '## Completion Checklist',
286
+ ],
287
+ template: currentTaskTemplate,
288
+ },
289
+ {
290
+ path: '.ai/session-handoff.md',
291
+ requiredSnippets: [
292
+ '# Session Handoff',
293
+ '## What Was Done',
294
+ '## Quality Review',
295
+ '## Next Steps',
296
+ ],
297
+ template: handoffTemplate,
298
+ },
299
+ {
300
+ path: '.ai/decisions.md',
301
+ requiredSnippets: ['# Decisions', 'Decision:', 'Impact:'],
302
+ template: decisionsTemplate,
303
+ },
304
+ {
305
+ path: '.ai/product-roadmap.md',
306
+ requiredSnippets: [
307
+ '# Product Roadmap',
308
+ '## Business Goals',
309
+ '## Completed Epics',
310
+ '## Planned Features',
311
+ ],
312
+ template: productRoadmapTemplate,
313
+ },
314
+ {
315
+ path: '.ai/tech-docs.md',
316
+ requiredSnippets: [
317
+ '# Technical Docs',
318
+ '## Architecture',
319
+ '## Data Model / DB Schema',
320
+ '## Auth, RBAC, and Security',
321
+ '## External APIs and Integrations',
322
+ ],
323
+ template: techDocsTemplate,
324
+ },
325
+ {
326
+ path: '.ai/changed-files.md',
327
+ requiredSnippets: ['# Changed Files'],
328
+ template: changedFilesTemplate,
329
+ },
330
+ {
331
+ path: '.ai/work-log.md',
332
+ requiredSnippets: ['# Work Log'],
333
+ template: workLogTemplate,
334
+ },
335
+ {
336
+ path: '.ai/reflection-log.md',
337
+ requiredSnippets: ['# Reflection Log', '## Unresolved', '## Resolved'],
338
+ template: reflectionLogTemplate,
339
+ },
340
+ {
341
+ path: '.ai/archive/.gitkeep',
342
+ requiredSnippets: [],
343
+ template: '',
344
+ },
345
+ {
346
+ path: '.ai/archive/tasks/.gitkeep',
347
+ requiredSnippets: [],
348
+ template: '',
349
+ },
350
+ ]