C.W.K.
Stream
Lesson 02 of 04 · published

Don't Spend a Call You Can't Land

~10 min · permission-before-inference, preconditions, dont-waste, gate

Level 0Cold Flint
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"If you already know you can't insert the answer, don't ask the question."

Check the Whole Operation Before You Start It

A strike is a small pipeline: capture, infer, insert. The insert step needs Accessibility permission. So the disciplined thing is to check for that permission at the start — before capture even leads to an inference call — because if you can't insert, the whole strike is doomed no matter what the model says. Validating the precondition for a late step before you begin the expensive step is what separates a careful pipeline from one that does costly work only to fail at the finish line.

Don't Spend a Call You Can't Land

Concretely: if Accessibility isn't granted, Flint does not make the model call. It stops immediately, tells the user permission is needed, and opens the Accessibility pane in System Settings. It never runs inference just to discover at the end that it has nowhere to put the result. An inference call costs time, and often money or a rate-limit slot; spending one you already know can't land is pure waste, and it leaves the user staring at a spinner for a result that was never going to arrive anywhere useful.

strike
  |
  +-- Accessibility granted?
  |     no  -> STOP: explain, open Settings pane. NO inference call.
  |     yes -> continue
  |
  +-- capture -> infer -> prove -> insert

The permission gate sits BEFORE inference, not after.

The Cost of a Wasted Call

This is the upstream half of a philosophy whose downstream half you already saw. Downstream (Track 6), when a call already happened and the target went stale, Flint salvages the result to the clipboard rather than waste it. Upstream, Flint refuses to make a call it knows it can't use in the first place. Both come from the same rule: an inference call is a resource with a cost, so don't spend it pointlessly and don't discard what you did spend. Guard the expensive step on the way in, and salvage its output on the way out.

Validate a pipeline's downstream preconditions before you pay for its expensive step. If a late stage has a hard requirement — a permission, a connection, a valid target — check it before you run the costly stage that precedes it. Doing the expensive work first and failing at the requirement afterward wastes the work and the user's time. The cheapest failure is the one you detect before spending anything; move the known preconditions to the front of the pipeline.
Make the permission failure actionable, not just informational. 'Accessibility permission required' is a dead end; the same message plus a button that opens the exact Settings pane is a fix. When you block on a missing precondition, don't just report it — carry the user to where they can resolve it. A guard that stops the user and shows them the door is helpful; one that stops them and shrugs is just an error.

Code

The permission gate, before any inference is spent·swift
func runMacro(_ macro: FlintMacro) async {
    // Precondition for the LAST step, checked FIRST.
    guard hasAccessibility() else {
        // Don't capture, don't infer — we could not insert the result anyway.
        notify("Flint needs Accessibility permission to insert text.")
        requestAccessibility()          // opens the System Settings pane
        return                          // no model call spent
    }

    guard let target = TargetCapture.snapshot() else { return }  // may be secure
    let prompt = macro.render(input: target.selection ?? "")
    let result = await pippa.applyFree(prompt: prompt,
                                       vault: macro.vaultContextMode)
    Insertion.place(result, into: target)
}

func hasAccessibility() -> Bool { AXIsProcessTrusted() }

External links

Exercise

Flint could check Accessibility permission at three points: (a) at app launch only, (b) right before inserting the result, (c) at the start of every strike, before inference. Evaluate each for wasted model calls and user experience. Then connect this to the clipboard fallback from Track 6: how are 'don't spend a call you can't land' and 'salvage a result whose target went stale' two halves of one rule?
Hint
(a) launch-only goes stale — permission can be revoked mid-session, so a later strike still wastes a call. (b) just-before-insert wastes the whole inference call when permission is missing. (c) start-of-strike is correct: no call is spent when insertion is already impossible. The connection: both treat an inference call as a costed resource — the gate refuses to spend one that can't land (upstream), and the clipboard fallback refuses to discard one already spent when the target moved (downstream). Guard going in, salvage coming out.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.