Skip to content

v2.0.0

Latest

Choose a tag to compare

@github-actions github-actions released this 08 Oct 03:44
91b07dd

2.0.0 (2026-10-06)

⚠ BREAKING CHANGES

  • waivers: code-only, hash-less single-ref and never-class waivers stop applying. waive, apply and import refuse a waive of a never-class code (verdict, disclosure, triage, hygiene, anchor), of an unpublished code, or with no requirement scope, with ERR_WAIVER_REFUSED; a ref is stored as refs [ref] plus the content hash. Stored waivers in those shapes (and hash-less refs) go inert: check ignores them and discloses each as an info waiver-inert diagnostic carrying its unwaive op and, for a wording or structural code, scoped replacement waive ops; stale-hash waivers are listed in data.ignoredWaivers. A waived blocking lint now demotes waived-blocking-lint, so it never yields verified true.

Features

  • config: pin the gate's run settings in symspec.config.json, and init --split (0d0b8a0)
  • document: format v4 schema with the vocabulary, intent and policy (38bb6fc)
  • numeric: disclose a quantity no read bound covers as FND_NUMERIC_UNCOMPARED (1dcf401)
  • ops: op directions and signal classes as data, measured by G-D (4502693)
  • waivers: enforce waivability: refuse never-class and unscoped waivers, inert stored ones (7afb20e)

