engine

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2026 License: MIT Imports: 25 Imported by: 0

README

blotless/engine

Detection and cleaning engine for blotless
Layer A Unicode, Layer B survey, C2PA / file metadata. Zero CGO.

Language: English | Русский

CI Go Reference Go Report Card License Latest Release Go Version


Overview

engine is the library of the blotless ecosystem — walk, classify, detect, merge, score, and plan patches. The CLI in blotless/cli is a thin Cobra wrapper around engine.Scan / engine.Clean.

Detectors receive a domain.Unit (already-loaded bytes). They do not read the filesystem.

Key Features

Category Capabilities
Layer A Invisible Unicode, exotic spaces, bidi, tags, VS, other Cf, Latin confusables
Layer B Eligibility survey; engine/rewrite hook; optional Ollama / openai (paraphrase / humanize / code / backtranslate / structural)
Files C2PA / EXIF / XMP in PNG, JPEG, WebP, SVG, PDF, DOCX, ODT, HTML, Markdown
Web audit engine/webaudit — SSRF-safe sitemap fetch
Go source Homoglyph idents; string / go:generate protect spans via internal/astgo
Stamps AI co-author / generator phrases in comments only
Clean Strip / normalize / rewrite; optional NFKC; gofmt for Go
Build CGO_ENABLED=0, Go 1.26+. Pre-release: task preflight (Taskfile.yml)

Installation

go get github.com/blotless/engine

Requirements: Go 1.26+, CGO_ENABLED=0.


Quick Start

package main

import (
	"context"
	"fmt"

	"github.com/blotless/engine"
)

func main() {
	eng, err := engine.New(engine.Config{
		Paths:      []string{"."},
		Aggressive: true,
	})
	if err != nil {
		panic(err)
	}
	defer eng.Close()

	res, err := eng.Scan(context.Background())
	if err != nil {
		panic(err)
	}
	fmt.Printf("findings=%d score=%d\n", len(res.Findings), res.Score.Percent)
}

Architecture

walk → classify → detect → protect → merge → score
                              │
clean ← plan ← optional LLM ← Layer B survey

Public surface: engine.Config, engine.Scan, engine.Clean, engine.Rules, domain, ports.


Ecosystem

Project Description
blotless/engine Detection / clean library (this repo)
blotless/cli Command-line interface
blotless/skills Agent skill package (calls blotless on PATH)

License

MIT License — see LICENSE for details.


blotless — inspect first, then clean

Documentation

Index

Constants

View Source
const DefaultMaxFileBytes = 8 << 20

Variables

This section is empty.

Functions

func Report

func Report(w io.Writer, format string, res *Result, version string) error

Report writes findings using format (table|json|yaml|sarif).

func WriteFinding

func WriteFinding(w io.Writer, f domain.Finding, lastFile string) string

WriteFinding prints one live finding. Pass lastFile from the previous call.

Types

type Config

type Config struct {
	Paths          []string
	Include        []string
	Exclude        []string
	Aggressive     bool
	FailOn         domain.Confidence
	LLM            LLMConfig
	Write          bool
	Backup         string
	MaxFileBytes   int64
	DisabledRules  []string
	Gofmt          bool
	LayerB         bool
	LayerBStrength string
	NFKC           bool
	ForceText      bool
	ForceKind      string // auto|text|image|container
	Logger         *slog.Logger
	Progress       ports.Progress
}

Config is the CLI-facing engine configuration. Cobra/Viper must not leak in.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine orchestrates walk, detect, merge, and clean.

func New

func New(cfg Config) (*Engine, error)

New constructs an engine from config. LLM adapters are wired here.

func (*Engine) Clean

func (e *Engine) Clean(ctx context.Context) (*Result, error)

Clean plans patches and optionally writes them.

func (*Engine) Close

func (e *Engine) Close() error

Close stops a managed Ollama process if this engine started it.

func (*Engine) Scan

func (e *Engine) Scan(ctx context.Context) (*Result, error)

Scan walks paths and returns findings. It never writes files.

type LLMConfig

type LLMConfig struct {
	Mode     string
	Model    string
	Endpoint string
	Timeout  time.Duration
	APIKey   string
}

LLMConfig selects an optional language-model adapter.

type Result

type Result struct {
	FilesScanned int
	FilesSkipped int
	Findings     []domain.Finding
	Patches      []domain.Patch
	DryRun       bool
	Score        domain.Score
	After        *domain.Score
	Leftover     []domain.Finding
	Streamed     bool
	TextFiles    int            `json:"text_files,omitempty" yaml:"text_files,omitempty"`
	ImageFiles   int            `json:"image_files,omitempty" yaml:"image_files,omitempty"`
	DocFiles     int            `json:"doc_files,omitempty" yaml:"doc_files,omitempty"`
	DetectorHits map[string]int `json:"detector_hits,omitempty" yaml:"detector_hits,omitempty"`
	LayerA       int            `json:"layer_a"`
	LayerFiles   int            `json:"layer_files"`
	LayerB       int            `json:"layer_b"`
	LayerBOpt    int            `json:"layer_b_optional,omitempty"`
	LayerBFiles  []string       `json:"layer_b_files,omitempty"`
}

Result is the outcome of Scan or Clean.

func (Result) ShouldFail

func (r Result) ShouldFail(failOn domain.Confidence) bool

ShouldFail reports whether findings meet FailOn.

type RuleInfo

type RuleInfo struct {
	ID          string `json:"id" yaml:"id"`
	Family      string `json:"family" yaml:"family"`
	Severity    string `json:"severity" yaml:"severity"`
	Confidence  string `json:"confidence" yaml:"confidence"`
	Clean       string `json:"clean" yaml:"clean"`
	Description string `json:"description" yaml:"description"`
}

RuleInfo is a public view of an embedded rule spec.

func Explain

func Explain(id string) (RuleInfo, error)

Explain returns one rule spec.

func Rules

func Rules() ([]RuleInfo, error)

Rules returns the embedded catalog.

Directories

Path Synopsis
internal
astgo
Package astgo parses Go source and yields byte-offset spans for comments, identifiers, and string literals.
Package astgo parses Go source and yields byte-offset spans for comments, identifiers, and string literals.
layerb
Package layerb plans best-effort rewrites against token-sampling watermarks (Kirchenbauer / SynthID-Text).
Package layerb plans best-effort rewrites against token-sampling watermarks (Kirchenbauer / SynthID-Text).
llm
Package rewrite implements the Layer B text rewrite hook (WR rewrite_text.py).
Package rewrite implements the Layer B text rewrite hook (WR rewrite_text.py).
Package webaudit audits URLs from a sitemap (WR audit_website.py), SSRF-safe.
Package webaudit audits URLs from a sitemap (WR audit_website.py), SSRF-safe.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL