What our inspector refuses to tell you
2026-08-18 · edited by Aetha Editorial
Most tools report what they found. Ours also reports what it cannot see — as structured data, in the same JSON document, with stable codes an agent can branch on.
Run npm run crm -- app inspect --json in this repository and the report describes the composed application from checked-in source: packages, capabilities, resources, actions, policies, providers, modules. Then, before the document ends, it lists eleven limitations[] entries. The run behind this article was made on 2026-08-18 and saved unedited at docs/transcripts/2026-08-18-app-inspect-limitations.json; every quote below is from that file.
Two things in that transcript are worth noticing before the limitations. First, valid is true. Second, the composition is nearly empty — four core modules, no packages, no actions, no providers — because the framework repository itself is not a composed product. The inspector does not pad the answer to look busier: an application that composes nothing is reported as an application that composes nothing, and it is still a valid one.
The eleven refusals
The codes group naturally into what the inspector never opens, what it cannot know, and what it admits about itself.
It never opens your database. DATABASE_NOT_INSPECTED says it plainly: "the configured application database is never opened, so what a particular database has applied, holds or is missing is unknown." Its sibling SECRETS_NOT_INSPECTED adds that no secret, credential, token or environment value is read, and no provider is contacted. DATA_QUALITY_UNKNOWN closes the set — source-only inspection "can say which records exist, never whether their data is correct, complete or duplicated."
It refuses to infer runtime state. RUNTIME_STATE_UNKNOWN ("nothing here reports what is running, deployed or reachable"), PROVIDER_HEALTH_UNKNOWN (a registered provider definition means a provider was composed, "never that it is reachable, configured or operational") and CI_EVIDENCE_NOT_INFERRED (no CI, browser-smoke or benchmark result is read) all guard the same line: a source tree is evidence about source, and pretending otherwise is how a report becomes a rumor.
It refuses to parse prose into claims. EVIDENCE_NOT_AGGREGATED states that JTBD and quality-gate status "live in Markdown maintained by people; they are referenced by path and never parsed into structured claims." The report's evidence block carries the paths and a status of not_aggregated rather than a synthesized score.
It names what does not exist anywhere. the current posture separates three facts: the framework ships no authentication verifier, authorization is enforced, and isolation is one tenant per application instance rather than shared-database row tenancy. And ADMIN_EXTENSIONS_UNSUPPORTED makes a distinction most tools skip: adminExtensions is empty "for every project — not merely empty for this one." An empty array is ambiguous; this code removes the ambiguity in the direction least flattering to the framework.
It confesses its own execution model. The two remaining codes are about the inspector, not the application. PACKAGE_SOURCE_TRUSTED: reading a code-first package means importing it, so "package code runs with this process's authority. Nothing here is sandboxed." PROCESS_ISOLATION_BOUNDED: the load runs in its own process group under a timeout, so an ordinary spawned child is stopped with it — but a package that deliberately detaches a process into a new group outlives the inspection, and the message adds that tracking descendants is not attempted "and would not be a sandbox either."
That last pair is not modesty for its own sake. tests/app-inspect.test.js demonstrates a package that really does write to disk while being inspected — which is exactly why PACKAGE_SOURCE_TRUSTED is a published limitation rather than a footnote — and measures the detached-process case that PROCESS_ISOLATION_BOUNDED describes. The same suite pins the codes in place: the count of limitation entries is asserted, each code must appear in the human-readable view as well as the JSON, and a clean, fully valid composition still reports all eleven. Validity and self-knowledge are different questions, and the report answers both.
Why codes, not a disclaimer
A disclaimer is written for a person with a lawyer's patience. These limitations are written for a consumer with none: a coding agent deciding what to build next.
An agent that reads this report learns what exists — and, from the same document, the exact boundary of what the report can testify to. The adversarial-review skill in this repository turns that into an instruction: read valid, then problems[], then limitations[], and treat every limitation as a hard boundary on what you may claim. An agent that ignores prose disclaimers — which is to say, every agent — cannot ignore a field in the JSON it is already parsing.
The design consequence shows up one layer above the inspector. A Solution Plan in this framework is a checked-in file validated against a real inspection, so a plan written against a composition that has since moved reports itself stale instead of being taken at its word (docs/SOLUTION_PLAN.md). That mechanism only works because the inspection says what it does not cover: a plan validator that believed the inspector knew about runtime state or database contents would approve plans the framework has no way to check.
There is a quieter benefit, too. When a tool enumerates its blind spots, the blind spots become reviewable. ADMIN_EXTENSIONS_UNSUPPORTED exists because someone had to decide whether an empty array meant "none here" or "none possible", and the decision is now a sentence in the output instead of tribal knowledge. If a future change gives packages an Admin seam, this code has to be removed in the same change — the limitation list is source code, and it drifts or holds with the rest of it.
What this article cannot claim either
The same boundary applies here. The inspector is source-only and read-only; everything above describes what a checked-in tree declares, not whether any running system is healthy, and this article inherits every refusal it quotes. The transcript is the framework repository inspecting itself — a composed project built from the framework reports its own, larger composition, and its limitation list is the same eleven codes because the blind spots belong to the tool, not to the project.
The pattern travels beyond this codebase, and it costs almost nothing to adopt: when you build a tool for agents, return your blind spots as data. A capability list tells an agent what it can rely on. A limitation list tells it what it must go verify by other means — and the second list is the one that prevents the confident, wrong plan.
What this post does not mean
These pages describe this repository at this commit. None of them implies the framework is deployable, and none of them is a roadmap: nothing that is not merged appears on this site, in any tense.
- No authentication ships: the framework authenticates nobody. Production Spine v1 (ADR-038) gives the framework verified identity, organizations and memberships, server-authoritative authorization and one tenant per application instance — so tenancy and authorization now exist and are enforced. What does not exist is authentication: no login, password, session or OIDC implementation ships, and a deployment must supply the adapter that verifies the request. Production mode refuses to start without one. In local-development mode an actor header is accepted as an assertion and is not an identity, which is the default developer posture. This is not shared-database multi-tenancy and it is not a readiness claim.
- Not shared-database tenancy. createAccordoAppAsync can boot one tenant onto dedicated PostgreSQL databases. Shared-database row-level tenancy is not implemented, and this is not a production-readiness claim.
- Timers exist; a service that runs them for you does not. Durable jobs, a transactional outbox and scheduled asks exist for self-hosted applications that explicitly start a worker. Nothing autostarts; a timer opens an ask, never makes a decision, and no managed worker service or recurrence is included.
- No email, calendar or marketing integrations. An in-memory notification provider contract exists. MK1 marketing records supplied funnel observations and human-reviewed proposals only; it has no sending, publishing or spending path.
- The build benchmark has not been run. The protocol is designed and published; no Successful Agent Build Rate exists yet. Any number you see quoted for this project is not ours.
- Ownership means vendored source: there is no framework dependency to bump. The published create-accordo@0.1.0 scaffolds vendored source; it is the August 19 snapshot, not the current repository feature set. Use a current source checkout for the capabilities described here; upgrades require merging source (L-08). The framework is copied into the project, not installed as a framework library dependency. The accordo npm name is an empty reservation; the @accordo scope is claimed and deliberately empty.
Every claim and every limitation is on one page, and the questions this project refuses to answer are published beside them.
The evidence this post rests on
Claims
- C-13 A customer-authored domain package attaches and detaches with the kernel's fingerprint unchanged, and reaches another package only through a capability it declares.
LimitThe scaffold that starts one writes an empty package and nothing else: no business logic, no composition, no global identity-uniqueness check. There is no registry, no marketplace, no publication and no sandboxing — package code runs with the host process's authority. Detaching leaves its data behind; there is no uninstall.
- C-14 One command tells an agent what an application actually is — packages, capabilities, resources, actions, policies, providers — read from checked-in source, in a single deterministic JSON report.
LimitSource-only and read-only. It never opens the database, contacts a provider, reads a secret, or reports runtime, CI or authorization state — and it lists those blind spots as machine-readable limitations in its own output.
- C-15 A Solution Plan is a checked-in file with a contract and a canonical fingerprint, validated against a real inspection — so a plan written against a composition that has since moved reports itself stale.
LimitA document contract, not a planner and not a runtime. Nothing executes a plan, and the validator refuses a plan that carries a command.
Grounded in
docs/transcripts/2026-08-18-app-inspect-limitations.json
Editor of record
- Aetha Editorial