Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions .github/workflows/laser-ratchet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Year-1 circular laser vs chainsaw feed.
#
# JTS SoT path is doc/laser-ratchet.json (this repo uses doc/, not docs/).
# Proofs observatory vendors grootstebozewolf/NetTopologySuite.Proofs
# docs/laser-ratchet.json (Pages rebuilds on that path). This workflow is
# the JTS side of that feed. Stdout-only timings are the discarded-timing bug.
#
# Version history is git log -- doc/laser-ratchet.json. On push to
# feature/sfa-curve-rgr the job commits a retip when the JSON changed.
# That bot commit uses a skip-ci token so GitHub does not loop (the JSON
# path is also a trigger). Do not put that token in human commit bodies
# or this workflow will not run.
#
# HOLD — do not add these as reasons to expand work:
# ClothoidHalley / Year-2 zoo, N-SS hierarchy, SHARED_SNAPPED_RAY walk,
# 64-a Proofs sweep, OverlayNGCurve rename, non-linear SegmentString.
#
# Optional Proofs Pages ping: repository_dispatch type laser-ratchet.
# GITHUB_TOKEN cannot cross-repo. Set secret PROOFS_DISPATCH_TOKEN (PAT)
# only if you want automatic vendor. Unset = skip; never fail the jts job.

name: Laser ratchet

on:
workflow_dispatch:
push:
branches:
- feature/sfa-curve-rgr
paths:
- 'modules/curve/**/*PerfGate*'
- 'modules/curve/**/exactcurve/**'
- 'modules/curve/**/overlayng/curve/**'
- 'modules/app/**/DistanceConstructionPerfGate*'
- 'modules/curve/**/ExactArcOptionAMillionTrialTest*'
- 'modules/curve/**/PredicateOptionBMillionTrialTest*'
- 'modules/core/**/LaserRatchetSink.java'
- 'doc/LASER_RATCHET.md'
- 'doc/CHAINSAW_LASER_PROGRAM.md'
- 'doc/laser-ratchet.json'
- 'doc/EXACT_CURVE_BIBLE.md'
- 'dev/run-year1-laser-ratchet.sh'
- 'dev/assemble-laser-ratchet.sh'
- '.github/workflows/laser-ratchet.yml'
pull_request:
paths:
- 'modules/curve/**/*PerfGate*'
- 'modules/curve/**/exactcurve/**'
- 'modules/curve/**/overlayng/curve/**'
- 'modules/app/**/DistanceConstructionPerfGate*'
- 'modules/curve/**/ExactArcOptionAMillionTrialTest*'
- 'modules/curve/**/PredicateOptionBMillionTrialTest*'
- 'modules/core/**/LaserRatchetSink.java'
- 'doc/LASER_RATCHET.md'
- 'doc/CHAINSAW_LASER_PROGRAM.md'
- 'doc/laser-ratchet.json'
- 'doc/EXACT_CURVE_BIBLE.md'
- 'dev/run-year1-laser-ratchet.sh'
- 'dev/assemble-laser-ratchet.sh'
- '.github/workflows/laser-ratchet.yml'

# contents: write = same-branch retip push. actions: write = upload-artifact.
# Setting permissions replaces the default token scopes; both are required.
permissions:
contents: write
actions: write

jobs:
year1-circular:
runs-on: ubuntu-latest
steps:
# Branch ref (not detached SHA) so the retip step can commit + push.
- uses: actions/checkout@v2
with:
ref: ${{ github.head_ref || github.ref_name }}
persist-credentials: true

- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8

- uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-

- name: Run Year-1 circular PerfGates and write doc/laser-ratchet.json
env:
LASER_RATCHET_TIP: ${{ github.sha }}
LASER_RATCHET_BRANCH: feature/sfa-curve-rgr
LASER_RATCHET_PR: ${{ github.event.pull_request.number }}
run: bash dev/run-year1-laser-ratchet.sh

