| @@ -291,7 +291,7 @@ test('escapeMd neutralizes HTML-sensitive characters', () => { | ||
| test('rendering escapes injection in project name and content', async () => { | ||
| const { tree } = await fixtureTree(); | ||
| const md = renderMarkdown(tree, { projectName: 'x</summary></details><script>alert(1)</script>' }); | ||
| - | assert.ok(md.includes('# ๐ณ Prompt Tree: x</summary></details><script>'), 'project name not escaped'); | |
| + | assert.ok(md.includes('# Prompt Tree: x</summary></details><script>'), 'project name not escaped'); | |
| assert.ok(!md.includes('Prompt Tree: x</summary>'), 'raw HTML in project name'); | ||
| }); | ||
| @@ -299,10 +299,10 @@ test('renderers: markdown, json, handoff are consistent and footer-credited', as | ||
| const { tree } = await fixtureTree(); | ||
| analyzeTree(tree); | ||
| const md = renderMarkdown(tree, { projectName: 'demo' }); | ||
| - | assert.ok(md.startsWith('# ๐ณ Prompt Tree: demo')); | |
| + | assert.ok(md.startsWith('# Prompt Tree: demo')); | |
| assert.ok(md.includes('## Goal')); | ||
| assert.ok(md.includes('## Reusable Prompt Pack')); | ||
| - | assert.ok(md.includes('generated by [treetrace]') || md.includes('Generated by [treetrace]')); | |
| + | assert.ok(md.includes('[treetrace]')); | |
| const json = renderJson(tree, { projectName: 'demo' }); | ||
| assert.equal(json.schemaVersion, '0.2'); | ||
| @@ -318,13 +318,13 @@ test('renderers: markdown, json, handoff are consistent and footer-credited', as | ||
| const handoff = renderHandoff(tree, { projectName: 'demo' }); | ||
| assert.ok(handoff.includes('## Original goal')); | ||
| - | assert.ok(handoff.includes('Constraints learned the hard way')); | |
| - | assert.ok(handoff.includes('Agent memory lessons')); | |
| + | assert.ok(handoff.includes('## Constraints')); | |
| + | assert.ok(handoff.includes('## Lessons')); | |
| const report = renderReportMarkdown(tree, { projectName: 'demo', generatedAt: '2026-01-01T00:00:00.000Z' }); | ||
| assert.ok(report.startsWith('# TreeTrace Report - demo')); | ||
| assert.ok(report.includes('## Output map')); | ||
| - | assert.ok(report.includes('## Handoff brief')); | |
| + | assert.ok(report.includes('## Artifacts')); | |
| assert.ok(report.includes('TREETRACE_REPORT.md')); | ||
| }); | ||
| @@ -344,16 +344,16 @@ test('analysis renderers produce failures, lessons, evals, and memory', async () | ||
| assert.ok(failures.correctionChains.length >= 1); | ||
| const lessons = renderLessonsMarkdown(tree, { projectName: 'demo' }); | ||
| - | assert.ok(lessons.includes('# TreeTrace Lessons')); | |
| - | assert.ok(lessons.includes('Source nodes:')); | |
| + | assert.ok(lessons.includes('# Lessons')); | |
| + | assert.ok(/\[node_\w+/.test(lessons), 'lessons should inline node ids in brackets'); | |
| const evals = renderEvalsJsonl(tree).trim().split('\n').map((line) => JSON.parse(line)); | ||
| assert.ok(evals.length >= 1); | ||
| assert.ok(evals.every((e) => e.source === 'treetrace' && e.sourceNodeIds.length >= 1)); | ||
| const memory = renderMemoryMarkdown(tree, { projectName: 'demo' }); | ||
| - | assert.ok(memory.includes('TreeTrace Agent Memory')); | |
| - | assert.ok(memory.includes('Constraints the user enforced')); | |
| + | assert.ok(!memory.includes('TreeTrace Agent Memory'), 'H1 title removed in diet'); | |
| + | assert.ok(memory.includes('## Constraints'), 'compact constraints header'); | |
| assert.ok(!memory.includes('Keep TreeTrace local-first')); | ||
| }); | ||
| @@ -468,7 +468,7 @@ test('analysis: a PAT-update prompt produces an inferred security signal even wi | ||
| assert.ok(sec, 'expected an inferred security signal from the PAT-update prompt'); | ||
| assert.equal(sec.tier, 'inferred'); | ||
| const memory = renderMemoryMarkdown({ nodes: [root, intent] }); | ||
| - | assert.ok(memory.includes('## Security-sensitive actions'), 'memory should list the security section'); | |
| + | assert.ok(memory.includes('## Security'), 'memory should list the security section'); | |
| assert.ok(/stated intent/.test(memory), 'memory should tag the stated intent'); | ||
| }); | ||
| @@ -492,7 +492,7 @@ test('analysis: the constraints section extracts directive requirements and neve | ||
| title: 'no em dashes', kind: 'direction', status: 'accepted', parent: root, actions: [], | ||
| }; | ||
| const memory = renderMemoryMarkdown({ nodes: [root, rule] }); | ||
| - | const block = memory.slice(memory.indexOf('## Constraints the user enforced'), memory.indexOf('## Lessons')); | |
| + | const block = memory.slice(memory.indexOf('## Constraints'), memory.indexOf('## Lessons')); | |
| assert.ok(/no em dashes/i.test(block), 'em-dash constraint should be listed'); | ||
| assert.ok(/inline code comments/i.test(block), 'inline-comment constraint should be listed'); | ||
| assert.ok(/apache/i.test(block), 'license constraint should be listed'); | ||
| @@ -506,8 +506,8 @@ test('analysis: a benign descriptive prompt with no directive yields no false co | ||
| title: 'looks good', kind: 'direction', status: 'accepted', parent: root, actions: [], | ||
| }; | ||
| const memory = renderMemoryMarkdown({ nodes: [root, benign] }); | ||
| - | const block = memory.slice(memory.indexOf('## Constraints the user enforced'), memory.indexOf('## Lessons')); | |
| - | assert.ok(/No explicit constraints were flagged/.test(block), 'benign descriptive text should not mint constraints'); | |
| + | // Diet spec: omit-if-empty; empty constraints section should not appear at all | |
| + | assert.ok(!memory.includes('## Constraints'), 'benign descriptive text should not mint constraints'); | |
| }); | ||
| test('analysis: a destructive-then-recovery turn yields a known bad path and is not the preferred next work', () => { | ||
| @@ -527,10 +527,10 @@ test('analysis: a destructive-then-recovery turn yields a known bad path and is | ||
| const bad = analysis.failures.filter((f) => f.type === 'abandoned_path'); | ||
| assert.ok(bad.length >= 1, 'destructive-then-recovery should produce a bad-path entry'); | ||
| const memory = renderMemoryMarkdown({ nodes }); | ||
| - | const badBlock = memory.slice(memory.indexOf('## Known bad paths'), memory.indexOf('## Security-sensitive')); | |
| + | const badBlock = memory.slice(memory.indexOf('## Bad paths'), memory.indexOf('## Security')); | |
| assert.ok(!/No abandoned paths were detected/.test(badBlock), 'must not claim no abandoned paths when a destructive event occurred'); | ||
| assert.ok(/recover|destructive/i.test(badBlock), 'bad-path entry should warn about the destructive event'); | ||
| - | const nextBlock = memory.slice(memory.indexOf('## Preferred next work')); | |
| + | const nextBlock = memory.slice(memory.indexOf('## Next')); | |
| assert.ok(!/messed up the deck/i.test(nextBlock), 'preferred next work must not parrot the apology turn'); | ||
| assert.ok(/develop these sections/i.test(nextBlock), 'preferred next work should point at the real forward direction'); | ||
| }); | ||
| @@ -595,7 +595,7 @@ test('analysis: latest accepted direction is chronological, not insertion order' | ||
| assert.ok(/Amazon Nova/i.test(stand), 'handoff should name the chronologically newest accepted direction'); | ||
| const memory = renderMemoryMarkdown(tree, { projectName: 'demo' }); | ||
| - | const next = memory.slice(memory.indexOf('## Preferred next work')); | |
| + | const next = memory.slice(memory.indexOf('## Next')); | |
| assert.ok(/Amazon Nova/i.test(next), 'agent memory should point at the chronologically newest direction'); | ||
| }); | ||
| @@ -956,7 +956,7 @@ test('security report: surfaces real signals and omits benign sessions', () => { | ||
| const benignTree = { nodes: [benign] }; | ||
| assert.ok(!hasSecuritySignal(benignTree, dir), 'benign session should have no security signal'); | ||
| const benignReport = renderSecurityReport(benignTree, dir, { projectName: 'demo', generatedAt: '2026-01-01T00:00:00.000Z' }); | ||
| - | assert.ok(/No security-sensitive touches/.test(benignReport), 'benign report should state nothing was found'); | |
| + | assert.ok(/None detected\./.test(benignReport), 'benign report should state nothing was found'); | |
| } finally { | ||
| rmSync(dir, { recursive: true, force: true }); | ||
| } | ||
| @@ -1033,7 +1033,7 @@ test('mcp: initialize, tools/list, and tools/call return well-formed JSON-RPC', | ||
| const call = responses.find((r) => r.id === 3); | ||
| assert.ok(call.result && Array.isArray(call.result.content), 'tools/call must return content array'); | ||
| assert.equal(call.result.content[0].type, 'text'); | ||
| - | assert.ok(/TreeTrace Lessons/.test(call.result.content[0].text), 'lessons tool should return the lessons markdown'); | |
| + | assert.ok(/# Lessons/.test(call.result.content[0].text), 'lessons tool should return the lessons markdown'); | |
| const bad = responses.find((r) => r.id === 99); | ||
| assert.ok(bad.error && bad.error.code === -32602, 'unknown tool should return a JSON-RPC error'); |