Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7a1a256
feat: add deterministic compliance audit report builder
woahwhattheheck Oct 6, 2026
8aefa9e
feat(compliance): expose audit report builder on module
woahwhattheheck Oct 6, 2026
f2c336e
feat(compliance): export audit report API
woahwhattheheck Oct 6, 2026
e0a3e1f
test: cover compliance audit reports
woahwhattheheck Oct 6, 2026
95a9c77
docs(compliance): document audit report boundary
woahwhattheheck Oct 6, 2026
f2d74f2
docs(compliance): link audit report guidance
woahwhattheheck Oct 6, 2026
bad9c56
docs(api): expose compliance audit report builder
woahwhattheheck Oct 6, 2026
9b6680b
fix(compliance): reject invalid audit statuses
woahwhattheheck Oct 6, 2026
081637e
test: cover malformed compliance audit status
woahwhattheheck Oct 7, 2026
95850db
fix(compliance): reject invalid evidence sources
woahwhattheheck Oct 7, 2026
909908a
test(compliance): cover invalid evidence source
woahwhattheheck Oct 7, 2026
fa9d7c0
docs(compliance): document runtime source validation
woahwhattheheck Oct 7, 2026
2e6694e
fix(compliance): reject malformed report input safely (#40)
woahwhattheheck Oct 8, 2026
f6e74e3
test(compliance): cover malformed runtime report input (#40)
woahwhattheheck Oct 8, 2026
c83b824
docs(compliance): document runtime report input boundary (#40)
woahwhattheheck Oct 8, 2026
5136808
fix(compliance): reject sparse runtime arrays
woahwhattheheck Oct 8, 2026
8136f70
fix(audit): validate sparse evidence id lists
woahwhattheheck Oct 8, 2026
e21297c
test(audit): reject sparse evidence id arrays
woahwhattheheck Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@ const aegis = new AegisClient({
});
```

## Compliance Audit Reports

Build deterministic, typed summaries from caller-supplied protocol evidence with
`client.compliance.buildAuditReport(...)` or the standalone
`buildComplianceAuditReport(...)` export. The builder performs no network I/O
and does not make legal or financial compliance determinations.

See [Compliance Audit Report Builder](./docs/compliance-audit-report.md) for the
data model, stable validation errors, evidence requirements, ordering rules, and
security/compliance boundary.

## Role Discovery & Capability Checks
Check what an address is classified as, and what it can currently attempt through the SDK.
This is a client-side convenience for UI gating, not on-chain authorization — see the
Expand Down
14 changes: 14 additions & 0 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ Either `environment` or both `rpcUrl` and `networkPassphrase` must be provided.

Whitelist / KYC verification module. Accessed via `client.compliance`. Wraps the contract's `is_whitelisted` read-only function.

### `buildAuditReport(input: ComplianceAuditInput): ComplianceAuditReport`

Builds a deterministic schema-v1 report from caller-supplied evidence and check
statuses. This method is pure: it performs no RPC calls and delegates to the
standalone `buildComplianceAuditReport()` export.

Non-`unknown` findings require at least one known evidence id. Invalid or
ambiguous input throws `ComplianceAuditInputError` with a stable error code.
Overall status precedence is `fail > unknown > warn > pass`.

See [Compliance Audit Report Builder](./compliance-audit-report.md) for the data
model, validation table, deterministic ordering, examples, and the
security/compliance boundary. The report is not legal or financial advice.

### `checkWhitelist(address: string): Promise<boolean>`

Queries the contract to check if a user is KYC-approved (whitelisted).
Expand Down
85 changes: 85 additions & 0 deletions docs/compliance-audit-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Compliance audit report builder

The SDK provides a deterministic report builder for **caller-supplied protocol evidence**. It is available as the standalone `buildComplianceAuditReport()` helper and as `client.compliance.buildAuditReport()`.

The builder performs no RPC calls, does not discover evidence, and does not decide whether an entity is legally or financially compliant. Its output is a structured summary of the evidence and statuses supplied by the caller.

## Example

```typescript
import { AegisClient } from '@aegis/sdk';

const report = client.compliance.buildAuditReport({
subject: 'asset-42',
asOf: new Date().toISOString(),
evidence: [
{
id: 'kyc-ledger',
source: 'protocol',
description: 'Current protocol whitelist observation',
reference: 'ledger:123456',
},
],
checks: [
{
code: 'KYC_STATE',
summary: 'Protocol whitelist observation is present',
status: 'pass',
evidenceIds: ['kyc-ledger'],
},
],
});

console.log(report.overallStatus); // pass
```

The same operation is available without constructing a client:

```typescript
import { buildComplianceAuditReport } from '@aegis/sdk';
```

## Deterministic output

Reports use schema version `1`.

- findings are sorted by `code`;
- evidence is sorted by `id`;
- duplicate evidence references inside a finding are removed and sorted;
- summaries count `pass`, `warn`, `fail`, and `unknown`;
- overall precedence is `fail > unknown > warn > pass`.

The builder does not read the network or the local filesystem. The caller is responsible for obtaining evidence and choosing each check status.

## Validation and failure states

Invalid input throws `ComplianceAuditInputError` with a stable `code`:

| Code | Meaning |
| --- | --- |
| `EMPTY_SUBJECT` | Report subject is blank. |
| `EMPTY_CHECKS` | No checks were supplied. |
| `EMPTY_IDENTIFIER` | A check code or evidence id is blank. |
| `DUPLICATE_CHECK_CODE` | Two checks use the same normalized code. |
| `DUPLICATE_EVIDENCE_ID` | Two evidence records use the same normalized id. |
| `UNKNOWN_EVIDENCE_REFERENCE` | A finding references an evidence id not present in the input. |
| `EVIDENCE_REQUIRED` | A `pass`, `warn`, or `fail` finding has no evidence reference. |
| `INVALID_STATUS` | A runtime check status is outside `pass`, `warn`, `fail`, or `unknown`. |
| `INVALID_EVIDENCE_SOURCE` | A runtime evidence source is outside `protocol`, `sdk`, or `operator`. |
| `INVALID_REPORT_INPUT` | A runtime report, list, record, text field, or evidence-id list has the wrong shape or type. |

An `unknown` finding may intentionally have no evidence. That state represents an unresolved observation rather than an evidenced conclusion.

## Security and compliance boundary

Treat the builder as a formatting and normalization boundary, not an authority:

- runtime report shapes are validated before normalization; malformed arrays, records, and text fields fail with `INVALID_REPORT_INPUT` rather than leaking native exceptions;
- report evidence emits only the declared `id`, `source`, `description`, and optional `reference` fields; undeclared caller properties are not copied into exported reports;
- evidence is accepted as caller-supplied data and is not independently verified;
- a `pass` status does not establish legal, financial, regulatory, KYC, AML, or transfer eligibility;
- a `fail` status does not replace protocol enforcement or professional review;
- consumers should preserve authoritative evidence references so dashboards and audit trails can trace each finding back to its source;
- callers should avoid placing secrets, private keys, credentials, or unnecessary personal data in evidence descriptions or references.

Every report includes the SDK disclaimer: the report summarizes caller-supplied protocol evidence and is not legal or financial advice.
Loading