The CARLOS app specification

Version 0.1, draft for comment, 2026-10-26.

This document says what makes an app a CARLOS app. It turns the attributes on carlosframework.com/attributes into rules that the people who build an app, and the people who run it, can check themselves against.

This is a draft. Every app we have built fails some of it today, and we expect the rules to change as more apps are measured against them. Questions we have not settled are listed at the end.

0. How to read this

0.1 Keywords

MUST, MUST NOT, SHOULD, SHOULD NOT and MAY mean what RFC 2119 says they mean. In short: a MUST or MUST NOT is a requirement. A SHOULD or SHOULD NOT may be departed from once you understand the consequences. CARLOS adds one condition: record the departure and its reason in your declaration (0.5). A MAY is a choice.

0.2 Who each rule binds

Each rule is tagged with the parties it binds. One person or company can play more than one part.

A rule tagged with more than one party binds each of them for the part it is responsible for. For example, in 7.4 the platform supplies a way to take an export, and the fleet operator lets tenants use it.

0.3 Terms

0.4 Conformance

An implementer, fleet operator or platform conforms when it:

In version 0.1, conformance is a self-assessment. Publish your declaration and a checklist of the rules with your answer to each. There is no certification.

0.5 The declaration

The declaration is the app's written statement of its design. In version 0.1 it is a section of the app's README or AGENTS.md with these headings, in this order. A machine-readable format will follow in a later version.

CARLOS declaration: <app>, <date>, <who decided>
One instance is:       <the unit> (person : instance = 1:1 | N:1 | 1:N | N:N)
Central apps:          none | <name>: <what it holds>, one per line
Workloads and class:   instance = <S | A1 | A2 | A/pub | B | C>; <other workload> = <class>
Declared residue:      <every plaintext surface>, one per line
Keys live:             <in browsers | in instance memory while awake | n/a>
Personal data:         <kind>: <purpose: required | logging | tracking with consent>; <how long it is kept>, one per line
Third parties:         <who>: <what they receive>, one per line
Dependencies:          <service>: required | optional, one per line
Setup:                 <every step outside the binary>, one per line
Schedules:             <job>: <path>, <cadence or trigger>, <time zone>, <what happens to a missed run>, one per line
Endpoints:             liveness <path>; version <path>
Ephemeral state:       none | <what is lost on a stop, and how clients recover>
Wake budget:           500 ms | <budget>: <reason>
Audit trail:           <what is recorded; who can read it>
Licence:               <SPDX identifier or "proprietary">; licence class L1 to L5
Security contact:      <URL or address>
Departures:            <rule>: <reason>, one per line

A fleet operator chooses some things the implementer cannot know in advance: which processors it uses, how long it keeps logs, which regions it runs in, and which optional features are turned on. It records these in a deployment declaration with the same headings, plus two more:

Regions:               <where data is stored, including replicas, backups and logs>
Features turned on:    <optional features and integrations in use>

It keeps the deployment declaration consistent with the app's. A platform records its own choices, such as its processors, regions, log retention and how much recent data a host failure could lose, in a platform declaration with the same headings, including the two above.


1. Tenant isolation

1.1 [I] An app MUST declare its tenancy boundary: what one instance holds. Examples: one instance per person, per team, per repository, or many-to-many.

1.2 [I] An app SHOULD hold one tenant's content per instance, in that instance's own database.

1.3 [I] If an app holds more than one tenant's content in one instance, it MUST say so in its declaration and MUST enforce the separation in its own code. A request for one tenant's data MUST NOT reveal another tenant's data, or whether it exists.

1.4 [I] An instance MUST NOT read or write another instance's data except through a declared, authenticated interface (10.2).

1.5 [I+F+P] The credentials and keys an instance holds MUST be scoped to that instance. That covers API tokens, sealing keys, storage credentials and mail credentials. The test: a request made with a credential taken from one instance and used against a sibling MUST be refused, for reading, writing and deleting. A credential that can create or delete instances MUST NOT be given to tenant instances.

1.6 [F+P] Backups, replicas, logs and exports MUST keep the tenancy boundary. They MUST be keyed by an instance identifier that is never reused, and authorised per instance. A restore into the same instance MUST check that the data belongs to that instance. Importing an export into a new instance MUST check that the tenant owns the data, and the new instance MUST get new credentials.

1.7 [I] An app MAY have central apps. A central app:

Instances MUST check permissions themselves, not trust a central app's list. If a central app is down, instances SHOULD keep serving people who are already signed in.

2. Trust classes and data security

A trust class says what the host can read inside an instance. These are the classes published at carlosframework.com/trust. A class belongs to a workload, not to a whole product: an end-to-end encrypted app with an automation helper may need two.

Class The host holds
S, stateless No user data at all.
A1, host-blind Ciphertext only. Only the shape of the traffic leaks: who connects when, sizes, timing.
A2, host-blind with declared residue Ciphertext, plus a published list of plaintext metadata.
A/pub, public by design As A1, plus surfaces that are public on purpose, listed one by one.
B, sealed single-tenant Data sealed at rest (database, replicas, files). The running instance holds a key while it is awake, because unattended work needs plaintext.
C, host-sighted Plaintext at rest, chosen and written down. For example, for support visibility, or SQL over personal data.

Classes are ordered S, then A, then B, then C. The A variants are flavours of one grade, not separate grades.

The test for every class is the same: publish the database and see what leaks. An A1 database leaks nothing but its shape. An A2 or A/pub database leaks its declared residue and nothing more. A B database copied while cold leaks nothing. A C database leaks the data, and the declaration said so first.

2.1 [I] Each workload MUST declare a trust class.

2.2 [I] The declaration MUST list every plaintext surface as declared residue. That covers columns, metadata, file names, logs, and data cached on devices. An app SHOULD check this automatically: write a marker through every path that stores data, then search the raw database, its write-ahead log and stored objects for it.

2.3 [I+F] If an operator does not need to see data to run a service, the operator SHOULD NOT have access to it.

2.4 [I] An app MUST NOT claim a class its design does not meet. Its interface, help pages and marketing MUST NOT claim more protection than its declared class. For example, a class B or C app must not say "we can't read your data".

2.5 [F+P] When a person acting for the operator or the platform reads tenant content, the read MUST be recorded with who, when, why and which tenant. That covers support access, admin tools, database downloads, reading logs that hold content, and shell access to a host. Records of reads that go through the platform or the app MUST be visible to the tenant. Automated processing, such as backups and malware scanning, is declared once and is not recorded per read.

2.6 [I+F+P] Data in transit MUST be encrypted. At rest:

2.7 [I] Secrets MUST NOT be compiled into the binary or written to logs. Sign-in links, one-time codes and first-run admin tokens are secrets. A development fallback that writes them to a log MUST refuse to run in production.

2.8 [I] If a required secret, key or dependency is missing, the app MUST refuse to start and say what is missing. It MUST NOT fall back to an insecure default.

2.9 [F+P] An operator MUST run each workload so that it keeps its declared class. It MUST NOT add plaintext surfaces the class does not allow, such as logging request bodies or keeping unsealed copies.

This section separates logging from tracking. Logging is how an app learns whether it works and what people use. It is fine and needs no consent. Tracking follows a person. It needs their consent, and it should be rare. What this section is against is tracking that takes as much as it can, follows people around and interrupts them to get consent. That kind of tracking is a large part of how products get worse for the people who use them.

Terms

Two things are not tracking. Staying signed in is not tracking. An identifier kept only for a declared operational, security, billing or audit purpose, and used only for that purpose, is logging. Using it for anything else makes it tracking.

Logging becomes tracking when it is tied to a person to build a profile, joined with data from other apps or sites, given to a third party for that party's own purposes, or kept longer than its purpose needs.

Data

3.1 [I+F] An app MUST NOT store personal data or tenant content unless it is required, is logging that meets 3.4 to 3.9, or is tracking that the person has agreed to under 3.10 to 3.14.

3.2 [I] The declaration MUST list every kind of personal data the app stores, including data in logs and data about people who are not tenants, why it is held, and how long it is kept. Data SHOULD be deleted when the reason for keeping it ends (16.3).

3.3 [I+F] The declaration MUST list every third party that receives data about a person, and what it receives. That includes processors that handle data only on the app's behalf, such as log storage, email delivery and push notification services. A fleet operator lists the processors it chooses in its deployment declaration.

Logging

3.4 [I+F+P] An app or operator MAY log to run, secure and improve the service without asking for consent.

3.5 [I+F] Logs SHOULD hold only the identifiers their purpose needs. For example, a log may keep an account id to help with a support case. Identifiers SHOULD be dropped, or the data aggregated, as soon as the purpose allows.

3.6 [I+F] Analytics SHOULD collect the least data that answers the question. Counts are better than profiles. Data kept by the app is better than data sent to a third party. Short retention is better than long.

3.7 [I+F+P] Using log data to build a profile of a person, joining it with data from other apps or sites, or giving it to a third party for that party's own purposes, is tracking. It MUST NOT happen without the person's consent under 3.11 to 3.14.

3.8 [I] An implementer SHOULD decide what the app needs to log and what it needs to be able to audit, and write both in the declaration. An audit trail records who did what to which data, and when. How much an app needs depends on what it does: an app that handles money, ownership or health records needs a full audit trail, and a static site may need almost none. The tenant SHOULD be able to read the audit trail for their own instance.

3.9 [I+F+P] Logs and audit trails SHOULD be stored in a protected place:

A platform SHOULD offer an append-only place to send logs, and an app MAY send its logs there.

Tracking

3.10 [I+F] An app SHOULD NOT track anything that is not required.

3.11 [I+F+P] Any tracking MUST have the person's explicit consent. That means they take an action that agrees to that tracking. A box that is already ticked does not count. Neither does continuing to use the app, nor consent hidden in a list of terms or vendors.

3.12 [I+F+P] Consent MUST be asked for at the point it is needed, for one purpose at a time. It MUST NOT be gathered up front in one sweeping question, at sign-up or on the first visit.

3.13 [I+F+P] Saying no MUST NOT make anything worse that does not depend on the tracking.

3.14 [I+F+P] Withdrawing consent MUST be as easy as giving it, and MUST stop the tracking.

Operators

3.15 [F+P] An operator MUST NOT add tracking to an instance unless the tenant turns it on. Once the tenant has turned it on, the operator can offer it. Tracking MUST NOT start for any person until that person has agreed under 3.11 and 3.12. Analytics that meet the logging rules need no per-person consent.

4. The user's attention

4.1 [I] An app SHOULD NOT interrupt a person on a critical path. A critical path is the steps from starting a task to finishing it: signing up, signing in, paying, saving work, recovering from an error. Pop-ups, surveys, upsells, newsletter prompts and tours all wait until the task is done.

4.2 [I] A consent question that a step itself needs (3.12) is part of that step, not an interruption. Any other question waits.

4.3 [I] A person SHOULD be able to turn off each kind of message the app sends them. Messages about their account's security are the exception.

4.4 [I] An app that sends messages people sign up for, such as mailing lists and newsletters, MUST record each person's consent with the wording they saw, MUST check it when each message is sent, not when it is queued, and MUST let people leave with one click.

5. Security

5.1 [I] An app SHOULD check its dependencies for known vulnerabilities and its code for leaked secrets on every change. For Go, govulncheck and gitleaks are examples.

5.2 [I] An implementer MUST publish a way to report security problems, for example a /.well-known/security.txt file (RFC 9116), and SHOULD say how fast they respond. One policy MAY cover a family of apps.

5.3 [F+P] The platform MUST be able to patch the platform and its hosts without tenant action. The fleet operator MUST be able to move every instance to a patched release of the app. A tenant's choice to stay on an older release MUST NOT stop the operator applying a security fix, though the operator SHOULD give notice.

5.4 [I] A web app SHOULD send security headers, including a content security policy that allows no inline scripts, and MUST protect requests that change state against cross-site request forgery.

5.5 [I] An app that fetches addresses supplied by users or outsiders MUST refuse to fetch private, loopback and internal addresses.

6. Full-stack units

The rules in this section apply to server workloads. Native apps are covered in section 18.

6.1 [I] An instance MUST run from one binary, containing its own database, web server, background jobs, HTML, CSS and JavaScript. It SHOULD run as one process. Any helper process MUST be declared as a workload with its own trust class. Large files MAY live in an object store the operator provides, and the app SHOULD also work with a local directory instead.

6.2 [I] Static assets MUST be built into the binary.

6.3 [I] Every external service an app depends on, such as email, object storage or an inference API, MUST be listed in the declaration as required or optional. When an optional one is missing, the app SHOULD start and serve the parts that do not need it. When a required one is missing, 2.8 applies.

6.4 [I] An app MUST be configurable through flags and environment variables, and every required value MUST be something a person can supply without depending on any one platform. Every setup step outside the binary, such as secrets, schedules and registering with a third party, MUST be listed in the declaration. The app's own setup, such as generating its keys and its first admin, SHOULD need nothing but the binary.

7. Self-hosting and portability

7.1 [I] Self-hosting MUST be first class. The binary a fleet operator runs MUST run on any platform that meets this spec, and MUST NOT refuse to start away from a particular one. Unless the app's licence class is L4 (hosted only), the same binary MUST be available for others to run themselves. Platform services an app relies on, such as scheduled wake-ups, email and secret storage, MUST have documented contracts that someone hosting it themselves can meet.

7.2 [I] A feature MUST NOT depend on only one infrastructure provider for compute, storage, email, DNS or key management. A provider's feature MUST sit behind an interface with a provider-neutral alternative. A service that is the app's purpose, such as the payments provider behind a payments dashboard, is exempt, and is listed in the declaration.

7.3 [I] A tenant MUST be able to export everything they own, including content, files, settings and membership, in a documented format that can be read without the operator's secrets. A tenant SHOULD be able to start a new instance from that export. Other tenants' data cached in the instance, and the instance's signing keys, are not part of it. For class A apps, the export MAY be made in the person's client, where the keys are.

7.4 [F+P] The platform MUST provide a way to export an instance's database and files, to someone authorised over all of that instance's data. The fleet operator MUST let tenants take their export (7.3) without waiting for a person to approve it.

7.5 [I] Server binaries MUST build without cgo for Linux on amd64 and arm64. They MAY also build for macOS and Windows.

8. Hibernation and wake

8.1 [I] An instance MUST survive being stopped at any moment without losing data it has acknowledged. [F+P] For the loss of a whole host, the operator MUST publish how much recent data could be lost.

8.2 [I] Durable state MUST NOT depend on memory surviving a stop. Ephemeral state MAY be lost on a stop if the declaration lists it and clients recover. Examples: who is online, a live call, a per-boot key, a secret shown only once that can be issued again.

8.3 [I+F+P] The request that wakes a sleeping instance SHOULD be answered within 500 ms, so that waking is hard to tell apart from a regular request. The time runs from the request reaching the operator's entry point to the first byte of the response, including start-up, and the target is at least 95 of every 100 waking requests over a stated period. An app MAY declare a larger wake budget, and its reason, such as decrypting or rebuilding state at start. A declared budget replaces the 500 ms target for that app. Work done at start SHOULD be bounded, or cached between starts.

8.4 [I] Scheduled work MUST be declared: the path the operator calls, how it is authorised, its cadence or trigger, its time zone, and what happens to a run that was missed. Wake-ups an app asks for at runtime are declared by kind. A long job MUST either resume after a wake or show that it was interrupted and can be restarted. A recurring schedule SHOULD NOT run more often than the operator's idle period without a declared reason, since it keeps the instance awake.

8.5 [F+P] An operator SHOULD hibernate idle instances, and MUST wake them for a request or a declared schedule. An app MAY declare that a workload must never hibernate, with its reason, and the operator MUST honour that.

9. Scale and placement

9.1 [I] Growth MUST be horizontal: adding tenants adds instances at the declared tenancy boundary (1.1). Tenant content MUST NOT live in a database that several instances share.

9.2 [I] An instance SHOULD be movable between hosts and regions with no code change. If its keys or passkeys are bound to its web address, the declaration MUST say so, and [F] the operator MUST keep that address when it moves.

9.3 [F+P] An operator MUST tell each tenant which regions hold their data, including replicas, backups and logs. Before moving a tenant's data to another region on its own initiative, it MUST tell the tenant and record the move.

9.4 [I] An app MAY run read replicas at the edge. If it does, its declaration MUST say which data can be stale and for how long.

10. Decentralisation

10.1 [I] An instance SHOULD serve requests without calling a central app or a control plane. Starting a new sign-in MAY depend on a declared identity provider. Sessions that already exist SHOULD keep working while it is down.

10.2 [I] Features that span instances, such as sharing, MUST go through explicit, authenticated interfaces between instances, not shared storage. An identity assertion passed between apps MUST be signed, addressed to one app and instance, usable once, and short-lived.

10.3 [P] Instances SHOULD keep serving when the platform's control plane is down.

11. APIs, CLIs and agents

11.1 [I] Everything a person can do in the interface SHOULD be possible through an API or agent tools with typed inputs and outputs. Sign-in ceremonies such as enrolling a passkey are the exception.

11.2 [I] An app's admin and operator tasks SHOULD be commands in the same binary.

11.3 [I] If an app has an API, each credential MUST belong to one person, device or agent, and MUST be revocable on its own. A server MUST store only a hash of the bearer credentials it checks. A client MUST keep the credentials it holds in the operating system's credential store or an equivalent protected place. A capability URL, such as a calendar feed link, is a credential. Credentials SHOULD be limited to what they are for.

11.4 [I] API and command output SHOULD be machine-readable on request, and error responses SHOULD carry stable codes an agent can act on.

11.5 [I] An agent MUST act as itself. What an agent does MUST be recorded as the agent's action, on behalf of the person who runs it, never as the person's action alone.

12. Development and build

12.1 [I] Server workloads MUST be written in a compiled language and build to one binary. Engines embedded in that binary, such as WebAssembly modules, are allowed. Native apps use the languages of their operating system.

12.2 [I] A release MUST be buildable again from its source, its lockfile, a documented toolchain version and a documented build procedure. A rebuilt release MUST behave the same on the same platform, and SHOULD be identical byte for byte. A release MUST carry a version that identifies a single build. A placeholder such as "dev", or a build with uncommitted changes, does not count.

12.3 [I] An app SHOULD run its tests on every change. It SHOULD state how long the suite takes and on what machine, and keep it fast enough to run on every change.

12.4 [I] Several versions of an app SHOULD run side by side on one machine. Ports and data directories MUST be configurable, and the default listening address SHOULD be the loopback address.

12.5 [I] Pages SHOULD be rendered on the server and work with scripts turned off. JavaScript SHOULD add to a working page rather than be needed to draw it. Views of class A content, which can only be decrypted in the browser, are exempt.

13. Performance and efficiency

Speed is a feature, and people feel it before they can name it. These are targets for what a person experiences. Server times are measured at the server, on the operator's real hardware. Native app times are measured on the devices the app supports.

13.1 [I+F+P] A GET request SHOULD be answered in 150 ms or less, from the server receiving it to the server sending the first byte of the response, for at least 95 of every 100 requests. Requests that wake an instance are measured under 8.3 instead.

13.2 [I+P] The app or the platform SHOULD report server timings with each response, for example in a Server-Timing header, so that 8.3 and 13.1 can be checked from outside.

13.3 [I] An action a person takes within a page, in a web app or a native app, SHOULD look like it is doing something, even when it is instant.

A form that loads a new page counts as visible progress, because the browser shows it.

13.4 [I] Every action in a native app SHOULD respond near-instantly. The app SHOULD show the action's effect, or show that it has started, within 100 ms of the tap, click or key press. Work that takes longer runs in the background, and the interface never freezes while it does.

13.5 [I] An idle instance SHOULD be able to hibernate: no timers that keep it awake or need it awake, outside its declared schedules.

13.6 [I] An implementer SHOULD publish the instance's typical memory use and request throughput, with the hardware, data size, workload and concurrency used to measure them.

14. Upgrades

14.1 [I] Each release MUST identify the earlier releases it can upgrade from, and MUST migrate their data without manual steps.

14.2 [I] An instance MUST report its version through a documented, machine-readable endpoint.

14.3 [I] Migrations SHOULD leave data readable by the previous release, so an operator can roll back. Each release MUST state which earlier releases it can roll back to, or say "none".

15. Observability

15.1 [I] An instance MUST answer a liveness check, such as /healthz, without authentication and without returning any data. The declaration MUST name its path and what a healthy answer looks like. Deeper health checks MAY exist, and MUST be authenticated.

15.2 [I] An instance SHOULD log in a structured format, such as logfmt or JSON. It MUST NOT log tenant content unless its trust class is C and its declaration says so. What logs may hold about people, and how they are kept, is in 3.4 to 3.9.

16. Deletion

16.1 [I+F+P] A tenant MUST be able to destroy their data, and MUST be told when it is done. Destroying a whole instance MUST be limited to someone authorised over all of its data. Destroying an instance is different from retiring it while keeping its data, and the interface MUST make clear which is happening.

16.2 [F+P] The operator MUST remove destroyed data within a published period, whether a whole instance was destroyed or one tenant's data within a shared instance. That covers backups, replicas, old object versions, snapshots, logs and what central apps hold about the tenant. Destroying the only copy of the key that seals data counts as removing it. Audit records listed in the declaration MAY be kept for their declared period, but MUST hold no tenant content: only who did what, and when.

16.3 [I] People MUST be able to delete the items they own inside an instance. Deleted items, their history and rows marked as deleted MUST be purged within the retention period the declaration states.

16.4 [I+F] A person who is not a tenant, such as a guest or someone who booked a slot, MUST have a way to have their data deleted.

17. Accessibility

17.1 [I] Web interfaces SHOULD conform to WCAG 2.2 Level AA, for full pages and complete processes. Native interfaces SHOULD meet the same success criteria as they apply to native software (WCAG2ICT).