- name: Upload laser-ratchet JSON
if: always()
uses: actions/upload-artifact@v4
with:
name: laser-ratchet-json
path: |
doc/laser-ratchet.json
target/laser-ratchet/rows.jsonl
if-no-files-found: warn

- name: Remove JTS artifacts from cache
if: always()
run: |
find . -name '*.tar.gz' -exec rm {} \;
rm -rf $HOME/.m2/repository/org/locationtech/jts

# Same-branch retip only. Not on pull_request, not on forks.
- name: Commit doc/laser-ratchet.json
if: >-
github.repository == 'grootstebozewolf/jts'
&& github.ref == 'refs/heads/feature/sfa-curve-rgr'
&& (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -B feature/sfa-curve-rgr
git add -- doc/laser-ratchet.json
if git diff --cached --quiet; then
echo "no doc/laser-ratchet.json diff"
exit 0
fi
git commit -m "chore(laser): retip doc/laser-ratchet.json [skip ci]"
git push origin HEAD:refs/heads/feature/sfa-curve-rgr

# GITHUB_TOKEN cannot dispatch into NetTopologySuite.Proofs.
- name: Optional Proofs repository_dispatch
if: >-
github.repository == 'grootstebozewolf/jts'
&& github.ref == 'refs/heads/feature/sfa-curve-rgr'
&& (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
continue-on-error: true
env:
PROOFS_DISPATCH_TOKEN: ${{ secrets.PROOFS_DISPATCH_TOKEN }}
run: |
if [ -z "${PROOFS_DISPATCH_TOKEN:-}" ]; then
echo "PROOFS_DISPATCH_TOKEN unset; GITHUB_TOKEN cannot cross-repo — skip"
exit 0
fi
curl -fsS -X POST \
-H "Authorization: token ${PROOFS_DISPATCH_TOKEN}" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/grootstebozewolf/NetTopologySuite.Proofs/dispatches \
-d "{\"event_type\":\"laser-ratchet\",\"client_payload\":{\"source_repo\":\"grootstebozewolf/jts\",\"tip\":\"${GITHUB_SHA}\"}}"
27 changes: 27 additions & 0 deletions dev/assemble-laser-ratchet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Assemble doc/laser-ratchet.json from PerfGate JSONL.
# Gates emit target/laser-ratchet/rows.jsonl (stdout-only is the bug).
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
OUT="${1:-$ROOT/doc/laser-ratchet.json}"
TIP="${LASER_RATCHET_TIP:-$(git rev-parse HEAD)}"
DIR="${LASER_RATCHET_DIR:-$ROOT/target/laser-ratchet}"
ROWS="$DIR/rows.jsonl"
if [[ ! -f "$ROWS" ]]; then
echo "missing $ROWS — run Year-1 PerfGate tests first" >&2
exit 1
fi
CP="$ROOT/modules/core/target/test-classes"
if [[ ! -d "$CP" ]]; then
echo "compile jts-core tests first (mvn -pl modules/core test-compile)" >&2
exit 1
fi
IMPORTED="${LASER_RATCHET_IMPORTED:-$(date -u +%Y-%m-%d)}"
BRANCH="${LASER_RATCHET_BRANCH:-feature/sfa-curve-rgr}"
PR="${LASER_RATCHET_PR:-}"
exec java -Dlaser.ratchet.tip="$TIP" -Dlaser.ratchet.dir="$DIR" \
-Dlaser.ratchet.imported="$IMPORTED" \
-Dlaser.ratchet.branch="$BRANCH" \
-Dlaser.ratchet.pr="$PR" \
-cp "$CP" test.jts.perf.LaserRatchetSink assemble "$OUT" "$ROWS"
39 changes: 39 additions & 0 deletions dev/run-year1-laser-ratchet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Year-1 circular PerfGates → doc/laser-ratchet.json (Proofs-schema feed).
# ClothoidHalley / Year-2 zoo / N-SS / SHARED_SNAPPED_RAY walk are HOLD — not run.
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
export LASER_RATCHET_DIR="${LASER_RATCHET_DIR:-$ROOT/target/laser-ratchet}"
export LASER_RATCHET_TIP="${LASER_RATCHET_TIP:-$(git rev-parse HEAD)}"
mkdir -p "$LASER_RATCHET_DIR"
rm -f "$LASER_RATCHET_DIR/rows.jsonl"

# Class names only (surefire 2.15 cannot mix Class#method with a list).
# Do not add ClothoidHalleyPerfGateTest.
GATES="LargestEmptyCirclePerfGateTest\
,DirectedHausdorffDistancePerfGateTest\
,DiscreteFrechetDistancePerfGateTest\
,DiscreteHausdorffDistancePerfGateTest\
,CurveOpsDistConPerfGateTest\
,MultiCurvePerfGateTest\
,ReverseDispatchPerfGateTest\
,CurveWKBPerfGateTest\
,OverlayNGCurvePerfGateTest\
,DistanceConstructionPerfGateTest\
,ExactArcOptionAMillionTrialTest\
,PredicateOptionBMillionTrialTest"

# -am walks build-tools / io / etc. Surefire 3.x on those modules fails
# unless failIfNoSpecifiedTests is off (failIfNoTests is the 2.x name).
mvn -pl modules/core,modules/curve,modules/app -am test \
-Dtest="$GATES" \
-DfailIfNoTests=false \
-Dsurefire.failIfNoSpecifiedTests=false \
-Dcheckstyle.skip=true \
-Dpmd.skip=true \
-Dlaser.ratchet.dir="$LASER_RATCHET_DIR" \
-Dlaser.ratchet.tip="$LASER_RATCHET_TIP"

exec bash "$ROOT/dev/assemble-laser-ratchet.sh" \
"${1:-$ROOT/doc/laser-ratchet.json}"
18 changes: 15 additions & 3 deletions doc/CHAINSAW_LASER_PROGRAM.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Chainsaw → Laser · arc-native program

Tip pin: `feature/sfa-curve-rgr` with ExactCurve* Year-1 lock (#63) and optional OrientableSegment adapter.
Canonical architecture: [`EXACT_CURVE_BIBLE.md`](EXACT_CURVE_BIBLE.md).
Tip pin: `feature/sfa-curve-rgr` @ `316258a8` (PR #128) · Year-1 circular re-verify measured on `29b5d169`.
Canonical architecture: [`EXACT_CURVE_BIBLE.md`](EXACT_CURVE_BIBLE.md).
Day-zero feed: [`LASER_RATCHET.md`](LASER_RATCHET.md) / [`laser-ratchet.json`](laser-ratchet.json).

**Year-1 lock:** `ExactCircularArc` is the privileged pure primitive (`exactcurve` + thin `ExactCurve`).
`OrientableSegment` is a demoted, optional adapter (Bible §3).

Prior sequence stop: M.5→ML.2→HP.4→N-SS expand @ `c956b50d`.
Prior sequence stop: M.5→ML.2→HP.4→N-SS expand @ `c956b50d` — **still STOPPED**.

Contract: parity or named densify-shim · `t_laser ≤ 1.15 × t_chainsaw` · no silent ConcaveHull · OverlayNGCurve never *Curved* · core `SegmentString` stays linear.

Expand All @@ -23,6 +24,17 @@ Contract: parity or named densify-shim · `t_laser ≤ 1.15 × t_chainsaw` · no
- Full **D-HF TAG** green (`fail()` kept)
- **M.4** / **R.3** / **ML.3** / **HP.5**
- 74-file N-SS lie · curvature-order on `SHARED_SNAPPED_RAY`
- Year-2 zoo + `ClothoidHalleyPerfGateTest`: library work, not a JTS PR #7 leftover
- Extra 1M §7 near-degenerate cells
- 64-a Proofs campaign

## Year-1 circular re-verify (this pin)

Gates emit JSONL (`target/laser-ratchet/rows.jsonl`); `dev/run-year1-laser-ratchet.sh` / `dev/assemble-laser-ratchet.sh` write the Proofs-schema feed.
CI: `.github/workflows/laser-ratchet.yml` (not `build-and-test.yml`). Version history is `git log -- doc/laser-ratchet.json`. Stdout-only is the discarded-timing bug.

Cell scoreboard this run: **green 119 · chainsaw-only 13 · HOLD named**.
Previously ungauged observatory harnesses (WKB, DHD, Discrete Hausdorff/Fréchet, LEC, MultiCurve) now have `now_*`. ReverseDispatch has no red column.

## Pointers

Expand Down
14 changes: 10 additions & 4 deletions doc/EXACT_CURVE_BIBLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,19 @@ This document supersedes all previous Proofs option discussions, temporary STOP
implementations are package-private and compose `ExactCircularArc`.
See `doc/ORIENTABLE_SEGMENT_ADAPTER.md`.

Day-zero performance feed: [`LASER_RATCHET.md`](LASER_RATCHET.md) /
[`laser-ratchet.json`](laser-ratchet.json). Year-1 PerfGates write
`target/laser-ratchet/rows.jsonl` via `LaserRatchetSink` (not stdout-only).
CI: `.github/workflows/laser-ratchet.yml`. Proofs vendors that JSON.
Year-2 zoo types stay unimplemented — library work, not JTS PR #7.

### Audit (`feature/sfa-curve-rgr` @ `d8c4c9b8`)

Tree matches §3–§4.2 and the bullets above: `ExactCircularArc` + thin
`ExactCurve` in `org.locationtech.jts.algorithm.exactcurve`; no extra
protocol methods; `OrientableSegment` composes `ExactCircularArc`; no
Year-2 `Exact*` zoo types; `exactarc.AngleBetween` remains a deprecated
alias.
Year-2 `Exact*` zoo types (library work, not JTS PR #7);
`exactarc.AngleBetween` remains a deprecated alias.

Already locked on this branch:

Expand All @@ -193,8 +199,8 @@ Already locked on this branch:

### HOLD (do not implement from this lock)

- Year-2 zoo: `ExactEllipticalArc`, `ExactCubicBezier`, `ExactClothoid`,
`ExactNurbsSegment`
- Year-2 zoo (`ExactEllipticalArc`, `ExactCubicBezier`, `ExactClothoid`,
`ExactNurbsSegment`): library work, not a JTS PR #7 leftover
- N-SS hierarchy, HotPixel-driven N-SS, Proofs 64-a sweep
- `SHARED_SNAPPED_RAY` walk
- Making `SegmentString` non-linear (or remaking the existing Option B
Expand Down
57 changes: 47 additions & 10 deletions doc/LASER_RATCHET.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,63 @@
# Laser ratchet

Tip `c956b50d` · PR #7 session · `feature/sfa-curve-rgr` lineage
Prior: `1cd9f498` (Sync→M.3→R.2→ML.4 stop)
Tip measured `29b5d169` on `feature/sfa-curve-rgr` (base `316258a8` = merge of PR #128).
Feed: [`laser-ratchet.json`](laser-ratchet.json) — Proofs vendors this file for day-zero reading.
Gates emit `target/laser-ratchet/rows.jsonl`; assemble with `dev/assemble-laser-ratchet.sh`.
CI: [`.github/workflows/laser-ratchet.yml`](../.github/workflows/laser-ratchet.yml) runs Year-1 circular gates and writes this file.
Version history: `git log -- doc/laser-ratchet.json`. On push to `feature/sfa-curve-rgr` a bot retip commit lands when numbers change (skip-ci token on that commit only, so the JSON path does not loop).
Prior pin: `c956b50d` (user-board 16 / 3 / 11 hold — kit grain, stale vs cell feed).

**Contract:** `t_laser ≤ 1.15 × t_chainsaw` · OverlayNGCurve never *Curved* · Draft v6 MMF Option B
**Contract:** `t_laser ≤ 1.15 × t_chainsaw` · OverlayNGCurve never *Curved* · Year-1 circular only

## Scoreboard (user board pin)
## Scoreboard (Year-1 circular cells, this run)

OpenJDK 8 · nanoTime p50 of 31 after 15 warmups · one machine.
Do not hand-edit numbers; they come from the JSONL.

| metric | count |
|--------|------:|
| green | 16 |
| chainsaw-only | 3 |
| measured | 11 (11 hold) |
| green (laser ≤ 1.15×) | 119 |
| chainsaw-only (named chord-path) | 13 |
| measured operation rows | 130 |
| primitive gates | 2 (P1-A 0.122×, P1-B 0.309×) |
| HOLD (not run / not Year-1) | see below |

119 = 117 operation lasers + 2 primitive. Max non-chord operation ratio this run: **0.674** (LEC CompoundCurve vs toLinear). Zero Year-1 circular lasers missed 1.15×.

**Previously ungauged on the Proofs observatory — now have numbers:**

| harness | cells |
|---------|-------|
| CurveWKBPerfGateTest | disc WKB 0.019× · plain LineString chord-path |
| DirectedHausdorffDistancePerfGateTest | 4 lasers, all ≤ 0.021× |
| DiscreteHausdorffDistancePerfGateTest | two discs 0.0003× · arc-segment 0.028× · plain chord-path |
| DiscreteFrechetDistancePerfGateTest | discs / arc / M.5 rings ≤ 0.56× · 2 chord-path |
| LargestEmptyCirclePerfGateTest | 5 lasers ≤ 0.674× · 3 chord-path |
| MultiCurvePerfGateTest | length vs linearise **0.0039×** (was missing from Proofs JSON) |

ReverseDispatch: 15 cells, `now_*` only — no red column invented.

Sequence M.5 → ML.2 → HP.4 → N-SS expand remains **STOPPED**. Not resumed.

## HOLD (refused)

**Sequence M.5 → ML.2 → HP.4 → N-SS expand → stop** landed @ `c956b50d`.
- Year-2 zoo is library work, not a JTS PR #7 leftover: ExactEllipticalArc, ExactCubicBezier, ExactClothoid, ExactNurbsSegment
- ClothoidHalleyPerfGateTest: library / not PR #7; not a circular Exact* laser on this fork
- Full D-HF TAG green (`fail()` kept)
- M.4 / R.3 / ML.3 / HP.5
- 74-file N-SS · `SHARED_SNAPPED_RAY` walk (stamp may exist; not walked)
- Extra 1M §7 near-degenerate cells
- 64-a Proofs sweep / 64-file campaign
- Growing ExactCurve · non-linear core SegmentString · OverlayNGCurve rename · reminting ADR-0004

## Related

- Program: [CHAINSAW_LASER_PROGRAM.md](CHAINSAW_LASER_PROGRAM.md)
- Seams: [OVERLAYNGCURVE_P2_SEAMS.md](OVERLAYNGCURVE_P2_SEAMS.md)
- Metric: [METRIC_KIT_MX.md](METRIC_KIT_MX.md)
- Bible: [EXACT_CURVE_BIBLE.md](EXACT_CURVE_BIBLE.md)

## Re-verify @ `c956b50d`
## Re-verify @ `29b5d169` (impl = post-#128 `316258a8`)

M.5 concentric Frechet · ML.2 half-disc MIC · HP.4 SHARED_SNAPPED_RAY stamp · N-SS Option-B two-shell crossing expand. Holds: M.4 · R.3 · ML.3 catalog · HP.5 · 74-file N-SS · full D-HF TAG.
`OverlayNGCurvePerfGateTest` 80/80 · other Year-1 `*PerfGateTest` + P1-A/P1-B **BUILD SUCCESS**.
`check-no-curved` OK. Feed written from the same JVM run (not stdout transcription).
Loading
Loading