# How Hallmark's Project Memory System Works Using `.hallmark/log.json`

> Discover how Hallmark's project memory system uses .hallmark/log.json to store design runs. Learn how it enforces diversification rules and prevents repeated macrostructures for unique project outputs.

- Repository: [Hassan El Mghari/hallmark](https://github.com/Nutlope/hallmark)
- Tags: internals
- Published: 2026-08-14

---

**Hallmark stores a chronologically-ordered array of design runs in [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json) to enforce diversification rules that prevent consecutive executions from reusing the same macrostructure, theme, navigation, or footer archetype.**

This lightweight JSON log lives inside a hidden `.hallmark` folder at your project root. It gives Hallmark persistent **project memory**—enabling intelligent, non-repetitive UI generation across multiple design sessions. The system is fully defined in [`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md) and operates through a simple read-modify-write cycle on every run.

## What [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json) Stores

The log file contains a JSON array where **newest entries appear first** (index 0). Each entry records the complete configuration of one Hallmark execution:

```json
{
  "date": "2026-04-30",
  "macrostructure": "Bento Grid",
  "theme": "Coral",
  "enrichment": "E1 clipped-edge",
  "brief": "Tracejam · SaaS observability"
}

```

Custom-theme runs extend this schema with additional fields like `theme_axes` and `vibe`, documented in [`skills/hallmark/references/custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/custom-theme.md) ([SKILL.md §2.5, lines 303-307](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md#L303)).

## When Hallmark Reads the Log

Before selecting any design elements, Hallmark detects and loads [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json) if it exists. This preload step is mandatory for the diversification system to function:

> "If the project has a [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json) file (created by previous Hallmark runs), **read it before** picking the macrostructure or theme." ([SKILL.md §2.5, lines 298-300](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md#L298))

The log absence simply means Hallmark treats the run as the first in sequence—no errors, no mandatory initialization.

## Diversification Rules Enforced via Project Memory

With the loaded history, Hallmark builds a **rotation block** from the last 3-5 entries and applies strict non-duplication constraints:

- **Macrostructure** — must differ from all entries in the last three runs
- **Theme** — must differ from the most recent entry on at least one of three axes (paper band, display style, accent hue)
- **Navigation and footer archetypes** — must differ from the immediately preceding run

> "Your macrostructure pick must not match any of the last three… Your theme pick must differ from the last on at least one axis…" ([SKILL.md §2.5, lines 308-311](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md#L308))

These rules ensure visual variety without requiring manual theme selection between runs.

## Writing and Maintaining the Log

After generating design output, Hallmark **prepends** a new entry to the array, guaranteeing the freshest record always occupies index 0:

> "After you write the stamp, update (or create) [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json) at the project root. **Append a new entry at the **front** of the array**…" ([SKILL.md §2.5, lines 460-466](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md#L460))

To prevent unbounded growth, Hallmark automatically **truncates to 20 entries**:

> "Trim the file to the last 20 entries (rotate the oldest off). Create `.hallmark/` and the file if they don't exist…" ([SKILL.md §2.5, lines 466-468](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md#L466))

The `.hallmark` directory is Git-ignored per `.gitignore` line 36, keeping project history local and version-control clean.

## Reading the Log: Node.js Implementation

```javascript
const fs = require('fs');
const path = './.hallmark/log.json';

let log = [];
if (fs.existsSync(path)) {
  const raw = fs.readFileSync(path, 'utf8');
  log = JSON.parse(raw);
}

// Extract newest 3 entries for diversification checks
const recent = log.slice(0, 3);
console.log('Recent macrostructures:', recent.map(e => e.macrostructure));
// → ['Bento Grid', 'Marquee Hero', 'Split-Screen'] 

```

## Appending Entries with Auto-Trim

```javascript
function addLogEntry(entry) {
  const logPath = './.hallmark/log.json';
  const dir = './.hallmark';
  
  // Ensure directory exists
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
  
  const log = fs.existsSync(logPath) 
    ? JSON.parse(fs.readFileSync(logPath, 'utf8')) 
    : [];

  // Prepend new entry
  log.unshift(entry);

  // Enforce 20-entry retention policy
  const trimmed = log.slice(0, 20);
  fs.writeFileSync(logPath, JSON.stringify(trimmed, null, 2));
}

// Example usage
addLogEntry({
  date: new Date().toISOString().split('T')[0],
  macrostructure: 'Marquee Hero',
  theme: 'Bloom',
  enrichment: 'E3 hand-built SVG',
  brief: 'Tally – SaaS analytics dashboard'
});

```

## Key Source Files

| Path | Purpose |
|------|---------|
| [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json) | Runtime project memory—array of design run records |
| [`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md) | Canonical specification of memory system and diversification logic |
| [`skills/hallmark/references/custom-theme.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/custom-theme.md) | Schema extensions for custom-theme log entries |
| `.gitignore` | Excludes `.hallmark/` from version control (line 36) |

## Summary

- **[`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json)** stores a reverse-chronological array of Hallmark design runs
- **Diversification rules** block repetition of macrostructures, themes, and nav/footer patterns from recent history
- **20-entry retention** keeps the log lightweight and performant
- **Git-ignored by default** so project memory stays local to each developer's environment
- **Prepend-on-write** architecture ensures consistent access patterns: newest entry always at index 0

## Frequently Asked Questions

### What happens if [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json) is deleted or corrupted?

Hallmark treats the next run as a fresh start with no memory constraints. The diversification rules only activate when valid JSON is detected and parsed. A new log file will be created automatically after the successful completion of that run.

### Can I manually edit [`.hallmark/log.json`](https://github.com/Nutlope/hallmark/blob/main/.hallmark/log.json) to force specific theme choices?

Yes—the file is plain JSON with no checksums or validation beyond schema conformity. Removing entries from the rotation block (first 3-5 items) effectively clears those constraints. Adding fake historical entries can also steer Hallmark toward permitted options.

### Why does Hallmark prepend rather than append new entries?

Prepending places the newest record at array index 0, enabling consistent access patterns: `log[0]` is always the immediate predecessor, and `log.slice(0, 3)` reliably yields the rotation block for diversification checks. Appending would require calculating `log.length - 1` offsets throughout the codebase.

### How does the 20-entry limit affect long-running projects?

Twenty entries preserve roughly 2-3 weeks of active iteration at typical usage rates. Older designs rotate out of consideration entirely, allowing macrostructures and themes to eventually recur—useful for seasonal refreshes or A/B revisits. The limit is hardcoded in [`SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/SKILL.md) §2.5 with no current configuration override.