style: remove every em-dash and en-dash

Eighteen occurrences across fourteen files. Each sentence was repunctuated to
suit what the dash was doing rather than swapped for a hyphen, which produces
comma splices. The minus sign in folio-web's ledger is a minus sign and stays.

Claude-Session: https://claude.ai/code/session_01A5KmftdEJ49A9z5mF5ESrX
This commit is contained in:
pj committed 2026-08-12 20:48:33 +05:30
1 parent 7c3c2b206f
commit 40cdb455bd
14 files changed
+19 -19

No files matched your search

+1 -1
View File
@@ -17,7 +17,7 @@
## PR Rules ## PR Rules
- Simple PR title, few-line description. Never write a wall of text — nobody reads it. - Simple PR title, few-line description. Never write a wall of text. Nobody reads it.
- Everything lowercase in PR titles, descriptions, and comments. - Everything lowercase in PR titles, descriptions, and comments.
### PR Description Rules ### PR Description Rules
+2 -2
View File
@@ -82,8 +82,8 @@ Traces land in `./sanderling/runs/<timestamp>/`.
The same `sanderling/spec.ts` runs under either generator: `--generator seeded` The same `sanderling/spec.ts` runs under either generator: `--generator seeded`
(the default weighted fuzzer) or `--generator llm`, where a vision model picks (the default weighted fuzzer) or `--generator llm`, where a vision model picks
from the SAME weighted candidate set — reading the screenshot plus a numbered, from the SAME weighted candidate set (reading the screenshot plus a numbered,
weight-annotated list of concrete actions — and returns one number. The spec's weight-annotated list of concrete actions) and returns one number. The spec's
`generator = llm({ model, instructions })` export configures it. `generator = llm({ model, instructions })` export configures it.
```sh ```sh
+1 -1
View File
@@ -192,7 +192,7 @@ export const actionsRoot = weighted(
// The LLM generator is orthogonal to actionsRoot: with `--generator llm` a model // The LLM generator is orthogonal to actionsRoot: with `--generator llm` a model
// picks from the SAME weighted candidate set above, reading the screenshot and a // picks from the SAME weighted candidate set above, reading the screenshot and a
// numbered, weight-annotated list; the default `--generator seeded` ignores it. // numbered, weight-annotated list; the default `--generator seeded` ignores it.
// instructions describe only WHAT the app is, never HOW to test it — the model // instructions describe only WHAT the app is, never HOW to test it. The model
// figures out how to surface bugs on its own. With a plain OpenAI key, drop the // figures out how to surface bugs on its own. With a plain OpenAI key, drop the
// vendor prefix from the model id. // vendor prefix from the model id.
export const generator = llm({ export const generator = llm({
+1 -1
View File
@@ -68,7 +68,7 @@ func TranslateStringSelector(selector string) (string, bool, error) {
// - everything else passes through, including non-ASCII // - everything else passes through, including non-ASCII
// //
// Callers should not pass this output into identifier contexts (class names, // Callers should not pass this output into identifier contexts (class names,
// tag names) — use an attribute selector form (`[class~="..."]`) instead. // tag names). Use an attribute selector form (`[class~="..."]`) instead.
func cssEscape(value string) string { func cssEscape(value string) string {
var builder strings.Builder var builder strings.Builder
builder.Grow(len(value)) builder.Grow(len(value))
+3 -3
View File
@@ -45,9 +45,9 @@ func TestThunk_TransitionFromHoldToViolate(t *testing.T) {
wantSequence := []Verdict{ wantSequence := []Verdict{
VerdictHolds, // true VerdictHolds, // true
VerdictHolds, // true VerdictHolds, // true
VerdictViolated, // false — latches VerdictViolated, // false: latches
VerdictViolated, // true after violation — still violated VerdictViolated, // true after violation: still violated
VerdictViolated, // true after violation — still violated VerdictViolated, // true after violation: still violated
} }
for index, want := range wantSequence { for index, want := range wantSequence {
got := evaluator.Observe() got := evaluator.Observe()
+1 -1
View File
@@ -34,7 +34,7 @@ const (
// screenshot, picks ONE number, and echoes that action so a mismatch can be // screenshot, picks ONE number, and echoes that action so a mismatch can be
// caught. The app-specific description (spec instructions) is appended. // caught. The app-specific description (spec instructions) is appended.
const llmSystemPrompt = "You are exercising a UI to find bugs. Each turn you get a screenshot and a numbered list of concrete actions, each with a weight hinting how much the test author wants it exercised (higher = more). " + const llmSystemPrompt = "You are exercising a UI to find bugs. Each turn you get a screenshot and a numbered list of concrete actions, each with a weight hinting how much the test author wants it exercised (higher = more). " +
"Pick the ONE action most likely to make progress or expose a defect. Bugs often hide in repeated or rapid actions, so once a screen works, deliberately stress it — for example submitting the same form twice in a row to check it is not applied more than once — rather than only advancing. " + "Pick the ONE action most likely to make progress or expose a defect. Bugs often hide in repeated or rapid actions, so once a screen works, deliberately stress it (for example submitting the same form twice in a row to check it is not applied more than once) rather than only advancing. " +
"Respond with your reasoning, the chosen number, and chosen_action copied verbatim from that line. For a typing action, also provide the text to enter." "Respond with your reasoning, the chosen number, and chosen_action copied verbatim from that line. For a typing action, also provide the text to enter."
// llmSource selects each step's action with an OpenAI-compatible vision model // llmSource selects each step's action with an OpenAI-compatible vision model
+1 -1
View File
@@ -92,7 +92,7 @@ type Action struct {
// LLMChoice is the 1-based number the model picked from the candidate list; // LLMChoice is the 1-based number the model picked from the candidate list;
// LLMChosenAction is the action description it echoed for that number. The // LLMChosenAction is the action description it echoed for that number. The
// runner strict-skips when the echo disagrees with the numbered entry, so on // runner strict-skips when the echo disagrees with the numbered entry, so on
// a recorded action the two always agree — the replay UI shows them to // a recorded action the two always agree; the replay UI shows them to
// confirm the reasoning matched the executed action. // confirm the reasoning matched the executed action.
LLMChoice int `json:"llm_choice,omitempty"` LLMChoice int `json:"llm_choice,omitempty"`
LLMChosenAction string `json:"llm_chosen_action,omitempty"` LLMChosenAction string `json:"llm_chosen_action,omitempty"`
+2 -2
View File
@@ -12,8 +12,8 @@ export function next(predicate: () => boolean): Formula {
return globalThis.__sanderling__.next(predicate); return globalThis.__sanderling__.next(predicate);
} }
// An unbounded `eventually` never forces a violation within a finite run — // An unbounded `eventually` never forces a violation within a finite run.
// prefer `.within(n, unit)` when you want the verifier to fail a property // Prefer `.within(n, unit)` when you want the verifier to fail a property
// that stalls. // that stalls.
export function eventually(predicate: () => boolean): EventuallyFormula { export function eventually(predicate: () => boolean): EventuallyFormula {
return globalThis.__sanderling__.eventually(predicate); return globalThis.__sanderling__.eventually(predicate);
+1 -1
View File
@@ -151,7 +151,7 @@ export function installRuntime(
defineLockedGlobal("__sanderlingExtractors__", () => evaluateExtractors()); defineLockedGlobal("__sanderlingExtractors__", () => evaluateExtractors());
// __sanderlingSetupAction__ walks ONLY the setup generator once, for the LLM // __sanderlingSetupAction__ walks ONLY the setup generator once, for the LLM
// action generator (Go), which drives selection itself and must not run the // action generator (Go), which drives selection itself and must not run the
// seeded action root — but still wants setup's precondition steps (e.g. login) // seeded action root, but still wants setup's precondition steps (e.g. login)
// to run first. Returns null when setup is unset or yields nothing. // to run first. Returns null when setup is unset or yields nothing.
defineLockedGlobal("__sanderlingSetupAction__", () => { defineLockedGlobal("__sanderlingSetupAction__", () => {
resolveRoot(); resolveRoot();
+1 -1
View File
@@ -113,7 +113,7 @@ export interface State {
/** /**
* State as observed inside a web (V8/browser) extractor. Adds the live * State as observed inside a web (V8/browser) extractor. Adds the live
* `document` and `window` handles. `state.document` is V8-only — goja-side * `document` and `window` handles. `state.document` is V8-only, so goja-side
* predicates do not see it; if you need DOM data in a predicate, surface it * predicates do not see it; if you need DOM data in a predicate, surface it
* via an `extract()`. * via an `extract()`.
*/ */
@@ -7,7 +7,7 @@ import {
} from "../lib/action-format"; } from "../lib/action-format";
import { summary } from "./fixtures"; import { summary } from "./fixtures";
// Bug class: selector parsing mislabels every action row — splitting on the // Bug class: selector parsing mislabels every action row. Splitting on the
// wrong colon, treating a value-with-colon as the kind, or dropping the prefix // wrong colon, treating a value-with-colon as the kind, or dropping the prefix
// ellipsis would render the wrong target tag for every step. // ellipsis would render the wrong target tag for every step.
describe("parseSelector", () => { describe("parseSelector", () => {
+1 -1
View File
@@ -28,7 +28,7 @@ export function useTheme(): { theme: ThemeMode; toggle: () => void } {
try { try {
window.localStorage.setItem(STORAGE_KEY, theme); window.localStorage.setItem(STORAGE_KEY, theme);
} catch { } catch {
// private mode or storage disabled — theme still applies for the session. // private mode or storage disabled. Theme still applies for the session.
} }
}, [theme]); }, [theme]);
+2 -2
View File
@@ -18,8 +18,8 @@ export interface RunHistory {
// that armed it, so the checker records the violation on the DETECTION step // that armed it, so the checker records the violation on the DETECTION step
// while its witness names the CAUSE step. The timeline dot (the backend's // while its witness names the CAUSE step. The timeline dot (the backend's
// markViolations) already sits on the cause step; mirror that here so the // markViolations) already sits on the cause step; mirror that here so the
// Violations tab and property lanes light up on the same step — the guilty // Violations tab and property lanes light up on the same step: the guilty
// action — not the unrelated action that happened to be running when the // action, not the unrelated action that happened to be running when the
// obligation resolved. Steps are cloned, never mutated in place. // obligation resolved. Steps are cloned, never mutated in place.
export function relocateViolationsToCause( export function relocateViolationsToCause(
steps: (Step | null)[], steps: (Step | null)[],
+1 -1
View File
@@ -26,7 +26,7 @@ val maestroVersion = "2.4.0"
// Maestro 2.4.0 still declares grpc-netty:1.50.2 and grpc-okhttp:1.50.2 which // Maestro 2.4.0 still declares grpc-netty:1.50.2 and grpc-okhttp:1.50.2 which
// were compiled against AbstractManagedChannelImplBuilder removed in grpc-core 1.64+. // were compiled against AbstractManagedChannelImplBuilder removed in grpc-core 1.64+.
// Force them to the version we pin so they stay binary-compatible. // Force them to the version we pin so they stay binary-compatible.
// Also exclude GraalVM JS — not used by our sidecar and causes shadow JAR expansion errors. // Also exclude GraalVM JS: not used by our sidecar and causes shadow JAR expansion errors.
configurations.all { configurations.all {
resolutionStrategy.eachDependency { resolutionStrategy.eachDependency {
if (requested.group == "io.grpc" && if (requested.group == "io.grpc" &&