pubid 2.0.21 → 2.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.adoc +73 -31
- data/data/iec/legacy-notation.md +298 -0
- data/data/iso/historic-schemes.md +368 -0
- data/data/parg/doi_pfs.json +1 -0
- data/data/parg/iec.json +1 -1
- data/data/parg/iso.json +1 -1
- data/data/parg/iso.parg +142 -2
- data/data/parg/nist.json +1 -1
- data/data/parg/tables/iec_typed_stages.yaml +3 -0
- data/data/parg/tables/typed_stages_ballots.yaml +6 -0
- data/data/parg/tables/typed_stages_supplements.yaml +1 -0
- data/lib/pubid/doi_pfs/CLAUDE.md +72 -0
- data/lib/pubid/doi_pfs/builder.rb +18 -0
- data/lib/pubid/doi_pfs/identifier.rb +36 -0
- data/lib/pubid/doi_pfs/identifiers/resource.rb +31 -0
- data/lib/pubid/doi_pfs/identifiers.rb +7 -0
- data/lib/pubid/doi_pfs/parser.rb +10 -0
- data/lib/pubid/doi_pfs/pubid_urn_schema.rb +15 -0
- data/lib/pubid/doi_pfs/renderer.rb +10 -0
- data/lib/pubid/doi_pfs/urn_generator.rb +12 -0
- data/lib/pubid/doi_pfs.rb +68 -0
- data/lib/pubid/iec/CLAUDE.md +5 -1
- data/lib/pubid/iec/builder.rb +47 -0
- data/lib/pubid/iec/identifiers/amendment.rb +34 -0
- data/lib/pubid/iec/identifiers/corrigendum.rb +6 -1
- data/lib/pubid/iec/supplement_identifier.rb +55 -25
- data/lib/pubid/iho/CLAUDE.md +2 -1
- data/lib/pubid/iho/pubid_urn_schema.rb +2 -1
- data/lib/pubid/iso/CLAUDE.md +49 -0
- data/lib/pubid/iso/builder.rb +77 -0
- data/lib/pubid/iso/identifiers/amendment.rb +1 -1
- data/lib/pubid/iso/single_identifier.rb +7 -1
- data/lib/pubid/nist/CLAUDE.md +84 -10
- data/lib/pubid/nist/builder.rb +15 -0
- data/lib/pubid/nist/identifiers/base.rb +52 -1
- data/lib/pubid/nist/identifiers/federal_information_processing_standards.rb +44 -5
- data/lib/pubid/nist/identifiers/special_publication.rb +15 -0
- data/lib/pubid/nist/preprocessor.rb +14 -12
- data/lib/pubid/nist/router.rb +11 -0
- data/lib/pubid/nist/urn_parser.rb +1 -1
- data/lib/pubid/version.rb +1 -1
- data/lib/pubid.rb +4 -0
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41a0360b8ea34997a26ebf234cce2a8f0b913dd31f4a945225a38819945c80c5
|
|
4
|
+
data.tar.gz: fa8af772bf90a86b5998c3cda2a2781e35ed0d985c1d3bcd77f3681ed9709242
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cf7d608f5fac874a6c650abb0f73ff2f59bfcfd834972eecdd05f84cf69f822c8b5856705b3608cd4c307b4f9cbf3767b88a4ca8c9b0ad2c35d8abce70e9ea55
|
|
7
|
+
data.tar.gz: 1e044ccf572203720c893e16a269051da6721d72874dd3d57658458b9eee002621a4364c0bc55d951eb55e4195b411dcaf7275b022ca9b2f87abbb2de0f6e731
|
data/README.adoc
CHANGED
|
@@ -7,10 +7,13 @@ image:https://img.shields.io/github/commits-since/metanorma/pubid/latest.svg["Co
|
|
|
7
7
|
|
|
8
8
|
== Quick Start
|
|
9
9
|
|
|
10
|
-
[source,
|
|
10
|
+
[source,shell]
|
|
11
11
|
----
|
|
12
12
|
gem install pubid
|
|
13
|
+
----
|
|
13
14
|
|
|
15
|
+
[source,ruby]
|
|
16
|
+
----
|
|
14
17
|
require 'pubid/iso'
|
|
15
18
|
|
|
16
19
|
# Parse an identifier
|
|
@@ -18,13 +21,13 @@ id = Pubid::Iso.parse("ISO 9001:2015/Amd 1:2020")
|
|
|
18
21
|
|
|
19
22
|
# Access components
|
|
20
23
|
id.publisher.body # => "ISO"
|
|
21
|
-
id.
|
|
24
|
+
id.root.number # => "9001"
|
|
22
25
|
|
|
23
26
|
# Render back to string (round-trip)
|
|
24
27
|
id.to_s # => "ISO 9001:2015/Amd 1:2020"
|
|
25
28
|
|
|
26
29
|
# Generate URN
|
|
27
|
-
id.to_urn # => "urn:iso:std:iso:9001:amd:2020:v1"
|
|
30
|
+
id.to_urn # => "urn:iso:std:iso:9001:amd:1:2020:v1"
|
|
28
31
|
----
|
|
29
32
|
|
|
30
33
|
== Overview
|
|
@@ -78,12 +81,15 @@ README.
|
|
|
78
81
|
|link:docs/flavor-guides/iec.md[IEC: TRF format grammars]
|
|
79
82
|
|IECEE and IECEx Test Report Form patterns — the `&` part join, the
|
|
80
83
|
`F_II`-style sub-versions, the `_EMC`/`_PS`/`_SOF` test-type suffixes, and the
|
|
81
|
-
IECEx `_`/`v` separator
|
|
84
|
+
IECEx `_`/`v` separator — plus the general IEC forms (supplement faces,
|
|
85
|
+
CSV/CMV/RLV wrappers, standalone supplements). Ported from the archived
|
|
86
|
+
pubid-iec README.
|
|
82
87
|
|
|
83
88
|
|link:docs/flavor-guides/plateau.md[PLATEAU: the Handbook #11 edition split]
|
|
84
89
|
|Why an edition-1–3 "Handbook #11" reference with a part suffix parses as
|
|
85
|
-
Handbook #06 / #04 (the rule encoded in `data/plateau/update_codes.yaml`)
|
|
86
|
-
|
|
90
|
+
Handbook #06 / #04 (the rule encoded in `data/plateau/update_codes.yaml`),
|
|
91
|
+
and the Handbook volume label (本編 / 本編+付録). Ported from the
|
|
92
|
+
archived pubid-plateau README.
|
|
87
93
|
|
|
88
94
|
|link:docs/RENDERING_GUIDE.md[Advanced Rendering Styles Guide]
|
|
89
95
|
|ISO short/long supplement abbreviation preservation and IEC `AMD1` vs
|
|
@@ -192,23 +198,22 @@ PubID V2 implements RFC 5141-bis compliant URN generation for ISO and IEC identi
|
|
|
192
198
|
|
|
193
199
|
[source,ruby]
|
|
194
200
|
----
|
|
195
|
-
require 'pubid
|
|
196
|
-
require 'pubid/iec'
|
|
201
|
+
require 'pubid'
|
|
197
202
|
|
|
198
203
|
# ISO: Parse and generate URN
|
|
199
204
|
id = Pubid::Iso.parse("ISO/IEC 13818-1:2015/Amd 3:2016")
|
|
200
205
|
id.to_urn
|
|
201
|
-
# => "urn:iso:std:iso-iec:13818:-1:amd:2016:
|
|
206
|
+
# => "urn:iso:std:iso-iec:13818:-1:amd:3:2016:v1"
|
|
202
207
|
|
|
203
208
|
# IEC: Parse and generate URN
|
|
204
209
|
id = Pubid::Iec.parse("IEC 60068-2-2:1974/Amd 1:1993")
|
|
205
210
|
id.to_urn
|
|
206
|
-
# => "urn:iec:std:iec:60068-2-2:1974
|
|
211
|
+
# => "urn:iec:std:iec:60068-2-2:1974:::::amd:1:1993"
|
|
207
212
|
|
|
208
213
|
# Round-trip: parse URN back to identifier
|
|
209
|
-
id = Pubid::Iso.parse_urn("urn:iso:std:iso:9001:amd:2020:v1")
|
|
210
|
-
id.to_s # => "ISO 9001/
|
|
211
|
-
id.to_urn # => "urn:iso:std:iso:9001:amd:2020:v1"
|
|
214
|
+
id = Pubid::Iso.parse_urn("urn:iso:std:iso:9001:amd:1:2020:v1")
|
|
215
|
+
id.to_s # => "ISO 9001/AMD 1:2020"
|
|
216
|
+
id.to_urn # => "urn:iso:std:iso:9001:amd:1:2020:v1"
|
|
212
217
|
----
|
|
213
218
|
|
|
214
219
|
=== Features
|
|
@@ -228,9 +233,9 @@ id.to_urn # => "urn:iso:std:iso:9001:amd:2020:v1"
|
|
|
228
233
|
`#to_urn` follows the registered grammar of the organization, which can
|
|
229
234
|
drop values (RFC 5141 has no year). `#to_pubid_urn` is pubid's own URN: it
|
|
230
235
|
carries every value, always round-trips through `Pubid.parse_urn`, and is
|
|
231
|
-
safe to use as an HTTP path.
|
|
232
|
-
|
|
233
|
-
|
|
236
|
+
safe to use as an HTTP path. Every flavor supports it (the per-flavor
|
|
237
|
+
schemas live in `lib/pubid/<flavor>/pubid_urn_schema.rb`;
|
|
238
|
+
link:docs/URN-SCHEMES.adoc[URN schemes] documents each).
|
|
234
239
|
|
|
235
240
|
[source,ruby]
|
|
236
241
|
----
|
|
@@ -410,6 +415,9 @@ Pubid::Ecma.parse("ECMA-418") === Pubid::Ecma.parse("ECMA-418-1")
|
|
|
410
415
|
# => false (ECMA-418 has no part)
|
|
411
416
|
Pubid::Ecma.parse("ECMA-418-1") === Pubid::Ecma.parse("ECMA-418-1 ed1")
|
|
412
417
|
# => true
|
|
418
|
+
Pubid::Ecma.parse("ECMA-262 Edition 5.1") === Pubid::Ecma.parse("ECMA-262 ed5.1")
|
|
419
|
+
# => true (the human edition faces — "Edition 5.1", "ed 5.1", a bare
|
|
420
|
+
# trailing edition — parse in as aliases of the canonical " ed<N>" face)
|
|
413
421
|
----
|
|
414
422
|
|
|
415
423
|
A reference asks for every part of a document with `all_parts`:
|
|
@@ -480,15 +488,18 @@ backend, without parsing.
|
|
|
480
488
|
----
|
|
481
489
|
require 'pubid'
|
|
482
490
|
|
|
491
|
+
Pubid.eager_load_flavors! # flavor modules register lazily; load them all
|
|
492
|
+
|
|
483
493
|
Pubid::Iso.prefixes
|
|
484
|
-
# => ["ISO", "ISO/IEC", "IEC/ISO", "ISO/IEC/IEEE"]
|
|
494
|
+
# => ["ISO", "ISO/IEC", "IEC/ISO", "ISO/IEC/IEEE", "ISO/IEEE"]
|
|
485
495
|
|
|
486
496
|
Pubid::Bsi.prefixes
|
|
487
|
-
# => ["BS", "BSI", "DD", "PD", "PAS", "NA", "TS", "HB",
|
|
497
|
+
# => ["BS", "BSI", "DD", "PD", "PAS", "NA", "TS", "HB", "PP", "BIP", "EP",
|
|
498
|
+
# "BS EN", "BS ISO", "BS IEC", "BS EN ISO", "BS EN IEC"]
|
|
488
499
|
|
|
489
500
|
# Look up a single flavor by name
|
|
490
501
|
Pubid.prefixes(:iec)
|
|
491
|
-
# => ["IEC", "CISPR", "IECEE", "IECEx", "IECQ", "ISO/IEC", "IEC/ISO", "ISO/IEC/IEEE"]
|
|
502
|
+
# => ["IEC", "CISPR", "IECEE", "IECEx", "IECQ", "ISO/IEC", "IEC/ISO", "ISO/IEC/IEEE", "IEC/IEEE"]
|
|
492
503
|
|
|
493
504
|
# Reverse index: prefix token => owning flavor(s)
|
|
494
505
|
Pubid.prefix_flavors["ISO/IEC"] # => [:iec, :iso]
|
|
@@ -1012,7 +1023,7 @@ require 'pubid'
|
|
|
1012
1023
|
id = Pubid::Nist.parse("NIST SP 800-53r5")
|
|
1013
1024
|
|
|
1014
1025
|
# Access components
|
|
1015
|
-
id.series
|
|
1026
|
+
id.series.to_s # => "SP"
|
|
1016
1027
|
id.number # => "800-53"
|
|
1017
1028
|
id.revision # => "r5"
|
|
1018
1029
|
|
|
@@ -1021,7 +1032,7 @@ id.to_s # => "NIST SP 800-53r5"
|
|
|
1021
1032
|
|
|
1022
1033
|
# Parse historical NBS patterns
|
|
1023
1034
|
id = Pubid::Nist.parse("NBS LCIRC 1019r1963")
|
|
1024
|
-
id.to_s # => "NBS
|
|
1035
|
+
id.to_s # => "NBS LC 1019r1963"
|
|
1025
1036
|
|
|
1026
1037
|
# CSM volume-number format
|
|
1027
1038
|
id = Pubid::Nist.parse("NBS CSM v6n1")
|
|
@@ -1029,7 +1040,22 @@ id.to_s # => "NBS CSM v6n1"
|
|
|
1029
1040
|
|
|
1030
1041
|
# Supplement with revision
|
|
1031
1042
|
id = Pubid::Nist.parse("NBS CIRC 154supprev")
|
|
1032
|
-
id.to_s # => "NBS CIRC
|
|
1043
|
+
id.to_s # => "NBS CIRC 154sup"
|
|
1044
|
+
|
|
1045
|
+
# FIPS PUB printed form: the official FIPS face is "FIPS PUB <number>"
|
|
1046
|
+
# ("PUB" is part of the Federal Information Processing Standards
|
|
1047
|
+
# PUBlication designation); every printed spelling parses to the same
|
|
1048
|
+
# identity (same hash, URN and MR string as the canonical parse)
|
|
1049
|
+
id = Pubid::Nist.parse("FIPS PUB 205")
|
|
1050
|
+
id.to_s # => "FIPS PUB 205"
|
|
1051
|
+
id = Pubid::Nist.parse("NIST FIPS PUB 205")
|
|
1052
|
+
id.to_s # => "FIPS PUB 205"
|
|
1053
|
+
|
|
1054
|
+
# Hyphenated numbers and the revision forms ride the alias too
|
|
1055
|
+
id = Pubid::Nist.parse("FIPS PUB 180-4")
|
|
1056
|
+
id.to_s # => "FIPS PUB 180-4"
|
|
1057
|
+
id = Pubid::Nist.parse("FIPS PUB 140-3 rev1")
|
|
1058
|
+
id.to_s # => "FIPS PUB 140-3r1"
|
|
1033
1059
|
----
|
|
1034
1060
|
|
|
1035
1061
|
**Language:**
|
|
@@ -1039,20 +1065,34 @@ id.to_s # => "NBS CIRC 154supprev"
|
|
|
1039
1065
|
|
|
1040
1066
|
==== IEC
|
|
1041
1067
|
|
|
1042
|
-
The IEC parser handles
|
|
1068
|
+
The IEC parser handles the supplement faces, the value-added wrappers, the
|
|
1069
|
+
project-committee working documents, and the standalone supplements:
|
|
1043
1070
|
|
|
1044
1071
|
[source,ruby]
|
|
1045
1072
|
----
|
|
1046
1073
|
require 'pubid'
|
|
1047
1074
|
|
|
1048
|
-
#
|
|
1049
|
-
id = Pubid::Iec.parse("IEC
|
|
1050
|
-
id.
|
|
1051
|
-
|
|
1075
|
+
# Supplements render the compact official face (AMD1 vs the long "Amd 1")
|
|
1076
|
+
id = Pubid::Iec.parse("IEC 60050-351:2013/AMD1:2016")
|
|
1077
|
+
id.to_s # => "IEC 60050-351:2013/AMD1:2016"
|
|
1078
|
+
|
|
1079
|
+
# Value-added editions are VapIdentifier wrappers (+AMD… CSV)
|
|
1080
|
+
id = Pubid::Iec.parse("IEC 60950-1:2005+AMD1:2009+AMD2:2013 CSV")
|
|
1081
|
+
id.class # => Pubid::Iec::Identifiers::VapIdentifier
|
|
1082
|
+
id.to_s # => "IEC 60950-1:2005+AMD1:2009+AMD2:2013 CSV"
|
|
1052
1083
|
|
|
1053
|
-
#
|
|
1054
|
-
id = Pubid::Iec.parse("
|
|
1055
|
-
id.
|
|
1084
|
+
# Working documents
|
|
1085
|
+
id = Pubid::Iec.parse("1/2457/FDIS")
|
|
1086
|
+
id.class # => Pubid::Iec::Identifiers::WorkingDocument
|
|
1087
|
+
id.to_s # => "1/2457/FDIS"
|
|
1088
|
+
|
|
1089
|
+
# A standalone supplement (a supplement face without its base) parses on
|
|
1090
|
+
# its own, is == its from_hash(to_hash) round trip, and its root is the
|
|
1091
|
+
# bare base number
|
|
1092
|
+
id = Pubid::Iec.parse("IEC/FDAM 60038-1")
|
|
1093
|
+
id.to_s # => "IEC FDAM 60038-1"
|
|
1094
|
+
Pubid.from_hash(id.to_hash) == id # => true
|
|
1095
|
+
id.root.to_s # => "IEC60038"
|
|
1056
1096
|
----
|
|
1057
1097
|
|
|
1058
1098
|
===== Pattern 4: Relationship Identifiers ✨
|
|
@@ -2206,12 +2246,14 @@ require 'pubid/nist'
|
|
|
2206
2246
|
id = Pubid::Nist.parse("NIST SP 800-53r5")
|
|
2207
2247
|
|
|
2208
2248
|
# Access components
|
|
2209
|
-
id.series
|
|
2249
|
+
id.series.to_s # => "SP"
|
|
2210
2250
|
id.number # => "800-53"
|
|
2211
2251
|
id.revision # => "r5"
|
|
2212
2252
|
|
|
2213
2253
|
# Render to string
|
|
2214
2254
|
id.to_s # => "NIST SP 800-53r5"
|
|
2255
|
+
----
|
|
2256
|
+
|
|
2215
2257
|
==== OIML
|
|
2216
2258
|
|
|
2217
2259
|
OIML supports 9 identifier types with edition and supplement support:
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# IEC legacy notation — old faces, modern counterparts, and the DAM family
|
|
2
|
+
|
|
3
|
+
**Status: RULED and LANDED (owner ruling 2026-11-12, "Yes, do this now").**
|
|
4
|
+
Sections 1–6 are the research record the ruling was made on; section 7
|
|
5
|
+
records the disposition as implemented. Companion to
|
|
6
|
+
`data/iec/stage-codes.md` (same precedent: provenance, sources, tables,
|
|
7
|
+
reconciliation with the pubid registry).
|
|
8
|
+
|
|
9
|
+
The owner's refined ruling holds that the base-less publisher-slash input
|
|
10
|
+
`IEC/FDAM 60038-1` is not garbage to reject: it is the **old face** of
|
|
11
|
+
`IEC 60038-1/FDAM 1`, the way old ISO printed parts with a slash and years
|
|
12
|
+
with a dash before the modern `-part` / `:year` convention settled. This
|
|
13
|
+
document collects the evidence for that mapping, the exact behaviour of the
|
|
14
|
+
current model, the gaps, and the disposition options.
|
|
15
|
+
|
|
16
|
+
## Sources (all local; the IEC site is WAF-gated and yields no identifier-format examples)
|
|
17
|
+
|
|
18
|
+
| Source | What it evidences | Freshest state used |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `pubid-iec` **1.15.21** installed gem (the v1 reference implementation; parslet grammar `lib/pubid/iec/parser.rb`) | the historical grammar's treatment of every face probed below | probed live 2026-11-12 |
|
|
21
|
+
| `relaton-data-iec` (33k records; local clone, main @ `04a8dc449` "update documents") | the real stored docidentifiers and the serialized shapes the consumer reads | 2026-11-12 |
|
|
22
|
+
| `relaton-data-iso` (local clone) | the modern stored docidentifiers of the joint (ISO/IEC) documents behind the owner-cited forms | 2026-11-12 |
|
|
23
|
+
| pubid `main` @ `be6a43c2` (2.0.21) — `grammars/iec.parg` edition-2 artifact, builder, `SupplementIdentifier#ensure_base` | the current decode of every face probed below | probed live 2026-11-12 |
|
|
24
|
+
| `spec/fixtures/iec/**` (full 12,534 inputs, pass/ and fail/ mined raw) | what the corpus pins | 2026-11-12 |
|
|
25
|
+
| `IEC-ISO Harmonized APIs` v0.0.8 (2023-06) / v0.0.7 (2021-05) PDFs | stage codes only (see `stage-codes.md`); **no identifier-format examples** | 2026-10-22 extract |
|
|
26
|
+
|
|
27
|
+
Historical background (not locally citable — needs the owner's citation if
|
|
28
|
+
this doc ships): IEC moved onto the 60000–69999 namespace in 1997 under the
|
|
29
|
+
ISO/IEC agreement; old `IEC 68` became `IEC 60068` (number += 60000, parts
|
|
30
|
+
unchanged).
|
|
31
|
+
|
|
32
|
+
## 1. Old IEC numbering (the 60000-namespace move)
|
|
33
|
+
|
|
34
|
+
- **Fixtures:** `spec/fixtures/iec/**` carries **zero** old-number inputs
|
|
35
|
+
(`IEC 68`, `IEC 65`, `IEC 68-1` … appear nowhere in full/, pass/ or fail/).
|
|
36
|
+
The only sub-1000 numbers in the fixtures are joint ISO/IEC documents
|
|
37
|
+
(`ISO/IEC 9594-*`, `ISO/IEC 9075-*`, `ISO/IEC 9899`, `ISO/IEC 8825-*`),
|
|
38
|
+
which are ISO-side numbers and were never IEC-old numbers.
|
|
39
|
+
- **v1 gem:** old numbers parse and render round-trip: `IEC 68:1980` →
|
|
40
|
+
`IEC 68:1980`, `IEC 68-1:1988` → number `68`, part `1`.
|
|
41
|
+
- **pubid 2 (current):** identical — `IEC 68:1980` → number `68`,
|
|
42
|
+
`IEC 68-1:1988` → number `68` part `1`. Old numbers still parse; there is
|
|
43
|
+
no 60000-offset inference anywhere in either implementation.
|
|
44
|
+
- **relaton-data-iec:** the crawler stores the **modern** number even for
|
|
45
|
+
pre-1997 editions — `data/iec-60068-1-1960.yaml` is stored as
|
|
46
|
+
`IEC 60068-1:1960` (1960 edition, modern number). Exactly one short-number
|
|
47
|
+
file exists (`iec-112-2021.yaml`, a genuinely modern number). **No record
|
|
48
|
+
carries an old number; the old→new mapping is never encoded in the corpus** —
|
|
49
|
+
the crawler resolved designations to the modern namespace at crawl time.
|
|
50
|
+
- Parts: old `IEC 68-1` style == modern `IEC 60068-1` style; the part
|
|
51
|
+
separator was already `-` on both sides of 1997. No `IEC 68/1` slash-part
|
|
52
|
+
face exists in any local source.
|
|
53
|
+
|
|
54
|
+
## 2. The old supplement faces and the DAM family
|
|
55
|
+
|
|
56
|
+
### 2.1 The JTC1/ISO-style prefix face (the DAM family)
|
|
57
|
+
|
|
58
|
+
The letters **DAM / PDAM / FDAM / FPDAM** (Draft / Proposed Draft / Final
|
|
59
|
+
Draft / Final Proposed Draft Amendment) are JTC1 ballot faces: the type
|
|
60
|
+
token (with its amendment number) is printed **before** the base
|
|
61
|
+
designation.
|
|
62
|
+
|
|
63
|
+
Owner's rule under verification: **DAM/PDAM/FDAM/FPDAM without a number
|
|
64
|
+
means Amendment 1.**
|
|
65
|
+
|
|
66
|
+
Evidence:
|
|
67
|
+
|
|
68
|
+
- **relaton-data-iec, exhaustive scan:** across all 32,835 records the
|
|
69
|
+
letters PDAM/FPDAM/FDAM appear in **exactly one file**
|
|
70
|
+
(`iso-iec-21000-14-2007.yaml`) — a **joint** record, and only inside an
|
|
71
|
+
abstract that cites sibling drafts (`ISO/IEC 21000-4:2006/FPDAM 1`,
|
|
72
|
+
`ISO/IEC 21000-5:2004/FDAM 2`) — never in a docidentifier. Word-bounded
|
|
73
|
+
bare `DAM`: **zero occurrences**. **IEC-only records never use the DAM
|
|
74
|
+
letters.** The DAM family is JTC1/ISO ballot vocabulary that rides only on
|
|
75
|
+
joint (and pure-ISO) work; IEC's own catalogue never printed it.
|
|
76
|
+
- **"No number means Amendment 1":** consistent with the joint corpus —
|
|
77
|
+
`ISO/IEC PDAM 12207` names the ballot that became
|
|
78
|
+
`ISO/IEC 12207:1995/Amd 1:2002` (the first amendment; stored docidentifier
|
|
79
|
+
in relaton-data-iso). Every one of the 7,366 published supplement records
|
|
80
|
+
in relaton-data-iec (4,923 AMD + 2,306 COR + 137 ISH) carries its **own
|
|
81
|
+
number** (`number: '1'` …), so the published corpus never contradicts the
|
|
82
|
+
rule; the numberless face exists only at ballot time.
|
|
83
|
+
- **v1 gem:** the prefix face was never decoded — `IEC/FDAM 1 60038-1:2004`
|
|
84
|
+
raised, and the joint forms "parsed" only by the catch-all number rule
|
|
85
|
+
swallowing the tokens whole (`ISO/IEC FDAM 1 14496-12:2004` → number
|
|
86
|
+
`"FDAM 1 14496-12"`, type `:is`) — a mangle, not a decode.
|
|
87
|
+
- **pubid 2 (current):** the prefix face raises in both the iec and iso
|
|
88
|
+
flavors (see the coverage table).
|
|
89
|
+
|
|
90
|
+
### 2.2 IEC's own historical amendment faces
|
|
91
|
+
|
|
92
|
+
The stored docidentifiers of real IEC amendments are uniformly the modern
|
|
93
|
+
on-base slash form, with the base designation whole and the supplement
|
|
94
|
+
numbered: `IEC 60038:1983/AMD1:1994`, `IEC 60038:2009/AMD1:2021`,
|
|
95
|
+
`CISPR 1:1961/AMD1:1967`, chained `ISO/IEC 9075-1:1999/Amd 1:2001/Cor 1:2003`
|
|
96
|
+
(relaton-data-iso), consolidated `+AMD1:1994+AMD2:1997` (file
|
|
97
|
+
`iec-60038-1983+amd1-1994+amd2-1997-csv.yaml`), titles "Amendment 1".
|
|
98
|
+
**No IEC-only record carries a numberless supplement** (checked across all
|
|
99
|
+
7,366 supplement rows).
|
|
100
|
+
|
|
101
|
+
### 2.3 The publisher-slash face `IEC/FDAM 60038-1`
|
|
102
|
+
|
|
103
|
+
- **v1 gem (1.15.21):** the face **did not parse at all** —
|
|
104
|
+
`IEC/FDAM 60038-1`, `IEC/DCOR 60038-1`, `IEC/DISH 60038-1`,
|
|
105
|
+
`IEC/CD 60038`, `IEC/FDIS 60038` all raised `ParseError`. v1's
|
|
106
|
+
`std_document_body` accepted `( "/" | space ) >> type` for **types**
|
|
107
|
+
(TS/TR/PAS/GUIDE: `IEC/TS 80000-1` parsed, `IEC CD 60038` parsed), but
|
|
108
|
+
FDAM/DCOR/DISH/CD are **stage** abbreviations, not types, so the slash
|
|
109
|
+
forms never reached a rule. The space-stage forms were mangled in v1
|
|
110
|
+
(`IEC FDAM 60038-1` → number `"FDAM 60038-1"`, type `:is`;
|
|
111
|
+
`IEC DISH 60038-1` → `/DISH60038`).
|
|
112
|
+
- **pubid 2 (current):** the `standalone_supplement` grammar rule accepts
|
|
113
|
+
`publisher / TYPE number` for **any** table token and `#ensure_base`
|
|
114
|
+
resolves it. See §3 for the resolution — which is the load-bearing finding.
|
|
115
|
+
- **relaton-data-iec:** **zero** docidentifiers of this shape (the pattern
|
|
116
|
+
`IEC/FDAM`-family or any `ORG/STAGE number` face: 0 of 32,835). The face
|
|
117
|
+
exists in no real record.
|
|
118
|
+
|
|
119
|
+
### 2.4 The old dotted on-base spelling `/Amd.1`
|
|
120
|
+
|
|
121
|
+
`IEC 60068-1:1988/Amd.1:1992` raises in **both** v1 and pubid 2. The dotted
|
|
122
|
+
spelling (real on ISO covers, and inside IEC abstracts citing joint work,
|
|
123
|
+
e.g. `ISO/IEC 21000-5:2004/Amd.1:2007`) was never accepted by the IEC
|
|
124
|
+
flavor. ISO flavor accepts it; IEC does not. Recorded as a gap, not chased
|
|
125
|
+
here.
|
|
126
|
+
|
|
127
|
+
## 3. How the current model resolves the old face (the load-bearing answer)
|
|
128
|
+
|
|
129
|
+
Probed on `main` @ `be6a43c2` (2.0.21):
|
|
130
|
+
|
|
131
|
+
| Input | base in to_hash | supplement own fields | to_s |
|
|
132
|
+
|---|---|---|---|
|
|
133
|
+
| `IEC/FDAM 60038-1` | `{"number" => "60038"}` | `{"stage"=>"fdamd", "number"=>"1"}` | `IEC FDAM 60038-1` |
|
|
134
|
+
| `IEC FDAM 60038-1` | `{"number" => "60038"}` | `{"stage"=>"fdamd", "number"=>"1"}` | `IEC FDAM 60038-1` |
|
|
135
|
+
| `IEC 60038-1/FDAM 1` (modern) | `{"number" => "60038", "part" => "1"}` | `{"stage"=>"fdamd", "number"=>"1"}` | `IEC 60038-1/FDAM1` |
|
|
136
|
+
| `IEC 60038-1/FDAM1:2021` | `{"number" => "60038", "part" => "1"}` | `stage fdamd, number 1, year 2021` | `IEC 60038-1/FDAM1:2021` |
|
|
137
|
+
| `IEC 60038:2009/AMD1:2014` | `{"number" => "60038", "year" => "2009"}` | `number 1, year 2014` | unchanged |
|
|
138
|
+
|
|
139
|
+
**The current model resolves the old form to "base 60038 with FDAM number
|
|
140
|
+
1": the bound hash captures `supp_number_with_part = "60038-1"`, the
|
|
141
|
+
builder splits it into number `60038` + part `1` on the supplement, and
|
|
142
|
+
`SupplementIdentifier#ensure_base` moves `@number` onto the synthetic base
|
|
143
|
+
while `@part` becomes the supplement's own number.** The base loses its
|
|
144
|
+
part; the "1" migrates into the supplement slot.
|
|
145
|
+
|
|
146
|
+
**Under the owner's reading this is wrong.** The old face names **FDAM of
|
|
147
|
+
60038-1**: the whole `60038-1` is the base designation, the type token is
|
|
148
|
+
unnumbered (→ Amendment 1 per the DAM rule), and the modern counterpart is
|
|
149
|
+
`IEC 60038-1/FDAM 1` — where the printed "1" after FDAM is the supplement
|
|
150
|
+
number the old face left implicit. The two faces must decode to the same
|
|
151
|
+
identifier, and today they do not (the space form of the old face and the
|
|
152
|
+
modern on-base form disagree on where the `1` lives — `{"number" => "60038"}`
|
|
153
|
+
vs `{"number" => "60038", "part" => "1"}`).
|
|
154
|
+
|
|
155
|
+
Note this correction touches the **space form too** (`IEC FDAM 60038-1`
|
|
156
|
+
would re-resolve to base 60038-1), and with it the #693-era equality work
|
|
157
|
+
and the six fixtures in `full/iec-pubid.txt` (rows 2195–2200) plus the
|
|
158
|
+
three normalization pairs the testsuite mirror carries (`FDAM/DCOR/DISH
|
|
159
|
+
60038-1`). The render would move from `IEC FDAM 60038-1` to the modern
|
|
160
|
+
on-base face (`IEC 60038-1/FDAM…` spelling per the ruling) or keep the old
|
|
161
|
+
render as a facet — an owner call (see §5).
|
|
162
|
+
|
|
163
|
+
## 4. Coverage table — the owner-cited forms (I own the ISO/IEC joint rows)
|
|
164
|
+
|
|
165
|
+
"Decode" = parses today under the current grammar, either flavor
|
|
166
|
+
(`Pubid::Iec.parse` / `Pubid::Iso.parse`; `ISO/IEC` routes to both via
|
|
167
|
+
`JOINT_PREFIXES`). Modern target = the stored docidentifier of the same
|
|
168
|
+
document in the joint corpus, where one exists.
|
|
169
|
+
|
|
170
|
+
| Input (historic face) | Decode today? | Historic identity (owner scheme) | Modern counterpart (evidence) |
|
|
171
|
+
|---|---|---|---|
|
|
172
|
+
| `ISO/IEC FDAM 1 14496-12:2004` | **no** (raises, both flavors) | FDAM **1** of base `14496-12:2004` | `ISO/IEC 14496-12:2005/Amd 1:2007` (corpus; the ballot predates the final edition year) |
|
|
173
|
+
| `ISO/IEC FDAM 19776-2:2005/Am1:2006` | **no** | FDAM (unnumbered → **1**) of base `19776-2:2005`, amendment already stamped `/Am1` on the base | `ISO/IEC 19776-2:2005/Amd 1:2008` (corpus) |
|
|
174
|
+
| `ISO/IEC FPDAM 10373-6/Amd 9:2001` | **no** | FPDAM (unnumbered → **9**, stated on-base) of base `10373-6` | `ISO/IEC 10373-6:2001/Amd N` family (corpus stores amd-1…7 of the 2001 edition) |
|
|
175
|
+
| `ISO/IEC FPDAM 9075/1` | **no** | FPDAM (unnumbered → **1**) of base `9075/1` — old slash-part spelling → base `9075-1` | `ISO/IEC 9075-1:1999/Amd 1:2001` (corpus) |
|
|
176
|
+
| `ISO/IEC 19772:2009/DAM 1:2019(E)` | **yes** (both flavors; on-base DAM) | DAM **1** of base `19772:2009` | none — the amendment died in ballot (corpus has only `Cor 1:2014`, then the 2020 edition) |
|
|
177
|
+
| `ISO/IEC PDAM 2 10646:2012` | **no** | PDAM **2** of base `10646:2012` | `ISO/IEC 10646:2012/Amd 1:2013` (corpus; Amd 2 followed) |
|
|
178
|
+
| `ISO/IEC PDAM TR 9573-11/Amd.1` | **no** | PDAM (unnumbered → **1**) of base `TR 9573-11`, amendment stamped on-base | TR amendment family (corpus: `iso-iec-tr-9573-11-*`) |
|
|
179
|
+
| `ISO/IEC PDAM 9541-1/Amd.4` | **no** | PDAM (unnumbered → **4**, stated on-base) of base `9541-1` | `ISO/IEC 9541-1:1991/Amd 4:2009` (corpus) |
|
|
180
|
+
| `ISO/IEC PDAM 12207` | **no** | PDAM (unnumbered → **1**) of base `12207` | `ISO/IEC 12207:1995/Amd 1:2002` (corpus) |
|
|
181
|
+
|
|
182
|
+
Pure-ISO rows of the owner's list (`ISO/FDAM 19119:2005/Amd.1`,
|
|
183
|
+
`ISO/PDAM 19110:2005/Amd.1`, `ISO 15877-5:2009 FDAM 1`, `ISO/PDAM 19973-2`)
|
|
184
|
+
belong to the ISO-side study; the DAM-letter evidence in §2.1 covers them
|
|
185
|
+
symmetrically (zero IEC-only usage).
|
|
186
|
+
|
|
187
|
+
Cross-cutting: the **on-base** DAM form already decodes (`19772` row) via
|
|
188
|
+
the same grammar branch as `/AMD1` — only the **prefix** (type-before-base)
|
|
189
|
+
faces and the old slash-part spelling are gaps.
|
|
190
|
+
|
|
191
|
+
## 5. Gap list (current grammar/model vs the historic scheme)
|
|
192
|
+
|
|
193
|
+
1. **Prefix supplement faces raise**: `[P|F]?DAM [N] BASE` — no rule in
|
|
194
|
+
`grammars/iec.parg` (joint or IEC-only; both flavors raise). Historic
|
|
195
|
+
face per the owner's scheme; zero published corpus occurrences
|
|
196
|
+
(ballot-time only), so the blast radius is inputs typed by humans, not
|
|
197
|
+
stored records.
|
|
198
|
+
2. **The old publisher-slash face mis-resolves**: `IEC/FDAM 60038-1` /
|
|
199
|
+
`IEC FDAM 60038-1` put the base's part into the supplement's number
|
|
200
|
+
(§3). The modern and old faces disagree on the same document's identity.
|
|
201
|
+
3. **Old slash-part spelling** (`9075/1`): never handled by either
|
|
202
|
+
implementation; the owner's ISO analogy places it in the same
|
|
203
|
+
historic-notation family.
|
|
204
|
+
4. **Dotted on-base `/Amd.1`**: raises in the IEC flavor (both
|
|
205
|
+
implementations); ISO accepts it. Abstracts of joint records cite the
|
|
206
|
+
dotted spelling.
|
|
207
|
+
5. **No old-number ↔ 60000-mapping knowledge** in either implementation:
|
|
208
|
+
old numbers parse as opaque numbers (`IEC 68` stays `68`); the corpus
|
|
209
|
+
never needs the mapping (crawler resolved at crawl time).
|
|
210
|
+
|
|
211
|
+
## 6. Disposition options (two house precedents) and recommendation
|
|
212
|
+
|
|
213
|
+
**Option A — ISO `original_abbr` spelling-facet style** (root CLAUDE.md,
|
|
214
|
+
"Spelling is not identity"): parse the historic face, store the modern
|
|
215
|
+
identity, keep the input's spelling as an `equality_ignored` facet so
|
|
216
|
+
`to_s` can reproduce it. Fits when both spellings live in the wild and
|
|
217
|
+
round-tripping the input spelling matters. Cost: a facet on
|
|
218
|
+
`TypedStage`/supplement components plus render plumbing in both flavors.
|
|
219
|
+
|
|
220
|
+
**Option B — IHO legacy-decode-to-modern style** (the IHO edition ruling):
|
|
221
|
+
decode the legacy face straight to the modern canonical identity, no
|
|
222
|
+
spelling kept. Fits when the legacy face is a ballot/era artefact that the
|
|
223
|
+
modern catalogue never stores. Cost: grammar decode + the identity
|
|
224
|
+
correction of §3; render emits the modern face.
|
|
225
|
+
|
|
226
|
+
**Option C — drop**: keep raising on the prefix faces and leave the
|
|
227
|
+
publisher-slash face as #693 left it. Contradicts the refined ruling.
|
|
228
|
+
|
|
229
|
+
**Recommendation: B, with one owner call.** The DAM-family faces and the
|
|
230
|
+
old slash-part spelling are ballot-era artefacts with **zero** published
|
|
231
|
+
corpus occurrences (measured above), so a spelling facet (A) buys nothing
|
|
232
|
+
for matching; decode-to-modern gives one identity per document. The decode
|
|
233
|
+
rule: `[P|F]?DAM [N] BASE` → supplement (P|F)DAM, number `N` defaulting to
|
|
234
|
+
**1** (the owner's rule), base designation kept **whole** (parts and
|
|
235
|
+
slash-parts resolved per the modern separator convention). The owner call:
|
|
236
|
+
whether the already-accepted faces (`IEC/FDAM 60038-1`, the on-base
|
|
237
|
+
`/AMD1`, the dotted `/Amd.1`) also move to the corrected base-whole
|
|
238
|
+
resolution — §3 shows the space form shares the defect, so the correction
|
|
239
|
+
cannot be scoped to the slash form alone. This doc records the evidence
|
|
240
|
+
for that decision; no implementation is proposed until the owner rules.
|
|
241
|
+
|
|
242
|
+
## 7. Disposition as implemented (the owner's ruling)
|
|
243
|
+
|
|
244
|
+
**Option B — IHO-style decode-to-modern — on ALL the already-accepted
|
|
245
|
+
faces too** (the §6 owner call): `IEC/FDAM 60038-1` and `IEC FDAM 60038-1`
|
|
246
|
+
both decode to the modern identity; the space form shares the defect, so
|
|
247
|
+
the correction is not scoped to the slash form alone.
|
|
248
|
+
|
|
249
|
+
The decode rule, as landed:
|
|
250
|
+
|
|
251
|
+
- **Base kept whole.** The designation after the stage token is the BASE's:
|
|
252
|
+
number, part, subpart and the date (old notation prints the base's year;
|
|
253
|
+
a draft supplement carries no publication date of its own). The base is a
|
|
254
|
+
concrete InternationalStandard, so the legacy face hash-matches — and
|
|
255
|
+
equals — the modern on-base parse: `parse("IEC/DCOR 60038-1") ==
|
|
256
|
+
parse("IEC 60038-1/DCOR 1")`.
|
|
257
|
+
- **Unnumbered = 1.** The supplement's number is the captured N, defaulting
|
|
258
|
+
to 1 (the DAM-family no-number rule, extended to the DCOR/DISH faces the
|
|
259
|
+
fixtures carry).
|
|
260
|
+
- **Draft-ness preserved.** Each face keeps its own stage: FDAM → `fdamd`
|
|
261
|
+
(50.xx), DAM → `damd` (40.xx), DCOR → `dcor`, DISH → `dish`, CDISH →
|
|
262
|
+
`cd`, FDCOR → `fdcor`; the joint ladder's PDAM (30.xx, CD level) and
|
|
263
|
+
FPDAM (50.xx, FDIS level) registered with the circulation slots 30.20 /
|
|
264
|
+
50.20 leading their harmonized lists (CDAM and FDAM own the
|
|
265
|
+
(type, leading-code) URN keys 30.00 / 50.00).
|
|
266
|
+
- **Slash-part.** `FPDAM 9075/1` — the `/1` is the base's part (base
|
|
267
|
+
9075 part 1), consistent with the ISO-side reading of the old
|
|
268
|
+
slash-part spelling.
|
|
269
|
+
- **Modern canonical face emitted.** `IEC/FDAM 60038-1` → `IEC 60038-1/FDAM1`;
|
|
270
|
+
the legacy face is decoded, not preserved as a spelling facet.
|
|
271
|
+
- **Stays untouched:** the modern on-base forms — `IEC 60038:1983/AMD1:1994`,
|
|
272
|
+
`IEC 60038-1/FDAM 1`, `ISO/IEC 19772:2009/DAM 1:2019(E)` — and the true
|
|
273
|
+
standalone self-base (`IEC/AMD 1:2017` → `IEC Amd 1-1:2017`).
|
|
274
|
+
|
|
275
|
+
Split of labour: the DAM-family prefix faces needed a new grammar rule
|
|
276
|
+
(`legacy_supplement`, pubid-grammar) — they raised before; the DCOR/DISH
|
|
277
|
+
(and CDISH/FDCOR/CDCor) faces already parsed through the standalone and
|
|
278
|
+
typed branches and were corrected in the builder
|
|
279
|
+
(`SupplementIdentifier#ensure_base`: the part-to-number move deleted, the
|
|
280
|
+
designation moved whole onto a concrete base, the supplement numbered 1).
|
|
281
|
+
A bare number after a DAM-family token is a base designation under the
|
|
282
|
+
JTC1 reading (`IEC FDAM 60038` → `IEC 60038/FDAM1`); a bare ordinal after
|
|
283
|
+
a non-DAM token stays the supplement's own number.
|
|
284
|
+
|
|
285
|
+
Replay gate (all 26,838 full-fixture inputs, main baseline vs the branch):
|
|
286
|
+
byte-identical everywhere except the six §3 rows (rows 2195–2200 of
|
|
287
|
+
`full/iec-pubid.txt`), which re-resolve; 0 inputs stopped parsing; the
|
|
288
|
+
prefix faces go raise→parse (pass 12,337 → 12,359 of 12,491; fail steady
|
|
289
|
+
at 132). The testsuite mirror normalization pairs
|
|
290
|
+
(FDAM/DCOR/DISH `60038-1`) flip to the corrected identities in the same
|
|
291
|
+
round.
|
|
292
|
+
|
|
293
|
+
Still raising, deliberately (gap 4 of §5, not chased here): the dotted
|
|
294
|
+
on-base `/Amd.1` spelling, and the stamped prefix faces whose base
|
|
295
|
+
designation carries an amendment stamp (`FPDAM 10373-6/Amd 9:2001`,
|
|
296
|
+
`PDAM 9541-1/Amd.4`, `FDAM 19776-2:2005/Am1:2006`, `PDAM TR
|
|
297
|
+
9573-11/Amd.1`) — they need the dotted/ISO stamp spellings the IEC flavor
|
|
298
|
+
does not carry; the ISO-side study owns that family.
|