Skip to content

TASK-C533-3: wires paint their live logic value on the canvas — the draw path consults WireNet.value for the first time #961

Description

@anadon

Abstract

The schematic canvas already paints a wire's live 1-bit-style logic state through color and stroke (issues #76/#77): a WireNet with no value draws dashed and in the "off" color, an all-zero net draws thin and in the "zero" color, and a net carrying any non-zero bit draws thick and in the "non-zero" color. What the canvas does not do is show a numeric value for a multi-bit net — every non-zero multi-bit bus paints identically regardless of whether it carries 1 or 0xFFFF, and there is no way to see a bus's actual value without opening ElementValueDisplays' modal report or the trace window. This task closes that specific gap: an on-canvas numeric value label for multi-bit WireNets, plus a UI toggle for on-canvas value rendering (color/stroke and the new label together), reusing the paint-time read the coloring already performs — no new sampling tap, no new serialized state.

Intended Audience & Impact

Status & Dependencies

tier: task
evidence_commit: c5cee1baff3451a85787b4a09bd0b2b05af7dfdd
part_of_feature: 533   # FEAT-C23-4; this task was filed as TASK-C533-3 under it
blocked_by: []
blocks:
  - 693   # sibling task under #533; directive states this task lands before it
  - 695   # sibling task under #533; its in-flight-event overlay draws on top of
          # this task's on-canvas value state, so it must land first
related:
  - 504   # CAP-23; its §1 step 3 wavefront animation is described as depending
          # on this task's rendering path, but 961 is a task and 504 is a
          # capstone — per scientific-task v6 rule 8 a task may not carry a
          # blocks/blocked_by edge to a capstone, so this is recorded
          # reference-only here (the capstone-side edge, if any, lives on #504)
  - 76    # prior art: the 1-bit color channel this task's label sits beside
  - 77    # prior art: ElementRenderer/CircuitRenderer split this task reuses
  - 527   # named by the old filing as the owner of recording/history and a
          # future SampleSink stream; neither WaveModel nor SampleSink exist
          # in the tree at evidence_commit (git grep, § Observations O6), so
          # this task reads WireNet.value directly, not through #527's stream

The #693/#695/#504/#527 relationships above are carried forward from the original filing's prose (maintainer directive, 2026-08-16); this migration did not and could not re-verify their current state on GitHub (out of scope for this pass — see § Open Questions & Decisions Needed).

1. Background & Prior Work

Wire and wire-end rendering moved off the model classes and into the jls.edit renderer registry in issue #77: ElementRenderers.draw (src/jls/edit/ElementRenderers.java:47-56 (quotes: * element's own {@code draw} if none is registered.; } else {)) dispatches to a registered ElementRendererWireRenderer for Wire and WireEndRenderer for WireEnd — registered in BuiltinElementRenderers.install() (src/jls/edit/BuiltinElementRenderers.java:100-101). Issue #76 added the "second channel" principle this task extends: value state must be readable without color vision, so Wire/WireEnd already carry both a color and a stroke/glyph encoding, pinned by test/jls/elem/WireValueChannelTest.java.

jls.sim.TraceGeometry (src/jls/sim/TraceGeometry.java:1-9) is the precedent this task's Outcome text points at for a "headless model, thin Swing consumer" split: pure display-geometry computation, deliberately free of AWT, unit-tested independently of the Swing trace viewer it feeds. ARCHITECTURE.md:224-226 (quotes: Layer 1 (present) is headless model assertions; layers 2 (Swing) names this the project's "Layer 1" (headless model assertions) versus "Layer 2/3" (Swing harness, render-to-image) split.

Issue #527 is named by the original filing as the eventual owner of value recording (a SampleSink stream); no WaveModel or SampleSink type exists anywhere in the tree at evidence_commit (git grep -rln "WaveModel\|SampleSink" -- '*.java' returns no results), so this task cannot attach to that stream and instead reads WireNet.getValue() directly at paint time, the same way the existing color/stroke encoding already does.

2. Observations

O1 — the color/stroke value channel for 1-bit-shaped state already exists and is a live paint consumer, not a test fixture. WireRenderer.draw (src/jls/edit/WireRenderer.java:58-91) reads the net's value every paint:

