Gaugedocs
Functional alpha v0.1.0-dev GitHub

Mechanics

Control is a set of weights.

A Stellar account does not have an owner in the usual sense. It has signers, thresholds and flags, and the protocol checks them on every operation. Gauge reads those public values, then asks whether they match what you said you expected.

Weights and thresholds

Every signer carries a weight. Every transaction carries one or more signatures, and each signature contributes its signer's weight. The protocol groups operations into three security tiers, each with its own threshold. An operation is authorized when the weights of the valid signatures reach the threshold for its tier.

Consider three signers and two thresholds:

SignerWeightNotes
A1An ordinary ed25519 key
B1An ordinary ed25519 key
C2Holds more weight than A or B alone
TierThresholdWhat reaches it
Medium2A and B together, or C alone
High3All three signers, or C plus one other

The protocol decides which operations sit in each tier. Gauge reports the threshold values and the signer weights as stored; it does not reinterpret them.

The master key is a signer

Horizon lists the account's master key inside the signers array, not as a separate field. Its weight is what older Stellar material calls the master weight. A master key with weight 0 cannot sign, even though it still owns the account in every other sense.

Stellar also supports hash(x) and pre-authorized transaction signers. Gauge decodes and labels those types, but the signer rules that would judge them are not shipped yet. Task 3.1 is blocked on threshold semantics that cannot be verified without submitting a transaction, which this project does not do.

Flags belong to issuers

Four flags change what an issuing account can do to the assets it issues. They are stored on the account and are public.

FlagWhat it means
auth_requiredA trustline must be authorized by the issuer before the holder can use the asset.
auth_revocableThe issuer can revoke authorization for a trustline.
auth_immutableThe issuer can never change these flags again.
clawbackThe issuer can claw back the issued asset from holders.

Gauge compares a flag only when the policy declares a value. An omitted flag means "not declared", not false.

Home domain and SEP-1

The home domain is where an account publishes a stellar.toml file at /.well-known/stellar.toml. SEP-1 defines the fields an issuer can publish, including NETWORK_PASSPHRASE, SIGNING_KEY and the list of ACCOUNTS it operates.

Gauge reads that document, through a guard that sits at the dial rather than in a pre-flight check. The host name is resolved, every address in the answer is classified against a table that rejects loopback, private, link-local including the cloud metadata address, unique-local, carrier-grade NAT and unspecified ranges, and the socket is then opened to the numeric address that was validated. That order is the point: a record that changes between the check and the connection cannot smuggle a private host through, and a redirect re-enters the guard with fresh resolution instead of inheriting the first answer. At most three hops, each required to be https with no credentials and no port but 443, one body cap of 102400 bytes, one deadline over the whole chain.

One captured testnet issuer served its stellar.toml as HTTP 200 with an HTML body, so validity keys on a strict TOML parse that yields at least one recognized identity field, never on the content type. Nothing from the document reaches the report: an unreachable domain names the step that failed and quotes no body. Three rules sit on that result, all WARN, and a home domain that was observed but never fetched is a warning rather than a pass. No test in this repository dials a real domain, so this fetcher has not been run against one.

What one run does, in order

  1. ValidateThe request is checked: network present, exactly one endpoint at v0.1, at least one account, a known failure threshold.
  2. Read networkThe endpoint's root document supplies its network passphrase and latest ledger.
  3. Compare passphraseA mismatch is recorded before any account read. Nothing is fetched from the wrong network.
  4. Fetch accountsAccounts are read in policy order through a pool of at most eight requests. The first non-404 failure cancels the rest.
  5. Fetch identityEach account that published a home domain is asked about it, under the same bound of eight, through the dial-time guard. A domain that was not published is not fetched, and the whole stage is skipped when the endpoint is on the wrong network.
  6. Evaluate rulesPure functions read the snapshot, the policy and the identity result. A rule panic becomes an internal finding and exit 3.
  7. Apply acceptsA live acceptance marks a finding accepted. Account rules, network rules and unreachable thresholds cannot be accepted.
  8. Render and exitThe report carries the limits footer. Findings at or above --fail-on produce exit 1; a completed run with none exits 0.

Network and endpoint

The network is always explicit. --network accepts mainnet, testnet or a full passphrase, and there is no default. The endpoint must be HTTPS, except for a loopback address, which exists for local tests. A read has a 10 second request timeout, a 1 MiB body cap, at most eight concurrent requests and three retries with capped backoff. Redirects are refused, and no response body is ever logged.

Why the passphrase check comes first. A testnet account and a mainnet account can share an ID. Reading an account from the wrong network would produce a confident report about the wrong chain, so the run refuses to read anything until the endpoint proves it is on the network you asked for.

The boundary

Gauge reads public ledger state only. It cannot see who holds a key, whether signers are separate people, or off-chain controls. Report limits footer

Control on-chain is not control in practice. A signer can be one person with two devices, a key can be stored badly, and a policy file can be edited by the same attacker who can edit CI. Gauge reports what the chain shows against what you declared, and nothing more.