Skip to content

feat(tool-scraper): record whether a tap cuts its thread or forms it - #94

Merged
JustinSGray merged 2 commits into
mainfrom
jsg-tap-thread-method
Sep 8, 2026
Merged

feat(tool-scraper): record whether a tap cuts its thread or forms it#94
JustinSGray merged 2 commits into
mainfrom
jsg-tap-thread-method

Conversation

@JustinSGray

Copy link
Copy Markdown
Contributor

Summary

  • Tool takes an optional threadMethod, 'cutting' | 'forming', beside form.
    TOOL_FORMS is unchanged — it is Fusion's vocabulary and Fusion has no form-tap type.
  • ToolRecord.threadMethod carries the same value on a tap and null on every other
    kind. toolRecord throws on a tap without one and on a non-tap with one.
  • Every tap family states it as a cited vendor-stated fact: Kennametal's three from
    its newTapType facet, EMUGE's two from the FG01/FG02 category split.
  • New family emuge_form_taps.csv — EMUGE category FG02, 1,432 cold-forming taps,
    previously unreachable. Same column labels and unit as emuge_taps.csv.
  • PRODUCT_LINE_COLUMNS gains FG02; PRODUCT_LINES deliberately gets no FG02
    table, so a geometry code passes through as the vendor's own.
  • MariTool's tap leaves and the rule that classifies them are recorded in
    families/maritool.ts and docs/MARITOOL_CATALOG.md. Nothing scrapes them.

Public package release

  • This PR changes no public package source.
  • I ran pnpm changeset and committed the generated Changeset.
  • This source change intentionally needs no release; I applied the
    no-release-needed label and explained why below.

@toolpath/tool-support minor, @toolpath/tool-scraper minor.

ToolRecord gains a required property, which breaks a hand-written record literal.
toolRecord keeps it optional on input and is the only documented way to build one,
so this is minor — flagging it in case that surface is judged real.

Validation

  • I ran the relevant checks and tests.

pnpm check with Docker running: openapi:verify, generate:check, lint, knip,
build, check-types all pass.

pnpm --filter @toolpath/tool-scraper test: 1036 passed, 177 skipped, 2 failed.
Both failures are maritool-corpus.test.ts (ER25M against /^ER\d+$/, BT30 and
CAT40), which fail identically on a clean tree at 992cf56 and are untouched here.

tool-support 189, tool-drawing 155, viewer 252, ui 183, app-support 21 —
all pass.

Both EMUGE tap families were scraped and the corpus tests run against them:

FamilyCategoryRowsDeclared
emuge_taps.csvFG0111,56611,566
emuge_form_taps.csvFG021,4321,432

Every FG01 part states a chamfer form and no lead taper form; every FG02 part
the reverse. All 12,998 rows map to records.

A thread former and a cut tap of the same size are the same record: identical
DC, TP, SFDM, OAL and LCF, often the same substrate and coating. Nothing
downstream could tell them apart, and the two need different hole sizes.
`Tool` carries an optional `threadMethod`, `'cutting' | 'forming'`, beside
`form` rather than as two more `TOOL_FORMS` values — that vocabulary is
Fusion's, and Fusion has no form-tap type. `ToolRecord.threadMethod` holds the
same value on a tap and `null` on every other kind; `toolRecord` refuses a tap
without one and a non-tap with one.
Neither vendor publishes it in a variant table, so it is a per-family fact.
Kennametal's three tap families cite its `newTapType` facet, which narrows the
same variants endpoint the scrape already calls and answers `3-Forming Tap` for
none of them. EMUGE's cite the category split, and the parts state it a second
way: every FG01 group carries a `chamfer form` and every FG02 group a `lead
taper form`, mutually exclusive across all 551 groups.
`emuge_form_taps.csv` scrapes FG02, the vendor's 1,432 cold-forming taps, which
went unreached until now — so `forming` is a value the catalog holds rather than
one only the type admits. It reads FG01's column labels unchanged, including
`length of cutting edge l₂`, which EMUGE keeps on a tool that has no cutting
edge. `PRODUCT_LINES` gets no FG02 table: the two categories share their
geometry codes and mean different products by them, so a code passes through as
the vendor's own.
`tests/tap-method.test.ts` walks the family tables and holds every tap family to
a cited, in-vocabulary, vendor-stated method, and to both methods being live.
`tests/emuge-corpus.test.ts` holds the two EMUGE facts to the chamfer/lead-taper
split over a real scrape, which is the only thing that can contradict a fact
that no column carries.
MariTool's tap leaves and the form/forming rule that classifies them are
recorded in `families/maritool.ts` and `docs/MARITOOL_CATALOG.md`, with the
mixed-unit problem a tap family there has to solve first. Nothing scrapes them.
@JustinSGray
JustinSGray merged commit 88c7ec2 into mainSep 8, 2026
2 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@JustinSGray