BitSet value = w.hasNet() ? w.getValue() : null;

(src/jls/edit/WireRenderer.java:62), then selects a Palette color per state:

else if (value == null) { // off
    g.setColor(JLSInfo.Palette.wireOffColor);
}
else if (!(value.isEmpty())) {
    g.setColor(JLSInfo.Palette.nonZeroColor);
}
else {
    g.setColor(JLSInfo.Palette.wireZeroColor);
}

(src/jls/edit/WireRenderer.java:69-76), and a matching stroke via strokeFor (src/jls/edit/WireRenderer.java:43-56): dashed for null/HiZ, a thick round stroke for any non-empty value, a plain 1px stroke for an all-zero value. This is called from the real interactive paint path, not only from a test: CircuitRenderer.draw calls ElementRenderers.draw(g, el) for every visible wire (src/jls/edit/CircuitRenderer.java:144), and CircuitRenderer.draw is itself called from SimpleEditor's paintComponent override:

CircuitRenderer.of(circuit).draw(g,selected,me);

(src/jls/edit/SimpleEditor.java:2488, inside paintComponent opening at src/jls/edit/SimpleEditor.java:2448). This refutes the original filing's Outcome claim that "Wire has no draw path that consults WireNet.value" — it does, and has since issues #76/#77.

O2 — no numeric value label is drawn on the canvas for any wire, 1-bit or multi-bit. BitSetUtils.toDisplay is the codebase's one value-to-string formatter (src/jls/BitSetUtils.java:237-244 (quotes: return str;)). git grep -n "BitSetUtils.toDisplay" -- '*.java' returns 14 call sites, all inside src/jls/elem/ (Display.java:295, InputPin.java:128, JumpEnd.java:314, JumpStart.java:313, Memory.java:950-951, OutputPin.java:114,224, Pin.java:289,293, Register.java:467,681,684, Wire.java:342) — every one feeds a tooltip/infoText/TellUser dialog or a System.out trace line, none a Graphics draw call. git grep -n "drawString" -- 'src/jls/edit/WireRenderer.java' 'src/jls/edit/WireEndRenderer.java' matches only the existing probe-name label (src/jls/edit/WireRenderer.java:106,112,123,128); there is no second drawString for a value.

O3 — Wire.infoText already formats a value string on click/hover, but only for that modal path, and toDisplay has no radix parameter. Wire.infoText builds ", value = " + BitSetUtils.toDisplay(getValue(),net.getBits()) (src/jls/elem/Wire.java:342). BitSetUtils.toDisplay's signature is toDisplay(@Nullable BitSet value, int bits) (src/jls/BitSetUtils.java:237) — it takes no radix argument and always returns the fixed composite string "0x" + hex + " (" + decimal + " unsigned, " + signed + " signed)", or "HiZ" for null (src/jls/BitSetUtils.java:239-243). There is no per-WireNet or global "active radix" setting anywhere this formatter consults; radix is instead a private, per-element display preference on individual elements — e.g. Constant's own default radix field (src/jls/edit/ConstantDialog.java:41) and Display's own radix radio buttons (src/jls/edit/DisplayDialog.java:79-120 (quotes: /** Radio button selecting binary display radix. */; radix.add(b16);)) are each configured independently per element instance, not from any shared or wire-scoped setting.

O4 — no on-canvas value-rendering toggle exists. git grep -n "showValue\|ShowValue\|valueRendering\|ValueRendering\|WireValueStyle" -- '*.java' returns no results. The color/stroke encoding of O1 is unconditional today: it runs on every paint of every wire with no way to turn it off from the UI.

