expressir 2.4.3 → 2.4.5

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.cargo/config.toml +3 -0
  3. data/.github/workflows/rust-ext.yml +41 -0
  4. data/.github/workflows/verify_remarks.yml +33 -0
  5. data/.gitignore +6 -0
  6. data/.rubocop.yml +4 -0
  7. data/.rubocop_todo.yml +1 -0
  8. data/Cargo.toml +7 -0
  9. data/README.adoc +105 -0
  10. data/Rakefile +12 -0
  11. data/TODO.parity-ee/00-overview.md +58 -0
  12. data/TODO.parity-ee/01-annex-g-rule-extraction.md +41 -0
  13. data/TODO.parity-ee/02-eeng-algorithm-inventory.md +8 -0
  14. data/TODO.parity-ee/03-eeng-oracle-harness.md +33 -0
  15. data/TODO.parity-ee/04-shtolo-concatenate.md +44 -0
  16. data/TODO.parity-ee/05-shtolo-longform-flatten.md +53 -0
  17. data/TODO.parity-ee/06-interface-scheduling-parity.md +47 -0
  18. data/TODO.parity-ee/07-semantic-checks-port.md +35 -0
  19. data/TODO.parity-ee/08-pretty-roundtrip-gate.md +27 -0
  20. data/TODO.parity-ee/09-smrl-index-and-listing.md +22 -0
  21. data/TODO.parity-ee/10-interface-dot-graph.md +21 -0
  22. data/TODO.parity-ee/11-import-eeng-tests.md +79 -0
  23. data/TODO.parity-ee/parity-matrix.md +108 -0
  24. data/exe/expressir +6 -0
  25. data/ext/expressir_core/Cargo.toml +24 -0
  26. data/ext/expressir_core/extconf.rb +30 -0
  27. data/ext/expressir_core/src/lib.rs +446 -0
  28. data/lib/expressir/cli.rb +49 -4
  29. data/lib/expressir/commands/check.rb +56 -0
  30. data/lib/expressir/commands/expand.rb +26 -0
  31. data/lib/expressir/commands/fix.rb +33 -0
  32. data/lib/expressir/commands/flatten.rb +29 -0
  33. data/lib/expressir/commands/parity_inputs.rb +85 -0
  34. data/lib/expressir/commands/validate.rb +22 -0
  35. data/lib/expressir/commands.rb +5 -0
  36. data/lib/expressir/express/adoc_hyperlink_formatter.rb +30 -0
  37. data/lib/expressir/express/adoc_source_formatter.rb +12 -0
  38. data/lib/expressir/express/builder_registry.rb +11 -2
  39. data/lib/expressir/express/builders/entity_decl_builder.rb +17 -7
  40. data/lib/expressir/express/builders/subtype_constraint_builder.rb +3 -1
  41. data/lib/expressir/express/builders/type_builder.rb +8 -0
  42. data/lib/expressir/express/builders/unique_rule_builder.rb +8 -1
  43. data/lib/expressir/express/checker.rb +458 -0
  44. data/lib/expressir/express/concatenator.rb +79 -0
  45. data/lib/expressir/express/core.rb +66 -0
  46. data/lib/expressir/express/formatter.rb +25 -3
  47. data/lib/expressir/express/formatters/data_types_formatter.rb +2 -2
  48. data/lib/expressir/express/formatters/declarations_formatter.rb +1 -0
  49. data/lib/expressir/express/formatters/remark_formatter.rb +30 -6
  50. data/lib/expressir/express/formatters/statements_formatter.rb +7 -1
  51. data/lib/expressir/express/interface_dot.rb +105 -0
  52. data/lib/expressir/express/listing.rb +174 -0
  53. data/lib/expressir/express/model_traversal.rb +42 -0
  54. data/lib/expressir/express/node_position_index.rb +18 -4
  55. data/lib/expressir/express/parser.rb +242 -4
  56. data/lib/expressir/express/pretty_gate.rb +61 -0
  57. data/lib/expressir/express/refs_overlay.rb +47 -0
  58. data/lib/expressir/express/remark_attacher.rb +122 -10
  59. data/lib/expressir/express/remark_overlay.rb +86 -0
  60. data/lib/expressir/express/schema_plain_source_formatter.rb +11 -0
  61. data/lib/expressir/express/schema_source_formatter.rb +5 -5
  62. data/lib/expressir/express/self_schema_reference.rb +126 -0
  63. data/lib/expressir/express/shtolo.rb +522 -0
  64. data/lib/expressir/express.rb +15 -0
  65. data/lib/expressir/model/concerns.rb +15 -1
  66. data/lib/expressir/model/declarations/entity.rb +6 -1
  67. data/lib/expressir/model/declarations/interface.rb +13 -0
  68. data/lib/expressir/model/declarations/schema.rb +90 -23
  69. data/lib/expressir/model/indexes/item_graph.rb +135 -0
  70. data/lib/expressir/model/indexes.rb +1 -0
  71. data/lib/expressir/model/model_element.rb +30 -1
  72. data/lib/expressir/model/remark_info.rb +20 -1
  73. data/lib/expressir/model/remark_placement.rb +15 -2
  74. data/lib/expressir/model/repository.rb +8 -2
  75. data/lib/expressir/model.rb +2 -1
  76. data/lib/expressir/version.rb +1 -1
  77. data/lib/tasks/verify_remarks.rake +9 -0
  78. data/rakelib/verify_remarks.rake +16 -0
  79. metadata +44 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b0fe8cde3b24a7a4ce39599fa68b61b02d3f8af45c1a8f5e45ce2607a213922
