Help us shape the future of Go! Take the 2026 Go Developer Survey

textsafe

package
v0.19.1 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package textsafe is the fail-closed remote text dissection engine used by sshx text. It classifies log lines, extracts exception blocks, applies bounded filters, and redacts secret-shaped spans. It never shells out.

Index

Constants

View Source
const (
	SchemaVersion     = "sshx.text.v1"
	HelpSchemaVersion = "sshx.text.help.v1"

	DefaultMaxHits      = 20
	DefaultMaxBytes     = 64 << 10
	DefaultMaxScanBytes = 8 << 20
	MaxContext          = 20
	MaxBlockLines       = 80
	MaxLineBytes        = 16 << 10
	DefaultJournalLines = 2000

	KindExceptionBlock = "exception_block"
	KindErrorLine      = "error_line"
	KindPanicLine      = "panic_line"
	KindOOMLine        = "oom_line"
	KindHTTP5xx        = "http5xx"
	KindPattern        = "pattern"
	KindSlice          = "slice"

	SourceFile    = "file"
	SourceJournal = "journal"

	ScanEnd   = "end"
	ScanStart = "start"

	LineOriginWindow = "scanned_window"
	LineOriginFile   = "file"
)

Variables

This section is empty.

Functions

func FileReadCommand

func FileReadCommand(path string, fromEnd bool, maxBytes int64, sudo bool) string

FileReadCommand is the sshx-owned privileged file reader. Path must already be a clean absolute path.

func HasTruncationReason added in v0.18.0

func HasTruncationReason(reason, want string) bool

HasTruncationReason reports whether the comma-joined truncated_reason list contains want. One window can stop for several reasons at once ("max_scan_bytes,max_hits"), so callers must test membership rather than string equality.

func JournalCommand

func JournalCommand(req Request, sudo bool) string

JournalCommand builds an sshx-owned journalctl argv string. unit/since/until must already have passed validation.

func Redact

func Redact(text string) string

Redact replaces secret-shaped spans. It is conservative: unmatched text is kept.

func ValidateJournalUnit

func ValidateJournalUnit(unit string) error

ValidateJournalUnit accepts systemd unit names sshx is willing to put on argv.

func ValidateTextPath

func ValidateTextPath(remotePath string) error

ValidateTextPath requires a clean absolute POSIX path. Remote paths never use the local OS separator, including when sshx itself runs on Windows.

func ValidateTimeBound

func ValidateTimeBound(value string) error

ValidateTimeBound allows journalctl-style since/until values without shell metacharacters.

Types

type FilterInfo

type FilterInfo struct {
	Presets []string `json:"presets,omitempty"`
	Pattern string   `json:"pattern,omitempty"`
	Context int      `json:"context,omitempty"`
}

FilterInfo records the applied presets and pattern.

type HelpDocument

type HelpDocument struct {
	SchemaVersion string       `json:"schema_version"`
	Verb          string       `json:"verb"`
	Summary       string       `json:"summary"`
	Workflow      []string     `json:"workflow"`
	Sources       []HelpFlag   `json:"sources"`
	Filters       []HelpFlag   `json:"filters"`
	Windows       []HelpFlag   `json:"windows"`
	Bounds        []HelpFlag   `json:"bounds"`
	Presets       []HelpPreset `json:"presets"`
	Examples      []string     `json:"examples"`
}

HelpDocument is the machine-readable usage surface for sshx text --help --json.

func Help

func Help() HelpDocument

Help returns the canonical Agent-facing usage document.

type HelpFlag

type HelpFlag struct {
	Flag        string `json:"flag"`
	Description string `json:"description"`
}

HelpFlag documents one CLI flag.

type HelpPreset

type HelpPreset struct {
	Name        string `json:"name"`
	Description string `json:"description"`
}

HelpPreset documents a lexical preset.

type Hit

