Repository navigation
Releases: f2i-com/formlogic.com
Release list
FormLogic v0.1.22
Before you update
- Updating by uploading files? Upload the hidden
.htaccesstoo. This release's fix is in that file, and many FTP clients skip it. An in-app update brings it with the rest. - Running on nginx? Add the two new
locationrules from the README's example to your server block, where the example has them. Without them nginx still serves the files listed below. - A file in the web root ending in one of the endings below now answers 404. If you serve one there on purpose (a
.zippeople download, say), move it outside the web root or under/api/.
What's fixed
Files left in the web root were served. The web root's .htaccess refused .env and .ht* files and nothing else of the kind. A .git folder (/.git/config, anywhere in the tree), backup.sql, site.zip, backup.tar.gz, index.php.bak, config.old and .DS_Store were plain downloads wherever someone had left them. The README's nginx example had no rule for them either.
Both now answer 404 for:
- any dot folder or dot file, except
.well-known - files ending in
.sql,.sql.gz,.db,.sqliteor.sqlite3(with their-waland-shmfiles),.zip,.tar,.tar.gz,.tgz,.7z,.rar,.bak,.old,.orig,.saveor.swp, in any case
The rules run after /api/ has gone to the backend, so API routes are unchanged, and .well-known still reaches the backend and the certificate challenge.
Nothing else changed since v0.1.21.
Tested with
SoftN v0.0.31 (ZIPP v0.0.32) and OAIY v0.1.12. Checked on Apache with every such file planted (13 refused; the app, its routes, /api/, /manifest.json and .well-known unchanged) and with the README's block on a real nginx.
FormLogic v0.1.21
Before you update
- Every site runs one full migration on its first request after this update. It's safe to repeat and usually takes seconds. If it takes longer, other requests answer 503 with
migration_in_progressandRetry-After, and pages wait with their spinner up and try reads again. Writes aren't repeated. - Running on nginx or Apache with
Alias? Replace your server block with the current example in the README. Nothing had ever run the old examples. On nginx every/api/request was a 404, embedded forms were refused, and the rules v0.1.20 added were missing. The Apache example had the same fault for/api/. The nginx example also cut any quiet request at 60 seconds, where a Studio round, an update or a backup can take ten minutes. - Updating by uploading files? Upload the hidden
.htaccesstoo. Many FTP clients skip it. Everything still works without it, but a missing build file gets the app's home page instead of a 404. - Behind Cloudflare or another CDN and coming from v0.1.19 or older? Purge
/sw.jsand/registerSW.jsonce, right after this update. A CDN already holding the oldsw.jscan go on serving it for hours. v0.1.20 and later tell it not to keep those files. - If you set
SMTP_HOST, mail may start going out.symfony/mailerwasn't in the release zip, soSMTP_HOSTdid nothing and an update removed a copy added by hand. It ships now. If you set it and never saw mail, check the address it sends from before you update. flow_kvkeys now differ by case.voucher:AB12andvoucher:ab12used to be one key, so one customer's value could overwrite another's. A flow that writes a key in one case and reads it in another no longer finds it. Stored rows aren't changed.- A CSV that isn't UTF-8 or a Western encoding is refused, with a message saying to save it as CSV UTF-8. Excel's Western files (Windows-1252, UTF-16 with a BOM, semicolons or tabs) import, and say what they were read as.
- Reports on
datefields may move to the right day. Totals that used to shift by the app's offset, or with daylight saving, no longer do, so a saved monthly figure can differ from an earlier one. - Use the wizard's upgrade? It works again, so turn it off afterwards. It answered an empty 404 from v0.1.18 on. It still needs
INSTALL_ENABLE=1, and while that's set it answers anyone who can reach the site, so remove the setting and deleteinstall.phpwhen you're done. - Rolling back below v0.1.18 with
DATA_ENCRYPTION_KEYset now has to be confirmed, on the admin page or with--allow-downgrade. Those releases can't read what's sealed, so authenticator codes, webhook signatures and hosted records break. The check names them. - Mail on mod_php and mod_fcgid. PHP-FPM is the setup to use if you can. Forgot-password holds to a 2-second floor on servers that can't end an answer early, so its timing doesn't tell an outsider which addresses have accounts. That's a floor and not a guarantee: a mail server that has died still shows, at 5 seconds. mod_fcgid holds short answers until PHP exits, which PHP can't change. Doctor warns of both, and
DEPLOYMENT.mdsays what's true of each.
What's new
- An open tab hears of a new release. A page built for another release shows one "A new version is ready" with Reload. It never reloads by itself, and embedded forms don't show it.
- Flows run on the desktop show their result. Every Run via Desktop relay used to go back to "Queued" and never showed one, since the feature was built.
- SoftN v0.0.31: an app says on the page when it can't save, when a page doesn't parse and when its code fails, and a loop of writes to one collection is no longer refused.
What's fixed
Updates and failures
- An in-app update could skip its migrations. If a request hit the old code in the moment the files were swapped, it marked the new release as done without running them. The recycle bin answered 500, two-factor setup failed, and
--checkand deep health stayed green. This release migrates once whatever an older one stamped, which also heals a site this already happened to.bin/upgrade.php --checkused to pass on a database 8 releases behind, and now compares properly. - A database that's down gets a clean 503 with
Retry-After. It used to be an empty 500 or, where PHP's error display was on, a 200 of stack trace with the server's paths. An admin no longer sees "Maintenance mode is ON" when the database is down. - A failed chunk reloads the page in Firefox and WebKit as well as Chromium, a chunk's stylesheet counts, and a page with unsaved answers is never reloaded. One case used to reload a thousand times in six seconds.
- An admin's page from v0.1.17 or older says it's out of date, where every admin write failed with a request for a password nothing asked for. The same goes for two-factor and a password box on a connected domain.
Search, dates and data that leaves
- An app's record search found nothing outside plain ASCII: José, Иван, 山田 or a URL. It now reads every language, for rows already stored, and sort folds accents. The linked-record search does too.
- App reports moved
dateanswers by the app's offset, so in New York 1 March landed in February and atodayfilter on a date field counted 0. Only the submitted time moves now, and by the offset of that row's own moment. - A dump restores anywhere. Restoring into a MySQL in another time zone moved every timestamp, and could stop partway with no users loaded.
- CSV exports keep the BOM Excel needs. Export then import keeps every answer type that can be kept, and the preview says what isn't.
- Text limits count characters, not bytes: a 700-character Japanese flow description was a 500.
Mail and backups
- A mail server that accepts the connection and then says nothing can't hold a visitor's submit for a minute. Mail goes after the response with a 5-second limit per step, and a failed mail is audited and shown by Doctor.
- A failed backup night still does its retention, recycle bin and upload clean-up, so the job that frees space runs when space has run out.
- Webhook retries reach the 6-hour step
DEPLOYMENT.mdpromises.
The desktop link
- A desktop that comes back lets go of what it held. Closing OAIY mid-turn used to hold a row, and one of a person's two places, for up to fifteen minutes. This needs no change in OAIY.
- Settings says why a linked desktop listed nothing, and offers Try again.
/api/v1honoursanswersGteandanswersLte, so a desktop flow asking for upcoming bookings isn't handed every booking.- A flow that ends in text, a number or a boolean shows its result, and a finished run's sealed copy is cleared when the page has opened it.
Smaller things
- An admin's password reset that can't be mailed says so and leaves the member signed in. It used to say "emailed" after signing them out.
- A migration over 15 seconds no longer gives other requests a 500.
- A path nothing answers is a 404 in plain words, where a 405 read "Internal Server Error".
- Cancel on an upload's password dialog no longer says the page is out of date.
- A new app no longer says a custom screen is saved but switched off.
- A host with
ini_setdisabled keeps its API. - The native runtime takes Tauri 2.12.2 and its plugins, Vite 8.3.5 and sha2 0.11.1.
Tested with
SoftN v0.0.31 (ZIPP v0.0.32) and OAIY v0.1.12.
FormLogic v0.1.20
Before you update
- This release replaces v0.1.19, which was withdrawn. Everything in it is here. If your site is on v0.1.19, update as usual.
- Behind Cloudflare or another CDN? Purge
/sw.jsand/registerSW.jsonce, right after this update. From now on the site tells a CDN not to keep those files, but one already holding the oldsw.jscan go on serving it for hours. Until it stops, returning visitors stay on the page they had stored, and on a site coming from v0.1.17 or earlier that page never asks for a password when setting up two-factor. An administrator then sees "Incorrect password" and can't reach the admin panel. Your password is fine: reload with Ctrl+Shift+R and the password box appears. If you're still locked out, addADMIN_MFA_REQUIRED=falsetoapi/.env, set up two-factor, then remove it. - Coming from v0.1.17? Read the v0.1.18 notes first. Your update still runs under the old updater, which deletes anything in the web root and
api/that isn't in the package, such as a.user.ini,robots.txtorapi/.env.backup-*. Copy those out first. Administrators still need two-factor, and the scheduled jobs inDEPLOYMENT.mdstill need adding. - Scheduled jobs: use the new log paths. The old lines wrote to
/var/log/formlogic-*.log, which the web server's user can't create, so the job never started and nothing said so. If you copied them into that user's crontab, replace them with the lines inDEPLOYMENT.mdorINSTALL.txt, which log underapi/logs/. - Connected a custom domain?
APP_URLis still the right setting. Members can now sign in without it on a site installed with the wizard, because the site's address is read fromCORS_ORIGIN, but a site still on the examplelocalhostvalue has no address to send them to. New wizard installs writeAPP_URLfor you, and connecting a new domain needs it. - Hosted app databases now use WAL, so back up
api/storagethe safe way. A plaintarof a running site can miss recent writes to them. Use FormLogic's own backups, or stop the site first. SeeDEPLOYMENT.md. - Custom screens on public forms.
FormLogic.submit()gives a visitor back the answers they sent, with the record's id, status and timestamps. Calculated fields and tags stay with the form's owner, so a quiz has to work out its own score in the screen. - A form whose script made an HTTP request and then stopped now answers 409 with
scriptRan: true, not 503. If your own code retries on 503, this is what stops it charging a card twice. The sameidempotencyKeykeeps getting that answer and doesn't run the script again, so to send it again after checking, use a new key. A script that made no call answers as before. - Form-limited API keys only reach form routes since v0.1.18. A script that also calls flows, AI or data nodes needs a key without that limit.
- Version history keeps the newest 200 versions of each form. Older ones are removed as new ones are saved.
bin/upgrade-aokie-receptionist.php. Connector grants are no longer added back on their own, because a grant an owner declined looks the same as a missing one. A dry run lists them, and--approve-grantadds the ones you name.
What's fixed
Saving and editing
- Two people editing one record at the same moment: one of them got a server error, every time. Both edits now land, and neither is lost.
- Two tabs saving a form at the same instant could both succeed, and the later save removed the other's work. One now wins and the other is told.
- Answering a form while it's being deleted now says the form is gone, instead of a server error.
- A capped form with a script holds a person's place through the script, so nobody is charged by a script and then told the form is full. Such a form takes people one at a time, and anyone behind a slow script is told it's busy after a second, so a rush doesn't slow the rest of the site.
- If a form's script made an HTTP request and the record then isn't stored, or the script stops or refuses, no copy of it can run the script again, whether from an offline queue, the service worker, a second tab or a lost answer, so a script that charges a card can't charge twice by itself. The person is told to check first, and can still send it. A script that makes no call retries as before.
- A busy public form says it's busy, instead of telling the visitor to check their connection.
- Sending a record's answers in the wrong format through the API is refused. It used to wipe the record and its files.
- One invitation goes out when two people send it at once.
- Reports, documents and app settings changed by two AI tool calls at once no longer lose one of the changes.
Forms and the builder
- Add relation always failed. It works now, and from the Studio's Data step too.
- Uploading a real logo or background stopped the whole form saving and publishing, with nothing to say why. Images are now shrunk on upload.
- Simple Mode conditions on choice questions could never match after an option was renamed, because they compared the label. They now use a picker. Conditions on dates and calculated fields are fixed too.
- Version history has Restore on every row, shows a failed load instead of an empty list, and reaches past the newest 50.
- The Studio's Data step no longer erases fields added elsewhere, can add a field called Value or Count, and shows when a save failed.
- Opening the builder from the Studio no longer says a form needs an app.
- Clicking into an app's description and away no longer erases it.
- A chat that changes a form while another part of it is saving no longer leaves your next edit refused with no way out.
- A changed AI service key is no longer replaced by the old one after a test.
- "Run on server & log" recorded a run that never ran, so it's gone.
Apps
- Hosted apps no longer run one action at a time: readers don't wait for writers, and a busy app says so.
- Opening one app while another is still loading can no longer show the wrong app.
- A form link on a domain connected to a SoftN app opens the form again.
- A first visit to a connected domain shows its app, never FormLogic's pages, however slow the connection.
- Self-hosted sites no longer make every page wait for a domain lookup: only the first page in each browser does.
- Uninstalling a pack puts hosted and native apps in the bin, with their data. If the bin can't keep a copy, nothing is deleted, and you can choose Delete anyway: whatever can be copied still goes to the bin, and only what can't is gone for good.
- A form whose file is damaged can be deleted now, after one more question. It had no way out.
- A crash during an uninstall can no longer cost a live private form its keys.
- Deleting a staff account no longer deletes the app's call routing groups.
- A pack can no longer turn on public records for one of its forms.
Chat and AI
- A chat thread stopped working for good once its history got too big. Long threads now keep working, and the older images give way first.
- A chat with a broken template or a silent service no longer stays on "Thinking…". There's a Stop button, and a turn is given up on after five minutes of silence, or 15 minutes in all.
- One empty reply from a model no longer breaks its thread, and threads it already broke work again.
- With Site AI off, generating a form says to connect your AI, instead of "try rephrasing".
Offline
- "Saved on this device" could appear when nothing was saved, on a nearly full device.
- Answers queued by one account can no longer be sent under the next one to sign in.
- A slow desktop command now says it may have run, so a call or a message isn't sent twice by trying again.
Accounts and access
- "Forget this browser" failed every time, in every release that had it.
- Connecting a site's own address to an app locked everyone out of signing in. A site in that state now works again.
- Signing in to an app on its own domain says when the site couldn't be checked, with a Try again button, instead of saying it isn't connected.
- A password reset now says that it signed out API keys and linked apps.
- Two refreshes of one OAuth token no longer unlink a client.
- Any app member could read the Companion staff list.
- Erasing an account could report done with app data left on disk.
- A taken role or group name showed a database error. Database errors no longer reach the page: busy ones say to try again.
Running a site
- An administrator can pause a runaway flow without the owner's leave.
- The Companion relay no longer throttles apps during a live call.
- A CDN can no longer hold a release back. The site now sends
sw.js,registerSW.jsandindex.htmlwithCache-Control: no-cache, so returning visitors get the new release instead of staying on the page they had stored. - Two-factor setup from an out-of-date page now says the page is out of date, instead of "Incorrect password".
- A build file that no longer exists answers 404, instead of the app's home page under a script's name.
- A self-hosted site's home page no longer says "This domain isn't connected yet".
- A webhook whose worker died on its last attempt no longer stays stuck.
webhook-worker.php --looprides out a passing database error, and exits if the connection is lost, so run it under something that restarts it. - Older form ids, such as one with a dot in it, can be restored and updated again.
NATIVE_WORKERS_PER_APPsets how many native workers one app may use.
Tested with
SoftN v0.0.30 (ZIPP v0.0.32) and OAIY v0.1.11.
FormLogic v0.1.18
Before you update
- This one update runs under the old updater. v0.1.17's updater deletes anything in the web root and
api/that isn't in the package, so copy out your own files first if you have any: a.user.ini, arobots.txt, another folder,api/.env.backup-*. From this release on, an update removes only files a release shipped. - Add the scheduled jobs you don't have yet.
backup-accounts.phpwas in no install guide, and it runs the nightly backups, the recycle-bin purge, upload cleanup, record retention and the webhook log prune.native-record-dispatch.php,flow-outcome-dispatch.phpandartifact-sweep.phpwere also missing from some lists.INSTALL.txt, the wizard andDEPLOYMENT.mdnow name the same ten jobs. Run them as the web server's user. - Set
DATA_ENCRYPTION_KEY, and keep a copy off the server. It now encrypts two-factor and webhook secrets and hosted app records. A site with no key keeps working and the Doctor says so. Without the key, whatever it encrypted can't be read. Seedocs/DATA_ENCRYPTION.md. - Administrators need two-factor. Outside development an administrator has to have it on to reach the admin tools (
ADMIN_MFA_REQUIRED=falseturns this off). Every admin write now also asks for the password again. - Manual installs: check
APP_ENV. The oldINSTALL.txtdidn't mention it, so a hand-made.envcopied from the example ran in development, which shows errors to visitors and treats any domain claim as proven. SetAPP_ENV=productionandAPP_DEBUG=false. - If you have a custom domain connected, set
APP_URLbefore you update. Put this site's own address inapi/.env, for exampleAPP_URL=https://forms.example.com. Members now sign in on the main site instead of on the domain, and withoutAPP_URLthe domain doesn't know where that is: members of a members-only app get a sign-in form that refuses them. Public apps on a domain keep working. The install wizard doesn't write this setting, so a site set up with the wizard needs the line added by hand, and connecting a new domain is refused until it's there. - nginx sites: update the
/screen-host.htmlblock fromformlogic/README.mdif you want custom screens in embeds. The old block is safe but leaves them blank. Apache's rules come with the release. - Scripts calling the API. A submission by anyone but the form's owner now returns the record's id, status and timestamps, not the stored record. A wrong password or code when turning off two-factor, regenerating recovery codes or resetting an admin's two-factor is now 403, not 401. Report routes are limited to 120 a minute per user.
- Reserved addresses.
OFFICIAL_EMAILandDEMO_EMAIL(official@formlogic.localanddemo@formlogic.localby default) can no longer be registered.bin/bootstrap-admin.phpnow needsADMIN_BOOTSTRAP_PASSWORDto promote an address that already has an account, and replaces that account's password and two-factor. - FormLogic Backups, a new OAIY plugin, needs
PRIVATE_FORMS=trueandDATA_NODES=trueon the server. It works with OAIY v0.1.11 as it is. Install the zip for your system from this release in OAIY's Plugins tab. The Windows zip is attached here, and a Mac zip may follow. There's no Linux zip, because OAIY gives a plugin on Linux no display to ask you with.
What's new
- FormLogic Backups for OAIY. Keep sealed copies of your apps and forms on your own computer, on a schedule, in a folder you choose, and restore them. Set it up from Settings through the computer's existing OAIY link.
- Apps on their own domain. A SoftN app can run full screen on a connected domain. Nobody signs in on the domain itself: members sign in on FormLogic and the domain receives a one-time code. Attachments open there too.
- Stored data is encrypted. Secrets and hosted app records are encrypted at rest under
DATA_ENCRYPTION_KEY, nightly backups can be sealed to a key you hold, and a Settings download can have a passphrase. - Custom screens in embeds. A form with a custom screen now shows on a customer's own page, where it used to be blank.
- Backups carry more. Flow storage, hosted apps and private forms come back with a restore.
What's fixed
Public forms
- A visitor whose answer was refused, or never reached the server, was told "Thank you", and the owner received nothing. They now see the reason, and their answer stays in the browser only for forms that really are device-only.
- Embedded forms no longer fail on a return visit, and no longer crash when third-party storage is blocked.
- A rule's pattern now gives the same verdict in the browser and on the server. A date pattern with an escaped slash used to refuse every answer on the server.
- Submitting during an upload waits for it, instead of dropping the file.
Your work
- Two tabs, a second device or an AI client can no longer silently overwrite a form's fields: the later save is refused and says so.
- Device-only forms survive a session ending, and are named in the sign-out warning. Moving a form from the cloud to the device and back can no longer wipe its fields.
- The flow editor saves when you leave, and asks if that fails.
- A backup with a private form in it can be restored, and large forms and archives come back from the recycle bin. A restore can no longer damage a private form that's in the bin.
- Exports can't leave out committed rows. A CSV export cut off at its limit says so.
- Retention now reaches forms that have gone quiet, webhook logs no longer keep answers for good, and a script setting status
spamno longer destroys the submission. - A long offline queue on the desktop app is sent in pieces instead of failing as a whole.
Apps and their members
- One app can't walk a member's requests into another app or into their account, and a flow carries a member's session only into its own app.
- Apps stay apart on a server's workers and budgets, and the runtime sandboxes itself.
- What a member saves in an app stays through a session ending, a rename and a second tab.
- Nobody can take a deleted app's data, and it goes when the app is gone for good.
- A hosted action stops at its first failed operation and says why.
OAIY
- OAIY stays connected: a new tab asks for no new code, and the token moves to the account by itself.
- The Desktop control opens its menu again when OAIY is connected, with its services and plugins.
Accounts and access
- A crafted OAuth redirect could turn a stolen code into an account-wide API key.
- Anyone could keep any account locked out of password sign-in from one address. A reset link now ends a lockout.
- A public report could show fields outside the ones the form's owner chose to show, and one crafted answer could tie up a server core.
- Records no longer reach app members through a report's labels, through a form taken out of the app, or through queued connector events. An app can't use the viewer's own OAIY, AI or device without asking.
- An administrator acting for an account can't open a way to its records, and a session alone can't take over two-factor.
- Audit rows are no longer lost for OAuth clients, and member changes are recorded.
Running a site
- Updates keep your own files, check for disk space first, keep the newest three code snapshots, and ask before installing an older version.
bin/upgrade.php --rollback=<id>puts the code back if an update is killed part way. - Scheduled jobs keep working on a server with a second site or a second user, and fail loudly if they can't start.
- Relay streams and frames have limits per account, and a busy app no longer blocks its own update.
- A site set up with the wizard gets the index a long forms list needs, and API key hashes are unique there too. Both are added by themselves on update.
Templates
- OHS & QMS: Action Items and Corrective Actions can be created. This applies to new installs; an installed copy keeps its fields.
Tested with
SoftN v0.0.30 (ZIPP v0.0.32) and OAIY v0.1.11.
FormLogic v0.1.17
Before you update
- Nothing to migrate. This release installs SoftN v0.0.30 (still ZIPP v0.0.32, the same engine and protocols as v0.0.28).
- To use OAIY's built-in engine as the Desktop AI, update OAIY on that computer to v0.1.11 or later. Earlier OAIY releases didn't offer their engine through the relay, so FormLogic said "this desktop has no provider named "oaiy-engine"".
What's fixed
- AI Studio says which AI it is using. Inside FormLogic, Studio's settings and status showed "FormLogic AI · FormLogic default · localhost:11434 · no key", as if it were using a local server it never talks to. Studio now shows the AI FormLogic actually answers it with: "FormLogic Site AI", or "Desktop AI (OAIY), · ", or the name you gave a custom provider. Its settings offer a Test button and no provider list, because the choice is made in FormLogic.
- Clearer messages when OAIY's engine can't be reached. When an older OAIY refuses its built-in engine through the relay, the AI source card and the Connect AI wizard now say so and say to update OAIY. They used to show only "The saved provider is not available".
- 3D models in SoftN apps draw. Since v0.1.15 FormLogic has accepted glTF, GLB, OBJ, STL and FBX files in a SoftN app's
assets/, but Scene3D refused every one ("Unsafe model URL"). SoftN v0.0.30 fixes that, and an end-to-end test now uploads an app with a model and checks that it loads.
Tested with
SoftN v0.0.30 (ZIPP v0.0.32) and OAIY v0.1.11's CLI. CI and the end-to-end suite are green. The release was first checked with the OAIY CLI v0.1.10, which is the same code, then CI was run again on OAIY v0.1.11 once it was published.
FormLogic v0.1.16
Before you update
- Nothing to migrate, and the same SoftN release (v0.0.28) as v0.1.15.
- If you added a framing exception for
/app/.../nativeto your web server to work around the problem below, remove it: nothing frames that page any more.
What's fixed
- SoftN app previews work on a real server. The SoftN app workspace's preview and App Studio's website preview were blank, with the browser reporting
Framing '…' violates the following Content Security Policy directive: "frame-ancestors 'none'". Both framed the app's own FormLogic page, which the web root's.htaccess(rightly) lets nothing frame. They now show the app in place, at the width you choose, with nothing to configure on Apache, nginx or anything else. - The end-to-end suite now runs under the same framing rule as a real server, and a build check refuses any iframe in FormLogic that points at one of its own pages, so this can't come back unnoticed.
Tested with
SoftN v0.0.28 (ZIPP v0.0.32), OAIY CLI v0.1.10. CI and the end-to-end suite are green, run locally under production's framing headers as well.
FormLogic v0.1.15
Before you update
- This release installs SoftN v0.0.28 (ZIPP v0.0.32, as before: no sandbox rebuild). Its app frame needs this FormLogic's checks: a FormLogic before v0.1.15 runs the new frame, but its
test:zipp-sharingcheck refuses the frame'sconnect-src data:. - Nothing to migrate. Native app data, keys and backups are untouched.
What's new
Hosting SoftN apps
- Apps open with their seed data. The
.xdbfiles a SoftN app ships with are added to each visitor's copy before the app first draws: once per record, never over the visitor's own, and a removed seed stays removed. A collection too large for browser storage (about 30,000 characters) is skipped with a console warning, and the app opens with the rest. - More media: video (MP4, WebM), more sound and picture formats, TrueType/OpenType fonts, 3D models (glTF, GLB, OBJ, STL, FBX) and WGSL shaders, text and Markdown can be uploaded with an app. The browser and the server check the same list, and a test keeps them together.
- Apps without a backend need no runtime on the server: they install, publish and restore (including from account backups) where the native runtime is not prepared, and the hosting panels no longer warn about it for them.
- A native app's helper logic reaches its backend (it got the browser's fetch before the entry file's bridge ran), methods like
postwork, and a request'sIdempotency-Keyreaches the app's handler, so a retried write can be told from a second one. A write that commits late is no longer reported to the app as failed. - Request bodies keep
{}and[]apart, both ways. A burst of requests waits briefly for a free runner instead of being answered busy. - Saves to an app's browser storage no longer count against its four backend calls, so a busy screen's saves aren't refused.
- "The app could not load" shows only when the app did not open, not over a running app that hit an error inside it.
- An app that dropped its manifest
idin a later version restores with its keys; a version without aserverblock can't replace a backend whose migrations have run (it says why); anapiVersionwritten1.0and file names with..are refused as you choose the file, as the server refuses them.
Creating apps
- Create app now asks what you want to make: Forms & data, Website or web app (AI, the visual starter, or a file), or Bring an app you have (
/apps/new?type=upload: drop the.softnfile, the name is optional). On phones the choices are compact rows. - The starter app's button uses
@click, so the Visual Builder opens it without a warning. - On phones the Apps header no longer cuts its title to "A…".
Tested with
SoftN v0.0.28 (ZIPP v0.0.32), OAIY CLI v0.1.10. CI and the end-to-end suite are green, including new end-to-end checks for seeded apps (40 records, reopened without duplicates) and an oversized seed.
FormLogic v0.1.14
FormLogic 0.1.14 makes adding an app easy: any SoftN app can be uploaded, with a backend of its own or none, and the places you would look for it say how.
Before you update
- Native app hosting takes apps without a backend. A
.softnfile with noserverblock in itsmanifest.json(most SoftN apps) is now installed: it runs in the member's browser alone, no runner is started for it, and it has no database on the server, so what it saves stays in each visitor's browser. Chat and MCP's native project tools take such projects too. Aserverblock, even an empty one, is still held to every rule a backend must meet. - An app's
idis optional. An app that declares none runs under one named after the app (formlogic.app.<app id>, as the starter does); its stored project and its download stay exactly as uploaded. The identity is kept in the app's host configuration: updates keep it, and so does a key-preserving restore under a new app id (the scheduled site backup); an account export's restore reissues an app's keys, as before. - Seed data is kept but not loaded yet.
.xdbseed files are now accepted and kept with the app, but the Softn v0.0.27 runtime FormLogic embeds does not load seed data, so such an app starts with no records.
What's new
- Add any SoftN app. Create app → SoftN app → Upload takes a
.softnfile with or without a backend, reads it as soon as it is chosen (or dropped anywhere on the form), and says what it is (for example "Fieldnotes · runs in the browser, no backend") or exactly why it cannot be hosted, file by file, before any app is created. The app name is optional: an uploaded app keeps its own. A backend written for another SoftN host is refused up front with what FormLogic needs, instead of leaving an empty app behind. - Apps → Import opens "Import an app" and says that a
.softnfile is added as an app of its own and a FormLogic export brings its apps and forms. The empty Apps page offers Import an app beside Create and the marketplace, and the first-run welcome links to making an app as well as a form. - Apps without a backend say so in their workspace: what they save stays in each visitor's browser, and the Data tab explains there is no database on the server instead of showing an empty table list.
- A SoftN app's card no longer says "0 forms".
Fixes
- Create app, Connect an AI and a single response's view each rendered a second main landmark inside the page's own; each page now has one.
- On a phone, the "No desktop" chip no longer floats over the page's fields when no desktop is linked; a linked desktop's chip still shows, and Settings and Flows keep the status.
Maintenance
- The FormLogic end-to-end suite now adds a browser-only app by upload on the standard test account, so CI covers it.
Tested with Softn v0.0.27 and the CLI of OAIY 0.1.10.
Full Changelog: v0.1.13...v0.1.14
FormLogic v0.1.13
FormLogic 0.1.13 moves to Softn v0.0.27 on ZIPP v0.0.32, runs native apps without Node where Softn carries its runner, and takes the pending dependency updates.
Before you update
- Native apps run on softn-runner. On Linux and Windows x86-64 the API now runs native apps on
softn-runner, which this release's Softn runtime carries, instead of Node; the native-hosting check says which one a server uses. Nothing needs setting up. Node still runs them on any other platform, or whereFORMLOGIC_NATIVE_RUNNER=nodeasks for it. What an app's backend may notice is listed in softn-runner's README: among it, SQLite is 3.53.2 and keeps temporary data in memory, andsoftn.time.formatends some 262,000 years from year 0. - On Linux, softn-runner locks itself down before it reads a request (Landlock and seccomp): it may read the app's own folder and write only in its database folder, and it cannot start a program, open a socket or signal another process. It needs no root, container or configuration; a kernel without Landlock still gets the seccomp filters.
- Native app SQL on either runner: a
LIKEorGLOBpattern over 1,000 characters now fails its statement, and a request whose transaction SQLite ends under it (INSERT OR ROLLBACK) writes nothing more. - The script engine is larger: 7.34 MB (about 1.8 MB with Brotli), downloaded once by a browser that opens a form with logic. It is still left out of the offline precache.
What's new
- Softn v0.0.27. The app runtime, Builder and Studio that FormLogic embeds are the v0.0.27 release (from v0.0.25). Among it: a template expression can no longer write onto the page's shared objects; an app writes the clipboard, saves a file or opens a file picker only from a press aimed at it; an app's stylesheet can no longer redraw the permission bar's words or open a picker over it; and the host's notices are drawn where an app's CSS cannot hide them. See the Softn v0.0.26 and v0.0.27 notes.
- ZIPP v0.0.32. The script engine, in the browser and in the server sandbox, is 0.0.32 (it was 0.0.29). An arrow function in a class method reads the method's own variable where that has the class's name, a typed array subclass's own methods are called, and
String.prototype.normalizefollows Unicode 18.0. Logic still has noWebAssemblyand nothing of Node (process,require,Buffer), in the browser and in the server sandbox. - Native apps without Node. softn-runner answers native app requests with the app's logic in ZIPP compiled to WebAssembly under wasmtime, and the API server needs no Node for them. Each runner and its licences are held to the digests the installed runtime records.
Security and access
- A link in place of a native app's database, or of its data or private folder, is refused (409) before the records view, record management, event dispatch, the backup or an update opens it, and no events are delivered from one. A link left there could otherwise have handed the app's owner another app's records.
- Build tools: zod 4.6.7 (high: memory exhaustion validating oversized collections), fast-uri 3.1.9 and serialize-javascript 7.1.4. All three are build-time only; nothing a server or browser loads changed.
Maintenance
- Dependencies updated: framer-motion 14.6.0, lucide-react 1.61.0, zustand 5.0.16, Vite 8.3.5, typescript-eslint 8.72.0, PostCSS 8.5.31 and PHPStan 2.3.2.
- The server sandbox is built from ZIPP v0.0.32's source with Rust 1.92.0, as before.
- preact stays on its current major: custom screens run on it.
Tested with Softn v0.0.27 and the CLI of OAIY 0.1.10.
Full Changelog: v0.1.12...v0.1.13
FormLogic v0.1.12
FormLogic 0.1.12 moves to Softn v0.0.25 on ZIPP v0.0.29, closes a round of access and billing holes, and takes the pending dependency updates.
Before you update
- PayPal webhook. Subscribe the webhook (
/api/billing/webhook/paypal) toPAYMENT.CAPTURE.COMPLETED,.REFUNDED,.REVERSED,.DECLINEDand.DENIED. Without the refund and reversal events, a refunded payment keeps the time it bought. See DEPLOYMENT.md. - Behind a reverse proxy, set
TRUSTED_PROXY_HEADERto the one header your proxy writes the client address into (x-forwarded-for,x-real-iporclient-ip). Unset keeps the old order of headers, in which a client could choose the address it is limited and logged as; a misspelt value trusts none. IPv6 clients are now rate-limited by their /64, so IPv6 counters start again. - Package exports made before this release carry no record of the account that exported them, so they import as
community(an untrusted screen) even into their own account, andREQUIRE_VERIFIED_PACKAGESrefuses them. Apps already stored as verified stay as they are. Export again from 0.1.12 for a verified round trip. - Members-only native apps start with empty browser storage for each member: what such an app kept in the browser before is not handed to any account. Archived native apps no longer run, for their owner either; draft previews still do. See docs/NATIVE_RUNTIME_SESSION_ISOLATION.md.
What's new
- Softn v0.0.25. The app runtime, Builder and Studio that FormLogic embeds are the v0.0.25 release (from v0.0.19): an app's page may be written as HTML, with every existing
.uiand.logicapp reading as before; an app's styles stay inside the app;softn.net.fetchsends no cookies or referring address, andnetwithoutallowed_hostsno longer reaches this computer or its local network; local AI runs GGUF models on ZIPP; and logic that opens with"use strict"runs strict. See the Softn v0.0.25 notes. - ZIPP v0.0.29. The script engine, in the browser and in the server sandbox, is 6.57 MB (about 1.6 MB with Brotli). An error's stack now counts from the app's own logic.
- Native apps keep each account's data apart. A members-only native app's browser data is kept per installation and account, and an app runs only for the account the server admitted it for: signing out, an expired session or switching accounts clears the departing account's data, and other tabs follow. An app on Softn v0.0.21 or later is told when its writes are stored.
- Offline submissions. A queued submission survives maintenance, waits however long the server cannot be reached, and resumes when the form is reopened; one that failed can be sent again or discarded, and none stays on the device for good. A submission answered by a Wi-Fi sign-in page is no longer taken as sent.
- Python apps keep their client imports and public package declarations when they are imported or edited.
- Dates from the server are read as UTC everywhere, so they show the right time, and Safari shows them at all.
Security and access
- Members: only the owner changes a member with an app-level role, and members no longer see drafts, forms they cannot open, or linked labels they may not read. Files, linked records, exports and app configs are held to what the caller may read.
- Packages: this server's signature is trusted only for the account that exported the package, and an imported pack cannot bring consent or raw link targets with it.
- Billing: a capture whose amount or currency differs from the order is not credited, and turning complimentary access off no longer ends paid months.
- Installer: the database step runs before
.envis written, an installed site's install step cannot replace.envfrom outside the server, an uninstalled site behind a local proxy is not open to every visitor, and a replaced.envis kept as a backup. It can be run again after a failed step. - Sign-in and AI tools: the per-account limit holds for every spelling of an address, "Ask first" holds on the hosted path, scoped tokens stay inside their scope, and revoking a connection ends its grant.
- Outbound requests and flows: the address checks know more reserved ranges, a flow's
Hostheader or line break cannot reroute a request, and the flow key-value store is capped per app. - The server sandbox cannot stall on its child's output, reports itself unavailable when PHP cannot start processes, and
storage/is never served over HTTP.
Maintenance
- Dependencies updated: React 19.3.1, framer-motion 14.3.0, lucide-react 1.59.0, ESLint 10.13.0, typescript-eslint 8.71.2, Vitest 5.0.5, jsdom 30.1.3, Playwright 1.64.1, @axe-core/playwright 4.14.0, PostCSS 8.5.30, uuid 14.0.3, @types/node 24.19.2 and PHPStan 2.3.1.
- Three new DOMPurify advisories, reached through the code editor (Monaco), are fixed with DOMPurify 3.4.17.
- On PHP 8.2, the once-an-hour warning about a client-address setting reads its marker's time from disk (8.2's
touch()left the old time cached). - preact stays on its current major: custom screens run on it.
Tested with Softn v0.0.25 and the CLI of OAIY 0.1.9.
Full Changelog: v0.1.11...v0.1.12