4
- data.tar.gz: 869991a150512a7b12fb94f18f97e66bc6954317c311f630b3fac41d55d001b0
3
+ metadata.gz: 2b92ce4a74f26a9a05edb583616053db6229b64705bbde94435fa5e6e326e84b
4
+ data.tar.gz: 1d3fa87cf6305caf6c4dffe592be2927b4a7101c993bcd5a3fdcecdb8c595ab7
5
5
  SHA512:
6
- metadata.gz: d04f62c906dc98f43a469f88ec56382decf8636407766c94b1248f94fbc21a2667144cc421a021dda592ea5d56987937ca20ea819a4300540589ea935c2767c2
7
- data.tar.gz: eeaa19435f4e66921136fbe3cee4ac729f5dfd5fa4f5731cc5b88a601639518c6be3ebfa70af4d29ef8f78500e80586a50df7636a88892a03f93787d9bee2182
6
+ metadata.gz: 5b3a8686a796910f01abb565a00fdb995e4d5b14f159941eeddbdecdba1b5c4ec793b4c17e3231113e8342e1d62f91d9b778acb1d1b0c7398abc5780d60a32bc
7
+ data.tar.gz: a5df0468bd977b6ac6cca9abbddbd60b8c8cee60149f5584132b7e2d2bc62aabe9d586237fb04200ae1232cc23c06592150b1071cfae5dfd2de0eacc54579148
@@ -0,0 +1,3 @@
1
+ # Git deps fetch over SSH by the system git CLI (cargo HTTPS auth fails locally).
2
+ [net]
3
+ git-fetch-with-cli = true
@@ -0,0 +1,41 @@
1
+ name: rust-ext
2
+
3
+ on:
4
+ push:
5
+ branches: [master, main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ build-ext:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: dtolnay/rust-toolchain@stable
14
+ - uses: ruby/setup-ruby@v1
15
+ with:
16
+ ruby-version: "3.4"
17
+ bundler-cache: true
18
+ - name: Build the expressir-core extension
19
+ working-directory: ext/expressir_core
20
+ run: |
21
+ gem install rb_sys
22
+ ruby extconf.rb
23
+ RB_SYS_CARGO_PROFILE=release make
24
+ - name: Smoke test the bridge
25
+ run: |
26
+ bundle exec ruby -e '
27
+ require "expressir"
28
+ require "expressir/express/core"
29
+ raise "native unavailable" unless Expressir::Express::Core::NATIVE_AVAILABLE
30
+ src = File.read("spec/syntax/multiple.exp")
31
+ m = Expressir::Express::Core.parse_to_model_hash(src, "multiple.exp")
32
+ raise "bad model" unless m["schemas"].first["id"] == "multiple_schema"
33
+ puts "bridge OK"
34
+ '
35
+ # The default `rake` CI job covers the pure-Ruby parse path (no
36
+ # extension built there); this job pins the core parse path: with the
37
+ # extension present the parser defaults to it, so the whole suite runs
38
+ # against the Rust wire hydration.
39
+ - name: Run the suite on the core parse path
40
+ run: |
41
+ bundle exec rspec spec/expressir spec/syntax --tag ~production_scale
@@ -0,0 +1,33 @@
1
+ name: "verify_remarks"
2
+
3
+ permissions:
4
+ contents: read
5
+
6
+ on:
7
+ push:
8
+ branches: [ main ]
9
+ pull_request:
10
+ workflow_dispatch:
11
+
12
+ concurrency:
13
+ group: '${{ github.workflow }}-${{ github.ref }}'
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ remarks:
18
+ name: Verify remark conservation
19
+ runs-on: ubuntu-latest
20
+
21
+ steps:
22
+ - name: Checkout
23
+ uses: actions/checkout@v4
24
+
25
+ - name: Install Ruby
26
+ uses: ruby/setup-ruby@master
27
+ with:
28
+ ruby-version: "3.2"
29
+ bundler-cache: true
30
+ cache-version: 0 # Increment this number if you need to re-download cached gems
31
+
32
+ - name: Verify remark conservation
33
+ run: bundle exec rake verify:remarks
data/.gitignore CHANGED
@@ -42,3 +42,9 @@ Gemfile.local.lock
42
42
  Gemfile.original
43
43
  benchmark/
44
44
  CLAUDE.md
45
+
46
+ # Rust workspace
47
+ /target/
48
+ Cargo.lock
49
+ /ext/expressir_core/target/
50
+ /ext/expressir_core/*.bundle
data/.rubocop.yml CHANGED
@@ -12,3 +12,7 @@ AllCops:
12
12
  NewCops: enable
13
13
  Exclude:
14
14
  - 'vendor/**/*'
15
+ - 'metanorma-mirror-*/**/*'
16
+
17
+ Lint/UnusedMethodArgument:
18
+ AllowUnusedKeywordArguments: true
data/.rubocop_todo.yml CHANGED
@@ -144,6 +144,7 @@ Performance/MapMethodChain:
144
144
  RSpec/AnyInstance:
145
145
  Exclude:
146
146
  - 'spec/expressir/commands/package_edge_cases_spec.rb'
147
+ - 'spec/expressir/express/remark_attacher_performance_spec.rb'
147
148
 
148
149
  # Offense count: 11
149
150
  # Configuration parameters: Prefixes, AllowedPatterns.
data/Cargo.toml ADDED
@@ -0,0 +1,7 @@
1
+ [workspace]
2
+ resolver = "2"
3
+ members = ["crates/expressir-core"]
4
+
5
+ [workspace.package]
6
+ edition = "2021"
7
+ license = "MIT"
data/README.adoc CHANGED
@@ -211,10 +211,14 @@ Commands:
211
211
  expressir benchmark-cache FILE_OR_YAML # Benchmark schema loading with caching
212
212
  expressir changes SUBCOMMAND # Commands for EXPRESS Changes files
213
213
  expressir clean PATH # Strip remarks and prettify EXPRESS schema at PATH
214
+ expressir expand PATH # Concatenate the interface closure into one .exp
215
+ expressir flatten PATH # Flatten the interface closure into an ISO 10303-11:1994 longform schema
216
+ expressir fix PATH # Rewrite self-schema-qualified references (#125)
214
217
  expressir format PATH # pretty print EXPRESS schema located at PATH
215
218
  expressir help [COMMAND] # Describe available commands or one specific command
216
219
  expressir validate load *PATH # validate EXPRESS schema located at PATH
217
220
  expressir validate ascii PATH # Validate EXPRESS files for ASCII-only content (excluding remarks)
221
+ expressir validate check *PATHS # eeng check-p11 semantic checks
218
222
  expressir coverage *PATH # List EXPRESS entities and check documentation coverage
219
223
  expressir version # Expressir Version
220
224
  ----
@@ -508,6 +512,83 @@ expressir clean schemas/resources/action_schema/action_schema.exp --output clean
508
512
  | `--output PATH` | Path to save the cleaned schema (optional, defaults to stdout)
509
513
  |===
510
514
 
515
+ === Expand schema (concatenated artifact)
516
+
517
+ The `expand` command flattens the interface closure of a root EXPRESS schema
518
+ into a single concatenated artifact (one section per source schema, ordered
519
+ alphabetically — the same shape eeng emits for `--concat_schema`).
520
+
521
+ [source, sh]
522
+ ----
523
+ expressir expand schemas/resources/action_schema/action_schema.exp \
524
+ --output action-concatenated.exp
525
+ ----
526
+
527
+ [options="header"]
528
+ |===
529
+ | Option | Description
530
+ | `--output PATH`, `-o PATH` | Write the artifact to PATH (defaults to stdout)
531
+ | `--manifest PATH` | ELF schema manifest YAML defining where schemas live (primary
532
+ resolution mode)
533
+ | `--stepmod DIR` | STEPmod checkout root — explicit opt-in to directory-convention
534
+ resolution as the fallback
535
+ |===
536
+
537
+ The closure is resolved by scanning `USE FROM` / `REFERENCE FROM` names in the
538
+ root source. Schema resolution order: `--manifest PATH` (an ELF schema
539
+ manifest — explicit, layout-independent) first; `--stepmod DIR` (the STEPmod
540
+ directory convention) as an explicit fallback; otherwise the file's own
541
+ directory, with a failed lookup warning and pointing at the two explicit
542
+ modes.
543
+
544
+ === Flatten schema (SHTOLO longform)
545
+
546
+ The `flatten` command converts a STEPmod-style multi-schema root into a single
547
+ ISO 10303-11:1994 "longform" schema (expressir#32). It runs the Annex G
548
+ conversion locally: interface-closure copy with rename resolution and name
549
+ munging, then extensible enum/select resolution, subtype-constraint
550
+ elimination, RENAMED→DERIVE, GENERIC_ENTITY→GENERIC.
551
+
552
+ [source, sh]
553
+ ----
554
+ expressir flatten schemas/resources/action_schema/action_schema.exp \
555
+ --output action_lf.exp --longform_name action_schema_lf
556
+ ----
557
+
558
+ [options="header"]
559
+ |===
560
+ | Option | Description
561
+ | `--output PATH`, `-o PATH` | Write the longform schema to PATH (defaults to stdout)
562
+ | `--longform_name ID` | Identifier for the resulting SCHEMA (default: `<root>_lf`)
563
+ | `--extenders all|none` | `all` (default, the WG12 requirement): fold every extensible
564
+ SELECT/ENUMERATION extension in the closure into its base type — for
565
+ `EXTENSIBLE GENERIC_ENTITY SELECT` that means every entity the closure
566
+ carries. `none`: leave extensible types exactly as declared.
567
+ | `--manifest PATH` | ELF schema manifest YAML defining where schemas live (primary
568
+ resolution mode)
569
+ | `--stepmod DIR` | STEPmod checkout root — explicit opt-in to directory-convention
570
+ resolution as the fallback
571
+ |===
572
+
573
+ The longform output is verified against Express Engine: for
574
+ `description_assignment`, `eengine --compare` of our longform against
575
+ eengine's own reference artifact reports *No differences detected*
576
+ (`spec/expressir/express/shtolo_eengine_oracle_differential_spec.rb`).
577
+
578
+ === Fix schema (self-schema references)
579
+
580
+ The `fix` command rewrites string literals that qualify an item with the
581
+ CURRENT schema's name — `'THIS_SCHEMA.ITEM'` inside THIS_SCHEMA is
582
+ technically incorrect: the item usually comes from another schema,
583
+ imported implicitly through a USEd supertype. Local items drop the
584
+ prefix; foreign items gain their true defining schema
585
+ (`'GEOMETRY_SCHEMA.B_SPLINE_SURFACE'`); unknown items are left untouched.
586
+
587
+ [source, sh]
588
+ ----
589
+ expressir fix schemas/aic_topologically_bounded_surface.exp --output fixed.exp
590
+ ----
591
+
511
592
  === Validate schema
512
593
 
513
594
  The `validate load` command performs validation checks on EXPRESS schema files.
@@ -536,6 +617,30 @@ The command reports any schemas that:
536
617
 
537
618
  If all validations pass, it will display "Validation passed for all EXPRESS schemas."
538
619
 
620
+ === Validate semantic checks (eeng check-p11)
621
+
622
+ The `validate check` command runs the eeng `check-p11` note subset
623
+ implemented in `Expressir::Express::Checker`: redundant interfaces,
624
+ duplicate interface resources, unresolved interface schema/resource
625
+ refs, SUBTYPE OF targets, SELECT/ENUM BASED_ON targets, and WHERE/UNIQUE
626
+ label patterns.
627
+
628
+ [source, sh]
629
+ ----
630
+ # Check a single file
631
+ expressir validate check schemas/resources/action_schema/action_schema.exp
632
+
633
+ # Check all .exp files under a directory
634
+ expressir validate check schemas/resources/
635
+
636
+ # Resolve the closure through an ELF schema manifest (or --stepmod DIR)
637
+ expressir validate check modules/description_assignment/mim.exp \
638
+ --manifest schemas-srl.yaml
639
+
640
+ # Exit 1 when any :error note fires
641
+ expressir validate check schemas/resources/action_schema/action_schema.exp
642
+ ----
643
+
539
644
  === Validate ASCII content
540
645
 
541
646
  The `validate ascii` command validates that EXPRESS schema files contain only
data/Rakefile CHANGED
@@ -14,3 +14,15 @@ task default: %i[spec rubocop]
14
14
  require "yard"
15
15
 
16
16
  YARD::Rake::YardocTask.new
17
+
18
+ Dir.glob(File.expand_path("lib/tasks/*.rake", __dir__)).each { |task| load task }
19
+
20
+ desc "Regenerate the EXPRESS grammar JSON embedded in expressir-rs"
21
+ task :"expressir:grammar:dump" do
22
+ require "expressir/express/grammar/parser"
23
+ json = Expressir::Express::Grammar::Parser.cached_grammar_json
24
+ dir = ENV.fetch("EXPRESSIR_RS_DIR", File.expand_path("../expressir-rs", __dir__))
25
+ path = File.join(dir, "assets", "express-grammar.json")
26
+ File.write(path, "#{json}\n")
27
+ puts "wrote #{path}"
28
+ end
@@ -0,0 +1,58 @@
1
+ # Parity with Express Engine (eeng) — SHTOLO and algorithms
2
+
3
+ **Status: PLANNED (2026-09-21)**
4
+
5
+ ## Mission
6
+
7
+ 1. **SHTOLO** (expressir#32): SHort-TO-LOng — generate ISO 10303-11:1994
8
+ "long form EXPRESS" (one self-contained schema) from the STEPmod
9
+ multi-schema structure (edition 2: shared files, USE FROM /
10
+ REFERENCE FROM). The normative conversion rules are
11
+ **ISO 10303-11:2004 Annex G** — local sources:
12
+ `~/src/mn/iso-10303-11/sources/sections/ag-single-schema.adoc`.
13
+ 2. **Concatenation** (expressir#247, metanorma/iso-10303#539): the SHTOLO
14
+ precursor — a dependency-closure concatenation of all interfaced
15
+ schemas into one publication artifact (`.exp`), plus SMRL index.
16
+ 3. **Validation** of both, against the reference implementation:
17
+ Express Engine (`~/src/external/exp-engine-engine`, Common Lisp),
18
+ whose `qualify.sh` runs the full operation catalog over the exact
19
+ SMRL corpus we already load (`resources.lst`/`modules.lst` ==
20
+ our SRL manifests).
21
+
22
+ ## Reference implementation map
23
+
24
+ | eeng source | operation (qualify.sh) | task |
25
+ |---|---|---|
26
+ | `plugins/p11/wo-pretty.lisp` | Pretty Print `.exp` + compare | 08 |
27
+ | `plugins/p11/wo-flat.lisp` + `run-op :flat` | **Flatten to long form** | 05 |
28
+ | mode `:concatenated` (`kernel/engine.lisp`) | **Concatenate schema** | 04 |
29
+ | `plugins/p11/wo-list.lisp` | List declarations | 09 |
30
+ | `plugins/p11/wo-smrl-xml.lisp` | SMRL index XML | 09 |
31
+ | `kernel/dot-graph.lisp` | Dot interface graph | 10 |
32
+ | `kernel/check.lisp` (835 lines) | semantic checks | 07 |
33
+ | `plugins/p11/schedule-*.lisp`, `kernel/resolve-interface.lisp` | load/resolution scheduling | 06 |
34
+ | `kernel/compute-inheritance.lisp`, `supertypes.lisp`, `derive-attrs.lisp`, `inverse-attrs.lisp` | entity computations | 02/07 |
35
+
36
+ ## What we already have (expressir)
37
+
38
+ Compiled schema set (batch + EXSCS1 artifact + overlays), repository
39
+ indexes + reference graph (37.7k subtype edges, interfaces, closures),
40
+ `Schema#interfaced_items`, resolver, formatter (clean/hyperlink),
41
+ `RepositoryValidator`, Part 21 parser = **not started** (see 02).
42
+
43
+ ## Task index
44
+
45
+ 01 Annex G rule extraction · 02 eeng algorithm inventory (what we do
46
+ differently) · 03 eeng oracle harness · 04 concatenation (#247) ·
47
+ 05 SHTOLO longform flatten (#32) · 06 interface scheduling parity ·
48
+ 07 semantic checks port · 08 pretty-print round-trip gate ·
49
+ 09 SMRL index + listing · 10 interface dot graph ·
50
+ 11 import the eeng test suite (scripts/ drivers, docs/issues bugs,
51
+ SHTOLO paper, BNFs, DTDs)
52
+
53
+ ## Additional eeng assets (via 11)
54
+
55
+ `scripts/*.sh` — 14 release-suite drivers (qual/pretty/xml/dot);
56
+ `docs/issues/` — bug corpus incl. a shtolo old-vs-new differential;
57
+ `docs/` — SHTOLO paper PDF, Part 11/14/21 BNFs, XML DTDs,
58
+ interface/qualify notes; `00check.txt` — check design notes.
@@ -0,0 +1,41 @@
1
+ # 01 — Annex G rule extraction (executable spec for SHTOLO)
2
+
3
+ **Status: NOT STARTED**
4
+
5
+ ## Goal
6
+
7
+ Turn `~/src/mn/iso-10303-11/sources/sections/ag-single-schema.adoc`
8
+ (1957 lines) into an executable checklist: every conversion rule with
9
+ an identifier, inputs, outputs, and a fixture that exercises it. This
10
+ is the contract both for our implementation (05) and for judging
11
+ eeng's coverage.
12
+
13
+ ## Source structure (verified)
14
+
15
+ - Fundamentals: multi-schema → intermediate single "artifact" schema →
16
+ rewrite using 1994-only constructs; subtype/supertype graph pruning;
17
+ interface knowledge (visibility + instantiability) becomes rules;
18
+ total_over constraints become rules.
19
+ - **Name munging**: name-clash policy; identifiers-as-strings.
20
+ - **Stage 1 (multi → intermediate)**: primary population (per
21
+ interfaced item: artifact-schema rule + function capturing
22
+ visibility/instantiability), secondary population, **prune** rules
23
+ (rules whose parameters are not all visible are deleted, etc.).
24
+ - Stage 2 (intermediate → 1994 longform): rewrite of constructs not in
25
+ the 1994 edition.
26
+
27
+ ## Steps
28
+
29
+ 1. Read the full annex; number every rule `G.<n>` with a one-line
30
+ statement, inputs/outputs, and stage.
31
+ 2. Build a fixture matrix: for each rule, the smallest STEPmod schema
32
+ pair(s) that trigger it (mine the SMRL corpus for real cases).
33
+ 3. Cross-reference which rules eeng implements (grep its sources for
34
+ the mechanisms) and mark: implemented-in-eeng / our-gap / both-gap.
35
+ 4. Encode the checklist as a spec document under
36
+ `spec/fixtures/shtolo/rules.md` (or adoc) that 05's suite cites.
37
+
38
+ ## Acceptance
39
+
40
+ Every rule in Annex G has an id, a fixture, and an eeng-coverage flag;
41
+ no rule left "uncategorized".
@@ -0,0 +1,8 @@
1
+ # 02 — eeng algorithm inventory: what they do vs what we do differently
2
+
3
+ **Status: SHIPPED (2026-09-21) — see parity-matrix.md for the audit and
4
+ expressir#373 for the bug the audit surfaced.**
5
+
6
+ See `parity-matrix.md` (same directory) for the full algorithm-by-
7
+ algorithm comparison: resolution scoping, interface scheduling,
8
+ entity computations, writers, and the concrete expressir gaps found.
@@ -0,0 +1,33 @@
1
+ # 03 — Build and run eeng as a differential oracle
2
+
3
+ **Status: NOT STARTED**
4
+
5
+ ## Goal
6
+
7
+ A working `eengine` binary (SBCL build) we can run over the SMRL corpus
8
+ to produce reference outputs (pretty, flat, concatenated, list,
9
+ smrl-xml, dot, checks) for differential validation of our ports.
10
+
11
+ ## Steps
12
+
13
+ 1. Install/locate SBCL; build: `sbcl --load sbcl/compile` then
14
+ `sbcl --load sbcl/deliver` (per README.txt) → `eengine`.
15
+ 2. Reproduce `qualify.sh` flow for a handful of modules from
16
+ `qualify-mod.txt` (their lists == our SRL corpus names).
17
+ 3. Golden corpus: run all qualify operations for the full
18
+ `resources.lst` + `modules.lst`; commit distilled outputs (not the
19
+ whole tree) under `spec/fixtures/eeng-oracle/` (LFS-sized check
20
+ first).
21
+ 4. Script `script/eeng-oracle` (or Rake task) exposing one-command
22
+ regeneration; document known eeng bugs/limitations found while
23
+ driving it (feeds 01's coverage flags).
24
+
25
+ ## Acceptance
26
+
27
+ One command regenerates the golden corpus; at least arm/mim pretty +
28
+ flat + concatenated outputs exist for 10 modules and 10 resources.
29
+
30
+ ## Tests
31
+
32
+ Refreshes the expected outputs consumed by 11's imported specs; the
33
+ qual-* drivers are the oracle's entry points.
@@ -0,0 +1,44 @@
1
+ # 04 — Concatenated EXPRESS artifact (expressir#247)
2
+
3
+ **Status: SHIPPED (2026-09-21)** — `Expressir::Express::Concatenator`
4
+ (closure + writer + one-call `call`), eeng-semantics ordering and
5
+ section format (alphabetical, `-- NAME (file)` separators, verbatim
6
+ source copies); specs: synthetic closure/round-trip + ENV-gated eeng
7
+ differential (byte-identical sections vs `--concat_schema` for
8
+ description_assignment ARM). Golden oracle outputs committed for ARM
9
+ and MIM. During this stage the small-input USE FROM parse bug was
10
+ found and reported as expressir#373.
11
+
12
+ ## Goal
13
+
14
+ `expressir` command producing a **concatenated** `.exp`: the root
15
+ schema followed by every USE FROM / REFERENCE FROM dependency
16
+ (non-circular closure), each as plain EXPRESS (no remarks), with an
17
+ SRL publication header listing the schemas. This is the SHTOLO
18
+ precursor and a WG12 qualification/provenance artifact.
19
+
20
+ ## Reference
21
+
22
+ - eeng mode `(:arm/:mim :concatenated)` — `kernel/engine.lisp` mode
23
+ table, `plugins/p11/top-level.lisp` (concatenated handling +
24
+ `arm_concatenated.exp` outputs in qualify.sh), SMRL index hook at
25
+ wo-smrl-xml.
26
+ - Our graph: dependency closure via `Repository#reference_index`
27
+ (interface edges) + topological, cycle-safe ordering already
28
+ demonstrated by the item-graph work.
29
+
30
+ ## Design sketch
31
+
32
+ - `Expressir::Express::Concatenator.call(repository, root_schema)` →
33
+ model-level ordered schema list (respect eeng's ordering rules —
34
+ read their code in 02 first).
35
+ - Writer: plain schemas (no remarks) + banner comment enumerating
36
+ sources (schema name, file, copyright per SRL conventions).
37
+ - CLI: `expressir concatenate <manifest/root.exp> -o out.exp`.
38
+
39
+ ## Acceptance
40
+
41
+ - Output parses back with our parser (self round-trip).
42
+ - Diff vs eeng `arm_concatenated.exp`/`mim_concatenated.exp` for the
43
+ 03 golden set: schema set + order identical (formatting differences
44
+ documented, ideally zero after 08).
@@ -0,0 +1,53 @@
1
+ # 05 — SHTOLO longform flatten (expressir#32) — the core port
2
+
3
+ **Status: NOT STARTED**
4
+
5
+ ## Goal
6
+
7
+ Port eeng's flatten (Annex G) into expressir: convert the STEPmod
8
+ multi-schema web into ONE ISO 10303-11:1994 longform schema — no
9
+ interfaces, no name clashes, interface visibility/instantiability
10
+ preserved as rules, pruned unreachable declarations.
11
+
12
+ ## Sources to port
13
+
14
+ - **Spec**: `ag-single-schema.adoc` (see 01's rule ids).
15
+ - **eeng**: `run-op (:flat)` + `print-flatten`
16
+ (`plugins/p11/top-level.lisp:847`), writer `plugins/p11/wo-flat.lisp`
17
+ (373 lines; note: eeng's flat output keeps structure and lowercases
18
+ identifiers — verify how much of Annex G eeng actually implements
19
+ before treating it as gospel; where eeng and the standard disagree,
20
+ the standard wins and the difference goes into 02's matrix).
21
+ - **Model surgery**: `add-declaration.lisp`, `remove-declaration.lisp`,
22
+ `copy-object.lisp`, `cleanup-interface.lisp`.
23
+
24
+ ## Design sketch
25
+
26
+ 1. Model-level `Expressir::Express::Flattener` operating on the
27
+ resolved repository (compiled set warm model): build the artifact
28
+ schema per Annex G — primary population (per interfaced item:
29
+ visibility/instantiability rules + generated function), secondary
30
+ population, name munging (clash policy), prune pass (rules whose
31
+ parameters are not all visible; unreachable subtype branches),
32
+ total_over → rules, then the 1994-construct rewrite.
33
+ 2. Writer: reuse the formatter with a "flat/1994" encoder profile
34
+ (no interfaces section; artifact rules emitted per Annex G).
35
+ 3. Validation gates:
36
+ - Annex G rule fixtures from 01 (each rule exercised).
37
+ - Differential: flatten output vs eeng `.flat` over the 03 golden
38
+ corpus; divergences classified standard-vs-eeng.
39
+ - Output parses as 1994 (no edition-2-only constructs — the
40
+ grammar-level edition profile check).
41
+ 4. SMRL-scale run: all 132 SRL resources + module arm/mim set; memory
42
+ via the compiled-set warm model.
43
+
44
+ ## Acceptance
45
+
46
+ - All Annex G fixtures green; SMRL corpus flatten completes with zero
47
+ unexplained diffs vs the 1994 profile.
48
+ - `expressir shtolo <manifest> -o longform.exp` ships.
49
+
50
+ ## Tests
51
+
52
+ bug39's shtolo old-vs-new outputs (see 11) are an additional
53
+ differential: eeng shtolo vs stepcode exppp vs us.
@@ -0,0 +1,47 @@
1
+ # 06 — Interface loading/resolution parity with eeng scheduling
2
+
3
+ **Status: SHIPPED (2026-09-21) — the resolution-side fix.**
4
+ `Schema#interfaced_items` is now repository-aware (foreign schemas
5
+ found through the parent chain into the enclosing repository) and
6
+ transitively USE-aware (items USEd by the foreign schema are visible,
7
+ unfiltered per the implicit-interfacing rule, cycle-guarded by a
8
+ visited-schema set). Probe results before/after: direct cross-file
9
+ item ref resolved; transitive-USE item resolved; interface cycle
10
+ terminates. Spec: `interface_visibility_spec.rb` (3 examples);
11
+ express suite 321/0. Remaining: unresolved-resource diagnostics and
12
+ USE-vs-REFERENCE error severity (eeng hard-errors; we warn) — folded
13
+ into 07's checker.
14
+
15
+ ## Goal
16
+
17
+ Match eeng's multi-schema load semantics: which declarations are
18
+ visible where, transitive USE FROM (implicit interfacing), rename
19
+ (AS) handling, and error cases ("Resource '~A' not found").
20
+
21
+ ## Differences already known
22
+
23
+ - eeng `resolve-interface.lisp`: USE FROM resolves **only**
24
+ entity+type; REFERENCE FROM resolves constant/entity/function/
25
+ procedure/type; unresolved resource = hard error. Our resolver
26
+ stamps base_path but never errors on unresolved interfaces.
27
+ - eeng runs interface **scheduling** (schedule-interfaces.lisp) so a
28
+ USE FROM can pull schemas already loaded in the session
29
+ (schemata/schemata1/schemata2) — closest to our repository + graph.
30
+ - Implicit interfacing (11-interface_specification.adoc): items
31
+ visible through USE FROM chains; our `interfaced_items` is
32
+ single-hop — verify transitive semantics.
33
+
34
+ ## Steps
35
+
36
+ 1. From 02's matrix, list each semantic difference with a fixture
37
+ (rename chains, transitively used items, interface cycles,
38
+ missing resource).
39
+ 2. Fix expressir resolution where we are wrong (spec wins), or
40
+ document deliberate divergence.
41
+ 3. Add unresolved-interface reporting (warning set) — SHTOLO's prune
42
+ stage consumes it.
43
+
44
+ ## Acceptance
45
+
46
+ Fixture suite covering rename/transitive/cycle/missing passes on both
47
+ paths (Ruby parser + core path byte-parity preserved).
@@ -0,0 +1,35 @@
1
+ # 07 — Port eeng semantic checks (kernel/check.lisp)
2
+
3
+ **Status: NOT STARTED**
4
+
5
+ ## Goal
6
+
7
+ A `check` operation in expressir that walks a schema/repository and
8
+ reports the same diagnostics eeng's check-p11 passes produce — the
9
+ validation half of the SHTOLO mission (inputs must be sound before
10
+ flattening).
11
+
12
+ ## Source catalog (check.lisp, 835 lines)
13
+
14
+ Per-node `check-p11` methods: schema, use-from/reference-from,
15
+ constant, local, entity (explicit/derive/inverse attributes),
16
+ function/procedure/rule parameters, subtype_constraint, type, plus
17
+ expression/statement checks. Also `check-notes.lisp` (note
18
+ collection) and `compare.lisp` (schema comparison — two loaded
19
+ sessions).
20
+
21
+ ## Design
22
+
23
+ - `Expressir::Express::Checker` modeled on our visitor infra; each
24
+ eeng check becomes one rule with the eeng note id preserved for
25
+ cross-referencing oracle output.
26
+ - Wire into `Repository#validate` (RepositoryValidator today is
27
+ interface-level only).
28
+ - Run order: checks → report (eeng note ids + our explanation) →
29
+ nonzero exit on error-class notes (eeng error severity model).
30
+
31
+ ## Acceptance
32
+
33
+ Golden-diff check reports vs eeng for the 03 corpus subset; any
34
+ divergent verdict justified against Part 11 clause text
35
+ (`~/src/mn/iso-10303-11/sources/sections/`).
@@ -0,0 +1,27 @@
1
+ # 08 — Pretty-printer parity gate (eeng wo-pretty)
2
+
3
+ **Status: NOT STARTED**
4
+
5
+ ## Goal
6
+
7
+ qualify.sh's core self-check, adopted for us: `.exp` → pretty `.exp`
8
+ → re-parse → identical model; plus diff vs eeng's `-pretty.exp` over
9
+ the golden corpus so SHTOLO outputs (04/05) can target eeng-stable
10
+ formatting.
11
+
12
+ ## Steps
13
+
14
+ 1. Read `plugins/p11/wo-pretty.lisp` encoder (spacing, casing,
15
+ remark policy, schema ordering) → document deltas vs our
16
+ `Formatter` (clean mode).
17
+ 2. Add `parser → formatter → parser` identity spec across the SMRL
18
+ corpus (model-level to_hash equality, not bytes, first; byte mode
19
+ only where eeng parity is wanted).
20
+ 3. Byte-diff our pretty vs eeng pretty on the 03 corpus; decide
21
+ adopt-eeng-format vs keep-ours (default: keep ours for rendering,
22
+ eeng profile as an encoder option for SHTOLO artifacts).
23
+
24
+ ## Acceptance
25
+
26
+ Corpus-wide round-trip identity green; eeng-profile diffs either zero
27
+ or explained line-by-line.
@@ -0,0 +1,22 @@
1
+ # 09 — SMRL index XML + declaration listing (wo-list, wo-smrl-xml)
2
+
3
+ **Status: NOT STARTED**
4
+
5
+ ## Goal
6
+
7
+ The SRL publication byproducts eeng generates: declaration listings
8
+ (`-list.txt`) and the SMRL index XML for longform/concatenated files
9
+ (`<concatenated_express_file_content_list>`), emitted from the same
10
+ model that powers 04/05.
11
+
12
+ ## Sources
13
+
14
+ `plugins/p11/wo-list.lisp`, `wo-smrl-xml.lisp` (element names:
15
+ concatenated_express_file_content_list, per-schema content entries),
16
+ top-level.lisp:748-793 (when the index is generated: XML output +
17
+ longform/concatenated modes).
18
+
19
+ ## Acceptance
20
+
21
+ Index/list output for the 03 golden set structurally identical
22
+ (element-for-element) to eeng's; wired into the same CLI as 04.