Your architecture docs, enforced on every pull request.

Striff reads the documents already in your repository, turns every sentence that makes a claim about the code into a rule it can evaluate, and answers all of them on each pull request. When a change contradicts what your team wrote down, it says so before the merge, and quotes the line.

Free on public repos Nothing to configure One check beside your CI

Striff / architectural-review Ericsson/ecchronos PR #1786 6 documents read Java

One of the 29 rules Striff could check in this repository’s own docs no longer holds. Nothing was configured. Striff catalogued 6 documents, turned their sentences into rules, and checked every one against both revisions.

1violated 27held 1pre-existing
Calls RepairScheduler.putConfigurations() to keep jobs up to date core.impl/README.md:136 NodeWorker depends on RepairScheduler Violated The rule holds at the base revision and fails on this pull request.
The ConnectionType enum (from utils) defines the three ecChronos control modes: connection/README.md:57 ConnectionType is in com.​ericsson.​bss.​cassandra.​ecchronos.​utils.​enums.​connection General term resolved Held The rule holds at the base revision and on this pull request.
VnodeRepairTask / IncrementalRepairTask — Concrete RepairTask subclasses for vnode and incremental repair respectively. core.impl/README.md:65 VnodeRepairTask depends on RepairTask, and IncrementalRepairTask depends on RepairTask One sentence, two rules Held The rule holds at the base revision and on this pull request.
Works with Java Python C# TypeScript

The problem

Nobody re-reads the docs on every pull request.

Your agents read your architecture docs as context, then write code that quietly contradicts them, and no reviewer re-reads those documents on every change to catch it. Left unchecked, each merge drifts a little further from what your team agreed until every change takes twice as long and nobody wants to touch the core. Striff catches the contradiction on the pull request, while it is still a one-line fix.

Why this is getting worse7 min read AI didn't make engineering discipline obsolete. It made it the whole job.

Computed, not generated.

Striff is neurosymbolic, not an LLM wrapper. A parser resolves every type and reference in your code at both revisions, the way a compiler does, and each sentence in your docs becomes a query over that model. Verdicts are computed, not predicted. A language model only reads the prose and ranks the results, and nothing is needed beyond the documents your repository already has.

01 How a finding is produced

  1. 01 Parse Deterministic

    Both revisions become a structural model of types, members, references and packages — resolved the way a compiler would, not by matching text.

  2. 02 Read Language model

    Your documents go to a language model, which proposes candidate rules from prose. The only step that reads English.

  3. 03 Ground and compile Deterministic

    Any candidate naming something absent from the model is dropped. What survives becomes a formal query over it.

  4. 04 Evaluate Deterministic

    The query runs against both revisions. A rule holds exactly when it returns nothing, and only a violation the change introduced is attributed to it.

  5. 05 Narrate Language model

    The model ranks and explains what the evaluation already found. It cannot originate a finding, rename one, or turn “could not answer” into a pass.

How we keep the model honest8 min read The reviewer is not allowed to be the source of any claim

02 What your reviewer sees

Review Summary

This PR moves repair-history setup into the incremental path. NodeWorker stops referencing RepairScheduler and the table lookups it used, and now depends on SchemaRefresher. RepairHistory drops a public newSession overload that 11 components reach for.

Documented Rules 29 checked · 27 held · 1 violated · 1 pre-existing

  • Calls RepairScheduler.putConfigurations() to keep jobs up to date NodeWorker depends on RepairScheduler Violated core.impl/README.md:136
  • Maintains a dedicated NodeWorker background thread per Cassandra node. NodeWorkerManager depends on NodeWorker Held core.impl/README.md:131
  • Alarms are fired by AlarmPostUpdateHook in core.impl after every repair state update. AlarmPostUpdateHook is in core.impl Held fault.manager/README.md:51
  • Afterwards a single RepairGroup is created. IncrementalRepairJob depends on RepairGroup Held docs/ARCHITECTURE.md:461
  • Fires AlarmPostUpdateHook if repairs are overdue RepairStateImpl depends on AlarmPostUpdateHook Pre-existing core.impl/README.md:93

5 of 29 shown

Structural Checks 14 checks · 5 flagged · 9 clean

  • Component scope3 flagged
  • Public contract stability2 flagged
  • Class-level coupling knots1 flagged
  • Boundary crossings1 flagged
  • Package cycles1 flagged
  • Cycle seedsclean
  • Module boundariesclean
  • Production → test edgesclean
  • Abstraction contractsclean
  • Tests for changed contractsclean
  • Interface downgradesclean
  • Encapsulationclean
  • Hub formationclean
  • Type relocationsclean