type Hit struct {
	Kind      string `json:"kind"`
	Level     string `json:"level,omitempty"`
	StartLine int    `json:"start_line"`
	EndLine   int    `json:"end_line"`
	Text      string `json:"text"`
}

Hit is one returned extraction. Text is already redacted when requested.

type ProgressObserver added in v0.18.0

type ProgressObserver interface {
	Progress(ScanProgress)
}

ProgressObserver receives progress samples. Implementations must not block and must never write to stdout, which carries the JSON result.

type Request

type Request struct {
	Kind             string
	Path             string
	JournalUnit      string
	Since            string
	Until            string
	Presets          []string
	Pattern          string
	Context          int
	AroundLine       int
	Offset           int
	Limit            int
	Tail             int
	Scan             string
	MaxHits          int
	MaxBytes         int
	MaxScanBytes     int64
	Redact           bool
	JournalLines     int
	SkipPartialFirst bool
	WindowStartByte  int64
	FileSize         int64
	// contains filtered or unexported fields
}

Request is the local dissection plan. Call Normalize before Scan.

func (*Request) Normalize

func (r *Request) Normalize() error

Normalize fills defaults and rejects contradictory options.

type Result

type Result struct {
	Source          SourceInfo `json:"source"`
	Filter          FilterInfo `json:"filter"`
	Stats           Stats      `json:"stats"`
	Hits            []Hit      `json:"hits"`
	Truncated       bool       `json:"truncated"`
	TruncatedReason string     `json:"truncated_reason,omitempty"`
	Redacted        bool       `json:"redacted"`
	LineOrigin      string     `json:"line_origin"`
}

Result is the engine output before host/lifecycle wrapping.

func Scan

func Scan(r io.Reader, req Request) (Result, error)

Scan reads r once and returns bounded, classified hits.

func ScanWithProgress added in v0.18.0

func ScanWithProgress(r io.Reader, req Request, observer ProgressObserver) (Result, error)

ScanWithProgress is Scan with bounded progress samples. The observer must not block and must not write to stdout.

type ScanProgress added in v0.18.0

type ScanProgress struct {
	Bytes        int64
	Lines        int
	MatchedLines int
	FileSize     int64
}

ScanProgress is a bounded progress sample taken while a scan is running. MatchedLines counts lines that matched --pattern so far and stays zero when no pattern was requested.

type SourceInfo

type SourceInfo struct {
	Kind            string `json:"kind"`
	Path            string `json:"path,omitempty"`
	JournalUnit     string `json:"journal_unit,omitempty"`
	Since           string `json:"since,omitempty"`
	Until           string `json:"until,omitempty"`
	Scan            string `json:"scan,omitempty"`
	BytesScanned    int64  `json:"bytes_scanned"`
	WindowStartByte int64  `json:"window_start_byte,omitempty"`
	FileSize        int64  `json:"file_size,omitempty"`
}

SourceInfo identifies what was scanned.

type Stats

type Stats struct {
	LinesScanned    int   `json:"lines_scanned"`
	BytesScanned    int64 `json:"bytes_scanned"`
	TotalHits       int   `json:"total_hits"`
	Returned        int   `json:"returned"`
	ExceptionBlocks int   `json:"exception_blocks"`
	TotalHitsExact  bool  `json:"total_hits_exact"`
	WindowStartByte int64 `json:"window_start_byte,omitempty"`
	FileSize        int64 `json:"file_size,omitempty"`
	// ExpectedScanBytes is how much this request expects to read: the byte
	// window it opened, capped by --max-scan-bytes. A caller can weigh it
	// before trusting TotalHitsExact, and a mismatch with BytesScanned means
	// the scan stopped early instead of covering its window. It is additive to
	// sshx.text.v1 and omitted when the source size is unknown (journal).
	ExpectedScanBytes int64 `json:"expected_scan_bytes,omitempty"`
}

Stats reports scan bounds. TotalHitsExact is false when the scan stopped early.

Jump to

Keyboard shortcuts

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