14 Commits
Author SHA1 Message Date
james.maesandClaude Fable 5.2 05518acd02 fix(renderer): scene 2 barcodes after independent review: no symbol reads as another value, rules by symbology, nothing painted over a symbol
maven / build (push) Successful in 6m59s
build / maven (push) Successful in 6m59s
A label is scanned, so a symbol must never read as something other than
the value it was given. Record values are untrusted and stay out of every
diagnostic and exception.

- No value, literal or bound, may hold the two characters an escape of the
  encoder begins with. \<FNC1> in a plain Code 128 value drew a GS1-128 of
  the record's choosing, \<FNC3> set the reader-programming flag, and QR
  dropped the escape. Refused in every symbology, with a count only.
- Interleaved 2 of 5 of an odd number of digits is refused, not padded.
- EAN and UPC values are the whole number with its check digit, which is
  verified; a shorter number is refused, never completed or padded.
- The check digit of every GS1 key in a gs1-128 element string is
  verified: the identifiers the GS1 Syntax Dictionary marks, as the
  bundled Zint carries it.
- VALUE_NOT_ENCODABLE joins the errors for these and for a value a
  symbology cannot hold; SCENE_INVALID is no longer used for a value. A
  symbol of more modules than the encoder draws is BARCODE_DOES_NOT_FIT.
- Quiet zones and the smallest module are a table by symbology
  (scene2/barcode/Symbology), each number with its source. barcodeProfile
  names the rule: none, gs1-general or gs1-logistics; not stated, the
  strictest written for the symbology. A GS1-128 is so held to 0.495 mm
  unless its scene says otherwise, at which a GTIN with a date and a
  serial number fits no label 4 in wide.
- The bars of a linear symbol must be as tall as its symbology asks, and
  the height is part of the fit. minHeight overrides, with the standing
  warning BARCODE_HEIGHT_BELOW_RECOMMENDED.
- QUIET_ZONE_INTRUDED is an error: an element later in the list whose ink
  would enter a symbol or its quiet zones is refused, when a scene is
  validated as when it is rendered.
- A barcode sits in the middle of its box unless the scene says otherwise.
- A bound barcode takes maxLength and is proven at validation in a linear
  symbology. FIT_NOT_PROVEN stays for no length and for two-dimensional
  symbols, whose encoders have no largest symbol of a length.

Codes and property names are added in one change: foundation's
FailureCode and warning set, the preview's sentences, the bridge's
accepted refusals and schema vocabulary, the renderer's vocabulary and
the schema. The three barcode goldens are unchanged byte for byte;
barcode-retail is new.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 18:19:02 -06:00
james.maes a147efee88 Merge pull request 'feat(renderer): scene 2 text: bundled fonts, measurement before drawing, stated fit rules (P2)' (#16) from feat/scene2-text into develop
maven / build (push) Successful in 7m40s
build / maven (push) Successful in 7m40s
2026-11-12 23:11:02 +00:00
james.maesandClaude Fable 5.2 589b6d41ee fix(renderer): scene 2 text after independent review: a proof that never cuts, a bounded shrink search, named refusals
maven / build (push) Successful in 10m28s
build / maven (push) Successful in 10m28s
The proof of `maxLength`
- The proof never cuts. With `overflow: truncate` the proof was given a cut
  block, which counts as fitting, so a bound element whose box held ten
  characters validated clean with `maxLength: 40` and every long value was cut
  at print. The proof now runs with cutting off. When it fails, an element
  that did not ask for cutting is refused as before; one that did still
  validates, since cutting is what its author chose, with the warning
  FIT_NOT_PROVEN at every validation carrying `measured.provenCharacters`,
  the longest length proven to fit whole (found by halving: fewer characters
  never fit worse), against `limit.characters`. No new code: FIT_NOT_PROVEN
  already means that the fit of a bound value is not proven.
- A bound element with `maxLength` is judged for legibility, when validated,
  at the size the proof shrank to (the floor when it fails and the element
  cuts), not at its stated size.

The shrink search
- The size chosen is still exactly the one a search of every quarter-point
  step gives, but that search is no longer made. A count that errs only
  toward yes says whether a size could hold the text: lines filled at any
  character, each held to a width no real line can be under, and a block to
  its lines' ascent, pitches and descent. It never refuses a size that fits
  and, once it allows a size, allows every smaller one, so the largest size it
  allows is found by halving and only the steps from there are laid out. When
  one line at the floor is higher than the box nothing is searched, and a cut
  tries no line count the box is too low for.
- 1024 characters at 600 dpi from 1000 pt to 1 pt took 180 to 250 ms a fit and
  now takes under 1 ms: at most 21 555 characters visited where the search of
  every size visits 15.6 million.
- A text is fitted once: what `check` composed is what `paint` draws.
- The text of one scene may take 64 million steps (a character visited while
  fitting is one, a character to be drawn 16, a glyph the scene draws for the
  first time at a size 4096, since the runtime rasterises it once). The
  element that passes it, and every text after it, is SCENE_INVALID at the
  element with `textWorkSteps`, as the painted-area limit is. The count is
  integer arithmetic: the same on every machine, and the same validated or
  rendered. A thousand of the worst elements validate in well under a second.

Ink outside the measure
- TEXT_INK_OUTSIDE_MEASURE was an IllegalStateException thrown while
  painting, which failed the whole render after part of the text was on the
  label. The dots of a text are now gathered first and reach the label only
  when none strayed; otherwise the one element is refused as
  TEXT_DOES_NOT_FIT with `glyphsOutsideMeasure` and `dotsOutsideMeasure`. A
  literal is held to the glyph bounds when the scene is validated.
- The bound is tested at 1, 2, 300 and 1000 pt as well as from 5 to 72 pt, for
  every character of every face at the three resolutions; nothing strays.

Schema and vocabulary
- `fit` declares `maxLines`, `shrinkTo` and `overflow` under `properties` with
  `additionalProperties: false`. The three names are in the renderer's and the
  host bridge's pointer vocabularies, and a wrong member is reported at the
  member (`/elements/3/fit/maxLines`, or in the override that states `fit`).
- A bound number is printed as the schema says: plain decimal digits, no
  exponent, no fraction that is only zeros (`1.0E10` prints `10000000000`,
  `2.50` prints `2.5`). A number that is not finite is VALUE_MISSING.

Tests
- The widest-advance check covers every character a face draws, inked or not
  (a no-break space advances the pen), so a font update cannot break the proof
  unseen.
- Property: `fit` equals the search of every size, block for block, over 3600
  generated texts, boxes, sizes, floors and line counts.
- The goldens are unchanged. A README beside them records the JDK builds and the
  FreeType each ships.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 14:58:53 -06:00
james.maesandClaude Fable 5.2 1db82957c9 fix(bridge): a placeholder of no area draws nothing; name the answer table for what it is
ZplRaster.hatch returns at once for an area of no width or no height. Its
outline and diagonals would otherwise be placed one dot outside the area:
with no width the diagonal's column divides down to -1 and a stray line is
drawn. The guard that the refused page had around its call is now in the
painter itself, so every caller has it. An empty printer font text field did
not reach the painter before this change either: such a field is refused as
no field (RASTER_FIELD), and by the output policy before that; the existing
test for it is unchanged. ZplRaster stays at 100% lines.

ReleasedRendererAnswerTest is renamed VersionOneAnswerTableTest and its
header says what it is: 71 synthetic answers in the shape the released
renderer answers with, and the outcomes of today's bridge for them. They were
not captured at the released tag, unlike the job frame golden, so the table
holds today's behaviour still and does not show equality with the release.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 14:38:14 -06:00
james.maesandClaude Fable 5.2 1828ae9c48 fix(bridge): ask the renderer's version again after any RENDERER_TOO_OLD
The comments said that nothing of a version 2 scene reaches a renderer
that cannot draw it. That is not so: the answer to the version question is
remembered, so after a renderer image is rolled back ONE job reaches the
old (0.1.0) renderer, scene and record values included, and is then
refused as RENDERER_TOO_OLD. The class, field, invoke and probe comments
now say exactly that.

The window stays one job in every case: a job that ends in
RENDERER_TOO_OLD, from render, validate or preview, forgets what was
remembered, so the next job that needs renderer 0.2.0 asks the version
first. An answer from 0.1.0 already did this; a refusal that renderer
0.2.0 names itself, as an error answer or among collected diagnostics, did
not.

FakeWorker can stand for an image that is replaced while a bridge uses it.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 13:49:06 -06:00
james.maesandClaude Fable 5.2 bbb4b60a1b test(bridge): golden of the released version 1 job frame and a table of released answers
Nothing held the version 1 print request to the released bytes, and the
0.1.0 answers were tested at the units and not through render().

- compat-v1/job-frame-render.json is the frame the bridge of tag
  v1.1.0-RC.2 (e9ffba484e) wrote to its
  exchange for one render() with fixed inputs. VersionOneJobFrameTest
  compiles unchanged at that tag and is its own capture tool; the .md
  beside the frame gives the inputs and the commands.
- The frame is compared byte for byte except for the order of the seven
  members of "stock": the released bridge writes them in the iteration
  order of an immutable Map.of, which the JVM changes from run to run (four
  captures at the tag gave four orders and were otherwise identical).
- ReleasedRendererAnswerTest is one row for each answer of
  qqq-renderer-0.1.0 to a version 1 job, accepted, refused by code or
  rejected, every row through render(), with the name the version rule
  gives the same frame.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 13:49:06 -06:00
james.maesandClaude Fable 5.2 9e5b16d686 fix(bridge): bound preview painting to sixteen times the page
ZplRaster painted a box and a placeholder by testing every dot of the
field's area. The output policy allows 6000 fields, so a label of
page-sized boxes was tens of thousands of millions of dots of work on the
host while an admission slot was held, and the page of a refused scene had
the same cost for each of up to 2048 diagnostic boxes.

- Every painter counts the dots it is about to paint, an overlap each
  time, and the field that would take the page past sixteen times its dots
  is refused as PREVIEW_TOO_LARGE. This is the renderer's own limit for a
  scene. A graphic counts eight dots for each byte.
- A box is the whole area when its border meets itself, else four bars
  that do not overlap, filled whole bytes at a time. The dots are the same
  as before.
- A placeholder (printer font text, a refused element's box) is an outline
  and its two diagonals, so it costs its perimeter and not its area. This
  changes its look: the diagonal hatch every six dots is gone.
- preview() returns the refusal as a result, like the page limit: not
  printable, no page, PREVIEW_TOO_LARGE with limit.paintedPercent 1600. For
  a refused scene it joins the diagnostics the worker sent.

Printing is not changed.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 13:49:05 -06:00
james.maesandClaude Fable 5.2 ed11495120 feat(preview): layout preview inside the QBit: service, action and record widget (P6b)
A person editing a label template sees the picture that would print, with
its refusals and warnings, before anything is printed, from the module's
own screens and with no host code.

- DocumentPreviewService: authorises by the existing permissions (a draft
  needs configure, a published revision needs view, a record needs
  generate and is read as the person, with their permissions and record
  locks, before any context is built), loads the draft or the published
  snapshot without writing, builds the context as generation does and
  calls IsolatedRenderer.preview. Data is a sample from the scene, the
  longest declared values, or one record. One log line, no content.
- "Preview layout" action on templates and published revisions: data,
  sample, record, stock and resolution; the result is the preview widget.
- "Label preview" section on the template record screen: the draft with
  sample data (the published revision for a person who may only view).
- The widget is fetched, never seeded from a process value: QQQ keeps the
  state of a finished process for hours (in a table with the shared
  provider), so the picture, the context and the diagnostics exist only
  in the answer to the widget request. The process state holds the
  person's choices only.
- Bounded answer: one page, a picture of at most 2 MiB, fifty diagnostics.
- The existing action is relabelled "Generate retained preview file"; its
  process name and behaviour are unchanged.
- The record selector asks for generate alone, so a person who may
  preview a published revision with a record can choose one.
- Help on every new process, step, field, section, widget and choice list.

Tests: DocumentPreviewTest (data sources, permission matrix, unreadable
record, nothing written, process state, PDF refusal, refused scene,
version 1 label, bounds, log line, help coverage, instance validation)
and LayoutPreviewServiceTest in bridges/renderer (through the service and
the bridge, the preview has the hash of the bytes the print path returns
at 203, 300 and 600 dpi). The registration and process tests are updated
for the new wiring and the relabel. bridges/renderer gains the RDBMS
module at test scope for that test.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 13:37:56 -06:00
james.maesandClaude Fable 5.2 bf546e16c5 feat(bridge): accept renderer 0.2.0, read its diagnostics, preview a label (P5)
maven / build (push) Successful in 12m32s
build / maven (push) Successful in 12m32s
On develop the renderer speaks qqq-renderer-0.2.0 and the bridge accepted
only 0.1.0, so the bridge refused its own renderer, a label could not be
previewed, and a render target was accepted and then ignored.

The version rule (RendererVersion). The bridge accepts 0.1.0 (the released
fields, the 13 released refusals) and 0.2.0 (the same with diagnostics and
detail, those refusals and the 15 scene refusals); any other version is
rejected. Each set is written out, replacing the temporary enum range. A
job is framed as 0.1.0 reads it unless it needs more. Before a job only
0.2.0 can do (a version 2 scene, a preview) the bridge asks the worker its
version by validating a fixed, empty version 1 scene, so an old image is
refused as RENDERER_TOO_OLD and receives nothing of the scene or the
record; an answer from 0.1.0 to such a job is refused whatever it says.

Diagnostics (WorkerAnswer, SceneFacts). A version 2 refusal is
RenderException(code, diagnostic). The worker is untrusted, so every field
is checked again: the closed vocabulary, whole numbers in bounds, an
element only if the scene that was sent declares it, and a pointer only of
array indexes, schema property names and declared ids. An answer holds at
most 2048 diagnostics in one megabyte beside its label, and no frame
passes the frame of the largest document the deployment admits. A refused
answer that carries any part of a label is rejected.

Render target. targetDpi is sent with a version 2 scene and the label is
held by the output policy to the page at that resolution. A version 1
scene or a PDF asked for another resolution than its stock's is refused as
TARGET_REQUIRES_SCENE_2 before any worker is contacted, because renderer
0.1.0 does not read the field. supportsRenderTarget() is true.

Preview. preview() is the print path stopped before retention: the same
job with collected diagnostics, the same integrity checks and output
policy, and a page decoded by ZplRaster from the accepted label bytes.
ZplRaster is its own strict reader of the policy's grammar and runs the
policy first; it paints ^GFA and ^GB exactly, hatches printer font text
(the page is then not exact) and writes a one-bit PNG itself. Refusals
come back as diagnostics, never as a label. A refused scene is drawn on
the host from the diagnostics' boxes alone: the worker sends no label for
it and the wire gains no field for the partial canvas, so no host can
print a label with elements missing. The design records the decision in
sections 6.1 and B.1, the version question in 11.3 and what the host now
reads from a scene in 8.1.

renderer/qualification.json said qqq-renderer-0.1.0 and qqq-barcodes-1;
it now says what the worker reports, and a test holds it to the answer.

The mutation campaign covers the page decoder and the answer frames. The
new classes are gated at 100% line coverage and the bundle gate rises to
the measured 90% of instructions and 88% of lines. The version 1 corpus is
untouched.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 12:02:54 -06:00
james.maesandClaude Fable 5.2 ad6b0ffa88 feat(renderer): scene 2 core: layout in physical units, one canvas, diagnostics (P1)
A source with schema qqq-zpl-scene/2 is a label layout in millimetres,
inches, points, percentages and dots that renders at 203, 300 or 600 dpi.
The worker routes by the schema alone: version 1 takes exactly the path it
always took (the compatibility corpus is unchanged and green), version 2
takes the new package com.kingsrook.qbits.renderer.scene2, and anything
else is refused by name.

- Length: parse, whole micrometres, dots by the rule of each use
  (position nearest, box size down, thickness nearest and at least one,
  module up, font size not rounded).
- Layout: nine-point anchors, offsets inward from the anchored edge,
  omitted sizes, content alignment, groups four deep, percentages of the
  container. Coordinates start at the top left of the printable area.
- Canvas and ZplEmitter: the whole label on one 1-bit canvas, emitted as
  trimmed ^GFA bands that pass the unchanged ZplOutputPolicy.
- Diagnostics: every refusal is one diagnostic with a code, the element
  id, the box and named integers; SCENE_INVALID carries a JSON pointer.
  A diagnostic names only an id the scene declares and points only
  through schema names, indexes and declared ids.
- box and group elements; overrides by resolution, checked for all three
  resolutions; samples accepted and ignored. Text, barcodes and images
  are parsed and placed and then refused as RENDERER_TOO_OLD by
  placeholder factories in their own sub-packages.
- Renderer 0.2.0: optional targetDpi and "diagnostics": "COLLECT" on the
  request, diagnostics on the answer, detail on a version 2 error, the
  REFUSED outcome, and INSPECT_ASSET and UPGRADE_SCENE routed and refused
  as UNSUPPORTED_OPERATION. A version 1 scene with a target other than
  its stock's dpi is refused as TARGET_REQUIRES_SCENE_2.

Tests: every length and rounding rule; all nine anchors; seeded property
tests (mirrored anchors, boxes never leave the printable area, the bitmap
rebuilt from the emitted fields equals the canvas); goldens at three
resolutions as pictures and as ZPL, the ZPL also checked against the host
gate in bridges/renderer; every refusal asserted as the whole diagnostic;
a mutation campaign over the version 2 parser. The new package is at 100%
line coverage.

Also, from the review of the foundations: the mutation campaigns accept
only declared refusals (a NullPointerException in a parser is now a
finding), git no longer treats the stored corpus as text, and both
compatibility tests pin the digest of the corpus manifest.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 10:01:21 -06:00
james.maesandClaude Fable 5.2 c6aa0bf6b0 feat(foundation): preview, diagnostic and render target ports with registration hooks (P6a)
maven / build (push) Successful in 6m19s
build / maven (push) Successful in 6m19s
The contracts the preview, bridge and render target packages plug into. No
label prints differently and no existing host adapter changes.

GenerationPorts:
- Diagnostic (with Severity): a code from a closed vocabulary, an author
  element id, a box and named integers. It has no field that holds free text.
- PreviewRequest, PreviewPage and Preview, and IsolatedRenderer.preview as a
  default that refuses, so an adapter written before it compiles unchanged.
- 15 version 2 FailureCode values after the 13 released ones, and
  RenderException(FailureCode, Diagnostic) beside the existing constructor.
- Integer targetDpi on RenderRequest (absent, 203, 300 or 600); the
  seven-argument constructor is kept and nothing reads the value yet.

Registration points, each an empty class that is already called:
GenerationPreviewProcesses, GenerationAssetProcesses,
GenerationUpgradeProcesses and GenerationAssetTables from the producer, and
GenerationPreviewWidget.section(table) from GenerationTables.

Bridge: IsolatedRendererBridge maps any FailureCode name from a 0.1.0 worker
to a typed refusal, so growing the enum alone would have widened what such a
worker can name. The 13 released codes are now the set a 0.1.0 worker may
name; BridgeTest asserts the other 15 stay generic.

Tests: record validation, default refusals, source compatibility of the
existing constructors, and that the producer registers exactly the tables,
processes, choices, widgets and template sections it did before (the lists
were captured from the untouched v1.1.0-RC.2 tag).

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-11 17:28:43 -06:00
james.maesandClaude Fable 5.2 3ba676106f build(coverage): gate renderer and bridge coverage at baseline; seeded mutation campaigns (P13)
Coverage gates:
- renderer and bridges/renderer gain JaCoCo (prepare-agent, report, check at
  verify) with a bundle rule at the measured baseline, rounded down: renderer
  94% instructions and 91% lines, bridge 85% instructions and 82% lines.
- New code is held to 100% line coverage from its first commit: packages
  com.kingsrook.qbits.renderer.scene2 and below, AssetInspector, ZplRaster,
  and the new foundation classes the label layout design names. The rules
  match nothing until those exist, so later packages do not edit these poms.
- The foundation's 85% instruction and 90% class rule is unchanged.

Fuzz scaffolding:
- MutationCampaign in each module's test tree: a seeded, bounded mutation
  harness with no clock and no unseeded randomness; a finding replays from
  its seed and iteration.
- One campaign per module in the normal test phase: what the version 1 scene
  parser accepts is a version 1 scene (checked by a second parser), and what
  the host printer gate accepts holds only the renderer's command set.
- docs/security/fuzzing.md: targets, properties, limits, seeds and replay.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-11 17:28:42 -06:00
james.maesandClaude Fable 5.2 ea776391ca test(renderer): version 1 scene compatibility corpus from v1.1.0-RC.2 (P0)
Version 1 scenes (qqq-zpl-scene/1) are frozen. This adds 42 render requests
and the exact ZPL the released renderer returned for each, so later work can
prove that labels already printing are untouched.

- renderer/src/test/resources/compat-v1: cases, stored ZPL, SHA256SUMS and a
  README with provenance and rules. The bytes were produced by the source of
  tag v1.1.0-RC.2 (e9ffba48), not by this branch, and the same test passed
  against the tag on Temurin 21.0.12 (Windows) and 21.0.9 (the CI image).
- renderer ZplSceneOneCompatibilityTest: fails on the first differing byte,
  on a manifest that does not name exactly the cases, and on a corpus that
  misses a version 1 element type, property or resolution.
- bridges/renderer ZplSceneOneCompatibilityTest: every stored output has its
  manifest hash and passes the unchanged ZplOutputPolicy. It reads the
  renderer's directory in place, so there is one copy of the corpus.

Covered: the four shapes Forge publishes at 203 and 300 dpi (GS1-128 with
fit and quiet, text in font 0, rasterText with fontAsset), the README and
BARCODE-FIT.md examples, and one scene per element and option at 203, 300
and 600 dpi. All values are synthetic.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-11 17:28:25 -06:00
ee782b7d6e chore: preserve unfinished document generation source and status
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (push) Skipped
QRun-IO/ci-policy: ci / gradle-1 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (push) Skipped
QRun-IO/ci-policy: ci / node-8 (push) Skipped
QRun-IO/ci-policy: ci / node-9 (push) Skipped
QRun-IO/ci-policy: ci / node-10 (push) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (push) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (push) Skipped
QRun-IO/ci-policy: ci / source-config-13 (push) Skipped
QRun-IO/ci-policy: ci / source-config-14 (push) Skipped
QRun-IO/ci-policy: ci / android-0 (push) Skipped
QRun-IO/ci-policy: ci / original-business (push) Skipped
QRun-IO/ci-policy: ci / original-mcp (push) Skipped
QRun-IO/ci-policy: ci / original-voyage (push) Skipped
QRun-IO/ci-policy: ci / original-cli (push) Skipped
QRun-IO/ci-policy: ci / not-enrolled (push) Failing after 7s
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
QRun-IO/ci-policy: ci / repository-policy (push) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (push) Skipped
QRun-IO/ci-policy: ci / ci-result (push) Failing after 5s
QRun-IO/ci-policy: native / native-result (push) Successful in 6s
Checkpoint implementation at user-requested stop; document known failures and incomplete release qualification.

Co-Authored-By: Claude <noreply@anthropic.com>

Co-Authored-By: GPT-6 Codex <noreply@openai.com>
2026-11-04 10:45:09 -06:00