VoiceDebrief iOS / credit

Credit: a balance that counts down, and how a top-up will be paid for

The app keeps a credit balance. It starts at £5.00, counts down as the app is used, may go below zero, and is topped up by paying. The model is the reading meter of newsroom.sgit.ai: an honesty box, not a paywall.

In test, and no money changes hands. The app has the ledger, the price list, the counter, the credit screen and a simulated top-up. Paying through the App Store is written and switched off: it has never run. Every price is a placeholder. What is built is the record.

What the app does today

The unitThe micro-credit: one millionth of a pound, always a whole number. A penny is 10,000. Prices are in whole pence for now; the unit leaves room below that
Starting credit£5.00, written as the first entry of a new ledger. A placeholder
What is chargedJust about everything the user does: see the price list below. Charged when the thing has been done: something that fails costs nothing. Running a note again is charged again
What is never chargedRecording. Capture without loss is the app's first rule, and credit never stops, delays or interrupts a recording
The counterThe balance, in the navigation bar of the Record and Library screens and as a row in Settings. It changes as things are charged. Pressing it opens the credit screen
The credit screenThe balance, what was used and topped up, top-up, takings by feature, every entry newest first with the balance after it, and the price list
Below zeroNothing is blocked and nothing is held back. The balance turns a warmer colour and the credit screen says how far over it is: "Nothing is blocked, and nothing will be. Top up when it feels fair." No banner, no reminder
DecliningA charge can be declined with a reason (the result was not usable, I did not need it, it was a test, another reason). It is given back as a new entry; the charge stays in the ledger
Top-upOne pack of £5.00. In this build it is simulated: the screen says that no money is taken, and the ledger entry reads "Top-up (simulated, no money taken)"

The prices, all placeholders

The owner's word, 13 November 2026: "Just about everything in the app should cost a bit of money ... maybe creating a vault costs 10p and uploading a file to a vault 1p ... For now, go for 1p increments." The figures are in one place in the code (PriceList in Model/Prices.swift), the credit screen says they are placeholders, and a test fails if one is free or is not a whole number of pence.

WhatPlaceholderKey in the ledger
A transcript3p a minute of audio; a started minute is a whole onetranscript
A debrief5pdebrief
A clean text1p a passagecleanPassage
Opening an audio file1pimportFile
Adding one of your words1pglossaryWord
Creating a vault10pcreateVault
Adding a vault made elsewhere1paddVault
Saving a note to a vault1p a file (a note is up to four)saveToVault
Sending a note to a recipient1psend
Adding a recipient1paddRecipient
Pushing a vault to a server1p, when something was sentpushVault
Pulling a vault from a server1p, when something was fetchedpullVault
Adding a server1paddServer
Opening a note to read it1p, once for each note while the app is openreadNote
Opening a file in a vault1preadVaultFile
Deleting a note1pdeleteNote
Forgetting a vault1premoveVault
Removing a server, a recipient or one of your words1p eachremoveServer, removeRecipient, removeWord

The 10p and the 1p a file are the owner's examples. The transcript's figure is the plan's "a few pence per minute", the debrief's is what newsroom charges for an article read to the end, and the rest are 1p. At these figures a 76-second note costs 6p to transcribe and 5p to debrief.

The owner accepted these figures for now on 13 November 2026, and said that a note which saves itself when it is finished is charged like any other save, and that push and pull are charged. A push or a pull that finds nothing to move costs nothing. Bundling several of these into one price is an idea for later.

The owner then said that reading and deleting are charged too. What was chosen: the deliberate act is charged, not a screen being drawn. A finished note opened from the library or the record screen is charged once while the app is open, as newsroom charges a page once in a session; the note that opens itself the moment a recording stops is not. A file opened inside a vault is charged each time. Deleting a note, forgetting a vault and removing a server, a recipient or a word are charged when they have happened.

Not charged: recording, discarding a recording that is still being made, listing a vault's contents, the settings, diagnostics and the credit screen itself.

A profit and loss for every feature

The owner's reason for charging for everything: "it provides us a way to understand which features are valuable ... we should actually have a P&L, literally, for every feature that we develop."

Built: the takings, on one device. Every charge carries the key of its feature, a short fixed string that is never display text and is never renamed. The credit screen has "Takings by feature": for each feature, how many times it was charged, how much, how many charges were declined and what was given back, and what is left, over all time, 7 days or 30. Declining is part of the signal: a feature people use and then decline is a feature they do not value at its price.

Not built: the costs, and everybody's figures together. Both are proposed:

The ledger model (Model/Credit.swift, Engine/CreditLedger.swift, Engine/Payments.swift) knows nothing about voice notes: features are keys and a price list is the app's own file. That is so the sgit app in this repository can use the same ledger with its own price list, by copying it or from a shared package later.

Where the ledger lives

One JSON file on the device, credit-ledger.json in the app's own storage, beside the notes. It is append-only: an entry says what was done, when, for which note, how much of it, what it cost and the balance after it. A declined charge is not removed; a refund is written after it. A top-up is credited once per payment reference.

The file is one device's log, with a random name for the device. That is the shape it needs to live in the user's vault later: two devices' logs join by taking every entry once, and the balance is the sum of the amounts, which does not depend on the order. Keeping it in the vault is proposed, and waits for the account.

Deleting the app deletes the ledger, and a new install starts again at £5.00.

How this differs from newsroom, and why

NewsroomThe appWhy
Counts in pence and tenths of a pennyCounts in micro-credits, priced in whole pence for nowRoom for prices below a penny later, with no rounding
Charges for reading, by the share of a page readCharges for what the user does, by the minute or by the thingThere is nothing to read by degrees
Keeps running totals and the last 500 chargesKeeps every entry, and the balance is their sumA ledger that will be shared between devices cannot be a pair of running totals
Pays through a Stripe payment link, or a simulated cart with no linkWill pay through the App Store, or a simulated payment until thenApple's rules, below
A usefulness rating sets the priceNot builtThe app has no rating of a result yet. Declining with a reason is built

What Apple requires, checked on 13 November 2026

Credit spent inside the app must be bought by in-app purchase. Apple's App Review Guidelines, 3.1.1: "If you want to unlock features or functionality within your app, (by way of example: subscriptions, in-game currencies, game levels, access to premium content, or unlocking a full version), you must use in-app purchase." Apple Pay is named only for the other case, 3.1.3(e), goods and services consumed outside the app. So a top-up cannot be Apple Pay, a card form or a Stripe link. The same guideline says: "Any credits or in-game currencies purchased via in-app purchase may not expire." (App Review Guidelines)

A TestFlight build can make purchases that take no money. Apple's StoreKit documentation: "Apps that you download from TestFlight always run in the sandbox environment", and "Transactions from test accounts don’t incur charges because the sandbox environment simulates successful transactions using the App Store's infrastructure without processing actual payments." (Testing Apple In-App Purchases with sandbox)

But only once the products exist. The same page lists what must be true first: the Apple Developer Program account is active; "Your membership Account Holder has signed the Paid Applications Agreement"; and "You set up the product information in App Store Connect for the app you’re testing. At minimum, set up a product reference name, product ID, a localized name, and a price." Until then the App Store returns no products, and the app has nothing real to offer. That is why the top-up in this build is simulated.

Not checked here: Apple's commission on each purchase, the banking and tax forms the agreement asks for, and what App Review will say about a balance that goes below zero and is paid afterwards. The last is worth asking before the first submission.

What the owner must create to switch it on

  1. In App Store Connect, under Business, sign the Paid Applications Agreement (the Account Holder does this), with the banking and tax details it asks for.
  2. For the app ai.voicedebrief.app, under Monetization, In-App Purchases, create one product:
FieldValue
TypeConsumable
Product IDai.voicedebrief.app.credit.500
Reference nameCredit, £5
Display name£5 of credit
PriceThe tier nearest £5 (the owner's decision)
  1. Tell this repository it is done. Payments.appStoreIsOn in Engine/Payments.swift is then set to true, and the credit screen offers what the App Store returns instead of the simulated pack. A second pack is one more line in Payments.catalogue and one more product with the matching id.

StoreKit 2 needs no capability and no Info.plist key in the Xcode project, so nothing else changes. The App Store provider (AppStorePayments) is unverified: it compiles, it is covered by no test, and it has never met the App Store. It records the top-up in the ledger before it tells the App Store the purchase was delivered, and on opening the credit screen it collects any purchase that was paid for and never recorded.

What stops someone changing their own balance

Nothing, and this page says so on purpose. The app has no server of ours, and the ledger is a file on the user's own device: someone who can edit it changes their own balance, and deleting the app wipes a negative one.

Newsroom has the same question and answers it in its security model: every way of cheating changes a number only the cheater can see, and costs the site a payment it was never going to get, because the meter never blocks anything. Its own line is the one that matters here: "If the balance unlocked something, it would have to be held by a server or a signed receipt."

The app is in the same position today, because nothing is held back below zero. What would make the balance trustworthy, none of it built:

None of these stops a determined owner of the device from not recording a charge. Only a server that does the work, or meters it, can. The plan has no such server, so the position for now is newsroom's: an honesty box, said plainly.

Decisions that are the owner's