Use a scratch hash file to test Docly functions

Best practice By design
A new .hash file is live the moment you save it and can print anything the server computes, so a throwaway scratch page is the cheapest way to answer a question about the platform instead of guessing. This matters most for AI agents: Docly template syntax resembles several things it is not, so an agent writes plausible code that does not throw and is silently wrong - a field renders empty, a sort returns lexical order, a head element is dropped. Printing the value converts that silent failure into something you can look at. Use a standalone .hash with setMime text/plain, print typeof then Object.keys then only the fields you need (never dump objects that may hold secrets - it is a public URL), read it with curl, and delete it in the same session.

What you'll see

You are about to use a Docly function — getFiles(), docly.sort(), a #{ }# expression, an xdt:Transform merge, an API endpoint — and you are not certain what it returns, whether it accepts the argument you are about to pass, or whether the syntax you have in mind is even supported. The documentation covers the common case; your case is slightly off it. The tempting move is to edit the real page and reload it. Do not. Write a throwaway .hash file that prints the answer, read it, delete it.

What's actually happening

Docly has a property that is easy to under-use: a new .hash file is live the moment you save it, and it can print anything the server can compute. No build, no deploy, no restart. That makes a scratch file the cheapest possible way to answer a question about the platform — and answering it beats guessing, because guessing about a template language ends with you changing a real page to find out.

The economics are lopsided. A scratch file costs about thirty seconds to write and one HTTP request to read. Being wrong about getFiles()'s return shape on a live service page costs a broken page, in public, that you then debug under pressure. There is no reason to take the second bet.

Why this matters more for AI agents than for people

A human developer carries a mental model of the platform and notices when something feels off. An agent does not — it pattern-matches from documentation and from other codebases, and Docly's template language resembles several things it is not. The failure mode is specific and predictable: the agent writes plausible code, it does not throw, and the output is silently wrong. A field is undefined and renders as empty. A sort returns lexical order because the values are strings. A head element is dropped because it lacked xdt:Transform="Insert". Nothing errors. The page just quietly says the wrong thing.

A scratch file converts that silent failure into a printed value you can look at. For an agent, "print it and read it" should be the default reflex before writing anything non-trivial into a real file — not a fallback for when something breaks.

Two kinds of scratch file

  • A .hash page — for anything server-side: what a function returns, what a document's fields actually contain, whether an expression parses, how a template merges. Print with #JSON.stringify(x)# and read it in the browser or with curl.
  • An API .js endpoint — when you want machine-readable JSON to consume from a script, or you are testing the API surface itself (query/form field reading, response headers, status codes). Set the mime type and return real JSON.

Both are throwaway. Both are deleted when the question is answered. Neither is ever left in the tree "in case it is useful later" — that is how a site accumulates files nobody dares remove.

The one real risk: it is still live

A scratch file is a page on a public site the instant it exists. That is the whole point, and it is also the danger:

  • Anyone with the URL can load it, and so can a crawler that finds it. Always give it noindex,nofollow.
  • Never print secrets. API keys, connection strings, tokens, personal data from documents — if you dump a whole object to see its shape, you may be publishing whatever is inside it. Print field names first (Object.keys), then only the specific values you need.
  • Use an obscure filename, not /test. Under the # folder is better still if the thing you are testing does not need a public URL — see Keep private data under the # folder.
  • Delete it in the same session. A forgotten scratch file is an unmaintained public endpoint with unknown output. Deleting it is part of the task, not cleanup for later.

What to do

The scratch page

Create /_scratch-something.hash at the site root. Standalone — no #master directive, so there is no template merge between you and the output, and nothing to misattribute a wrong result to:

#{
  docly.setMime("text/plain");

  let filer = getfiles("/Tjenester");

  write("antall: " + filer.length + "\n\n");
  write("felter paa forste element:\n");
  write(JSON.stringify(Object.keys(filer[0]), null, 2) + "\n\n");
  write("forste element:\n");
  write(JSON.stringify(filer[0], null, 2));
}#

setMime("text/plain") is the important bit: you get raw output with no HTML escaping, no theme CSS, and no master template. What you see is what the server computed.

Read it with curl rather than a browser — no cache, no rendering, and the output lands straight in your terminal or agent context:

curl -s "https://example.com/_scratch-tjenester"

The scratch API endpoint

When you want JSON to consume from a script, or you are testing the API surface itself:

#{
  docly.setMime("application/json");

  let resultat = {
    query: request.query.id,
    finnes: fileExists("/Tjenester/Webdesign.docly"),
    antall: getfiles("/Tjenester").filter(x => x.Hovedmeny).length
  };

  write(JSON.stringify(resultat, null, 2));
}#
curl -s "https://example.com/api/_scratch?id=42" | jq

What to print, in what order

Do not dump the whole object first. Work inwards:

  1. typeof x — is it even what you think? Many surprises end here.
  2. Object.keys(x) — the field names. Safe to print; reveals shape without revealing contents.
  3. The specific fields you need — and only those. This is also the step that keeps secrets off a public page.
  4. JSON.stringify(x, null, 2) — only when you have established there is nothing sensitive inside.

For arrays, print length and one element. A hundred elements tell you nothing that one does not, and they bury the answer.

Questions worth a scratch file

  • What does this function actually return? Shape, types, whether it is an array or an object, what a document's fields are really called (Hovedmeny? hovedmeny? does it exist on every file?).
  • Does this expression parse? Docly's template language is JavaScript-like. Before assuming Math.ceil(), arrow functions, Object.entries or optional chaining work, print the result of one. Five seconds of certainty instead of a broken menu.
  • What is the real data? Which Order values are taken, which files have a flag set, how many items a filter actually returns. Read the truth instead of inferring it from a handful of files.
  • Sorting and comparison. String vs numeric sorting is a classic silent wrong answer. Print the sorted list and look at it.
  • Request context. What is in request.query, request.filepath, request.siteUrl on the actual server — not what you assume.

What a scratch file cannot tell you

It answers server-side questions. It does not tell you whether the page looks right, whether an image loaded, whether the JavaScript ran, or whether a static asset is being served from cache. For those, verify in a real browser with the Claude Chrome plugin — and with a cold cache. See Work safely on a live site.

One specific trap it does catch, though: if you are unsure whether a head element survived a master merge, a scratch file cannot help — but curl on the real page can. Fetch it and grep the raw HTML for your element. A missing xdt:Transform="Insert" is silent in the browser and obvious in curl.

Checklist

  1. Standalone .hash, no master directive, obscure filename prefixed _scratch-.
  2. docly.setMime("text/plain") (or application/json for an API endpoint).
  3. noindex,nofollow if it emits HTML at all.
  4. Print typeofObject.keys → specific fields. Never dump objects that may hold secrets or personal data.
  5. Read it with curl, not a browser.
  6. Delete it before you finish. Same session, no exceptions.

See also Work safely on a live site, Creating new docly files, Keep private data under the # folder, Reading query and form fields in API calls, and Hash files are cached.