Bug Fixes

  • advice: bind the numeric/relational repair waiver to its finding's ids and text (b3a7c03)
  • advice: scope a pair demotion's waiver op to its own pair (73f627e)
  • advice: scope the numeric/relational waiver repair to its own pair (57a677c)
  • atomize: keep a , or . between two digits inside its number (5f4de78)
  • check: a run on the stub embedder demotes with run-weakened and discloses data.run (a093538)
  • check: disclose FND_REACHABILITY_NOT_CHECKED when no state model is committed (77f03b4)
  • cli: every flagged command site carries only shell words (R63, R64) (ae268e3)
  • cli: every printed command is shell-safe and names full arguments (R60, R61) (6f7e957)
  • config: a git refusal with no config anywhere falls back and discloses (a158480)
  • config: a nested .git is a toplevel only when the enclosing repository agrees (5ed7bc9)
  • config: find the config with git rev-parse, name it with --config, disclose where it came from (e755084)
  • config: recognise the bare refusal by git's form; a dangling config link is present (36bb975)
  • config: refuse a committed bare-repository layout as the toplevel (50ea778)
  • config: take only git's whole discovery message for "no repository" (86492ea)
  • config: trust only a real .git as the toplevel, and make the pin repair converge (ef7e105)
  • document: label the v4 vocabulary, intent and policy keys experimental (ca83661)
  • document: nested v4 descriptions say what a later release will do (6509f0f)
  • engine: a --semantic-threshold above the default demotes as run-weakened (88af88d)
  • engine: a glossary alias carries its phrase's contraries (425372e)
  • engine: a glossary entry never merges two contraries onto one atom (a170157)
  • engine: AC-3-2 demotes contrary pairs under guards no checked group joins (ef3a5e3)
  • engine: an exact-set waiver suppresses only the finding over exactly its ids (a702d6b)
  • engine: apply the governed-preposition rule to every antonym row (d1dc7de)
  • engine: check "shall not only X but also Y" as a positive obligation (8879845)
  • engine: coverage prose names the real reason no pair was compared (d8fa1af)
  • engine: delete the two preposition guesses that widened a proof (8aeb330)
  • engine: demote on an opposite-polarity pair that differs only in inflection or number (f25d6d1)
  • engine: demote verified with solver-unknown when the contradiction enumeration hits unknown (8056269)
  • engine: demote, never certify, the pairs the antonym split stopped relating (07e66d5)
  • engine: demote, never prove, two responses apart only by their prepositions (92e51a2)
  • engine: discharge an opposition candidate only by its exact, text-bound pair waiver (661c933)
  • engine: disclose opposed numeric bounds under guards never asserted together (8404e95)
  • engine: disclose prohibition sets that conflict only all together (12e7ed8)
  • engine: each antonym verb drops only its own governed preposition (b765b3f)
  • engine: give an unmarked time bound before other text its own role (5a7bbe6)
  • engine: govern every preposition that names the place, per verb and per place (361d228)
  • engine: govern no within, and delete the deadline word list (e327e47)
  • engine: govern no locative, so two different locatives are never one key (cbc9e25)
  • engine: keep a bound's trailing condition, and never compare across it (5d9d65c)
  • engine: keep a digit separator inside its number in the quantity key (8f3a8b1)
  • engine: keep direction prepositions; drop only a class-governed one from the key (3c2617d)
  • engine: key a bound response's action too, disclose one behind other words, and read every asserting complement's copula (9cfe844)
  • engine: key an action's performance as a bound's subject, in every unit class (4cdbb92)
  • engine: key numeric quantities, relational groups and plan systems by the atom scope (54ce198)
  • engine: leave a bound in one cell when no clause holds it (43e378f)
  • engine: link a contrary glossary alias to its entry instead of dropping the equivalence (abb812e)
  • engine: participation means co-live in a decided group; demote unchecked conditional conflicts (28a8fc2)
  • engine: propose the AC-3-6 glossary merge in canonical space, never over a contrary pair (ffcfdbd)
  • engine: prove a numeric pair only on exact keys, and disclose every clause a spelling marks (8c6f0be)
  • engine: prove a response bound only after one noun, a holding verb's time, or a verb alone on a time (a244027)
  • engine: prove a response bound only where the sentence says it holds the quantity (79a3369)
  • engine: prove a role-marked bound only on a recognized time (57da786)
  • engine: read a bound in a response's subject clause by its finite verb too (f71b2dd)
  • engine: read a bound inside a condition with its whole clause (6e00b4d)
  • engine: read a duration after a postmodifier as the object's, not the action's (b2b16cd)
  • engine: read a negated numeric bound as a prohibition, not an obligation (7f13362)
  • engine: read a percent as its own dimension and disclose it against a bare number (966dbc3)
  • engine: read a response that does an action with no bound as doing it (5029c9f)
  • engine: read a two-token antonym head whole in the opposition-candidate tier (17b79cf)
  • engine: read all text after a numeric bound as its qualifier (1767891)
  • engine: read days and weeks as civil time against a bounded day length (f146a64)
  • engine: read every dash that leads a number as the minus sign (09b4eb4)
  • engine: read only the first place preposition as the verb's own place (e13a56a)
  • engine: read scientific notation in a numeric bound with its exponent (975a9fd)
  • engine: relate antonyms only by their pairs; same-side verbs keep their own atoms (a5a8247)
  • engine: report a numeric core only among requirements that can apply at once (c92ad5f)
  • engine: restate the AC-3-6 near-duplicate rule for AC-2-1 contraries (8d015e3)
  • engine: run the AC-3-6 inflection test on canonical response bodies (2e9e8ce)
  • engine: scope every candidate repair waiver to its exact pair and text (fac40ab)
  • engine: scope every propose-tier pair by the atoms' system scope, not the raw name (eb3c19f)
  • engine: split no bound off a subject that holds no clause (b5472d5)
  • engine: the AC-3-6 merge reads the solver's rows and never splits a shared atom (cec61dc)
  • engine: write the cross-side contraries the antonym classes meant as explicit seed rows (f15c48c)
  • formal: demote a pair whose numbers differ only in a digit separator (ce5fe2e)
  • formal: encode opposition as a contrary axiom, never a rename (a6e087d)
  • formal: fold committed glossary and term aliases in the number-spelling finder (224d301)
  • formal: keep case after a number only for unit tokens (956215e)
  • formal: keep every script's letters, the minus sign and unit case (0540279)
  • formal: normalization deletes only identity-free punctuation (47603f1)
  • formal: same-side antonym class members stay one atom (7af9f05)
  • formal: trigger and precondition share one guard namespace (414fa43)
  • formal: withhold event-driven guard-implication bridges from the snapshot (752a4ee)
  • import: exit 1 when a write fence refuses a record, still writing the rest (73be341)
  • import: fold side-table records through apply's fences, in stream order (b6d5f1b)
  • lint: exempt an R6 numeral only after a noun whose instances are numbered (6edd9de)
  • lint: read a numeral that names a converted bound's quantity as a label in R6 (da9d61c)
  • lint: read an _ between two digits as an R6 digit-group boundary (05632b8)
  • lint: read an R6 digit run inside a number the numeric tier read with a unit (50ad2d5)
  • lint: read an R6 identifier numeral only after a numbered noun a quantity verb governs (89708cb)
  • lint: read R6 units off the numeric tier's unit table (18a7f06)
  • numeric: decline a number grouped by _, a quote, or a space (77343c1)
  • numeric: key bounds on (quantity, dimension, unit) with exact conversion (6cdba7e)
  • numeric: prove only under every reading, disclose what the readings split (7defbfc)
  • numeric: read bounds through negation, role, and the whole subject (64da7ad)
  • numeric: read more than, fewer than, up to, and the other missing comparators (7a77050)
  • numeric: read more/fewer than or equal to as one bound (277aa78)
  • numeric: up to is not a comparator, and a leading-decimal quantity is seen (f1d26d7)
  • ops: an alias is weakening, strengthening may only displace, and G-D measures both (3fb1224)
  • ops: antonym is weakening, and displacement is defined per tier by its reporting granularity (e45db17)
  • ops: unwaive is weakening, a dangling edge is hygiene, waivability says it is not enforced (00c04ea)
  • parse: a hyphen neither hides a dropped marker nor stands in for the negator (d8f2af2)
  • parse: a subject negator sets negated only when it opens the main clause (913a645)
  • parse: AC-2-2 and AC-2-3 as outcome post-conditions over base's parse (138f9fd)
  • parse: find an unbound clause after any clause boundary, and before a bare subject (18af998)
  • parse: find an unbound clause behind decoration, and only where it ends before the subject (394e41a)
  • parse: keep negated for every negation that governs the modal (5c0a52b)
  • parse: measure the AC-2-2 dropped span against the modal the tier pivoted on (1b56038)
  • parse: name the whole dropped clause, and gate the AC-2-2 word-membership fallback (2735750)
  • parse: read an apostrophe-less contracted modal ("wont", "shant", "mustnt") as negated (7532a3b)
  • parse: refuse an unbound leading clause with ERR_CLAUSE_UNBOUND (4d67461)
  • parse: set negated only from a negation that governs the modal (31fda7e)
  • reachability: bound the cross-check by distinct states and withhold proofs it cannot examine (28e66ba)
  • reachability: cross-check every small-model proof by explicit-state search (a33ae93)
  • reachability: cross-check many-free-set models and keep a lone int bound on computed initials (28f2274)
  • reachability: let a free variable keep an out-of-range value so the frames nest (65bb3b3)
  • reachability: make frame decide the verdict it documents; ship an applicable repair; exit non-zero on a refused batch op (f1edf90)
  • reachability: reconstruct counterexample traces from the solver's state sequence (407ff09)
  • reachability: report an out-of-range write as FND_RANGE_VIOLATION instead of disabling the step (6d74bbb)
  • reachability: resolve enum members against the sort the type checker assigned (093abc7)
  • reachability: size the explicit-state cross-check by the states it visits (ebdeb57)
  • reachability: the feasibility gate's provable fixture declares the frame its proof needs (01cffbb)
  • release: repoint repository, homepage and bugs to laithalsaadoon/symspec (16905f2)
  • solver: re-issue Z3_interrupt until a cancelled query settles (3f96ea9)
  • state-model: refuse keyword-shaped names under case folding; keep integer literals exact (1567dd1)
  • temporal: a bounded UNSAT that rests on the within-k premise is warn (04da7ab)
  • temporal: read unwanted-behavior as the response obligation G((P ∧ T) → F R) (f5a0d23)
  • term: refuse an alias that overlaps a committed phrase, from either side (541328a)
  • waivers: an unwaive ref that a stored waiver names is that id first (R59) (be4516f)
  • waivers: apply crossed scoped waivers to terminology findings (R57) (c66eecf)
  • waivers: cross a stored waiver only in the shape the fold stores (R54) (b2c2713)
  • waivers: name only commands the CLI parses, no never-code waive prose (R56) (d3db1d0)
  • waivers: unwaive removes only the stored waiver it names (R55) (5264605)