Orbit
English
Sign in
← All release notes
2026.07.217 min read

Orbit 2026.07.2: Receipts, consequences, and other things we previously called “done”

Orbit 2026.07.1 was about control without guesswork. This release is about what happens after somebody presses the control.

dashboardautomodcdnmodulesanalytics

Does the deletion actually delete anything? Did the background job finish, or did the API merely accept its existence? Where did the current plan come from? What exactly was included when it was assigned? Can Support investigate a broken request without asking the user to photograph their browser console? Is an AI model ready for release because it passed its checks, or because the evaluation process managed not to fall over? Orbit can now answer considerably more of those questions. This is progress, although it does raise some uncomfortable questions about what we believed the answers were before.

We taught storage that files continue existing after the database stops mentioning them

Orbit storage has acquired a lifecycle. Previously, the system could tell you that a file had been uploaded and how large it was. What happened after that was largely a private matter between the database, the CDN, and whichever developer was unlucky enough to investigate the difference between them. The new storage workspace shows both logical file size and the physical space currently being consumed. It can search and filter managed files, distinguish normal files from compressed files and pending deletions, display current plan capacity, and show the state of active compression or deletion jobs. Downloads now pass through an authorized route rather than treating possession of an upload ID as proof of ownership, which was a wonderfully optimistic interpretation of access control. Deletion is no longer immediate. A deletion request records who requested it and schedules the operation for the next guild-local deletion window. Until that time arrives, the request can be cancelled. This means an administrator who clicks Delete and immediately remembers why the file was important now has a recovery path that does not begin with opening a support ticket and carefully avoiding the phrase “I thought the confirmation dialog was decorative.” Once the deletion window is reached, a worker rebuilds the active storage layout without the affected files, updates the database transactionally, marks dependent attachment mirrors appropriately, and only then removes obsolete objects. The dashboard differentiates between a deletion being scheduled and a deletion being completed. This distinction sounds obvious now that it is written down.

text
Delete requested
      ↓
Deletion scheduled
      ↓
Cancellation still possible
      ↓
Worker rebuilds active storage
      ↓
Database switches to new layout
      ↓
Old objects are removed

Compression uses private Brotli bundles targeting roughly 32 MiB. Every bundle records its compressed size, original size, SHA-256 digest, file count, state, and lifecycle timestamps. Each contained file keeps its own offset, length, and digest, so extracting a file does not rely on the highly technical verification method of “the bytes looked about right.” The worker verifies direct objects before packing them, uploads the new bundles, switches references under a guild-specific advisory lock, and removes newly created bundles again if the transition fails. Invalid offsets and digest mismatches now produce explicit failures instead of returning a handcrafted collage of neighbouring file contents.

Jobs now persist their state, progress, attempts, scheduled time, start time, completion time, and sanitized failure information. Work left running by a dead worker is recovered after thirty minutes. Failed jobs retry with bounded delays and eventually become visibly failed, rather than retrying forever with the confidence of a process that has never personally read its own exception.

Plans now provide something more substantial than a badge and a feeling

The guild plan page has been rebuilt around a fairly radical question:

What would an administrator actually want to know about their plan?

Us

The answer turned out to be more than its name. The current plan view now explains where access came from, when the term began, when it ends, whether it renews, whether it is permanent, when commerce was last synchronized, and how much time remains. It also shows the included features, included modules, active limits, current usage, and available capacity. Permanent access now says that it is permanent. It is no longer represented by an empty expiration date that could mean “forever,” “unknown,” or “somebody forgot to write this field.” Usage limits show the measured amount, remaining capacity, total allowance, and utilization percentage. Byte limits are displayed as storage values, while count-based limits remain counts. Unlimited values appear as unlimited instead of a number large enough to make everybody uncomfortable but not large enough to be technically infinite. The page also presents upgrade offers when they are genuinely relevant. An offer must be available, purchasable, inactive, and connected to a real purchase destination before Orbit recommends it. We decided not to advertise plans the guild already owns, despite compelling evidence that this is an established commercial strategy. The larger change is immutable plan history. Discord entitlements and subscriptions are mutable external state. Orbit now projects that state into stable historical records describing what was actually granted. Administrative plan assignments are recorded too. Each entry stores the plan name, description, source, source reference, term, status, metadata, comment, and a snapshot of the included features, modules, limits, and visual presentation. Changing a plan definition next month therefore does not quietly rewrite what last month’s assignment contained. The old record remains the old record, which is useful both for support and for anybody attempting to remember what they sold before the plan editor was “cleaned up.” Every historical entry can be downloaded as an English or German PDF. These documents are generated directly by Orbit and require valid access to the guild. They use private, non-cached responses and sanitized filenames.

