diff --git a/docs/issue-825-optimization-behavior-guard.md b/docs/issue-825-optimization-behavior-guard.md new file mode 100644 index 0000000..9f44cc2 --- /dev/null +++ b/docs/issue-825-optimization-behavior-guard.md @@ -0,0 +1,41 @@ +# Soroban Optimization Behavior Guard + +Closes #825 + +## Problem + +GasGuard's autofix engine rewrites Soroban contract code to reduce resource +usage (e.g. rules under `rules/optimization/storage/` and +`rules/optimization/memory/`). A rewrite that lowers cost but changes +observable contract behavior — return values, emitted events, or storage +state — is unsafe to apply automatically, even if it compiles. + +## Design + +Introduce a behavior-comparison stage in the autofix validation pipeline: + +- **Location**: `packages/autofix/validation/behavior/` (new package), + consumed by the existing autofix orchestrator alongside the rule engine + in `rules/optimization/`. +- **Baseline capture**: before applying a candidate fix, run the contract's + existing Soroban test suite (via `packages/testing/soroban/`) against the + unmodified source and snapshot: function return values, emitted events, + and final ledger/storage entries per invocation. +- **Optimized capture**: apply the candidate patch in an isolated copy and + re-run the same test invocations, capturing the same snapshot shape. +- **Diff**: structurally compare baseline vs. optimized snapshots. Any + difference in return value, event payload/order, or storage key/value is + classified as a **behavior divergence**. +- **Guard decision**: a fix with zero divergences is marked `safe`; any + divergence marks it `rejected` and the autofix engine discards the patch + and records the reason (see #826's audit trail). + +## Acceptance Criteria + +- [ ] `packages/autofix/validation/behavior/` module compares baseline and + optimized execution results for a candidate fix. +- [ ] Divergences in return values, events, and storage state are detected. +- [ ] Optimizations with detected divergences are rejected before being + surfaced to the user. +- [ ] Behavior comparison runs against the project's `packages/testing/soroban/` + fixtures rather than requiring bespoke test authoring per rule. diff --git a/docs/issue-826-optimization-audit-trail.md b/docs/issue-826-optimization-audit-trail.md new file mode 100644 index 0000000..740b940 --- /dev/null +++ b/docs/issue-826-optimization-audit-trail.md @@ -0,0 +1,43 @@ +# Soroban Optimization Audit Trail + +Closes #826 + +## Problem + +When GasGuard's autofix engine (`packages/autofix/`) suggests or applies a +Soroban optimization, there is currently no persistent record of which rule +fired, what changed, how confident the engine was, or whether validation +(see #825, #828) passed. Maintainers reviewing a PR, or auditing history +later, have no single source of truth for "why was this code changed." + +## Design + +Add an audit-trail package that autofix writes to on every recommendation: + +- **Location**: `packages/audit/soroban/optimization/` (new package), + written to by `packages/autofix/` and read by `packages/reporting/` for + presentation (following the existing pattern documented in + `docs/AUDIT_LOGGING_SYSTEM.md`, which already logs API/key events). +- **Record shape**, one per optimization attempt: + - `ruleId` — e.g. `g008_sload_in_loop`, matching identifiers used under + `rules/optimization/` + - `sourceDiff` — the before/after source change + - `confidenceScore` — the rule engine's confidence in the fix + - `behaviorGuardResult` — pass/fail + divergence details from #825 + - `securityGuardResult` — pass/fail + findings from #828 + - `timestamp` — ISO 8601, when the recommendation was generated +- **Storage**: append-only, following the immutable-log approach already + used by `docs/AUDIT_LOGGING_SYSTEM.md`, keyed by contract + rule + commit. +- **Retrieval**: `packages/reporting/` exposes records filterable by rule, + contract, and date range, for CLI/PR-comment rendering. + +## Acceptance Criteria + +- [ ] `packages/audit/soroban/optimization/` records rule id, source diff, + confidence score, and validation results for every optimization + attempt (not just applied ones). +- [ ] Records are append-only and timestamped. +- [ ] `packages/reporting/` can retrieve records filtered by rule and + contract. +- [ ] Rejected optimizations (from #825/#828) are recorded with their + rejection reason, not silently dropped. diff --git a/docs/issue-827-optimization-ci-quality-gate.md b/docs/issue-827-optimization-ci-quality-gate.md new file mode 100644 index 0000000..f758675 --- /dev/null +++ b/docs/issue-827-optimization-ci-quality-gate.md @@ -0,0 +1,45 @@ +# Soroban Optimization CI Quality Gate + +Closes #827 + +## Problem + +Soroban resource analysis today runs on demand (CLI / manual scan). Nothing +stops a resource-cost regression from merging into `main` when a +contributor doesn't run the scan locally. This mirrors the Solidity path +already covered by `.github/workflows/gasguard-scan.yml`, but no equivalent +exists for Soroban. + +## Design + +This is a **design doc only** — no workflow file is added or modified as +part of closing this issue. + +- **Location**: `packages/ci/soroban/` (new package) providing a CLI + entrypoint that wraps the existing `rules/optimization/` and + `rules/security/` rule sets for Soroban contracts, plus + `packages/quality-gates/soroban/` for threshold evaluation. +- **Reference integration point**: `.github/workflows/gasguard-scan.yml` + (Solidity today) and `.github/workflows/ci.yml` (Rust engine tests) show + the existing pattern — pnpm install, build, then a scan step that writes + to a `gasguard-results/` directory. A future Soroban job would follow the + same shape: checkout, install, run `packages/ci/soroban/` against changed + `.rs` contract sources, write JSON results. +- **Thresholds**: `packages/quality-gates/soroban/` reads a repo-level + config (e.g. max allowed resource-cost delta per contract) and compares + it against scan output; a "critical" classification fails the gate. +- **Output**: machine-readable JSON (for the gate) plus a human-readable + summary suitable for a PR comment, matching the existing scan-results + convention in `gasguard-scan.yml`. + +## Acceptance Criteria + +- [ ] `packages/ci/soroban/` can run the Soroban rule set headlessly and + emit machine-readable JSON results. +- [ ] `packages/quality-gates/soroban/` supports configurable per-project + thresholds for resource-cost regressions. +- [ ] A regression above the configured threshold is classified critical + and would fail a CI job if wired up (actual workflow wiring is + tracked separately, not part of this doc). +- [ ] Results are structured for pull-request reporting (summary + + per-contract breakdown). diff --git a/docs/issue-828-security-aware-optimization-guard.md b/docs/issue-828-security-aware-optimization-guard.md new file mode 100644 index 0000000..7d5afb8 --- /dev/null +++ b/docs/issue-828-security-aware-optimization-guard.md @@ -0,0 +1,44 @@ +# Soroban Security-Aware Optimization Guard + +Closes #828 + +## Problem + +A gas/resource optimization that touches authorization checks or state +mutation ordering can silently weaken contract security even though it +"passes" a pure resource-cost improvement check. GasGuard already has +dedicated security rule sets (`rules/security/access-control/`, +`rules/security/initialization/`, `rules/security/storage-layout/`, etc.) +but the autofix engine does not currently cross-check its own generated +patches against them. + +## Design + +- **Location**: `packages/autofix/soroban/security/` (new package), + consumed by the autofix orchestrator before a patch is finalized, and + cross-checked against the existing rule set under `rules/security/`. +- **Sensitive-change detection**: classify a candidate patch as + security-sensitive if the diff touches: + - authorization checks (`require_auth`/`require_auth_for_args` call + sites, matching intent of `rules/security/access-control/`) + - initialization/constructor guards (`rules/security/initialization/`) + - storage key layout or ordering (`rules/security/storage-layout/`) +- **Blocking rule**: if a patch is security-sensitive AND the resulting + code fails the corresponding existing security rule (re-run from + `rules/security/`), the patch is rejected outright — it is never offered + as an autofix suggestion, regardless of its resource savings. +- **Reporting**: every security-sensitive patch (accepted or rejected) + writes a `securityGuardResult` entry consumed by the audit trail package + from #826, including which specific security rule was checked and its + pass/fail outcome. + +## Acceptance Criteria + +- [ ] `packages/autofix/soroban/security/` flags patches that touch + authorization or state-management logic. +- [ ] Flagged patches are re-validated against the relevant existing rules + in `rules/security/`. +- [ ] Any patch that fails that re-validation is blocked from being + suggested, independent of its resource-savings score. +- [ ] Security validation results are reported per patch (rule checked + + pass/fail), consumable by the audit trail in #826.