O5 — batch/headless runs never reach the paint path this task touches, independent of any toggle. Batch mode is documented as one of JLS's "headless one-shot modes" (src/jls/ToolkitPolicy.java:24) and is offered as the -b flag "run in batch (headless) mode" (src/jls/JLSStart.java:763 (quotes: "run in batch (headless) mode"),)). WireRenderer, WireEndRenderer, CircuitRenderer, and SimpleEditor all live in src/jls/edit/, a package excluded from the headless core by design (ARCHITECTURE.md's headless-core packages, enforced by HeadlessCoreRatchetTest, test/jls/HeadlessCoreRatchetTest.java:53), and no batch code path constructs a SimpleEditor/CircuitPanel to invoke paintComponent. HeadlessCoreRatchetTest's FORBIDDEN_IMPORT pattern (test/jls/HeadlessCoreRatchetTest.java:56-58 (quotes: + "(?:java\.awt\.|javax\.swing\.|jls\.edit\.)");)) forbids java.awt.*/javax.swing.*/jls.edit.* imports inside CORE_PACKAGE_PREFIXES, which includes src/jls/sim/ and src/jls/elem/ (test/jls/HeadlessCoreRatchetTest.java:74-76) — i.e. the ratchet this task's AC2 cites is already the mechanism keeping value rendering out of headless code, and this task adds nothing to jls.sim or jls.elem that would trip it.

O6 — no SampleSink/WaveModel recording layer exists yet. git grep -rln "WaveModel\|SampleSink" -- '*.java' returns no results at evidence_commit. The original filing's "or #527's SampleSink stream where one is already attached" alternative is therefore not available today; this task can only read WireNet.getValue() directly, the same access WireRenderer already uses (O1).

O7 — no Wire-adjacent state is persisted today beyond connectivity and tri-state. Wire.save is a documented no-op: "Wires don't get saved." / public void save(PrintWriter output) { // do nothing } (src/jls/elem/Wire.java:120-125). WireEnd.save (src/jls/elem/WireEnd.java:586-593 (quotes: if (isAttached()) {)) writes only a tristate flag and, if attached, the connected put's name — no value, radix, or rendering-mode field of any kind.

3. Research Question

Can a multi-bit WireNet's current numeric value be shown on the schematic canvas, and on-canvas wire-value rendering as a whole be made user-toggleable, without adding a second sampling mechanism, without changing the .jls file format, and without adding an AWT/Swing import to jls.sim?

4. Hypothesis (falsifiable)

  • H1. A multi-bit numeric value label can be added to WireRenderer.draw's existing per-wire paint call, reusing the already-fetched BitSet value (src/jls/edit/WireRenderer.java:62) and the existing text-layout pattern the probe-name label already uses (src/jls/edit/WireRenderer.java:97-131 (quotes: } // end of draw method)), without any new field on Wire or WireNet and without a new Graphics acquisition path.
  • H2. A UI toggle for on-canvas value rendering (color/stroke plus the new label) can be added as pure state read at paint time — no persisted field, no .jls schema change — because no such state exists on Wire/WireEnd/WireNet today (O7) and save() for both element types already ignores rendering concerns entirely.
  • H3. Because WireRenderer/WireEndRenderer/CircuitRenderer already sit entirely inside src/jls/edit/, outside every package HeadlessCoreRatchetTest polices (O5), this task can satisfy "no AWT/Swing import added to jls.sim" (the surviving, narrower form of the old AC2) without any special-casing — the ratchet already forbids it structurally.

5. Predictions

  • P1. At evidence_commit, git grep -n "BitSetUtils.toDisplay\|drawString" -- 'src/jls/edit/WireRenderer.java' shows zero value-label draw calls (confirmed, O2). After the fix, it shows at least one, gated on the net being multi-bit (net.getBits() > 1) and on the new toggle being enabled.
  • P2. At evidence_commit, git grep -n "showValue\|ShowValue\|valueRendering\|ValueRendering" -- '*.java' returns no results (confirmed, O4). After the fix, it resolves to a discoverable toggle (menu item and/or preference field) with its own unit test asserting the paint path is unchanged when the toggle is off.
  • P3. test/jls/elem/WireValueChannelTest.java's existing assertions (O1's color/stroke encoding) continue to pass unmodified — this task does not touch the 1-bit color/stroke channel, only adds the multi-bit label and the toggle around the whole value-rendering feature.
  • P4. Saving a circuit with the new toggle on and again with it off produces byte-identical .jls output, because neither state lives on Wire, WireEnd, or WireNet (H2, O7) — no new save()/load() branch is added.
  • P5. test/jls/HeadlessCoreRatchetTest.java's BASELINE gains no new entries: the new label/toggle code lives in src/jls/edit/, never in src/jls/sim/ or src/jls/elem/ (H3).

6. Materials & Apparatus

  • Existing headless-render test harness pattern from test/jls/elem/WireValueChannelTest.java's render(Consumer<Graphics2D>) helper (renders to an off-screen BufferedImage, counts non-background pixels) — reusable for a new label-presence assertion without a display.
  • mvn verify (tests + SpotBugs, warnings-as-errors) as the standing gate; not run as part of this filing pass per the enhancement evidence standard (no build executed — see § Open Questions & Decisions Needed).
  • No new test rig needs to be built first: WireValueChannelTest's fixture-construction pattern (CircuitWireEnds → WireWireNetnet.setValue(...)) already exercises exactly the object graph a multi-bit label test needs, just with a wider BitSet/bits value.

7. Interface & Data Contract

7.1 External interfaces modified

GUI surface only: the schematic canvas (SimpleEditor's circuit panel) gains (a) a numeric value label drawn beside/along multi-bit wires and (b) a new toggle (menu item and/or preference) controlling whether on-canvas value rendering (existing color/stroke plus the new label) is active. No CLI/batch (-b) flag changes — batch mode never constructs the panel this touches (O5). No .jls file format change (docs/file-format.md) — Wire.save/WireEnd.save are unaffected (O7, P4). No HDL export change (jls.hdl is untouched by this task's scope).

7.2 External interfaces consumed