17.2 [I] An app SHOULD run automated accessibility checks that a change must pass before it is accepted.

17.3 [I] An implementer MUST NOT claim conformance without a manual audit. The audit record MUST name the release, the pages and processes covered, and any failures left unresolved. Saying an app is built to meet a level is a goal, not a claim of conformance.

18. Web and native apps

A web app and a native app are each good at different things. A web app that imitates a native app, or a native app that is a web page in a frame, is worse than the real thing on both counts. So each kind of app should be the best version of itself.

18.1 [I] A web app SHOULD behave like the web. Every page has a URL that can be shared, bookmarked and opened in a new tab. The back and forward buttons work. Links are links. Text can be selected and copied. Browser zoom, find in page, autofill and password managers all work.

18.2 [I] A web app SHOULD NOT pretend to be a native app. That means no imitation of an operating system's title bars or window controls, and no taking over scrolling or the back button. Standard HTML controls, which browsers draw in the system's style, are fine. Being installable from the browser is fine. Looking like another platform's app is not.

18.3 [I] A native app SHOULD NOT be a web app in a wrapper, such as a web view that shows the app's own web pages. A native app MAY use a web view for web content it links to, such as help pages or a sign-in page an identity provider requires, and for user-supplied content that runs in a sandbox.

18.4 [I] A native app SHOULD follow the culture, idioms and conventions of its operating system. That covers the system's interface guidelines, standard controls, menus, keyboard shortcuts and gestures. It also covers settings, files, sharing and notifications, and the user's choices of text size, dark mode and accessibility features.

18.5 [I] An app on more than one operating system SHOULD feel at home on each, rather than look the same everywhere. Sharing code, wording and behaviour underneath is fine. One interface for every platform is not the goal.

18.6 [I] If an app has both a web app and native apps, they SHOULD use the same API (11.1), so neither is treated as secondary.

18.7 [I] A native app SHOULD let the person choose which instance it connects to, so it works with self-hosted instances too.

19. Internationalisation

19.1 [I] User-facing text MUST be kept in a message catalogue, keyed by identifier with one catalogue per language, from the first release.

19.2 [I] Dates, numbers and currencies MUST be formatted with locale-aware functions, for the person's locale or the instance's. Timestamps meant for technical readers MAY use ISO 8601.

19.3 [I] An app SHOULD support right-to-left languages.

20. Customisation

20.1 [I] An app SHOULD let each instance be configured without changing its source code.

20.2 [I] Customisations made through the app's documented settings and extension points MUST survive an upgrade.

21. Openness

21.1 [I] An app MUST declare its licence and its licence class:

Class Meaning
L1 Libre: an open source licence, with no hosted offering from the implementer.
L2 Source available, with commercial terms.
L3 Open source, with a hosted offering.
L4 Closed source, hosted only.
L5 Closed source, hosted and installed on the customer's own machines.

21.2 [I] An app's data formats SHOULD be documented, whatever its licence.

21.3 [I] An app MUST ship the licence notices of the third-party code, fonts and assets it includes.

21.4 (Not a rule.) CARLOS encourages open source. An app does not have to be open source to conform.


Appendix A: Questions for comment

  1. What machine-readable format should replace the version 0.1 declaration, and should platforms read it?
  2. Should conformance have levels rather than one line?
  3. What reference hardware should 13.6 figures use?
  4. Should 18.3 (no wrapped web apps) be a MUST NOT? One way to put it: an app that wraps a web app is a web app, and is judged as one.
  5. Do cross-platform toolkits count as native under section 18? The definition says yes if they draw the system's own controls, which only some of them do.
  6. Is a per-account usage log, kept for billing or support, logging as written in section 3, or does it need its own rule?
  7. Which rules should carry an automated check, so conformance can be measured by a tool?

Appendix B: The attributes, and where they are covered

Some attributes on the attributes page describe how CARLOS is built rather than something an app can be checked against: agent-aware development, token efficiency, faster iteration and rapid prototyping. They stay on that page. The rest map to rules here:

Attribute Sections
Isolated data per tenant 1, 9
Multiple trust classes, encryption encouraged 2
Continuous security monitoring 5
Full-stack units 6
Self-hostable, easier to distribute 7
Hibernation and fast wake 8, 13
Multi-region, massively scalable 9
Decentralisable 1.7, 10
API-driveable apps 11
Compiled languages, CI coverage 12
Speed as a default, cost and performance 13
Audit-ready accessibility 17
Internationalisation and localisation 19
Customisability 20
Open source 21.4