Module administration is no longer an escape room

Casino, Party Hub, Quest Board, and Suggestions already contained substantial functionality. Operating them from the dashboard was considerably less substantial. Several administrative tasks effectively required finding the correct record ID, copying it into the correct command, remembering which action accepted which identifier, and trusting that the resulting message meant what it appeared to mean. This was technically usable in the same way that editing production data directly in a terminal is technically a user interface. Runtime modules can now declare proper control centers in their manifests. These control centers expose meaningful metrics, paginated records, recent administrative jobs, typed action forms, confirmation requirements, and localized labels. Actions are validated by the API and queued through declared module jobs, after which the dashboard refreshes the job and record state. A browser request no longer waits for a module worker to finish a complicated operation while the entire system pretends that distributed background processing is synchronous. Casino received a general control center and a dedicated manager workspace. Authorized administrators can inspect accounts, ledger entries, active sessions, Hold’em tables, achievements, and seasons. They can apply audited balance corrections, temporarily lock an account, invalidate a session, optionally refund its stake, or close a table and return player buy-ins. Sensitive actions require a reason. The system cannot prevent the reason from being “Kevin deserved it,” but it can ensure that this explanation remains attached to the audit trail for future generations. Casino also gained configurable payout margins. These margins reduce winnings above the returned stake without altering the committed random result. Commit-and-reveal evidence remains intact. Administrators can configure the economy, but they cannot look at the result and retroactively negotiate with mathematics.

Party Hub can now review community-submitted questions, schedule games in specific channels at specific times, and close stuck sessions. Its Predictions workspace can create, resolve, or cancel predictions, including multiple winning answers and one-time point awards. The phrase “one-time” is important. Reward systems become considerably less engaging when pressing Resolve twice creates inflation. Quest Board can publish or refresh its live board and run a safe season-rollover check. The check only closes a season when its configured duration has elapsed. It is therefore not a large red “erase everybody’s progress because I was curious” button, which is generally considered an improvement. Suggestions now exposes its complete workflow through the dashboard. Staff can change statuses, add public notes, edit submissions, publish staff comments, merge duplicates while preserving unique votes, refresh the roadmap, and inspect the complete audit history. Duplicate merging requires confirmation because moving community votes between records deserves more ceremony than selecting a different value from a dropdown.

Custom Commands became custom enough to justify the name

Custom Commands has reached version 2.0.0. This is unrelated to Runtime API v2. Both use the number two because our naming process remains an unsupervised environment. Configured slash commands can now be published directly instead of being forced below a fixed /custom command. A guild may create commands such as /apply, /rules, /event, or /report, and Orbit projects those configured definitions into Discord. The previous system called them Custom Commands while requiring every command to publicly identify itself as a child of /custom. The feature was technically telling the truth, but only after a lengthy explanation. Commands can define typed string, user, number, boolean, channel, and role options. Prefix commands understand positional arguments and quoted values. Slash-command input becomes available through placeholders such as {option.reason} or {option.member}. More importantly, commands can now use visual behavior trees. A behavior may reply, send a message to another channel, evaluate a condition, set a variable, select between then and else branches, or stop processing. Conditions cover equality, containment, string prefixes and suffixes, numeric comparisons, existence checks, and optional case sensitivity. A command can now express logic resembling this:

text
IF {option.topic} contains "security"
    SET {variable.queue} = "Safety"
    SEND TO #staff-queue
        New {variable.queue} request from {user}
        Reason: {option.reason}
    REPLY
        Your request has been forwarded.
ELSE
    REPLY
        Please select a supported topic.
STOP

The actual editor is visual, which reduces the probability that one missing quote reroutes every support request into the announcements channel. Existing single-response commands remain compatible. Behavior depth and node counts are bounded, message lengths respect Discord limits, variable names are restricted, and no arbitrary JavaScript can be executed. Custom Commands is more programmable. It is not a code-hosting platform disguised as a text field, because we would prefer not to release Orbit 2026.07.3 under the title “An apology from the security team.”

Feedback reports now bring evidence instead of homework

