sdg: IP 0001 — foundational machine surfaces for an external spec UI - #7
Open
lzrscg wants to merge 174 commits into
Open
sdg: IP 0001 — foundational machine surfaces for an external spec UI#7lzrscg wants to merge 174 commits into
lzrscg wants to merge 174 commits into
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
… seed Triage: improvement (new machine-consumable surfaces require SPEC.md changes). Developer confirmed CLI-only connection, UI-owned text editing, and saved-files-only analysis; audit candidates folded in on their merits (parse-local availability, tag sub-ranges, multi-file document view, comment ranges, invocation-anchored root, direct position query). SEED.md consumed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…odel, exit mapping, refresh, inventory provenance, preview edits, interface versioning Applied: I1 (identity/interpreted-data model for parseable-but-invalid files; invalid imports listed with unavailable targets), I2 (unavailable-data list corrected — occurrence targets never unavailable, source identities and import targets can be; parse-local claim scoped to positions/spellings), I3 (exit mapping stated: findings or unavailable data in the answer -> 1, clean complete answer -> 0, usage/config errors keep 2; answer always emitted), I4 (new query surfaces join read-time refresh on valid workspaces, modify nothing on imperfect ones; inventory never refreshes or writes), I5 (inventory availability restated as parse-independence; content provenance split into invocation/config/discovery, recorded generation state, filesystem), I6 (preview edit classes enumerated: occurrence rewrites, id-attribute rewrites, import specifier/addition/removal edits, section-move deletion/insertion/ self-closing rewrite, file relocation; derived-file removals added), I7 (machine-interface version value stated in SPEC.md, surface reports exactly it — per-build observable; contract scope defined), O1 (per-unit ranges for multi-unit declarations), O2 (identical-range tiebreak removed as unreachable), O3 (byte-classification claim scoped; position-resolution totality and EOF/ beyond-EOF rules), O4 (policy rules reported at coverage-profile depth), O5 (cross-drive anchoring rule). Rejected: none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…t-2 JSON channel, expansion definedness, enumeration domain, identification preconditions Applied: I1, I2, I3, I4, I5, O1, O2, O3, O4, O5. Rejected: none. - I1: change 8 gains a workspace-independence bullet — consults no workspace or configuration, cannot fail for configuration reasons. - I2: resolved via the channel arm (bullet 2 of change 6 already committed the IP to machine-consumable configuration errors): exit-2 errors emit a JSON error document as the entire standard output, amending the empty-stdout rule. - I3: occurrence spans stated per kind; MDX embedding spans the full braced container, which change 3's byte-classification claim now cites. - I4: dropped "hashes" from the unavailable-data list (no surface this proposal adds reports hashes; naming one would add an unrequested capability) and added the exact expansion-definedness rule (every transitively reached embedding records an occurrence, no cycle re-entered). - I5: finding reporting defined over a consulted domain; a target-only enumeration's domain is the whole discovered set, so masked files always surface as findings with exit 1. - O1: joint-location claim scoped to parseable files. - O2: created-target-file previews report the creation as its own class with the insertion point at file start. - O3: inventory's review-session listing is name-based and content-blind, corrupt sessions included. - O4: structured-diagnostics contract extended to rename/move refusal reasons. - O5: product version phrased as informational; testable contract carried by the machine-interface version. - Compatibility note records the two convention amendments (exit-2 JSON form, change-8 precedence exception). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
Applied all items; none rejected. - C1: widened change 4's view domain — when expanded text is requested, the domain gains every file the expansions transitively consult, so the finding blocking an expansion is always in-domain and the never-silent guarantee holds. - I1: change 1's target-node filter is now syntactic acceptance — a well-formed targetable identity selects (possibly zero) occurrences by resolved target; nonexistent, masked, identity-undefined, and unknown targets yield an empty answer with domain findings; only malformed spellings are usage errors; delta flagged in compatibility notes. - O1: default-export unit ranges (named construct vs. export declaration). - O2: graph-data area reported unconditionally as derived, xspec-owned. - O3: session listing selects directory entries by name whatever occupies the path. - O4: preview derived-file consequences defined as the identity-relevant delta, not the full regeneration set. - O5: preview/real-operation equivalence scoped to workspace state, not scheduling. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…ion, corrupt-record outcome, file-filter semantics, availability scoping Applied all items; rejected none. - I1: graph-data area reported as owned with the durable paths carved out and taking precedence — never a blanket derived, deletable unit. - I2: recorded state present but unreadable (corrupt graph data) gets a defined outcome: recorded entries explicitly unavailable, corruption a reported finding, exit 1, full inventory still emitted. - I3: change 1 file filter pinned to the existing file-glob convention (set restriction, empty admission = empty exit-0 answer); the malformed-identity usage-error sentence scoped to the target filter. - I4: change 4 closing sentence scoped to changes 1 and 3, naming where changes 5/7/8 state their own availability. - O1: explicit TypeScript spans — text(...) occurrence = whole call expression; marker occurrence = bare chain, no statement terminator. - O2: "the two" replaced — profiles and rules alike fully expanded. - O3: multi-file view order pinned to byte order of workspace-relative path. - O4: journal occupancy datum added (absence = empty journal). - O5: origin-deletion class's single range covers the adjunct dropped-line bytes, contiguous by construction; no separate class. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…ce-absence guarantee Iteration 5 of patch refinement for 0001-external-ui-apis (IP). Applied: - C1: replaced the graph-data area's contradictory per-occupant ownership composition with one rule stated once in the area entry: the area is a write reservation; reported durable and recorded derived paths are classified as reported; every other path under the area is unattributed — never listed, never claimed, never presented as rebuild-recoverable. The availability paragraph's review-session sentence now defers to that rule instead of asserting opposite ownership. - I1: the empty-finding-free-answer guarantee of change 1 is now scoped to the consulted domain, absolute exactly when no file filter narrows it. - O1: change 4's resolution-failure exemplars now include the unique-bearer-with-undefined-identity case change 1 cites. - O2: change 6 defines the concerned path for missing configuration with no --config: the search-origin directory (invocation working directory), invocation input like change 5's anchoring; compatibility note updated so the invocation-anchored exception covers both changes. - O3: change 5's configuration view names its shape: profiles and rules carried with complete definitions; group references stay names resolved against the view's own group list, never glob expansions. - O4: split the change-1 file-filter sentence and the change-5 provenance/availability sentences into separable statements, all clauses preserved. Rejected: none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…n unknowability (iter 6) Applied I1: change 2's second bullet now names the exact outputs that gain code-location ranges — occurrence records present their source graph node as one datum (identity plus that node's own construct range; changes 1 and 4 adjusted to match), review payloads generalize the present-node range rule from requirement nodes to graph nodes, and query edge endpoints explicitly remain bare identities. Applied I2: the graph-data-area bullet no longer claims an unattributed path is irrecoverable (false for the graph-data subcase per SPEC 12.1/13.3); the undeletable rule now rests on the consumer's inability to tell regenerable graph data from foreign content. Applied O1: view's glob form states the empty-match outcome (empty set, finding-free, exit 0), mirroring change 1. Applied O2: anchoring bullet's "never as absolute paths" now carries the different-Windows-drives carve-out stated at the change's end. Applied O3: a root's tags/coverage attribute are defined structural absence, not change 4 unavailability — no finding, no exit-1 consequence. Applied O4: preview edits explicitly carry no replacement text; the preview is a safety report, not an edit script whose external application would bypass the journaled mapping. Applied O5: the exit-2 JSON error document's trigger is delimited — --json among the arguments, or a JSON-only surface with no flag needed; the compatibility note now points at that delimitation. Rejected: none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…dinality, view domain) Applied: I1, I2, O1, O2, O3, O4. - I1: change 6 states the multi-construct location rule — one finding per condition instance carrying a location for every participating construct (duplicate-ID bearers, colliding import declarations, a cycle's full path), context entities as identity data; extended to refusal reasons (cycle a refused move would create). - I2: change 3 assigns the wrong-kind usage error to a discovered code source named directly and fixes the view glob's restriction universe as the discovered spec sources. - O1: change 2 scopes the absent-node clause to the range datum alone, leaving historical-text payload rules untouched. - O2: change 1 states that file and target filters combine conjunctively in one invocation. - O3: split the heaviest sentences in change 4's consulted-domain bullet and change 5's graph-data-area bullet. - O4: change 6 states the missing-configuration concerned path's reported form (change 5's anchoring; degenerate self-reference). Rejected: none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…rfect files (iter 8) Applied: - I1: change 4 now states the text-value principle for files with findings — Markdown compilation's removal rules classify constructs by syntactic form, never by validity or resolution (imports removed by form, tags removed with every spelled attribute, non-inventoried constructs preserved as content); resolution enters only via text(...) replacement, already the unavailable case. - I2: identity definedness disambiguated — chain conditions (presence, well-formedness, structural validity) are inherited; uniqueness constrains the section's own spelled identity alone, so a uniquely spelled descendant of duplicate-id ancestors keeps its defined identity; defined identity does not imply defined prefixes, and occurrence resolution / the target filter turn on the referenced identity's own definedness. - O1: spread attributes appear among the view's raw attribute spellings by form; invalidity is a located finding, never a view omission. - O2: position-resolution offset domain closed — a non-non-negative-integer offset value is the same usage error as a greater offset. - O3: stable-code scoping stated as deliberate — codes cover exactly the numbered conditions plus refusal reasons; plain usage errors carry no code but still get the JSON error document when JSON output is in effect. Rejected: - O4: the Branch header's mapping is deliberate harness bookkeeping — pushes go to the designated branch and the mapping is recorded in the patch header and PR #7; stripping it mid-process would name a branch nothing pushes to. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…imitation (iter 9)
Applied:
- I1: change 3's attribute parenthetical now reads "attribute inclusion is by
form" — it governs which attributes appear in the view (every spelled one,
validity notwithstanding), not per-attribute ranges. Git history confirms the
intent: the parenthetical entered in iteration 8 as an inclusion statement
("spread attributes appear among the view's raw attribute spellings by form");
"position" was a wording slip. Attributes are carried as raw spellings; ranges
are granted explicitly where intended (tag decomposition, change 6 findings,
change 7 id-rewrite edits).
- O1: the stable-code delimitation now covers review-operation refusals
explicitly — findings under the existing exit-code partition, neither numbered
conditions nor rename/move refusal reasons, uncoded because review flows lie
outside this proposal's UI scope (relied on unchanged).
- O2: change 2's disambiguated-unit sentence now says "each carry the range of
their own construct", ending the collision with change 1's coined "reference
occurrence" (SPEC.md 4.6 uses "occurrence" for the Nth same-named unit).
Rejected: none.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
Applied: I1, O1, O2, O3. - I1: change 4 now defines when a section spells an identity (id prop exactly once, quoted attribute form); missing and invalid-form id props (repeated — spellings agreeing or not — braced or valueless values) spell no identity: own identity undefined, descendants' chain broken, and no participation in uniqueness — an invalid-form claimant never poisons a well-formed bearer. Resolution grounded in the document's own principles (no fabrication from invalid syntax, tags/coverage analog, mid-edit containment). - O1: review-refusal aside in change 6 scoped past change 2's range generalization (removes the one self-contradiction reading). - O2: change 5's corrupt-recorded-state finding explicitly joins the numbered validation-error conditions with a stable code. - O3: an occurrence-less MDX-embedding spelling's finding range pinned to the full braced container, keeping change 3's byte classification exact on imperfect files. Rejected: none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…p exclusivity claim (iter 11) Applied: C1 — replaced change 5's false "alone among readers" claim with an accurate shared-reader statement (inventory + change 7's delta; existing check noted as covered by its staleness condition) and gave change 7's delta a defined outcome on recorded state that exists but cannot be read: the delta, both directions one datum, reported explicitly unavailable, same numbered condition and stable code as change 5's, exit 1, rest of the preview report emitted in full; stated as the succeed/refuse equivalence's one success-side exception (the real operation is not refused — corruption fails no build validation and finishing regeneration replaces it). Aligned change 4's summary pointer and change 6's refusal appositive with the new outcome. Applied: O1 — absent tags/coverage props define the existing defaults (no tags; coverage-required), closing the misreading that presence is required. Applied: O2 — the test seam tied to acquiring workspace exclusivity never engages on a preview, stated at behavior level (no flag prescription). Applied: O3 — reported edit ranges may nest: section-move re-identification rewrites locate inside the origin-deletion range in pre-operation coordinates. Rejected: none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
Iteration 12 review: no Critical or Important items — refinement converged. Applied O2: change 6 now states the invocation-anchored reporting form for every configuration-error concerned path (the found or --config-named configuration file, and the missing-configuration working-directory case), instead of leaving the non-missing cases to the compatibility note's plural. Applied O3: change 3's import entry now states the binding-name datum for a bindingless declaration is structural absence — reported as absent, never as unavailable — per the document's root tags/coverage taxonomy and change 4's closed unavailable-data list. Rejected O1: naming whether the unreadable-record finding becomes a new numbered condition or folds into the existing staleness condition is validation-section organization, which the patch's methodology preamble delegates to spec refinement; the information contract (reported finding, stable code, exit 1, full answer emitted, identical reporter set) is the same on both branches, as the review itself notes. Stage: Proposed -> Accepted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…iter 1) Integrates all eight accepted surfaces as timeless end-state requirements (review items C1-C9), with concrete invocations (I1): - 5.7 reference occurrences (concept, spans per kind, no-occurrence rule, total order); 11.3 `xspec occurrences [--file <glob>] [--to <node>]` with syntactic --to acceptance and malformed-only usage errors. - 1.7 rewritten: code-location ranges defined; presented in exactly two outputs (occurrence records, review payloads); edge endpoints stay bare identities; 10.7 payload generalized to present graph nodes. - 11.4 `xspec view` (tree, tag decompositions, raw attributes, imports, occurrences, comments, byte-classification guarantee, domain forms) and 11.5 `xspec at <file> <offset>` position resolution. - 11.2 availability contract: parse-local structure, spelled/defined identity, tags/coverage and expanded-text definedness, explicit unavailability, consulted domains, exit mapping, stale-data rule; 13.3 scoped so occurrences/view/at answer mid-edit. - 11.6 `xspec inventory` (anchoring, configuration view, sources, derived map with provenances, graph-data area write reservation and unattributed-path rule, durable files, deterministic ordering). - 14: stable codes for all 23 conditions, location cardinality, concerned paths, refusal-reason codes; new condition 23 (unreadable recorded state); 12.0 JSON error-document delivery whenever JSON output is in effect. - 6.6 previews (`--preview` on rename/move): full plan report, edit classes with pinned ranges, derived delta with condition-23 outcome, refusal equivalence with 13.5 scheduling exception; --test-hold with --preview pinned as a usage error (I2). - 12.6 `xspec version`: machine-interface version 1, workspace-independent, outside configuration-error precedence (14.14 scoped). - 12.0/12.5/13.3/13.5 conventions absorbed the new outcomes (C9). I3: no IP/delta framing survives; internal cross-references only. I4 modularity assessment: no module split - every added portion is consumer-facing interface/contract that PROCESS.md requires in SPEC.md itself, and it is densely interlocked with 1.7/12.0/13.3/14; no clean seam exists in the pre-existing content either. Single file retained under the SHOULD. O1 placement suggestion followed. Rejected items: none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…esh, import-edit, and view gaps (iter 2) Applied: - C1: node identities exist only over valid source paths — every node of a 14.19-invalid file (roots, sections, code units) has an undefined identity under 11.2; such files keep parse-local structure and their condition-19 finding accompanies every answer whose domain includes them; 1.5's #-unambiguity re-grounded on this rule; occurrences --to gains the invalid-path non-resolve case; 12.0 gains a marked byte-form representation rule for non-UTF-8 workspace-relative paths in outputs. - I1: read-time refresh leaves an unreadable record (14.23) unread, unrepaired, unreplaced; refreshing reads consult no record and report no finding for it; the state persists, reported by 11.6/6.6/14.10, until build or rename/move regeneration replaces the record (13.3, 14.23). - I2: import-removal extent pinned (declaration plus line-drop adjunct, as in 3); import addition inserted as a line of its own at a grammar-permitting, deterministic implementation-latitude offset equal to the previewed offset (6.5, 6.6). - I3: view --text consulted domain defined: exactly the files of resolved targets reachable through occurrence-recording embeddings; a non-resolving spelling is the expansion's boundary; a masked file is never consulted by expansion, its finding surfacing only when requested. - I4: argument checks of 11.3-11.5 precede answering — usage errors exit 2 whatever findings the workspace or named files carry (11.2). - I5: raw attribute spelling defined per attribute, in tag order: name as spelled (absent for spread), source range, and source text (name through value; a spread attribute's entire braced construct) (11.4). - I6: verified against pre-IP baseline (a724662): query was already JSON-only ("a single JSON document is its only output form"), so section 11's JSON-only statement alters nothing pre-existing — no change needed. - O2: 11.4 code-source operand rephrased "wrong-kind operand, a usage error" to avoid conflation with stable code invalid-argument. - O3: review export synopsis aligned to [--json] per its JSON-only text. - O4: confirmed intended, no edit — multiple view <file> operands are deliberate refinement latitude (IP: exact surface shapes settled during spec refinement), consistent with the mandated per-file multi-view response in one document; removing the form would lose harmless capability an editor plausibly wants (view several dirty files at once). Rejected: - O1 (modularization): declined. The extraction candidates (10.4-10.6, 7.4-7.5, 8) are load-bearing contract surface: strategy derivation determines export/next payloads, item identity, and invalidation, and coverage/policy evaluation is itself the command contract; PROCESS requires the full interface/contract in SPEC.md and forbids referencing module internals, so extraction would duplicate contracts rather than shrink the document. The SHOULD yields to those MUSTs here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…ncerns and file-operand parsing (iter 3)
Applied: C1 (new 12.7 — value forms for ranges, paths and the marked
byte form, the value/absent/unavailable three-state, finding and error
documents, and document forms for occurrences/view/at/inventory/
previews/version, with pinned orderings; 11.6 derived-map bullet aligned
with the record-supplied datum; pointers from 6.6, 11, 12.0, 12.6, 14).
I1 (condition 22 concerns the offending symlink component, one finding
per component; condition 23 concerns the graph-data area; record
conditions added to 14's concerned-path rule). I2 (12.0: # splits only
identity-form arguments, including <file>#<id> operands; bare <file>
operands and --file globs are whole paths with no delimiter role for #).
O1 (10.1 "directory entry" replaces "file"). O2 (5.7 occurrence
existence anchored to target resolution). O3 (13.4 orphan rule extended
to a missing or unreadable record). O4 (12.0 intra-exit-2 precedence:
syntax-only errors before configuration loading, configuration errors
before workspace-consulting argument checks). O5 (finding order and
preview-edit order pinned in 12.7).
Partially applied: O6 — removed the one redundant clause in 11.6's
unattributed-path rule ("the one whose deletion is undone by nothing");
the remaining statements carry distinct load (the foreign case's
definition, the inventory's stance, the consumer rule), so further
compression risks dropping content.
Rejected: O7 — no modularization: nearly all of sections 8-10 is
consumer-facing interface contract that PROCESS.md requires to remain in
SPEC.md itself, which the review itself concedes makes single-file
defensible; extracting mechanism prose mid-IP would churn cross-
references for no requirement.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
… total finding order (iter 4) Applied: C1 (refused previews leave the findings-alone list; they keep the four-member preview form with null mapping/files/delta), C2 (one gate phrase — "the validations of \`xspec build\`" — in 6.4, 11.2, 12.0, 13.3; the refusal branch of the all-or-nothing reads covers journal errors (14.13) and refused writes (14.22); refresh runs only where build would succeed and cannot fail; conditions 13/22 accompany no 11.3-11.5 answer — findings are the domain files' alone, finding-free answers stay exit 0), I1 (11 intro corrected: only occurrences/view/at/inventory have 12.7 document forms; query — JSON-only already before the IP — carries its defining section's information), I2 (finding order made total: concerned path with null-first, identities, message; identical findings collapse to one), I3 (list members are [] when empty; null only where a form states the datum absent), O1 (companion attribution via 13.1 naming stated in 11.6), O2 (duplicate unresolved-spelling clauses trimmed from 5.7 and 11.3), O4 (offset spelling pinned to ASCII decimal digits), O5 (recorded paths excluded from the staleness comparison), O6 (marked-byte-form list extended with inventory derived paths and view import targets). Rejected: O3 — no modules extracted: the candidates (§10 review mechanism, §14 condition catalog) are consumer-facing interface/contract, which PROCESS.md requires defined in SPEC.md itself, so no loosely coupled non-contract component exists to extract at the current size. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…ing spelling, unreadable-record staleness (iter 5) Applied: C1 (derived-file map and emit destinations structurally absent for .mdx-less discovered spec sources — 13.1, 13.2 via 7.3, 11.6, 12.7), C2 (view import name = default binding only, absent otherwise — 11.4, 12.7), I1 (canonical anchoring spelling incl. "." self-reference and separator — 11.6, 14), I2 (check reports an unreadable record as a condition-10 finding concerning the graph-data area — 14.10, 12.2), O1 (5.7 definition by resolution), O2 (prefix-first finding order — 12.7), O3 (occurrences in 13.3 content list), O4 (.xspec spelling pinned — 11.6), O5 (exit-2 document holds one finding — 12.7), O6 (positional tree parents to innermost enclosing section — 11.4). Rejected: none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…comparators, JSON contract details Iteration 6 of applying IP 0001. Applied: C1, I1, O1, O2, O3, O4, O5, O6. - C1: 6.6/6.5 — a created target file's entry reports its creation as its only edit, subsuming the insertion and the import additions composed into the file's initial content (per the IP's "one reported location without pre-operation coordinates"); the moved text's own rewrites stay reported in the origin file; 6.5's preview-offset promise scoped to files existing before the operation. - I1: 12.7 — between-findings `locations` ordering given its element comparator (file path bytes, range start, range end); identities' element rule spelled out alongside. - O1: 14/12.7 — a stable code's value pinned as the listed token string; numerals are ordinals for ordering, no part of the value. - O2: 12.7 — preview edit tiebreak pinned to class-name bytes. - O3: 11.2 — membership rule for a domain file's findings (a location in the file, or the file as concerned path); joint multi-file findings accompany whole when any participant is in the domain. - O4: 6.6 — a refused preview consults no record; no condition-23 finding accompanies a refusal. - O5: 11.5 — a non-UTF-8-path source is nameable by no argument value; its positions are reachable only through the view by glob. - O6: 12.7 — exit-2 error document moved under Document forms, lead exception amended. Rejected: O7 — modularization is a PROCESS SHOULD, not violated at the current size; the reviewer's own framing conditions extraction on future growth, and restructuring at convergence risks breakage with no requirement gain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
… refusal scope (iter 7) Applied: - I1: condition 12 carries no in-source locations and no concerned path (no file's finding per 11.2, so it accompanies no 11.3-11.5 answer, closing 7.5's check-only routing structurally); identities pinned as rule name, edge source, kind token, target; 14's cardinality paragraph and 12.7's identities description widened to match. - I2: the invalid-workspace refusal precedes the operation-specific validation, which is defined and evaluated only over a workspace passing build's validations - the refusal reports the workspace's findings alone, never mixed with refusal reasons (6.4, 14). - O2: 12.2 restated build validations under the build-validations clause so the "additionally" list holds only check-only verifications. - O3: preview `files` entries keyed by current pre-operation path, the relocated file's entry included; created target file by its new path. - O4: 13.3's recorded derived-file paths scoped to generated modules, companions, and emitted Markdown - graph data records no paths, its layout staying unenumerated. Rejected: - O1 (modularization): deferred deliberately - candidate components are bound to the core by dense numbered cross-references (5.4-5.6, 12.0, 12.7, 14) whose contracts could not move to modules without the restatement module rules forbid; the SHOULD is weighed, not dropped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…stination occupancy (iter 8) Applied: - I1: rename/move old-ID existence judged over spelled identities (11.2), parse-local — undefined-identity bearers still establish existence, no-identity spellings establish none, unparseable origin stays masked (6.4, 6.5). - I2: refused-invalid-id scoped to intrinsic ID form (dot-path of 1.4-valid segments); positional conformance (1.3) is refused-structural-parent's alone, evaluated only over intrinsically valid IDs — no identity reports under both (14). - I3: refused-destination-exists triggers on any occupant of the file-form destination path, whatever kind of filesystem object, symbolic links included (6.5, 14). - O2: a successful non-preview rename/move reports the applied mapping — the preview's mapping information (6.4, 6.5). - O3: finding-form identities content contractual exactly where 14 states it for the condition or reason, otherwise informational — deterministic, composition unpinned (12.7). Not applied: - O1 (modularization): standing deferral upheld. Extracting Review (10) or the query/JSON complex (11, 12.7) requires full interface restatement in SPEC.md per PROCESS module rules; the restructuring risk mid-refinement outweighs the SHOULD at current size. The deferral stays a recorded decision, not an omission. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…n timing (iter 9) Applied: - C1: section-form move target path occupied by anything other than a discovered spec source is refused under refused-destination-exists (6.5 body and refusal list, 14). - C2: rename/move origin operands pinned to discovered spec sources; a code-source origin is a wrong-kind usage error per 11.4's pattern (6.4, 6.5, 12.0 precedence bullet and exit partition). - I1: rename's collision check pinned post-mapping - vacated IDs are no collision, produced IDs checked too, identity-unchanged reports refused-identity-unchanged alone (6.4, 6.5, 14 refused-id-collision). - O2: 11.2 unavailability parenthetical no longer implies a structural view exists for code sources; occurrence's own range (11.3) named. - O3: unreadable-record outcome consolidated into 14.23 as its one normative home; 6.6 and 11.6 defer to it. - O4: explicit sentence in 14 that a refusal reports every applicable reason together, never only the first found. Rejected: - O1: modularization deferred again - the named candidates (Review, Coverage, validation catalogue) are consumer-facing contract that PROCESS.md requires to stay in SPEC.md itself and forbids modules to restate; extracting them mid-IP refinement would churn every section reference while yielding little movable non-contract content. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…ove operands (iter 10) Applied: - C1: 14.10 restructured into four forms — per-file staleness (generated modules/companions per 13.1, emitted Markdown per 13.2) and orphaned recorded files name the file; graph-data staleness (missing or mismatching under 13.3's comparison, recorded paths excluded) and the unreadable record are each one finding whose concerned path is the graph-data area, no path inside named, mirroring 14.23's shape. 12.2 now enumerates the verifications, graph data included, removing the 'generated files' ambiguity. Follows 13.3's existing commitment that check reports graph-data staleness while keeping 11.6's unattributed- path regime intact. - O1: 6.5 classifies move operands by spelling — a mixed-form invocation matches neither synopsis and is a usage error; the file form's inability to spell '#'-containing paths noted as harmless (14.19). - O2: 6.4 drops the '(12.7)' citation on the successful-rename report; 12.7 pins no form for it, so the report stays information-only per 12.0 — consistent with O4's recorded-gap stance. - O3: 7 qualifies 'Every command locates the configuration' to except version, matching 12.6 and 14.14. Rejected: - O5 (modularization): SHOULD, not MUST. The named components are not loosely coupled — 14 is cross-referenced from nearly every section, 10 and 11 interlock with 5.4-5.7, 12.0, 12.7, 13.3-13.5 — so extraction would duplicate contract text into SPEC.md or violate the no-reference-into-module rule; restructuring at convergence adds contradiction risk with no behavioral content. Consistent with prior rounds' deferrals. No-op: - O4: reviewer records the unpinned query/impact/coverage/review member names as a deliberate, IP-faithful gap for a future proposal; no change requested. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…e case (iter 11)
Applied:
- C1: 14.10/12.2 — the per-file content comparison judges the path's
occupant itself, never traversing a symbolic link (13.4): it matches
only a plain file holding exactly the generated content, so a symlink
(whatever its target holds), a directory, or any other non-plain-file
occupant is stale per se. Two conforming implementations can no longer
diverge on a symlinked byte-identical occupant.
- I1: 14.10 — per-file form now reads "missing or does not match",
covering check on a deleted generated module/companion/Markdown file,
parallel to the unit form, 13.3, and 13.4's deleted-file promise;
12.2 aligned ("present as plain files content-identical").
- O2: 11.6 — stated that the condition-23 finding is the only finding an
inventory answer ever carries; findings a listed file or path may bear
(14.19, 14.13, 14.21) report where their conditions assign them.
- O3: 12.7 — concerned-path ordering key pinned to byte-wise comparison
across presentation forms: marked byte-form and plain-string paths
sort in one byte order.
Rejected:
- O1: modularization deferred again — standing SHOULD acknowledged, but
the consumer-facing contract must stay in SPEC.md (PROCESS), limiting
the extractable interior, and restructuring mid-IP-refinement is not
clearly right this round.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…t causes (iter 12) Applied: C1, I1, O2, O3 - C1: one precedence statement for the 13.3-gated reads (12.0) — their argument checks precede the invalid-workspace gate, judged per 6.4's parse-local pattern with unparseable-named-file masking, so unknown names exit 2 whatever the workspace's findings; the gate precedes session reading, so a corrupt session (14.21) reports only on a passing workspace and item-ID checks are masked by the corruption (13.3, 10.1, 10.7, 14.21 aligned). - I1: a non-directory-occupied (symbolic link included) workspace-relative directory component of a move destination or of a derived path the destination would generate is one refusal cause under refused-invalid-destination (6.5, 14), disclaimed in 14.22 so refusal reports stay refusal-reasons-only and the finishing-regeneration infallibility claim holds; writes create nonexistent intermediate directories (13.4). - O2: 11.2 closing label no longer overstates — "Never stale; writing nothing on a failing workspace." - O3: duplicate profile/rule names named explicitly in 14.14. Rejected: O1 — modularization stays deferred, consistent with prior rounds; the Reviewer records it for completeness and states nothing reopens that decision. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…y findings, multi-# split (iter 13) Applied: - C1: 13.4/14.22 generalized from symlink-only to any non-directory occupant of a workspace-relative write-path directory component; condition 22 retitled obstructed-write-path, own-path and 6.5 destination-side exclusivities kept. Closes the plain-file-at-.xspec/outDir gap; 12.1's taxonomy, 13.3's gate enumeration, and 6.5's cannot-fail regeneration argument now cover the state. - C2: condition 1 pinned to id-attribute absence; repeated/invalid-form id is condition 17 alone; condition 2's mask extended to every spells-no-identity parent (11.2), so finding sets like <S id="a" id="a"> + child are derivable. - I1: 12.0 pins at most one '#' in <node>/<graph-node>/<file>#<id> spellings (mirroring 11.3); more is a malformed value, a usage error — split never ambiguous. - O1: 5.3 cycle detection attributed to validation (build and check alike). - O2: 7.5 pins captures as exactly $1-$9; every other $ is a literal byte. - O3: 12.0 wrong-kind illustration now cites the 11.1/12.4 node-kind checks. - O4: 6.6 delta rationale marked rationale-not-filter; degenerates toward the full set on an empty or lagging record. Rejected/deferred: - O5 (modularization): re-deferred — SHOULD-level; near-total contract locality keeps the single file; residual delegated to the downstream problems-file net per the standing closure ruling. Closing iteration per Liaison valve ruling: REVIEW.md deleted; patch 0001 Stage: Accepted -> Applied. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…table code tokens
Replace the condition-number finding model with SPEC 12.7's observable form
{"code", "message", "locations", "path", "identities"}: the 23 SPEC 14
condition tokens plus the nine refusal-reason tokens (with per-code ordinal
and exit class), located conditions carrying byte-range locations (condition
20's line/column converted to byte ranges and dropped from the model),
concerned-path conditions (10, 13, 14, 19, 21, 22) carrying `path`,
condition 12's contractual identities [rule, source, kind, target],
condition 11's foreign module as identity data, and cycle paths as identity
context (cycle-as-locations stays task A3). Every construction site across
core and workspace is ported; the JSON serializer emits exactly the five
members and the human renderer presents the same information. The 12.7
findings ordering and duplicate collapse land as one choke point
(core/findings.ts orderFindings) applied by every emitter; FIX_PLAN's A2 is
rewritten to its remainder (marked byte-form path values).
Suite: 98 failed / 539 passed vs the 142/495 baseline - 44 fixed, no new
failures; every residual is owned by a later plan task (A2-A5, B*, C*).
Self-tests and certification: 330/330.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…e form
FIX_PLAN A2. New src/core/path-text.ts is the one internal path
representation and shared path-value renderer (SPEC 12.0, 12.7, 14.19):
PathText = string | PathBytes, constructed from raw bytes only through
pathTextOf so a valid-UTF-8 path can never take the marked form;
pathTextJson renders the JSON value form ({"bytes": lowercase hex} for a
path with no plain string form), renderPathText the deterministic human
spelling <bytes HEX>, comparePathTexts one byte order over both forms.
Finding locations[].file and path are PathText; compareFindings and
compareLocations compare paths by exact bytes whatever the presentation
form; discovery's 14.19/14.14 findings carry the offending path's exact
bytes instead of the lossy U+FFFD decode; the human report, JSON report,
configuration-error diagnostic, and baseline diagnostic all render through
the shared helpers.
Verified: T12.7-2's build/query arms now emit
{"bytes":"73706563732f41ff2e6d6478"} sorted before the plain "specs/ha#…"
paths (remaining deltas in section-12.7 are A3 cardinality / A4 error
document / Stage B surfaces); section-14 (5 failed / 3 passed) and
section-11.2 / 12.1-12.2 / 13.3 (12 failed / 4 passed) byte-identical to
the pre-change baseline — no regressions; P-7 and sections 1.1-1.2 and 15
pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
SPEC 14 location cardinality (FIX_PLAN A3): - Duplicate IDs (14.3): one finding per duplicated identity locating every bearer, the first included, instead of one finding per repeated occurrence (mdx.ts validateStructure). - Import-binding collisions (14.15): one finding per collided identifier locating every colliding declaration, in xspec sources (spec-references.ts) and TypeScript files (code-analysis.ts) alike; the collision needs two distinct declarations. - Cycles (14.9): a dependency cycle locates its full path through every reference spelling recording a participating dependency edge (graph.ts records an edge-to-spellings map beside edge assembly; d = the entry's own expression, MDX embedding = the full braced container, 5.7); a spec import cycle locates every participating import declaration. The cycle path no longer travels as identities - it stays in the message. - A no-occurrence spelling of the MDX embedding form (14.6/14.8) is located by the full braced container, opening through closing brace - the span its occurrence would occupy (5.7). Also normalizes the raw NUL separator bytes in graph.ts edge keys to the escaped spelling (same value; keeps the file text for tooling). Verified: T14-8 passes; T7.5-2..6, T1.3-*, T2.1-*, T2.2-2.3, T2.4-*, T4-*, T5.1-5.3, T5.4-5.6, T3, T15, P1-P6 all pass. Remaining failures in sections 5.7/6.3/7.4-7.5/12-14 predate this change and belong to later FIX_PLAN tasks (A4 error document, Stage B surfaces, C-stage fixes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…ig paths
SPEC 12.0/12.7/14: with JSON output in effect — --json among the arguments
(even when the arguments are themselves the error) or a JSON-only surface
(query, review export; CommandSpec.jsonOnly carries the marking for the
Stage B registrations) — an exit-2 usage or configuration error emits
{"error": <finding form>} as its entire stdout. Plain usage errors carry
code/path null; configuration errors carry code configuration-error and
the concerned path in the 11.6 anchoring form relative to the invocation
cwd (the found or --config-named file, or "." for a failed upward search),
one merged finding however many defects. The anchoring spelling is the
shared helper src/workspace/anchor.ts (inventory reuses it in B7); stderr
diagnostics and exit codes are unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
A refused review operation (split on a wrong-kind or childless item,
resolve on a blocked item, create with an existing or case-colliding
name) now reports the findings-only document {"findings": [...]} with
one finding — code null (SPEC 14: review-operation refusals carry no
stable code), locations empty, path null, identities the session name
(+ item id / colliding name, informational) — exit 1, nothing modified,
human form through the shared findings renderer (SPEC 10.7, 12.0, 12.7).
Plan: A5 removed (verified: section-10.2-10.3, 10.7-i all green; the
10.7-ii and 10.1 refusal arms green — remaining reds there are C6's
T10.7-7/12 and the newly-diagnosed T10.1-5); C2 extended with the
corrupt-session-behind-the-gate ordering (T10.1-5, observed 14.21
reported in the gate's place); new task B2a added for parse-local
validation inside invalid-path (14.19) sources (T12.7-1 arm E, observed
the located 14.1 dropped with the file).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
SPEC 12.6/12.7: `xspec version` is a JSON-only surface emitting the
{"product", "interface"} document — interface exactly the string "1",
product read from the package's own metadata, fixed per build. It loads
no configuration and consults no workspace: main dispatches it before
workspace location, so configuration-error precedence (14.14) never
reaches it and the answer is byte-identical in any working directory.
Usage errors keep exit 2 and emit the 12.7 error document.
Verified: T12.6-1/2 pass; T12.0-9 advances past its version row (now
red at the unimplemented occurrences surface, task B4). Removes task B1
from specs/tmp/FIX_PLAN.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…undefined FIX_PLAN B2a (SPEC 11.2, 14.19, 12.0/12.7, 14): a discovered file whose path is invalid stays visible to analysis. Discovery carries such files as classification.invalidSources; the pipeline parses them into invalidPathSpecs/invalidPathCode (document.file/analysis.file the real PathText, path a never-rendered lossy stand-in), reporting their parse-local findings beside the 14.19 while defining no identity: no graph nodes, no hashes, no recorded inputs, no derived-file interaction. Import designation consults the whole discovered set through SpecSourceDomain (string- and byte-space designators; WorkspaceContent.readInvalidSource reads content by exact path bytes): a valid import of a 14.19 member is no finding, targetFile carries every valid import's member as PathText, and references rooted at such bindings report 14.5/14.6/14.7 at analysis. References from invalid-path files resolve in buildWorkspaceGraph (findings only; the local form never resolves), and spec import cycles run over exact path bytes with invalid-path files participating. Verified: T12.7-1 arm E's build --json leg passes (14.1 x1 located in the non-UTF-8-named file, marked byte forms; 14.19 x2); the arm's occurrences/view/inventory legs still need B2/B4/B5/B7. Full suite 63 failed / 574 passed, every failure in a pending B2-C7 task's scope; no regression in sections 1-5, 7, or certification. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…h data Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
FIX_PLAN B3 (SPEC 1.7, 4.6): every code location now carries its source range. CodeUnit.range (core/code-analysis.ts) is the construct binding the unit's name: a variable declaration's own node (name through initializer, never the multi-declaration statement); dotted-namespace units share the chain's outermost declaration — the one construct binding them all; a named default export takes the construct's own range with the `export default ` prefix excluded (later modifiers like `async` kept, per the construct), an anonymous one's `default` unit the whole export declaration; `@N` units their own occurrence's construct. CodeLocationNode.range (core/graph.ts) carries it into the graph — a whole-file location spans 0..the file's byte length — and StoredCodeLocation.range persists it (core/graph-data.ts, stored format version 4; an old store reads as malformed, hence a mismatch, SPEC 13.3). Nothing presents the range yet: occurrence records (B4) and review payloads (C6) are the two presentation points (SPEC 1.7), so query edges/reachable stay bare identities. Verified: typecheck, build, format clean; every T1.7-2 fixture shape (plus async-default, braced-nested-namespace, and parenthesized named function expression exports) checked byte-exact against the built analyzer and graph at the core level — T1.7-2 itself goes green with B4/C6. Full suite 63 failed / 574 passed, the failing set member-for- member identical to the pre-change baseline (CI run 124): no regression, every failure in a pending B4-C7 task's scope. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
… layer
Register `occurrences [--file <glob>] [--to <node>]` (SPEC 11.3, JSON-only)
emitting the 12.7 {"findings","occurrences"} document, with argument checks
preceding answering: an outside-root --file pattern and a malformed --to
spelling each exit 2 with the error document; --to acceptance is syntactic,
unknown or unresolving identities selecting nothing; the filters combine
conjunctively.
The shared SPEC 11.2 machinery lands in core/availability.ts (consulted
domain over the entire discovered set, invalid-path members by exact bytes;
accompanying-findings selection; node-spelling well-formedness; occurrence
selection joining each source datum's range through its graph node; the
any-finding-or-unavailable exit rule), with the pre-answer step in
workspace/availability.ts: configuration errors keep exit-2 precedence, a
failing workspace answers from current sources consulting and writing
nothing, and a passing one participates in the 13.3 read-time refresh.
Identity definedness (SPEC 11.2) is now definedIdentitySections in
core/mdx.ts — spelled + well-formed + structural with inherited chain
conditions, uniqueness own-only — and graph node construction builds nodes
for exactly those sections: the duplicate-ID winner-picking is removed, so
ambiguous references report 14.5-14.7 and record no occurrence, no winner
resolved through.
Verified: T11.3-1..4 and T5.7-1..4 green; T11.2-*, T13.3-1/2, P-11
occurrences arms pass, each failing only at its first `view`/`at`
invocation (tasks B5/B6). Full suite 54 failed / 583 passed, every failure
mapping to an open FIX_PLAN task.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
The whole-document structural view (SPEC 11.4) lands on the shared 11.2 availability layer: view is JSON-only with variadic <file> operands that assert membership in the discovered spec-source domain (unknown and wrong-kind operands exit 2 before any answer or refresh side effect; combining operands with --file is rejected at parse time), while --file restricts the domain under the glob rules of 7. Per parseable requested file the answer serves the positional section tree with construct ranges, tag-range decompositions, raw attribute spellings (SpecSection.attributes - repeated, unknown, and spread forms included), the three-state interpreted datums of 11.2 (identity via definedIdentitySections; tags/coverage via the new tagsDefined/coverageDefined), every import declaration with the specifier-form-and-discovery target datum (SpecImport.designatedFile), the file's occurrence records, and comment ranges. With --text each node carries own and subtree text, defined all-or-nothing over transitive expansion (TextAvailability) with the consulted domain extended by expansionConsultedFiles; the graph's embedding index now covers invalid-path files' embeddings so defined text values stay exact there. The workspace pre-answer step is split (analyzeWorkspaceForAvailability / finishAvailabilityRefresh) so discovery-consulting argument checks precede the 13.3 refresh. Verified: T11.4-1..6, T11.2-2, T11.2-4 pass; T11.2-1/3/5, T13.3-1/2 fail only on the unimplemented at (B6); P-12 stays red until B6 lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
SPEC 11.5: register the JSON-only at command — offset spelling and bound checks and view-equivalent operand membership precede the refresh, the innermost containing section resolves with its 11.2 identity datum, the containing occurrence reports its full 5.7 record, and an unparseable named file answers the explicit unavailability marker beside its 14.20. On a verified store (workspace/fast-read.ts) at answers store-backed and byte-identical to the full path without loading the TypeScript compiler, which holds P-12's exhaustive sweep inside its budget. Verified: T11.5-1..3 pass; P-12 passes (545s/600s); fast/full byte parity swept over 203 offsets; section-11.2 and section-13.3 at arms pass (their remaining failures are B7/C3/C4 territory). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
Register xspec inventory (SPEC 11.6) JSON-only and answer the ten-member 12.7 document without parsing sources, refreshing, or writing: anchoring via the shared 11.6 spelling, the resolved configuration view with every default and inferred kind explicit, every discovered source (invalid-path files included) with its memberships, the derived map by the NAME.mdx byte shape alone (specSourceDerivedPaths), the record-supplied datum through the new shared three-way record read (readDerivedFileRecord: absent = empty, unreadable = condition 23 with concerned path GRAPH_DATA_AREA, exit 1, everything else in full), journal occupancy by presence alone, and session files by name alone in byte order of file name. Discovery-level 14.14 keeps its exit-2 precedence; 14.19/14.13/14.21 are never the inventory's. T11.6-1..4 pass; T12.2-2/3, T13.3-2/3, T14-4 arms touching inventory stay red on the C4/C5/C2 defects the plan already names. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…d findings
B8: replace the ad-hoc first-failure {"refused": ...} refusals with the
12.7 findings report. src/core/refusal.ts evaluates every applicable
reason together over the valid workspace — intrinsic-form new IDs,
identity change, collisions locating every bearer, structural parent,
target parent, destination occupancy and validity (obstructed
destination-side directory components included, never 14.22), and the
would-be reasons evaluated in identity space over the current graph with
the mapping applied: refused-cycle (dependency and spec-import, located
at pre-operation coordinates) and refused-unresolvable-reference — one
finding per reason, exit 1. The invalid-workspace refusal still reports
the analysis findings alone; reanalysis remains only as an unreachable
guard. workspace/writes.ts gains probeOccupant and
nonDirectoryComponents; graph.ts exports findCycles; the preview (B9)
shares this evaluation.
Verified green: T6.4-1..7, T6.5-1/2/3/4/6/7, T14-7 (T6.5-5 stays red on
C1, T14-4's 14.21 arm on C2, T13.4-6 on C3, T6.6-* on B9/B10, as
planned).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
--preview on rename/move (SPEC 6.6, 12.7, 14.23; FIX_PLAN B9+B10, landed together as the plan anticipated): full validation and planning, performed on nothing. The planners collect classed preview edits (core/preview.ts) in the same pass as the applied edits — reference rewrites at 5.7 occurrence spans, id-rewrites at the attribute's own characters, removals extended over line drops, import additions at one deterministic offset now shared by the real edit and the preview (6.5) — and the CLI emits the four-member preview document: refusals keep the form with null plan members through the shared refusal path; success reads the derived-file record once (B7's reader), reports the record-based delta against the post-operation generation set (generatedDerivedPaths), and reports an unreadable record as the unavailable delta beside the shared condition-23 finding, exit 1, everything else in full. A preview takes no workspace exclusivity and --test-hold with --preview is a usage error before any lock. T6.6-2/4/5/6 and T12.7-3 green; T6.6-3 red only on its C1-shared usage arms (mixed-synopsis / non-UTF-8 operands), noted under C1. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
SPEC 6.5/12.0: a move operand containing more than one `#` is a malformed value and an invocation mixing the two synopses' forms matches neither — both are usage errors the invocation's syntax alone determines, now rejected in `parseArgv` (reported without loading configuration, before any lock or hold), and the non-UTF-8 positional exemption is removed so every argument value is UTF-8-checked (exit 2, never a destination or invalid-ID refusal). The handler's one-direction mixed check and its non-UTF-8 `<new-id>` refusal become unreachable and are removed, guarded by internal errors. Verified: section-6.5 (7/7) and section-6.6 (5/5) pass, T6.5-5 and T6.6-3 included; T12.0-13's move arms behave (smoke), its `show a#b#c` arms stay red for C2, noted in the plan. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…space gate SPEC 12.0/13.3 (FIX_PLAN C2): identity operands of show/query are judged parse-local against the named file (discovery kind, spelled identities, named units; an unparseable named file masks the id/unit half) before the gate report, via the split read pre-answer step (analyzeWorkspaceForRead + assessWorkspaceRead with a deferred commit); review subcommands judge session existence against the directory alone and report a session's corruption only past the gate, on passing workspaces (T10.1-5); multi-# <node>/<graph-node> values are parse-level malformed values reported without loading configuration (T12.0-10, T12.0-13). Adds a plan task for the newly-diagnosed resolvable-baseline-vs-gate defect (T13.3-3's impact arm) and sharpens C3/C4 with observed failure modes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
SPEC 6.3/12.0/13.3 (FIX_PLAN C2b): split baseline resolution into readBaseline (ref + journal prefix/replay, exit 2 before source validation) and validateBaselineContent (exit 2, only past the gate and before the refresh commit). impact --base and review create --base now report the gate's findings (exit 1) when the current workspace fails build's validations and the baseline shares them; replay judges only suffix lines, so a garbage journal line inside the shared prefix is the gate's 14.13, never a replay failure. T6.3-1..4 and T13.3-3's garbage-journal arm green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…odifying SPEC 13.4/14.22: an obstructed write path is any workspace-relative directory component occupied by a non-directory — plain file, symlink, or other — one condition-22 finding per distinct offending component, concerned path the component. classifyOccupant maps ENOTDIR/ELOOP to absent so per-file staleness and removals never crash below an obstructed component. The 13.3 gate (assessWorkspaceRead) now evaluates build's full write set before any store read, and the query/at store fast path verifies the write set unobstructed, falling back to the full path otherwise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…g read
SPEC 13.3/14.23/14.10 (FIX_PLAN C4): recorded generation state that exists
but cannot be read as a record is neither read, repaired, nor replaced by
the refreshing reads — they answer from the current analysis, report no
finding for it, and leave the store byte-for-byte — and `check` reports
the state as staleness under the exclusive unreadable-record unit form,
one condition-10 finding concerning the graph-data area, the recorded-file
per-file form undetectable while it holds.
- workspace/graph-data.ts: `LoadedGraphData.state` three-way
("absent" | "readable" | "unreadable"), one classification rule shared
with `readDerivedFileRecord` (now derived from the same load).
- workspace/refresh.ts, workspace/availability.ts: both refresh points
skip predicate and write on the unreadable state.
- workspace/check.ts: unreadable → `unreadableRecordStaleFinding()`
(path `.xspec`, locations empty), exclusive with the mismatch arm.
- core/graph-data.ts: comments brought in line with the new discipline.
T13.3-2 green in full (the corrupt-record sweep: every refreshing read
exit 0, store untouched, `inventory` still 14.23-unavailable, `build`
replacing the state); section-6.6/11.6/14 files green. T12.2-2/3 still
red at their family-3/missing arms on C5's concerned-path defect (the
mismatch unit form names `.xspec/graph.json`), as the plan records.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
SPEC 10.7/1.7: the self-contained payload of next --json, show, and export presents every present scope, context, and origin node — requirement node and code location alike — with its source range read from the current graph; an absent node carries none. A present code-impact scope now enters as identity + presence + sourceRange (CodeLocationNode.range, no text), and a currently-present origin node's entry carries its current range (the after side is the current graph's). The human origin rendering gains the matching range line. Verified: section-10.7-i/-ii, section-1.6-1.7, section-10.2-10.3 all green (T10.7-7 and T10.7-12 included); typecheck and format clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…tartup Three product fixes from the C7 sweep's two residual reds (P-11, P-12): - src/core/canonical-json.ts: one iterative single-buffer emitter behind canonicalJson and compactJson — linear time in the rendered text (the old per-level join re-copied every subtree, cubic on nesting depth), no native recursion, and pretty indentation bounded at 32 levels. Byte-identical output for every document nested within the bound (verified over view, query, check --json, and .xspec/graph.json on a staged workspace); a depth-4096 fuzz tower's view answer is ~35 MB in ~4 s instead of quadratic-indentation gigabytes past the harness's 64 MB guard. - src/cli/commands/view.ts: the node tree renders iteratively (children before parents over an explicit stack), so a depth-4096 balanced section tower no longer overflows the call stack (SPEC 11.4 answers any parseable nesting). - src/core/ts-module.ts: the TypeScript compiler API loads once through createRequire; the four former `import ts from "typescript"` sites route through it (type positions via `import type * as tst`). Importing the ~8.5 MB CJS file through the ESM loader cost ~0.2 s per invocation in format sniffing and named-export lexing; every configuration-parsing invocation drops ~0.5 s -> ~0.26 s. Verified: typecheck, format:check, build clean; full suite 636/637 — P-12 green at 321 s (was a 600 s timeout, locally and in CI run 33296625151), all previously-green files still green. The one red is P-11, now failing inside the harness: its recursive decodeViewNodeForm overflows on the depth-2048 view tree its own generator draws, after the product answers conformingly — see the FIX_PLAN C7 note; logged separately to TEST-SPEC-PROBLEMS.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
No product change can clear P-11: the harness's recursive view decoder overflows its call stack on the conforming depth-2048 answer its own generator provokes (CI seed 271828183, trial 1), a harness-implementation defect by the property machinery's own H-8 classification. Details, exact reproduction, and evidence in the entry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
Run 33298889697 (e239f0c): harness-self green, suite-linux 636/637 (P-11's harness error alone), Windows E-6 8/9 — its byte-identity arm starved because the suite-linux upload step skips on any test failure (no `if: always()`), which self-heals once suite-linux is green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…giant-nesting floor Applied REVIEW.md items: - C1 (Critical): added H-11 to section 0 — the harness must decode and evaluate every conforming answer at the scale its own staged inputs provoke (decoding and all per-datum traversals alike), with harness-side failures reported as harness defects, never product diagnoses or passes; added S-8 to section 17 gating that capacity against synthetic conforming-form documents at maximum staged scale before any product exists. No section 16 test content or SPEC-facing assertion touched. - I1 (Important): pinned a test-strength floor on P-8's giant-nesting mutation class (staged draws include nesting at least 2048 levels deep), inherited by P-11 through P-8's generators. Rejected: none. Resolved specs/tmp/TEST-SPEC-PROBLEMS.md (2026-08-30 P-11 entry): the document now states the obligation whose absence admitted the harness decoder defect and gates it red-green; the P-11/P-8 test text stands unweakened. Problems file deleted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
Applied I1 (Important): H-11's operative clause now covers the capture of
H-2's observed output streams — capacity limits dimensioned to staged
scales, exhausted capture limits surfacing loudly (silent truncation is
indistinguishable from the partial-document violation P-8/P-11 assert),
classification extended to failures while capturing — and S-8 gains a
capture arm at maximum staged scale via S-3's stand-in mechanism, making
obligation and pre-product gate coextensive with the whole pipeline.
Applied O1 (Optional): S-8's scale dimension rephrased as H-11's ("the
maximum scale the suite itself stages"), keeping the gate coextensive
with the obligation if a large deterministic fixture is ever added.
Rejected: none.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
…tures - C1 (Critical, applied): new T6.5-8 asserts 6.5's added-import line discipline (trailing U+000A; preceding U+000A at a mid-line offset) in TS and MDX arms, value-blind on identifier and insertion offset; T6.5-2/T6.5-7 cross-references updated. - I1 (Important, applied): S-2 gains round-trip scale vectors at P-8's giant-nesting floor and the largest staged document size. - O1 (Optional, applied): S-8 dimensioned to the answer scale H-11 obliges (expansion blowup included), not staged-input size. - O2 (Optional, applied): new T1.3-7 deterministically anchors P-8's 2048-depth floor outside the generator machinery; P-8 points to it. No items rejected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
….0-1 and P-1 precision
Applied C1: SPEC.md 12.7 fixes "the value forms every JSON output uses"
universally, pinning document forms only for the enumerated surfaces
(12.6 versions the whole contract; 1.7 lists 10.7/11/12.4 among the
range-carrying outputs). Rewrote H-3 as a two-tier contract — pinned
document forms plus universal value forms that adapters may never
re-map (latitude confined to the surrounding unpinned shape); updated
the §11 preamble's query routing; extended T12.7-1 with literal
{"start","end"} arms on query node/row ranges, show --json, and review
payload nodes, and widened the unavailable-member exclusivity walk to
every JSON document the suite captures.
Applied O1: reworded T12.0-1's flag-less/--json clause to
information-strength — byte-identity is not asserted (the two
invocations differ in argv; 12.0 determinism binds per identical
input), aligning with the §11 preamble.
Applied O2: P-1's segment property now judges the staged spelling's
resulting split (a .-containing draw stages as multiple segments,
nested beneath the chain its prefixes spell), mirroring the tag half;
structural-rule outcomes stay with T1.3-2..4.
Rejected: none.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Improvement Proposal
specs/patches/0001-external-ui-apis.md(Stage: Proposed), drafted from the seed "Foundational APIs for an external spec UI" and finalized against the Developer-confirmed scope: CLI-only connection (no service/watch surface), UI-owned text editing (no content-mutation commands), saved-files-only analysis.Proposed SPEC.md change areas: reference occurrences with source ranges; source ranges for code locations; a whole-document structural view (tag-range decomposition, imports, comments, occurrences, direct position resolution, multi-file form); a per-file parse-local availability contract for the new surfaces; a workspace inventory with invocation-anchored root; structured diagnostics with stable codes and ranges; rename/move previews; machine-interface identification.
Also carries the preceding Liaison commits on this branch (PHILOSOPHY.md updates, seed intake) and consumes
specs/tmp/SEED.md.Process notes: branch
claude/xspec-ui-apis-4df8fais this session's harness-designated push branch and stands in forpatch/external-ui-apis(recorded in the patch header). Merge happens only at Phase 11 perspecs/DEVOPS.md.🤖 Generated with Claude Code
https://claude.ai/code/session_01TyZ5zUv2UCkvTkM1tkYUp2
Generated by Claude Code