Skip to content

50 · A report's codes: QG and QC

A report from stalwart verify or a scan carries findings under two kinds of code. QG codes are the bug hunter's: ways through your rules, found in the agents' graph, the rulebook and the router. QC codes are the code checks': problems with how your own tool code handles the network and credentials. This chapter says how the two differ, lists every QC rule, and says how each family relates to the standards a security team files findings under.

Language support

The selector reads turns written in English and in Brazilian Portuguese (pt-BR). The language is chosen, never guessed from the turn: the console's Settings page (Language the selector reads), language on a plan request, or the settings.language of your vocabulary file; with none of them, English. A Portuguese turn may be typed with its accents or without them. European Portuguese is not a grammar the selector has, and a turn in any other language is unread.

Two families

QG -- the bug hunter QC -- the code checks
Reads the agents' graph, the rulebook or rule sheet, the catalogue, the router in front of them the source files of the folder agent.yaml is in: Python, JavaScript, TypeScript and Go
Runs on Stalwart's servers, as a hunt job on your machine, in the licensed runtime; your code never leaves it, only the count of findings by rule goes with the registration
A finding carries its rule, severity and type, the location in the file you edit, the flow, a reproduction, a checked fix, and its OWASP entries its rule, its CWE, the file and line, the path the value took to get there, and one sentence
Fails the gate by the gate's conditions: a new Critical finding, a broken row of your own tables, and the others of chapter 28; a project's quality profile can ask for more every finding, with no level, no waiver and no suppression comment: only changing the code clears it
Kept over time in a project, against its baseline, with a person's decisions -- false positive, accepted risk with an expiry (chapter 51) not kept: the next run reads the code as it is then

The first is a question about routes: whether a turn, a document or another agent can make the agent do what your rules say it must not. The second is a question about code: whether a tool sends data in clear text, trusts a server it should check, or keeps a secret where it can leak. A clean answer to one says nothing about the other.

The QG rules

The bug hunter has 49 rules, in four ranges:

  • QG0xx are found in a policy or an agent graph: a way through a rule.
  • QG1xx are review items, security hotspots: a person decides whether each is a problem.
  • QG2xx say what a scan could not decide or describe. QG201 Undecided is the one a clean report must still be read for.
  • QG3xx are found in a host built from your catalogue and the router in front of it.

The rule pages have one page per rule: when it is raised, why it matters, how to fix it, its severity and its OWASP entries. Chapter 28 reads a finding line by line.

The QC rules

Every rule the code checks run, from the rule bundle the runtime reads:

Network security

Rule CWE Raised where your code What clears it
QC001 CWE-1327 opens a listening socket -- a server, a bound port -- other than an MCP server on loopback over the declared http transport don't listen from tool code; an MCP server runs on stdio, or on loopback with --transport http
QC002 CWE-295 turns TLS verification off or replaces the trust store -- verify=False, rejectUnauthorized: false, InsecureSkipVerify, ssl.CERT_NONE, its own CA bundle remove the setting; the system's trust store is the one the checks accept
QC003 CWE-319 sends a request over http:// or ws:// to a host that is not loopback use https:// or wss://
QC004 CWE-918 sends a request to an address taken from a tool argument or from a response, not checked against a constant list first fix the host in the code, or check the value against a constant list (if host in ALLOWED) before the request
QC005 CWE-441 sends a request to a constant host outside the egress list declared with the catalogue (--egress) add the host to the egress list, or remove the request
QC006 CWE-693 goes around the environment's proxy -- trust_env=False, a cleared proxy setting, a raw socket leave the proxy settings as the environment gives them, and use an HTTP client
QC007 CWE-494 runs code it fetched, imports code from a URL, or installs packages at run time declare the dependency and install it before the agent runs

Credentials

Rule CWE Raised where your code What clears it
QC010 CWE-798 writes a secret into the source -- a token, a password, a key in a known format read it from an environment variable at run time, and revoke the one that was written down
QC011 CWE-532 puts a secret in a log line, an exception's message or a tool's result log and return what the secret was used for, never the secret
QC012 CWE-598 puts a secret in a URL's query string send it in a header
QC013 CWE-312 keeps a secret in a store of its own -- a file, a cache, a database read it from its environment variable each time it is needed
QC014 CWE-522 reads a credential from somewhere other than an environment variable -- a keyring, a .env file, a .netrc, a browser's cookies, a credential file such as ~/.aws/credentials read it from an environment variable the process is started with
QC015 CWE-522 runs its own sign-in flow -- an OAuth exchange, a token request let the gateway sign in (chapter 37) and pass the tool the token it gets

Code the checks cannot read

Rule CWE Raised where your code What clears it
QC020 -- cannot be read -- a file that does not parse, minified or generated code, a native extension, a language the checks have no rules for, code run from a string keep the readable source in the folder, or move what cannot be read out of it

A secret is a value read from an environment variable whose name holds a word such as token, secret, password or api_key -- but not one that only says where a secret is, such as TOKEN_FILE -- or a literal in a known key format. A tool argument is a value the model or the person gives a tool function. A request is a call of an HTTP client, a socket or a fetch.

QC005 needs an egress list to compare against: stalwart catalogue import takes one with --egress. stalwart verify has none, so it raises no QC005, and any listening socket is QC001.

Reading a QC finding

QC002 CWE-295 shop/tracking.py:8  This code turns TLS verification off (`verify=False`), at shop/tracking.py:8.
    shop/tracking.py:8  turns TLS verification off (`verify=False`)

The first line is the rule, its CWE, the place and the sentence. The lines under it are the path: where the value came from, each function it went through, and where it ended. A finding about a secret in a log starts where the secret was read; one about a request's destination starts at the tool argument it came from. Chapter 46 shows this finding in a full report.

The checks follow a value across your functions, so a finding can be in a file no tool imports directly. They read every source file of the folder, tools or not, since a tool can import any of them.

The standards

A QG finding carries the OWASP Top 10 for LLM Applications and the OWASP Top 10 for Agentic Applications entries it is an instance of, with their edition (LLM01:2026, ASI04:2026), in the report and in the SARIF's taxonomies (chapter 28). Chapter 39 has the reverse: which rules cover each entry.

A QC finding carries the CWE of the weakness in your code -- CWE-295 is improper certificate validation -- and no OWASP entry: the OWASP lists are about what an agent can be made to do, and a QC rule is about how a piece of code is written. QC020 has no CWE: it says the checks could not read the code, not that the code is weak.

The limits

  • The code checks read network security and credential handling, in Python, JavaScript, TypeScript and Go, and nothing else about what your code does: a tool that computes the wrong refund passes them.
  • Code the checks cannot read is a finding, QC020, never a pass: a file that does not parse, minified code, a native extension or code run from a string fails the gate until it is readable or gone.
  • A clean QC report is not a clean QG report, nor the other way: each answers its own question.