java.awt.Graphics/Graphics2D, FontMetrics for text measurement and drawString for the label — the same JDK surfaces WireRenderer.draw already consumes for the probe-name label (src/jls/edit/WireRenderer.java:97-131 (quotes: } // end of draw method)). No new JDK API, environment variable, font, or OS service.

7.3 Data consumed (structure)

The task reads WireNet.getValue() (a @Nullable BitSet, src/jls/elem/WireNet.java:428) and WireNet.getBits() (int), both already public accessors on the in-memory circuit model — trusted, process-local state, not hostile input (the .jls file itself is untouched, see 7.1). No external schema.

7.4 Internal interfaces provided — public

A value→style mapping in the spirit of TraceGeometry (src/jls/sim/TraceGeometry.java:1-9): given a BitSet/null value and a bit width, return the label text (reusing BitSetUtils.toDisplay, src/jls/BitSetUtils.java:237, or a narrower radix-free formatter — see Open Question on "active radix") and/or which of the existing three visual states (off/zero/non-zero) applies. Whether this becomes a standalone class (e.g. WireValueLabel alongside WireRenderer's existing strokeFor, src/jls/edit/WireRenderer.java:43) or stays a static method on WireRenderer is a Method-time (§8) decision; either way it must be a pure function over (BitSet, int) -> String/state, callable and testable without a Graphics context — the same shape strokeFor already has. Precondition: none (accepts null). Postcondition: total function, never throws for any BitSet/bits combination.

7.5 Internal interfaces provided — private

The toggle's read accessor inside the paint path (e.g. a static or instance boolean WireRenderer/SimpleEditor consults before drawing the label and/or the color/stroke) — implementation-private, enforced by keeping it package- or class-private the way WireRenderer's existing fields already are; not part of any public API surface.

7.6 Data provided (structure)

A drawn string on the Graphics canvas — visual output only, no new in-memory or on-disk structure. If §7.4's mapping is extracted as a standalone class, its return type (label text, and/or a value-state enum) is defined there, following strokeFor's existing BasicStroke return as precedent (src/jls/edit/WireRenderer.java:43-56).

7.7 Data durably tracked

N/A — no new durable state. The toggle, if it is to persist across sessions (a preference), would be the one durable addition; whether it does is an Open Question below. Wire/WireEnd/WireNet gain no new persisted field (O7, P4).

7.8 Data ephemerally used

The toggle's in-memory state (if not persisted) lives for the session only, the same lifetime as other SimpleEditor view preferences. Nothing is lost mid-operation if it resets — it only affects what the next paint draws, exactly as the existing color/stroke encoding already behaves with no persistence today (O4).

7.9 Concurrency model

Synchronous, EDT-only, matching the existing pattern: WireRenderer.draw already reads live WireNet value state from inside paintComponent (src/jls/edit/SimpleEditor.java:2448-2488), which Swing invokes on the Event Dispatch Thread. This task adds no new thread, lock, or SwingWorker — the label read is the same unsynchronized read of shared mutable simulator state the color/stroke encoding already performs every repaint; this task introduces no new concurrency exposure beyond what O1's already-shipped code has.

7.10 Data transformations

Let $w$ be a Wire, $n = w.\mathrm{net}$ its WireNet, $v = n.\mathrm{getValue}() \in \mathrm{BitSet} \cup {\bot}$ ($\bot$ = HiZ/no value), and $b = n.\mathrm{getBits}()$.

Existing (O1, unchanged by this task):

$$f_{\mathrm{style}}(v) = \begin{cases} \text{dashed, off-color} & v = \bot \ \text{thin solid, zero-color} & v \neq \bot \wedge v = \emptyset \ \text{thick solid, nonzero-color} & v \neq \bot \wedge v \neq \emptyset \end{cases}$$

New (this task):

$$f_{\mathrm{label}}(v, b) = \begin{cases} \varnothing & b \le 1 \ \mathrm{toDisplay}(v, b) & b > 1 \end{cases}$$

where $\mathrm{toDisplay}$ is the existing total function at src/jls/BitSetUtils.java:237-244 (quotes: return str;) (or a replacement formatter, per the Open Question on "active radix" below), and $\varnothing$ means "draw nothing" — 1-bit nets keep only $f_{\mathrm{style}}$, matching O1/O2 exactly.

$$f_{\mathrm{toggle}}(t, v, b) = \begin{cases} f_{\mathrm{style}}(v) \cup f_{\mathrm{label}}(v,b) & t = \mathrm{on} \ \text{today's unconditional } f_{\mathrm{style}}(v),\ \varnothing\text{ label} & t = \mathrm{off} \end{cases}$$

Every stage is total (no partiality) — $\bot$ and $b \le 1$ are both explicit cases, not omissions, so § 7.11 (Failure modes) has no undefined input to own for this pipeline specifically.

7.11 Failure modes & error handling

No I/O, no file parsing, no network — the only inputs are already-validated in-memory model state (BitSet/int). toDisplay already handles null (returns "HiZ", src/jls/BitSetUtils.java:239-240) and is total over all (BitSet, int) pairs, so there is no malformed-input case to guard against for the label itself. If §8 extracts a new pure model class, its constructor/static methods must not throw for any reachable (BitSet, int) combination (mirrors strokeFor's current total behavior, src/jls/edit/WireRenderer.java:43-56). An interrupted paint (e.g. window closed mid-repaint) is already handled by the existing try { CircuitRenderer.of(circuit).draw(...) } catch (Exception e) { ... } wrapper (src/jls/edit/SimpleEditor.java:2486-2491 (quotes: // draw all elements, selected ones last; e.printStackTrace();)); this task adds no new exception path outside that existing envelope.

7.12 Compatibility, versioning & migration

Old .jls files load unchanged — no field added to Wire/WireEnd/WireNet's save/load contract (O7). Save output is byte-identical with the toggle on or off (P4) because no rendering-mode bit is written to the file. All existing callers of WireRenderer/ElementRenderers/CircuitRenderer keep compiling — this task adds to WireRenderer.draw's body and possibly one new pure-function class, no signature of an existing public method changes. test/jls/elem/WireValueChannelTest.java's existing assertions hold unmodified (P3) — the 1-bit color/stroke round-trip is untouched.

8. Method / Experimental Design

  • Confirm at pickup that O1–O7 still hold (rule 6): re-run the six git grep commands in § Observations and re-open the cited files at the current HEAD; if any citation has drifted, re-derive the line numbers before proceeding.
  • Resolve the Open Question on "active radix" (below) — pick the label format before writing code, since it determines f_label's definition in §7.10.
  • Add a new regression test (e.g. WireValueLabelTest alongside WireValueChannelTest) asserting: (a) a 1-bit net's rendered ink is unchanged from WireValueChannelTest's existing baseline with the label feature present but inapplicable (b <= 1); (b) a multi-bit net with a distinguishing non-zero value renders additional ink versus the same net with the label suppressed; (c) the test fails at the pre-change commit (no label exists, O2) and passes post-change.
  • Implement f_label (§7.10) as a pure function, either a static method on WireRenderer beside strokeFor or a new small class — decide per the §7.4 note — and wire it into WireRenderer.draw gated on net.getBits() > 1 and the new toggle.
  • Add the toggle: a boolean read at the top of WireRenderer.draw (and, if the color/stroke channel is also meant to be gated per AC2's "with it off, the paint path is unchanged from today," the existing O1 branch too), plus its UI control (menu item and/or preference) and one test asserting the paint path is byte-for-byt identical to pre-change when the toggle is off.
  • Add a save/load round-trip test asserting .jls output is byte-identical with the toggle on vs. off (P4), pinning §7.12's compatibility claim.
  • Run mvn verify locally; confirm HeadlessCoreRatchetTest's BASELINE needs no new entries (P5) and WireValueChannelTest passes unmodified (P3).

9. Data Collection & Analysis

Each new/changed behavior is asserted by a named JUnit test: the multi-bit label by the new WireValueLabelTest (§8), the toggle's off-path no-op by a paint-path-unchanged test, and the save/load byte-identity by a round-trip test. mvn verify's SpotBugs pass and warnings-as-errors gate are the standing static-analysis check; their pass/fail is recorded in the PR, not re-derived here (no build was run during this filing pass — see § Open Questions & Decisions Needed).

10. Falsification Criteria

  • H1 is refuted if the multi-bit label cannot be added without a new field on Wire/WireNet or a new Graphics acquisition path distinct from WireRenderer.draw's existing one — investigate why the existing per-paint value read (O1) is insufficient before assuming a new sampling tap is needed.
  • H2 is refuted if the toggle turns out to need persistence that cannot be added without a .jls schema change — if so, P4 fails and the toggle must be re-scoped to a session-only (non-persisted) preference, or a follow-up issue must own the format change explicitly (rule 4, atomic scope).
  • H3 is refuted if any new code this task adds lands inside src/jls/sim/, src/jls/elem/, src/jls/hdl/, src/jls/module/, or src/jls/core/ and imports java.awt.*/javax.swing.*HeadlessCoreRatchetTest fails immediately (test/jls/HeadlessCoreRatchetTest.java:74-76), and the label/toggle logic must move into src/jls/edit/ instead.

11. Threats to Validity

  • This filing pass ran no build or GUI render (enhancement evidence standard — no mvn verify, no on-screen manual check); every O1–O7 observation above is git grep/file-read evidence at evidence_commit, not an executed test run. An executor must re-verify at pickup per rule 6.
  • Headless-vs-GUI divergence: WireValueChannelTest's off-screen BufferedImage rendering (no real display) is a good proxy for pixel-level assertions but does not exercise the real SimpleEditor/EDT paint cycle end-to-end; a manual GUI check (with platform) belongs in the PR per § Data Collection & Analysis.
  • Line numbers throughout are pinned to c5cee1baff3451a85787b4a09bd0b2b05af7dfdd and will drift with any edit to the cited files; re-derive before trusting (rule 1, rule 6).
  • The #693/#695/#504/#527/#533 cross-references in § Status & Dependencies are carried forward from the original filing's prose and were not independently re-verified against GitHub during this migration (no GitHub access in this pass) — see § Open Questions & Decisions Needed.

12. Related Work

13. Conclusion & Future Work

On completion, every visible multi-bit WireNet shows its numeric value as an on-canvas label reusing the existing paint-time value read, and a UI toggle governs whether on-canvas value rendering (color/stroke and the label) is active — with no .jls format change, no new sampling/recording mechanism, and no AWT/Swing import added to any headless-core package. Recording/history of wire values over time remains explicitly out of scope, owned by #527 whenever that work lands; an in-flight-event overlay drawn on top of this state is #695's scope, not this task's.

Open Questions & Decisions Needed

  • "Active radix" is not a concept that exists in the codebase for wires (O3). BitSetUtils.toDisplay always returns a fixed "0xN (N unsigned, N signed)"/"HiZ" composite string with no radix parameter; the only per-element radix settings that exist (Constant, Display) are each independently configured, not shared or wire-scoped. Options: (a) reuse toDisplay's existing fixed composite format as-is — no new state, automatically satisfies "no new per-element serialized state" (P4/§7.7) — recommended default; (b) add a new global "active radix" preference — new (session-only, non-persisted per H2) state, more work, matches the original AC's literal wording; (c) add a per-WireNet radix — would very likely require new persisted state, directly conflicting with the "no new per-element serialized state" criterion, not recommended. This blocks §8 step 1 (Method) but not filing.
  • Does the toggle persist across sessions? Left open in the original filing ("toggleable in the UI"). A session-only in-memory boolean is the safe default (avoids any .jls/preferences-file schema question); a persisted-preference version is a legitimate but larger alternative. Recommended default: session-only for this task; a persisted preference can be a fast-follow if requested. Does not block filing; must be resolved before §8 implementation.
  • The full observed-failure obligation (rule 3 / template line 23-26) was not discharged with an executed build or test run. Per the maintainer's 2026-08-17 evidence-standard ruling for enhancement issues, this filing pass derived structural evidence via git grep/file reads only (O1–O7) and did not run mvn verify or render the GUI. An executor must run the new regression tests (§8) against the pre-change commit to confirm they fail there, per rule 3, before relying on this filing's predictions as pre-verified.
  • The cross-issue edges in § Status & Dependencies (#693, #695, #504, #527, #533) are carried forward from the original body's prose, unverified against live GitHub state in this pass (no GitHub access during migration). Recommend the maintainer or the next executor confirm those issues' current numbers/status before treating blocks/related as authoritative.

14. Completion Criteria (Definition of Done)

  • Every post-fix prediction in §5 (Predictions) verified; command and output recorded in the PR
  • Every check in §10 (Falsification Criteria) performed post-fix; outcome (not refuted / refuted → action taken) recorded in the PR
  • Post-change code re-checked against §7 (Interface & Data Contract): interfaces provided/consumed, data structures, concurrency model, and compatibility claims hold as declared; any deviation recorded as an issue comment (rule 2), not silently absorbed
  • New regression tests fail at the pre-change commit and pass at the fix commit
  • Existing tests pass unmodified, including test/jls/elem/WireValueChannelTest.java (P3) — no asserted behavior in it is intentionally changed by this task
  • mvn verify green (tests + SpotBugs, warnings-as-errors)
  • No new entries in config/spotbugs-exclude.xml, or each new entry is Class-scoped with a justification
  • No new entries in test/jls/HeadlessCoreRatchetTest.java's BASELINE (P5)
  • No changes outside the scope of §8 (Method); adjacent work discovered en route is filed as new issues
  • Every blocked_by entry in Status & Dependencies has landed, or the dependency was waived per rule 10 — N/A, blocked_by is empty
  • Landing reported on feature FEAT-C23-4: an in-flight-event overlay and an ordinal trajectory scrubber replace wire-crawl stepping — per-gate delay becomes something a student watches, not a number in a dialog #533 with a STATUS: comment (part_of_feature is set), including any contract deviations the feature's plan must reconcile
  • Every cited evidence document and permalink resolves on the default branch at close — no branch-path links, no deleted docs
  • Every skipped or waived criterion carries a WAIVED: comment naming its successor issue (rule 10)
  • Not superseded: the § Observations gaps (O2, O4 — no label, no toggle) still reproduce at pickup (rule 6); citations re-derived if HEAD had moved
  • Every decision in Open Questions & Decisions Needed is resolved (or explicitly deferred), none left blocking
  • Saving a circuit with the toggle on and off produces byte-identical .jls output (P4), confirmed by the round-trip test in §8

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions