Reading your survey
The survey is the whole picture: what Tibyaan can prove about your app, what it refused, and exactly why. It is written for you, to decide whether to adopt. Here is how to read it.
A real survey
This is the output of a real scan, unedited. Lines that start with + are proven reads. Lines that start with - are refusals, each with its cause in brackets and a located reason.
Discovered (25):
by-id (16):
+ Contact: getContact -> ContactServiceImpl#findById; returns the entity Contact directly (section 4.1) (partial: 3 fields skipped)
+ ContactCategory: getContactCategory -> ContactCategoryServiceImpl#findById; returns the entity ContactCategory directly (section 4.1) (partial: 1 fields skipped)
+ ContactGroup: getContactGroup -> ContactGroupServiceImpl#findById; returns the entity ContactGroup directly (section 4.1) (partial: 1 fields skipped)
... (+13 more discovered by id; every one shown in full in the linked ledger)
list (9):
+ listAccount -> AccountServiceImpl#findAll
+ listContact -> ContactServiceImpl#findAll (paged)
... (+7 more discovered list reads)
Failed (9):
- EmailTemplate [NO_IDENTIFIER]: entity 'EmailTemplate' has @Id 'type' of type 'EmailTemplateType', which does not map to a bindable primitive, so no read-by-id capability is modeled (Volume 5 section 4.1). (partial: 1 fields skipped)
- OutboundEmail [NO_BACKING_METHOD]: no service method backs read capability 'getOutboundEmail' for entity 'OutboundEmail'.
- OutboundNotification [NO_BACKING_METHOD]: no service method backs read capability 'getOutboundNotification' for entity 'OutboundNotification'.
- Quote [AMBIGUOUS_BINDING]: read capability 'getQuote' for entity 'Quote' is backed by more than one candidate: [QuoteServiceImpl#findById (entity-returning), QuoteServiceImpl#getInvoice (view-returning byte[])]. (partial: 2 fields skipped)
- SMSMessage [NO_BACKING_METHOD]: no service method backs read capability 'getSMSMessage' for entity 'SMSMessage'. (partial: 1 fields skipped)
- Delivery [NO_BACKING_METHOD]: no service method backs read capability 'getDelivery' for entity 'Delivery'. (partial: 1 fields skipped)
- DeletedUser [NO_BACKING_METHOD]: no service method backs read capability 'getDeletedUser' for entity 'DeletedUser'.
- User [AMBIGUOUS_BINDING]: read capability 'getUser' for entity 'User' is backed by more than one candidate: [UserService#findById (entity-returning), UserService#findByUsername (entity-returning)].
- InventoryTransaction [NO_BACKING_METHOD]: no service method backs read capability 'getInventoryTransaction' for entity 'InventoryTransaction'.
List-refused (1):
- ProductCategory [LIST_AMBIGUOUS]: list capability 'listProductCategory' has more than one list-all candidate: [ProductCategoryServiceImpl#findAll, ProductCategoryServiceImpl#findAll].
Totals: discovered 25 (by-id 16, list 9), failed 9 (by cause: NO_IDENTIFIER 1, NO_BACKING_METHOD 6, AMBIGUOUS_BINDING 2), list-refused 1, skipped-by-parse 0, partial 13 (22 fields skipped), mis-bound 0Unedited output of the ERP benchmark survey (2026-07-17). Elisions are marked in the text and only shorten the discovered lists; every refusal is shown in full. The per-entity ledger is public (opens in a new tab).
Discovered
A discovered line names the capability, the entity, and the binding: the real class and method the tool will call. Two kinds of read are discovered today.
- by-id: a read of one entity by its primary key, for example
getContactbound toContactServiceImpl#findById. - list: the unfiltered list of an entity, for example
listAccountbound toAccountServiceImpl#findAll. A(paged)mark means the read returns a page, and the generated description says the page envelope is not modeled.
A (partial: N fields skipped) mark means some fields of the source entity are not represented in the model. The binding is still proven. The omission is disclosed rather than hidden: the generated OpenAPI schema names the fields that were left out.
Refusal causes
Every refusal carries one cause. None of them is an error in your code: each is the tool declining to guess.
| Cause | What it means |
|---|---|
NO_BACKING_METHOD | No service method structurally backs this read, so nothing is exposed. |
AMBIGUOUS_BINDING | Two or more methods both fit the shape of the read; the tool refuses rather than pick one. |
NO_IDENTIFIER | The entity has no identifier that maps to a bindable primitive, so a read-by-id cannot be formed. |
COMPOSITE_KEY | The entity's identifier is a composite key, so no single-identifier read-by-id is formed. |
LIST_AMBIGUOUS | More than one list-all candidate exists; the tool will not choose between them. |
Files that would not parse are listed separately as skipped-by-parse, each one named. The scan never aborts on a bad file, and a partial result never passes itself off as a complete one.
What is never discovered, by design
Writes and actions, and filtered reads such as findByStatus or search. A filter's meaning is a claim the tool cannot verify from structure, so it is not presented as verified. A person can carry such a read through attestation.
The totals line
The last line summarises the run:
discovered N (by-id A, list B), failed, list-refused, skipped-by-parse, partial, mis-bound| Field | Read it as |
|---|---|
discovered | Proven reads, split into by-id and list. These are what would ship. |
failed | Entities whose read-by-id was refused, broken down by cause. |
list-refused | Entities whose list read was refused. |
skipped-by-parse | Source files that could not be parsed. Each is named above. |
partial | Entities modeled with some fields left out, with the count of fields skipped. |
mis-bound | Tools bound to the wrong method. This is the absolute bar: it must be 0, on every run. |
When your project has an attestations file, the survey also reports attested entries and drafts as their own classes. They are counted apart and never summed into the discovered total.
A shareable report
Add --report to write the same survey as Markdown: a summary table, the operable subset with its bindings, the refusals grouped with their located reasons, and the single most common blocker. It is read-only, like the scan itself.
java -jar tibyan-cli-0.3.0-jar-with-dependencies.jar scan /path/to/your-app --report survey.mdIf you ran the preview on a real application, the maintainer would like to see the numbers: every real survey shapes what gets built next. The address is on the security page.
scan versus generate
They do two different jobs, which is why one shows more than the other.
- scan is the survey. It prints everything: every discovered capability, every refusal with its cause, every skipped file.
- generate and the Maven plugin produce the artifact. They emit only the proven capabilities, because the manifest is what an agent will act on. A refusal is a deliberate absence from the artifact.
If you only ran generate and wonder where a read went, run scan to see the reason.
The authoritative text is docs/CLI.md (opens in a new tab) in the repository. If this page and that document ever disagree, the repository wins.