Skip to content
mdlake

Refresh content

Move a snapshot site to newer lake content as a reviewed change. Covers the content report, the candidate preview, the route snapshot comparison and how to approve or reject.

On this page

A snapshot site does not change when editors publish. It changes when you move lake.lock to a newer lake commit. The refresh-content skill does that as a reviewable change. It shows what changed for this site, checks the new content, lets you look at it, and moves the lock only after you approve.

Use it when editors have published something the site should pick up. A live site does not need it, because it follows the newest commit by itself.

What you do

  1. Run the skill in the site folder.
  2. Read the content report, the snapshot comparison and the check results.
  3. Look at the site with the new content in your own terminal.
  4. Approve or reject.

Prerequisites

  • A site with a lake.lock in snapshot mode.
  • If you use a LAKE_PATH clone, it must be clean and at the locked commit. The skill never edits the lake.
  • git and sign-in to the lake’s mirror. In CI, MDLAKE_LAKE_TOKEN.
  • A committed site-snapshot.json. Without it, the comparison has nothing to compare with. Create it with npx mdlake snapshot --build at the locked commit.

Step 1: start the skill

/mdlake-builder:refresh-content

The skill reads lake.lock. lake.commit is the current pin. In live mode it says the skill is not needed and stops.

It then finds the newest lake commit, called the candidate.

  • A managed lake (no LAKE_PATH, and the lock has a remote): lake-status.mjs --candidate <site> puts .mdlake/lake at the locked commit, fetches the remote’s newest commit next to it, and prints locked, candidate and newer. It checks nothing out.
  • A LAKE_PATH clone: the skill makes sure the clone is clean and at the locked commit, fetches, and fast-forwards with git pull --ff-only. The candidate is its HEAD.

When the candidate equals the lock, the skill says “no new content” and stops. Errors such as a missing git, a refused sign-in or a commit that is not on the remote are printed as complete messages.

Step 2: read the content report

lake-diff.mjs <site> <locked> <candidate> compares the lake at the two commits, for this site only. It reads both with the site’s own loader, so the rules are the ones the build uses. The result is also written to .mdlake/lake-diff.json.

SectionWhat it lists
Bound documentsEdited, unpublished or deleted, and which fields changed (title, summary, body, tags, image).
CollectionsItems added, removed or edited.
AssetsChanged assets that the site uses.
Generated contentEach file in src/content/generated as fresh, stale (with the sources that changed, were unpublished or deleted, and its brief) or hand-edited.

For every changed, unpublished or deleted key, the skill also names the site-owned files that read it through getLakeDocument or getLakeCollection. It is one line each, for example: “src/pages/pricing.astro reads pricing, which was removed”.

The skill then reads the brief in plan.md and says where the new content meets it.

  • A new folder or document outside the scope is not used by the site. It is reported and not bound.
  • A deleted or unpublished document that the primary call to action or a must-have page depends on is a conflict: “this change drops the primary CTA from home”.
  • A live site must stay free of generated copy.

You decide what to do with each conflict. When an answer changes the brief, the brief is updated in the same change.

Step 3: check the candidate

The skill checks the new content without moving the lock.

PowerShell
$env:LAKE_LOCK_CANDIDATE = "<candidate commit>"
npm run check

LAKE_LOCK_CANDIDATE tells the lock check to expect another commit. mdlake prepare then checks the managed clone out at the candidate. Its commit is already in the cache, so it needs no network. Remove the variable afterwards:

PowerShell
Remove-Item Env:LAKE_LOCK_CANDIDATE

npm run check fails when a site-owned file reads a key whose document is missing at the candidate. That is the loud failure, and it names the key, the document ID and the files. The skill proposes a fix in the site-owned file and never hides the problem. Typical fixes are to bind another document, drop the page or section that used it, or adjust a collection query. A fix is applied only after you agree, and fixes to lake.config.ts or pages are part of the same change.

Compare the routes

Next the skill builds the candidate and compares it with the committed site-snapshot.json.

PowerShell
npx mdlake snapshot --compare

It builds into .mdlake/candidate-dist, writes the candidate’s snapshot to .mdlake/candidate-snapshot.json and prints a plain-language report. The report is shown as is.

Routes: 14 in the committed snapshot, 15 in the candidate.
Routes removed (1): /services/route-planning/
Routes added (2): /services/fleet-reports/, /services/driver-app/
/about/ lost 1 heading: "Our history"
Link to /services/route-planning/ now leads nowhere, on 2 pages: /services/, /
/cases/vindkant/ no longer shows 1 asset: 01JBXQCR6X1Y7Z3A5C0D4E9F8K
/contact/ has a new title: "Contact" -> "Contact us"
Text changed on 3 pages: /about/ (-42 words), /services/ (+0 words), /cases/vindkant/ (+18 words)
FindingMeaning
Routes removed or addedA page appeared or disappeared.
Headings lost or gainedA heading in the main content changed. Lost headings matter most.
Links that now lead nowhereA link in the new site has no route, redirect or file.
Assets goneA page no longer shows an image.
New titles and text changesInformation only.

With --strict, the command exits 1 when the candidate lost a route, a section, a link target or an asset. The snapshot stores, per route, the title, the heading outline, a hash of the visible text, internal links, broken links and asset IDs. Everything in it is deterministic, so the same site gives the same file.

If there is no committed snapshot, the command says so and tells you to take one at the locked commit first.

Generated copy

For every stale generated file, the skill offers to regenerate it with the same brief through generate-copy. The new copy is part of the same reviewable change. A hand-edited file is regenerated or reverted, never kept.

Step 4: look at it

The skill stops here. It shows the content report, the snapshot comparison, the check results and any proposed fixes. It asks you to review the site in npm run dev, in your own terminal.

For a managed lake, the skill first runs lake-status.mjs --preview <site> <candidate>. That checks the candidate out and remembers it. npm run dev runs mdlake prepare --dev, which keeps it. For a LAKE_PATH clone the candidate is checked out already.

Every page then shows a banner:

Previewing lake 1a2b3c4 (locked: 9f2c1d7) — not deployable

Reload the page after the clone moves. You do not need to restart the dev server.

npm run build and npm run check:bindings stay strict. They put a managed clone back at the lock, so run them before the preview or set LAKE_LOCK_CANDIDATE.

The skill does not go on without an explicit answer.

Step 5a: approve

When you approve:

  1. write-lake-lock.mjs <site> --commit <candidate> updates commit and lockedAt. The remote is kept, and the preview marker is cleared. It also moves .mdlake/candidate-snapshot.json into site-snapshot.json, so the lock and the snapshot always describe the same commit.
  2. The skill runs npm run check once more, without the override.
  3. It suggests a commit message that lists the content changes, and offers to commit.
Refresh content to 1a2b3c4: about edited, 2 services added, privacy unpublished

commit-site.mjs <site> --paths lake.lock,site-snapshot.json,<fixed files> --message "<message>" commits the lock move and the fixes together. The message names the old and the new lake commit.

Step 5b: reject

When you reject, the skill undoes the preview:

  • Managed lake: lake-status.mjs --discard-preview <site> forgets the preview and checks the locked commit out again.
  • LAKE_PATH: git -C "$LAKE_PATH" checkout <locked commit>.

lake.lock and site-snapshot.json stay untouched. The skill deletes .mdlake/candidate-snapshot.json and says what it undid.

If the lake moved under you

A LAKE_PATH clone that has moved makes npm run build stop with “The lake … is at X, but lake.lock locks Y”. Either build the pinned content again with git -C "<lake>" checkout <commit>, or take the new content on purpose with this skill.

The files involved

FileRoleEdited by
lake.lockThe pin.write-lake-lock.mjs, after approval.
site-snapshot.jsonThe committed route snapshot.npx mdlake snapshot, and write-lake-lock.mjs on approval.
.mdlake/lake-diff.jsonThe last content report. Ignored by Git.lake-diff.mjs
.mdlake/candidate-dist/, .mdlake/candidate-snapshot.jsonThe candidate build and its snapshot. Ignored by Git.npx mdlake snapshot --compare
.mdlake/lake-previewRemembers the candidate for the dev server. Ignored by Git.lake-status.mjs --preview

Site-owned files are never edited by the skill without your agreement. It reports what the change does to them.

What can go wrong

SymptomCause and fix
“No committed site-snapshot.json”Build the site at the locked commit and run npx mdlake snapshot. Commit the file.
npm run check fails and names a key and filesA bound document was unpublished or deleted. Rebind it, or remove what used it. See Safe content refresh.
The commit is not found on the remoteThe CMS has not mirrored it yet, or history was rewritten. Check Lake repository in the workspace settings. See Connect GitHub.
The banner does not appearReload the page. If it still does not, the clone was put back at the lock by a build or a check. Run the preview step again.
The skill says the lake clone is not cleanA LAKE_PATH clone has local changes. Commit or discard them, because the skill never edits the lake.

What’s next