You have one long master prompt you paste in every week. Some weeks the document comes out right, some weeks the sections are reordered or renamed, and some weeks the assistant says it created the file and nothing appears.
A chat prompt has no memory of last week, no way to run itself on a schedule, and in most consumer apps no permission to write into a folder you choose. Those are not wording problems, so no amount of rewriting reaches them. The run that claims success and does nothing is the worst case, and it is usually caused by an instruction telling the assistant not to refuse.
Everything in a weekly report is either exact or editorial, and the two need different machinery.
Exact: naming the file, putting it in the right folder, archiving last week's, numbering the week, appending a row to an index, sending it on. Code does all of that and never does it differently twice.
Editorial: the summary paragraph, and judgement calls like which items to highlight or what tone fits this particular owner. That is the only part that needs a model.
Nearly every 'inconsistent output' complaint is an exact job that was handed to a model.
If the files live in a personal Google account, Google Apps Script is the cheapest runtime that can actually do the work. It executes inside your own account, so Drive, Docs and Gmail access needs no OAuth setup and nothing to host. It has time-based triggers, so the weekly run fires on its own. It can keep the week number and any rotation state in a Sheet. It is free.
Skeleton. The model is called once, for prose only.
function weeklyRun() {
const state = readState(); // week number, what ran last time
const facts = gatherFacts(state); // from your sheet / API, not the model
const prose = callModel(buildPrompt(facts)); // the ONLY model call
archivePrevious(state.lastDocId); // rename + move: deterministic
const doc = createInFolder(FOLDER_ID, titleFor(state.week));
writeSections(doc, facts, prose);
appendIndexRow(INDEX_SHEET_ID, state.week, doc.getId());
verifyOrThrow(doc.getId(), titleFor(state.week)); // read it back
notify(doc.getUrl());
writeState({ week: state.week + 1, lastDocId: doc.getId() });
}After writing, open the document again and confirm the title and first heading are what you expect. If they are not, fail loudly instead of continuing.
This one step converts a silent failure into one you find out about in seconds, and it is the highest-value thing in this whole page.
If you have built up a detailed format over months, none of that is wasted. The named sections carry over, and so do the exact quantities and the specific rules. It stops being a prompt and becomes the spec your code builds against, which is a far more reliable place for it. The model is then asked only to fill in prose inside a structure it cannot reorder.