Users can continue submitting normal feedback without attaching diagnostics. When they explicitly choose to include diagnostics, Orbit can now capture a bounded and redacted snapshot of what the browser already knew. That snapshot may include the route, operation, diagnostic class, query states, request timings, stalled or slow operations, recent safe interface actions, navigation events, network status codes, request IDs, bounded request and response metadata, JavaScript errors, stack traces, environment information, performance data, connectivity state, and dirty-editor count. Sensitive routes are excluded from body capture. Feedback and telemetry endpoints are not recorded recursively. Headers, URLs, and structured values pass through the shared redaction layer before persistence. Uploaded files are represented by metadata such as filename, type, and size, not by their contents. This replaces a significant portion of the previous diagnostic process:

text
Please open Developer Tools.
Now reproduce the issue.
Now find the failed request.
No, the other failed request.
Open Response.
Remove anything private.
Send us a screenshot.
Not that screenshot.

Signed-in users now have a personal support-history workspace showing their own cases, status, subject, latest update, and any response available to them. They cannot view the internal feedback inbox, staff notes, other users’ cases, or administrative diagnostics. The System Team inbox received the deeper investigation tools. Reports are clustered by fingerprint so repeated failures appear as one incident with multiple occurrences rather than several independent opportunities to recommend clearing the browser cache. Staff can inspect stack traces, network requests, query evidence, diagnostic timelines, environment details, related reports, and Sentry references. Authorized team members can update the report status and add internal notes. A report saying “it stopped working” can now arrive beside evidence showing exactly what stopped, where it stopped, and how long it spent considering whether to stop.

AutoMod AI now needs evidence before it is allowed near users

The user-facing AutoMod model workflow remains intentionally limited. Guild administrators can select an already released model, configure their guild’s moderation policy, choose supported categories, define review and block behavior, inspect decisions, and submit optional feedback. They cannot upload training data, start training, modify examples, run evaluations, tune global model behavior, configure reviewers, approve snapshots, or publish releases. There is no guild-facing Train AI button. This is deliberate. A server administrator should not be able to upload fourteen thousand memes, label half of them as malware, and release CommunitySafety_Final_v3 before lunch. The user-visible improvement is that released models now pass a stronger internal process before becoming selectable. A release state means more than “the evaluation worker exited successfully.” Behind the scenes, the System Team now maintains a reproducible German and English corpus containing 64,988 examples. The release combines privacy-safe adaptations of public research sources with Orbit-authored community-style cases, hard negatives, replies, OCR-style text, and category boundary cases. The pipeline rejects secrets, invalid masked identities, unsafe sexual content involving young people, malformed data, and cross-split leakage. Identity-like values are replaced with reserved test data, public-source provenance remains recorded, and third-party image bytes are not bundled. Self-harm help-seeking remains reviewable rather than automatically punitive. A moderation model should not respond to somebody asking for help by deciding that the primary problem is policy compliance. Evaluation completion and release approval are now separate states. A successful evaluation means the evaluation finished. It does not automatically mean the model is accurate, calibrated, reliable on severe cases, safe on hard negatives, complete across categories, or ready for release. Golden validation now records explicit gates for non-zero behavior, verdict accuracy, category F1, category coverage, hard-negative false positives, severe-content coverage, severe-content recall, calibration, and reviewer availability. The System Team dashboard shows those gates individually. A green job label is no longer permitted to stand close enough to a release button that somebody mistakes them for the same thing. Internal evaluations may also produce bounded tuning recommendations through policy grids, calibration search, threshold refinement, category-specific optimization, and abstention search. Test-split recommendations remain diagnostic. Only validation-based batch evaluations may apply tuning, and applying a recommendation invalidates the previous Golden result because the effective model configuration changed. Tuning can improve how scores are interpreted. It cannot transform a weak classifier into a strong classifier by lowering the standard until the dashboard turns green. We already have project-management tools capable of that. Reviewer models must be separate, released, active, available Orbit-local models with valid bundles. A model cannot review itself, agree with itself, and record the process as independent oversight. We are considering applying this rule to meetings.

Core Tool defaults are now policy instead of oral tradition

Core Tool defaults can now be managed centrally with a stored default value, guild-toggleability, revision, reason, updating administrator, and timestamp. Newly provisioned guilds begin with most automation features intentionally opt-in. Existing guilds keep their previous behavior through explicit local overrides created by the migration. This gave us safer defaults without disabling every existing welcome message, moderation setup, logging configuration, and leveling system during deployment. That outcome required more work than simply declaring the migration “breaking,” which is why it deserves recognition. Guild managers can only change a Core Tool when the resolved policy says it is locally toggleable and no stronger authority owns the result. A disabled switch can no longer negotiate with platform policy by being clicked several times. System Moderators may create temporary guild-scoped overrides, but those overrides require both a reason and an expiry time. The word temporary is therefore enforced by a date instead of an internal comment reading “remember to remove this later.”

