Remastery — for large XML collections

Under the hood

Undo, a second way to use an LLM, and what the documents need underneath.

So far so good. We have seen the system in action, and it shows that the basic, happy path is working as intended. But there is more:

  1. undo changes (revoke);
  2. work with the interactive CLI mode;
  3. specialise and reapply issues;
  4. working at scale with jobs

1. Undo changes

It is almost unavoidable that errors will creep in when working with a large document collection. A worst case scenario is where a transform has updated a large number of documents and we need to manually go through each one of them to figure out what has happened. A much better outcome would be to undo all the changes up to that point, and reapply transforms going forward from there. This only works if there is a proper foundation. It also needs to be embedded in the right decision framework; just like a regular transform is formally approved before running, an undo action needs the same care and guardrails.

A revoke issue is a kind of issue that is specifically focused on "undoing" the application of an issue. In other words, it goes back to the input state when the issue was applied. The result state is never deleted, but any further work will start with the input state again.

A revoke issue has the option to replay other issues after reverting to the input state of the revoked issue. This is meant for situations where the other issues were applied after the revoked issue. An optional replay plan will apply a sequence of (other) issues to the input state of the revoked issue.

The screencast demonstrates an undone issue in a real-world collection. In this case, 15,701 changed documents are reverted. Afterwards, each document's log has one more event, a revert, and the states before it are still listed beside it. Nothing is deleted.

Undo an issue across 15,701 documents, from the interactive mode. About four minutes.

2. Work with the interactive CLI

The command line interface (CLI) is the primary way to work with the system. It is powerful, but that power comes at a cost: it can be quite intimidating for new users. LLMs are good with natural language, and with the right context, they can turn a sentence into a real command. The interactive mode does exactly that. You say what you want in your own words, and a model proposes a command, shown in full.

A proposed command runs only when you press enter. A proposal is the model's guess at what you meant, and your confirmation is the check between that guess and your documents.

Alternatively, if you know what you're doing and you are not afraid, you can sidestep the safety catch: put ! in front of a line, and it runs directly in your shell, with no questions asked (that includes rm -rf!).

To make good proposals, the model has to know the commands. Every LLM request carries a compact reference: one line for each command, plus the full details of the commands your sentence seems to be about. That reference is generated from the tool itself, not written by a model, so it describes the commands as they really are. How well this works still depends on the model. In general, anything under 14 billion parameters is too limited for this purpose.

The interactive mode does not share your documents with the model. When a command shows document text, you see it on your screen, but it is kept out of what is sent to the model. The session says so at the top: send documents: no. Text that you paste into a sentence yourself does go to the model, and the mode tells you so.

This topic shares its screencast with Undo changes, above. There, the undo is driven from the interactive mode. The operator types wb revoke iss-0009, a command that does not exist. The model replies that there is no such command, explains that undoing an issue means opening a revoke issue, and proposes the command that does that. One press of enter runs it.

3. Specialise and reapply

Sometimes a transform does the right thing for most documents, but later we find that a subset should have been treated differently. Say a transform that recodes lists works well across the collection, but in one group of documents the same pattern means something else. A new issue could handle that subset, but that brings two problems. The subset has already been transformed, and a new issue may no longer recognise it, because its match rule was written for the original markup. And the knowledge ends up split over two issues, when it really belongs to one.

A specialisation solves this inside the existing issue. It adds a narrower match rule with its own transform. When the issue runs, each document is checked against the specialisation first. If it matches, the specialisation's transform runs; if not, the issue's default transform does. The issue's overall match rule stays the same.

If the issue has already been applied, this is where undo comes in. The documents in the subset have to go back to the state they had before the issue, so the specialisation can treat them instead. That is a revoke issue with a plan that runs the issue again, and like every other change, it must be approved before it runs. Later issues that touched the same documents can be replayed in the same plan. The plan can safely cover the whole collection, not just the subset: outside the subset, the default transform produces exactly the same document again. Because every state is identified by its content, the system sees that nothing changed and records nothing. Nobody has to work out the subset by hand, which makes the operation simpler and safer.

4. Working at scale with jobs

Applying an issue across a large collection takes real time. The apply in the walkthrough went through more than 50,000 documents. Depending on the hardware, a job that size can easily keep the command line busy for minutes or longer. So an apply can run in the background instead. You get the prompt back immediately, the job keeps running after you leave the interactive mode, and you can follow its progress at any time. A job can also be set up now and started later, from another terminal or from a scheduler such as cron.

A job is also a record. When it starts, it fixes the list of documents it will look at, and that list can only get smaller, never larger. For each document, it records what happened: changed, skipped or failed. A failure does not stop the job. It is written down, and the next apply tries that document again.

A job can be cancelled, or a crash can interrupt it. Either way, what already finished is not rolled back. That is safe because every document changes on its own, with its own log: a document is either changed or not, never half-changed. So a half-applied issue is a perfectly valid state of the collection, and resuming the job simply picks up the rest. That behaviour is not a compromise, it is the point: the system is built so that stopping in the middle is never a disaster.

Do you hold a large XML collection, and have good reasons to put AI to work on it, but no safe way to begin? Here is how we would work together. It starts with an hour online, no charge: we look at your own documents, and you see the system running on them.