Skip to content

Prompt vs rule — invoked vs always-on

You now own both tools. Last chapter you wrote a rules file; this chapter you wrote a prompt file. They look similar — both are Markdown in .github/, both feed Copilot context, both kill repetition. But they fire at completely different times, and that difference is the whole decision.

Rules are always-on. A copilot-instructions.md or an *.instructions.md file is applied automatically, on every request, whether or not you’re thinking about it. You don’t invoke it. It’s ambient — Copilot pulls it into the conversation on its own, every time, and you’d have to go out of your way to not get it.

Prompt files are invoked. A .prompt.md does nothing until you call it with a slash command. It sits in the repo, inert, until the moment you decide now I want this procedure run. It applies exactly once, exactly when you ask.

Everything else follows from that. The question for any piece of repeated work is simply: should this apply to every request, or only when I ask for it?

If the thing should shape every answer Copilot gives in this repo, it’s a rule.

Your house style is the clean example. “Match the existing sort idiom.” “Emit audit events the way the other endpoints do.” “Lay out files this way.” You don’t want those sometimes — you want them whether you’re fixing a bug, scaffolding an endpoint, or answering a question in Ask mode. Anything you’d want true of every draft, regardless of what you happened to ask for, belongs in the always-on layer. That’s why you wrote them as rules last chapter: re-typing “match the style” on every request was the signal that it should’ve been ambient all along.

The test: if you forgot to mention this and Copilot did the opposite, would that be a mistake? If yes, it’s a rule. Forgetting your sort idiom is a mistake. So it’s always-on.

If the thing is a specific task you only want sometimes, it’s a prompt file.

“Scaffold an audited endpoint” is the clean counter-example. You absolutely do not want that running on every request — most of the time you’re fixing a bug or asking a question, and a prompt that scaffolds a whole endpoint would be noise, or worse, an unwanted action. You want it precisely when you sit down to add an endpoint and not one moment otherwise. That’s an invoked procedure, not an ambient convention.

The test inverts: if this fired on a request where you didn’t ask for it, would that be wrong? If yes, it’s a prompt file. An endpoint scaffold firing while you’re fixing a sort bug would be wrong. So it’s on-demand.

The strongest setup uses both at once, and your endpoint scaffold already does. The prompt file carries the procedure — the five ordered steps. The rules carry the conventions — how the resulting code should look. When you invoke the prompt, the rules are still applied underneath it, because they’re always-on. So the scaffolded endpoint comes out in your house style without the prompt file having to restate a single style instruction. That’s why the prompt’s body could end with “follow the repository’s custom instructions” and trust it to mean something: the always-on layer is already there.

Think of it as: rules are who Copilot always is in this repo; prompt files are tasks you hand that person on demand. You don’t choose between them — you decide, for each bit of repeated work, which layer it lives in.

The economics underneath make the same case. Always-on knowledge pays its full size on every request; an invoked container costs almost nothing until the moment it runs; anything you never write down gets re-typed every time it comes up. In the widget below, “rules file” is your always-on layer, “skill” is the invoked container — a prompt file, in Copilot’s terms — and “prompt” is just saying it in chat. Place each piece and watch the ledger:

Four things you keep teaching the agent, all currently crammed into the rules file. Each needs a home: the rules file (loaded every session), a skill (a 25-token menu line every session, full body only when invoked), or the prompt (said when it comes up). Re-home them and watch the ledger.

  • cents, not floatsfact · matters most sessions · ~22 tok

    Money is integer cents — amountCents: number, never floats.

    right home

    Twenty-two tokens a session and the float bug is extinct. A fact the agent must hold while writing any code has to be in view before it starts — that’s the rules file.

  • release checklistprocedure · runs ~2×/week · ~1.2k tok

    The release ritual: bump the version, regenerate the changelog, tag, build, smoke-test — fifteen steps in a fixed order.

    idle rent

    Fifteen steps loaded into every session to be used twice a week. The other eight sessions pay 1.2k tokens for a procedure that never runs — bulk that competes with your real rules for attention.

  • migration recipeprocedure · runs ~2×/month · ~900 tok

    Schema migrations follow expand → backfill → contract, with a fixture check and a written rollback plan.

    idle rent

    Twenty sessions pay 900 tokens each for every one that migrates. The rarer the procedure, the worse a rules file suits it.

  • today’s flakeone-off · this week only · ~25 tok

    Today’s job: chase the flaky auth test in login.spec.ts.

    rent for a one-off

    True this week, noise forever after. Next month the agent still “knows” about a flake that’s long fixed.

window cost21.5k tok/weekyou re-teach0×/weekmisplaced3 of 4

The procedures are paying rent in every session for the few that use them. Move them behind a skill stub: the knowledge stays one invocation away, and the window cost collapses.

Token numbers are illustrative; the ratios are the point. Assumes 10 sessions a week. A rule pays its full size in every session; a skill pays a ~25-token stub every session and its body only when it fires; a prompt pays only when said — but you’re the one saying it.

You’ve got the judgment. The last thing is to make the prompt file itself more capable — accept a parameter, pin a mode, control its tools. Next: Arguments, agent, and tools.