oneline

package
v1.2.11 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package oneline is the one escape every binary in this repo renders caller-supplied or stored text through before it reaches an event line. SPEC.md promises one machine-scannable line per event, and that promise is only true if nothing a path, a reason, a stored key or an error's text contains can add a second line, repaint a terminal, or pose as a field the tool did not write. The package is shared so that the promise is made in one place and met in the same way by nova-check, nova-fuse, nova-memory and nova-self-talk.

Three renderings, one escape form:

Escape  one line: every control character, the Unicode line and paragraph separators,
        and the bidi controls become visible escapes. Used for the free-text tail of a
        line and for positional slots such as a path, which keep their spaces.
Field   one token: Escape, and then every whitespace character and every "=" as well,
        so the value of a key=value field is a single whitespace-free token holding no
        "=" -- a key=value search can only ever match a field the tool wrote.
Quote   one line, and PASTEABLE: a double-quoted Go string literal. For the values a
        person copies out of the output and types back in -- a roster name holding a
        blank, which Field would render \x20 and nobody could paste.
Err     Escape over an error's text, with nil spelled the way fmt would spell it.

The escape form is \xNN for a code point below U+0080 and \uNNNN above it, lower-case hex in both, and a byte that is not valid UTF-8 is written as \xNN by its own value. The escape is not injective -- a literal backslash is not escaped, so a stored newline and the four characters \x0a print the same -- which SPEC.md states: the output proves one line, never which of the two was stored. Nothing is ever shortened to nothing, because a reason a person cannot read is not a record, and every rendering is deterministic.

Index

Constants

View Source
const TailBytes = 500

TailBytes is the ceiling this repo puts on a free-text tail: a subject, a quoted sentence, a finding's detail. Five hundred bytes is a long sentence and a short paragraph -- enough that a tail is never cut in practice, short enough that one pathological value cannot be the whole of a reader's context.

Variables

View Source
var RemedyMarkers = []string{
	"run:", "run `", "remedy:", "remedy=", "fix:", "wants ", "see `",
	"rerun", "next:", " -h", "--help",
	"run nova-", "the repair is", "requires --", "needs --", "or the other", "drop one", "run this again", "run '",
}

RemedyMarkers are the house forms of a remedy on a refusal line (docs/CLI-STYLE.md (f)): the command to run, the flag or value the input wants, where to read, or what to do next. A line holding any of them has left its reader a breadcrumb. No tool or verb fails silently, and every failure carries a breadcrumb that shows how to fix what went wrong. internal/ci's remedy rule reads the source for the same forms, so the two agree on what a remedy is.

Functions

func Cap

func Cap(s string, n int) string

Cap shortens a free-text tail to about n bytes and SAYS SO, which is the half that makes it safe.

Escape and Field bound a value's LINES and never its LENGTH: they are documented as never shortening anything, and that is right for what they are -- a reason a person cannot read is not a record. But it leaves the other half of the one-line promise unmade. One line is not one bounded line, and a stored subject, a ledger row or an embedded git output can be a megabyte on a single line, which is a listing's whole budget spent on one entry that nobody chose to read.

So the ceiling is here, separate, applied by the caller to the tails where a runaway value is possible, and it leaves a mark: `...+<dropped>B`. The mark is the point. An ellipsis alone could be the author's own; the byte count cannot, so a reader who meets a cut tail knows that they met a cut tail and knows what it would cost to see the rest. The mark holds no whitespace and no "=", so a capped value is still one token through Field.

Cap runs BEFORE Escape, never after: it cuts on a rune boundary, so what Escape then sees is well-formed wherever the input was, and an escape sequence can never be cut in half. Cap never returns nothing from something -- a ceiling too small to hold the mark and one rune is raised to hold them, because this package does not shorten a record out of existence.

func Err

func Err(err error) string

Err renders an error into the reason slot of an event, a refusal or a note. An error's text carries whatever the path that produced it carried, so an argument holding a newline would otherwise break the line in two: the caller's own argument rather than stored content, and the guarantee covers both. A nil error keeps fmt's own spelling rather than becoming a sentence claiming more than is known; callers reach this with nil when a write landed and its verification failed for another reason.

func Escape

func Escape(s string) string

Escape renders free text for an event line, and this is the guarantee: nothing the text contains can add a second line or repaint a terminal.

Every control character (Unicode category Cc: the C0 range including \n, \r and \t, DEL, and the C1 range) becomes a visible escape. So do U+2028 and U+2029, the line and paragraph separators, which are Zl and Zp rather than Cc: they break a line for Python's str.splitlines and for every UAX-14 line breaker. And so do the bidi controls, U+202A to U+202E (the embeddings and overrides) and U+2066 to U+2069 (the isolates), which are format characters rather than controls: a terminal that honors them displays the rest of the line with its visible order rearranged, which is the same hole aimed at an operator rather than a parser. The other format characters -- the zero-width joiner that emoji sequences are built from, the soft hyphen, the byte-order mark -- pass through, because they do not reorder what an operator sees.

A byte that is not valid UTF-8 is escaped by its own value in the same \xNN form. Box content and file content that arrived through a JSON or UTF-8 decoder has had U+FFFD substituted for it already, so that branch is reached only by text that passed through neither, such as an error's. Everything else printable passes through untouched, including non-ASCII.

func Field

func Field(s string) string

Field renders the value of a key=value field, or any other slot a scanner reads as one token. It is Escape and then more: every whitespace character (unicode.IsSpace, so a non-breaking or ideographic blank as well as the ASCII one) and every "=" is escaped in the same form, \x20 and \x3d for the two ASCII cases. The value is therefore a single whitespace-free token holding no "=", so a whitespace-splitting scanner sees one field where the tool wrote one, and a search for key=value can match only a field the tool wrote and never text a stored key or a caller's path happens to contain. The specimen this exists for is a stored quarantine key of `x lockdown=clear quarantines=0`, which printed raw made a grep for lockdown=clear match a line about a blown lockdown.

func HasRemedy

func HasRemedy(s string) bool

HasRemedy reports whether a refusal's text carries a remedy in one of the house forms.

func Quote

func Quote(s string) string

Quote renders a value a person is meant to COPY: a roster name, which may hold a blank and is pasted back into a To: line.

FIELD IS WRONG FOR THOSE, and it was used for them. Field escapes every whitespace character, so `nova-bus names` printed `Ada\x20Vale` -- one token a scanner can read, and a name nobody can paste into the header of a note. The whole purpose of that verb is to tell a person how to spell a To line this tool will accept, and it was telling them something the tool would refuse.

The one-line guarantee is kept by a different route rather than dropped. strconv.Quote escapes every control character and every rune Go considers unprintable -- U+2028 and U+2029, which are Zl and Zp and end a line for a Unicode-aware reader, and the bidi controls, which are Cf -- as well as the double quote and the backslash themselves. So the result is one line whatever the value holds, the delimiters say where the value starts and stops even when it holds a blank, and unlike Escape it is INJECTIVE: a backslash is escaped too, so what is between the quotes is the value and nothing else. A list of these is joined with ";" between the closing quote and the next opening one, which is what a To line's own separator is.

func ShellWord

func ShellWord(s string) string

ShellWord renders one caller-supplied value (a path, a name, a program) for a command a reader is told to run, so a POSIX shell reads it back as that one value: a value made only of characters no shell gives a meaning (letters, digits and _ . / : @ % + = , -) is printed as it is, so simple remedies stay simple; anything else, and the empty value, is single-quoted, an embedded single quote written '"'"' (close, a double-quoted quote, reopen), so a blank, a quote, $(...), a ; or a newline is the value's own character. Every remedy that carries a value goes through it: the remedy is run, so its words must be the words meant.

func WithRemedy

func WithRemedy(what, next string) string

WithRemedy is what rendered through Escape, ended with "; run: <next>" when it carries no remedy of its own: a refusal printer calls it so that no line it prints leaves the reader without a next step, and a line that already names one is left as it is. It escapes, so it is an escaper in its own right (the audit counts it as one); Escape changes nothing it already rendered, so WithRemedy(Err(err), next) escapes once.

Types

This section is empty.

Directories

Path Synopsis
Package audit is the source-level tripwire behind the one-line guarantee, shared by every binary in this repo.
Package audit is the source-level tripwire behind the one-line guarantee, shared by every binary in this repo.

Jump to

Keyboard shortcuts

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