Seeing a page no longer implies ownership of everything on it

Several platform permissions now distinguish inspection from mutation. System Support remains read-only across guild administration, forms, feedback, and support cases. System-wide guild and health mutations are reserved for System Administration. Moderation handoffs use separate permissions for inspecting and editing. Workflows derive their required permissions from the actions they actually perform, and forms that modify Discord roles require real Discord authority.

Several quiet fixes reduce the number of spectacular future incidents

Configured CORS values are now normalized as URL origins. A harmless trailing slash or path no longer makes the dashboard appear to come from a completely different dimension, while unrelated origins remain rejected. We previously had punctuation-sensitive network security. It was very precise, just not in a useful way. The public readiness endpoint now exposes only status and check time. Internal dependency details remain inside authenticated operational views. A load balancer needs to know whether the service is ready. It does not need a complimentary infrastructure tour. Missing dashboard access policy state now fails closed. A deleted singleton row no longer becomes accidental permission to reopen login and registration. Configuration drift is treated as drift rather than consent. Globally disabled modules cannot be restarted or reloaded through weaker controls. Starting and stopping a module also updates the registry state so the platform and runtime stop presenting two incompatible versions of reality. Disabled, archived, or Trust and Safety restricted public forms now become unavailable at the inspection boundary as well as the submission boundary. Previously, a blocked form could remain visible enough to advertise that something had been blocked, which was neither private nor especially useful. Telemetry URLs remove embedded user credentials, and sensitive workspace credentials are excluded from request logging. These are improvements whose ideal user experience is that nobody ever notices them.

Module execution stopped downloading itself during commands

Versioned module artifacts are now prepared during installation or resynchronization. Live Discord commands resolve an already materialized local artifact instead of opening a CDN connection, downloading the package, verifying it, unpacking it, writing it to disk, and politely asking Discord’s interaction timeout not to take any of this personally. Artifacts are checked against expected sizes and digests, cryptographically unpacked, written with restricted permissions, cached locally, and stored in shared memory when available. When preparation has not finished, Orbit returns a controlled temporary-unavailable state. This is less exciting than allowing a user interaction to become an impromptu deployment pipeline, but substantially more reliable. Artifact providers and signing configuration are also initialized lazily. Deployments that keep the versioned-artifact feature disabled no longer need unused artifact credentials merely to start. We had previously implemented an optional feature whose missing optional configuration could crash every process. This was a very persuasive feature-adoption strategy. Module runners now track load and unload state, pending invocations, timeouts, process availability, and controlled shutdown. If a runner exits, pending work is rejected and contained. A broken module can still be broken, but it has less authority to turn that into a platform-wide group activity. First-party publishing can reuse an existing artifact only after verifying its plaintext digest, encrypted package digest, source digest, object sizes, and the continued existence of both stored objects. If verification fails, Orbit rebuilds. If verification passes, Orbit avoids compiling and uploading the same bytes again merely because watching CI move feels productive. Rebuilding verified identical artifacts is not extra safety. It is expensive nostalgia.

Known limitations, because confidence should have boundaries too

Storage lifecycle work is asynchronous and may take time on large guilds. A repeatedly failing job eventually requires operator attention rather than a fifth increasingly optimistic retry. Compression reduces physical storage usage, not the original logical size of each file. Scheduled deletion is reversible only until the worker processes it. Plan history can reconstruct information that still exists in Orbit or Discord state. It cannot recover metadata that was never recorded, no matter how meaningful the administrator’s expression is while asking. Plan PDFs document Orbit’s records and are not payment-provider tax documents. Dynamic Custom Commands remain subject to Discord’s naming, registration, and option limits. Behavior trees are intentionally bounded and cannot execute arbitrary code. Module control centers can only expose actions declared by the module. A queued action is not an instant action, regardless of how satisfying the button animation was. Diagnostic reports are bounded and redacted. They are not unrestricted browser archives. Guild administrators may only select released AutoMod models. Training, datasets, evaluation, tuning, reviewer configuration, and release approval remain System Team-only. The Runtime v2 engagement modules remain disabled until explicitly installed and enabled. We have resisted the temptation to solve adoption by silently activating Casino everywhere.

Orbit 2026.07.1 established that a disabled switch should be disabled, a saved field should be saved, and a spinner should eventually explain itself. Orbit 2026.07.2 adds that a deletion needs a lifecycle, a purchase needs evidence, a background job needs an honest status, and an AI release needs slightly more peer review than asking itself whether it did a good job.

Orbit System