The diagram

Every pull request gets a structural diff diagram.

The classes a change touched, what each one gained and lost, and how they connect at both revisions, so you can see the shape of a change you didn’t write. Green was added, red was removed, and each finding is pinned to the class it is about.

The diagram engine is open source: striff-lib on GitHub MIT
Ericsson/ecchronos PR #1786 Java 3 HIGH · 5 MEDIUM
Striff / architectural-review
Striff structural diff of Ericsson/ecchronos PR #1786, framed on the repair history package: RepairHistoryService and RepairSessionImpl with added members in green, changed ones in blue, and the old newSession(...) form removed in red
Architecture diagram of this PR
HIGH
The README no longer matches the code

core.impl/README.md says NodeWorker calls RepairScheduler. After this PR, it doesn’t.

HIGH
New dependency cycle

multithreads and repair now depend on each other.

HIGH
Public method changed

RepairHistory.newSession(…) changed its signature, and 11 classes depend on RepairHistory.

For engineering managers

Your architecture stops living in people’s heads.

Keeping a system coherent while people and agents change it every day is the part nobody owns. Striff makes it part of the process instead: reviews that do not wait on your seniors, documents that stay true, and a trend you can show.

Get started

Start with public repos. Scale to your team.

Nothing to learn and no workflow to change: Striff shows up as one more check on the PRs your team already opens. Start free on public repos, add private repos when you're ready.

Free

$0 forever

Public repositories

Your documented rules and 14 structural checks on every public pull request, plus the browser extension for any public PR you visit.

Starter

$29 /mo · 5 repos

One team's private repos

Your documented rules and 14 structural checks on every private pull request, for one team’s repositories.

Team $59/mo · Scale $149/mo →

Enterprise

Talk to us

Self-hosted & 50+ repos

Private deployment, SSO, and audit workflows for organizations that need full control.

FAQ

Common questions

How does Striff know what my architecture is supposed to look like?

You already wrote it down. Striff catalogues the documents in your repository that make claims about the code, turns each of those sentences into a rule it can evaluate, and answers it against the model your pull request produces, quoting the sentence and linking the file it came from. Nothing is configured and no rule format is invented: your documentation is the rulebook. Underneath that, fourteen deterministic structural checks run on every PR whether or not you have a single doc, flagging the regressions that are almost never intentional: new dependency cycles, first-ever dependency directions between packages, a component reaching into a namespace it had never touched, a public contract changing with no test. Every one of the fourteen is listed in the Check with its own result, whether it fired or not.

What languages does Striff support?

The structural checks and the diagram run on Java, TypeScript, Python and C#. Striff parses source into a full structural model with its own parser, not regex or text matching, so references, inheritance and coupling resolve the way a compiler sees them. Documented rules are further along on some of those than others: Java and C# are production-ready, Python extracts rules from your docs but cannot yet answer all of them, and TypeScript is still being proven out. We would rather say that here than have you install and find out. Go is coming.

Is it just an LLM wrapper?

No, and the architecture is the answer. Every finding is produced by deterministic analysis of the structure your change actually creates: the parser builds a model of both revisions, the checks are queries over that model, and a documented rule holds exactly when its query returns nothing. The model is fact-gated, which means it can rank findings, explain them and write the summary of what your PR did structurally, but it cannot originate one, rename one, or turn "could not answer" into a pass. That last constraint is why a rule Striff cannot evaluate is reported as unanswered instead of quietly counted as green.

Will it slow down or block my pull requests?

No. Striff runs as a GitHub Check next to your CI and posts its results when the analysis finishes, typically within a few minutes. It never blocks a merge unless you choose to make the check required.

What do I need to set up?

Just install the GitHub App. It works on public and private repos alike and posts checks automatically on every PR, with no per-developer setup. Plans start at $29/month, based on how many repos actually get reviewed each month, not how many you connect. Separately, there's a free browser extension: a standalone tool that analyzes any public PR directly in GitHub's UI, a handy way to try Striff on open-source code without installing anything on the repo (bring a free GitHub token; it stays in your browser).

Is my source code sent to a third party or stored?

Your code is parsed on Striff's servers in memory and not persisted. The AI explanation layer works from the structural model (component names, relationships, metrics, and doc excerpts), not your raw source files. For teams that need full control, self-hosted deployment is available on the Enterprise plan.

Code is cheap now. Changing it isn't.

Every unchecked merge makes the next change a little more expensive. It compounds quietly, and nobody can point at the day it started. Striff starts checking on your next pull request.