What I built

I built Hedge because Git diffs show changed lines, while security review needs to understand changed architecture.

A pull request can add a public route, remove an authorization check, connect request data to object storage, or expand a workflow's authority without looking dramatic line by line. Hedge compares the exact base and head revisions, builds an evidence-linked attack-surface graph, and reports the security architecture delta: changed entry points, trust boundaries, controls, privilege, data operations, and workflows.

It is deliberately not a generic "AI security scanner." Hedge surfaces supported attack-surface changes and design risks. It does not claim to find or prove vulnerabilities.

The design choices that shaped it

The implementation follows four rules I was not willing to trade away:

  1. Code establishes facts before a model interprets them. Handler-scoped TypeScript analysis produces exact file-and-line evidence. GPT-5.6 can explain a meaningful delta, but it cannot create repository facts.
  2. Silence is a feature. A complete no-delta change causes no model call and no pull-request comment.
  3. The model does not own the verdict. Deterministic observations, confidence-bearing inferences, and policy decisions are separate artifacts. The Action fails only from a recorded policy or invariant decision, never from model prose.
  4. A test file is not proof of repair. A finding reaches verified only when the same sealed witness reproduces the behavior before the repair, is blocked after it, legitimate behavior still works, and the intended architecture control changed.

I also separated authority across the GitHub workflow. The collector can read pull-request source but has no OpenAI key. The reasoning job has the key but no checkout or GitHub write authority. The publisher can write the report but has no OpenAI key. SHA-256-bound manifests connect those jobs, and policy is loaded from the trusted base revision so a pull request cannot weaken the tool reviewing it.

What works today

Hedge ships as a Node 24 GitHub Action and Node 22 CLI with a checksum-verified, no-build release bundle.

The supported analysis boundary is TypeScript with:

  • Next.js App Router route handlers
  • Next.js Pages API routes
  • exported Server Actions and middleware matchers
  • basic Express routes and middleware
  • Prisma/database, object storage, outbound network, command execution, logging, environment credential, dependency, and GitHub workflow patterns
  • authentication, authorization, ownership, validation, rate-limit, upload-size, and content-type controls

It produces an interactive HTML security diff, Markdown, SARIF, machine-readable graph/delta/analysis JSON, GitHub annotations, a stable risk register, generated JSON Schemas, replay artifacts, and tamper-evident proof bundles.

The CLI includes installation and compatibility diagnostics, graph initialization and comparison, evidence explanation, witness generation, history, proof-bundle verification, deterministic replay, evaluation, lifecycle status, and repair planning. The repository also includes approval-gated Codex remediation and secretless counterfactual-verification workflows.

How GPT-5.6 and Codex were used

GPT-5.6 is part of the product only after a deterministic architecture delta exists. Routine deterministic recommendations and confirmed no-delta runs use zero model calls. Sensitive or high-consequence deltas go directly to GPT-5.6 Sol. Ambiguous deltas can use Luna before optional Sol review. Requests, patches, outputs, reasoning effort, and retries are bounded, and every accepted proposal must resolve to the deterministic evidence index.

The initial Build Week foundation was developed in ChatGPT with GPT-5.6 Sol and preserved as an immutable baseline commit before the project moved into the primary Codex thread. Codex then helped me validate and harden the system across the repository: AST extraction, coverage semantics, workflow trust boundaries, strict schemas, fixture expansion, release reproducibility, Pages API support, real-repository testing, live GitHub canaries, remediation, verification, and the judge experience.

I retained the product direction, security commitments, scope decisions, and final adjudication. The repository includes a decision log and a factual provenance record so that boundary is inspectable.

What I can prove

  • 259 unit, contract, replay, workflow, and schema tests pass across 53 test files.
  • All 47 bundled deterministic DriftBench cases pass, including benign silence and repeated stability. This is a supported-pattern fixture result, not a general accuracy score.
  • Source-only smoke tests on one App Router repository, one Pages API repository, and one Express repository were silent on documentation-only changes and produced exact evidence for supported upload/storage changes. The two unresolved framework patterns were disclosed as partial coverage.
  • A benign judge-lab pull request produced no Hedge comment and no model call.
  • A live architecture-changing pull request completed the full collect -> reason -> publish path, rejected one unsupported model proposal, cited exact evidence, and recorded a BLOCK decision.
  • One remote verification run passed all four requirements and recorded HEDGE-009 as verified through a reviewable state pull request.
  • Public CI runs formatting, schemas, typecheck, tests, evaluation, build reproducibility, release validation, demo validation, and a high-severity dependency audit.

The part that did not work perfectly

I ran one frozen ten-case model evaluation three times without tuning against it. All 30 slots were recorded. Three deterministic no-delta runs correctly used zero calls. Of 27 model-routed runs, 15 completed and 12 failed. Accepted output retained 100% exact-evidence validity and the instruction boundary held, but exact finding/decision signatures were stable for only two cases. I preserved the operational gate as FAIL instead of rerunning until it looked better.

Codex also produced a bounded, digest-bound three-file remediation patch, but the target fixture's generic test command stopped on a pre-existing empty Vitest suite, so the automated draft publisher did not complete. The recovered draft is labeled experimental.

Those failures matter. They are why I present the deterministic architecture diff and the completed verification canary as proven, while model reliability and automatic remediation publication remain next-release work.

What I would do with more time

First I would spend 3-4 weeks hardening the current TypeScript release: finish remediation publication diagnostics, investigate model failures against a newly frozen corpus, expand expert review, and deepen imported-helper and monorepo analysis.

After that, Hedge can reuse its graph, policy, reporting, and verification layers with new language frontends. Under a one-engineer-plus-Codex assumption, I estimate 8-12 weeks for release-quality FastAPI/Flask support, 9-12 weeks for Go HTTP/Gin/Chi, 10-14 weeks for Rails, and 12-16 weeks for Spring. Those ranges include parser integration, exact evidence, explicit coverage, framework semantics, fixtures, real-repository validation, packaging, and held-out evaluation. A regex-only adapter would be faster, but it would break the reason I built Hedge.

Try it

The hosted dashboard is the fastest no-install path. The GitHub release contains checksum-verified prebuilt Action and CLI bundles, and the repository includes an offline deterministic replay. Judges can also install the immutable Action into a compatible same-repository TypeScript pull request without rebuilding Hedge.

Built With

  • esbuild
  • github-actions
  • node.js
  • openai-codex
  • openai-gpt-5.6
  • typescript
  • typescript-compiler-api
  • vitest
  • zod
Share this project:

Updates