Skip to content

Latest commit

 

History

History
13 lines (11 loc) · 7.05 KB

module-organization.md

File metadata and controls

13 lines (11 loc) · 7.05 KB

module-organization — notes

Hand-written. ../harvested/module-organization.md is what the documents say; this file is what the implementation found, and it wins. Each entry names the harvested entry it answers by that entry's stable key.

Conflicts

  • Autoloading: the design wins — lib/dexpace.rb issues explicit requires and no gem in this repository loads Zeitwerk. Resolves module-organization/bf6411ad. This is a library-versus-application distinction rather than a preference: Zeitwerk is itself a gem, so require "zeitwerk" in dexpace-core is an add_dependency line, and dexpace-core.gemspec is asserted to have zero runtime dependencies (SEAM-1, NFR-1). An application can afford the autoloader; a zero-dependency core cannot. What the SDK does instead: lib/dexpace.rb requires the whole tree explicitly, which also turns the require-graph audit into a text scan rather than a runtime trace; adapter gems follow the same rule for consistency even though NFR-2's one-third-party-library budget would technically permit them an autoloader. Everything else the styleguide chapter asks for is kept unchanged — the file-path-to-constant mapping, one constant per file, nested module/class form, no load-time side effects, no top-level constants outside Dexpace:: — so the convention Zeitwerk would have enforced is enforced by review and by the runtime surface snapshot instead. The styleguide-amendment alternative (carving out gems whose dependency budget forbids an autoloader) was considered and not taken; this is recorded as an SDK deviation instead. review · docs/work/mvp/2026-09-05-ruby-sdk-v1-roadmap-design.md · high · sha:manual-roadmap-conflict-2
  • File paths under lib/dexpace/http/ and lib/dexpace/error/ organise files; they are not namespace segments, and the public wire model's constants are flat. Resolves module-organization/3ff5433e. Two binding documents disagree and the rule has to break one of them: docs/sdk-design-ruby/02-gem-and-workspace-layout.md §2.3 puts the domain model under lib/dexpace/{http,...,error}/**.rb, while §3.2, §3.7 and §5 of the same design name the constants Dexpace::Response, Dexpace::RequestOptions, Dexpace::TransportError and Dexpace::PipelineError — no HTTP:: or Error:: segment — and every later phase is written against those names. The constant wins, and the styleguide's own chapter asks for exactly that: module-organization/7d1041eb says to re-export the public contract from the gem's top-level namespace (Commerce::Order rather than Commerce::Checkout::Order). This port satisfies it by defining the constant there rather than by aliasing, because an alias would put two names for one class into both artifacts NFR-4 diffs — the sig/**/*.rbs tree and the runtime surface manifest. What the SDK does instead: Dexpace::Request lives in lib/dexpace/http/request.rb and Dexpace::InvalidArgumentError in lib/dexpace/error/invalid_argument_error.rb; a nested public constant still maps exactly (Dexpace::Headers::Builder is lib/dexpace/http/headers/builder.rb); and a subsystem whose design already names it with a namespace keeps it, so Dexpace::IO::Buffer, Dexpace::Serde::JSON, Dexpace::Instrumentation::Bundle and Dexpace::Outcome::Success are unaffected. Everything else chapter 12 asks for is kept: one public constant per file, nested module/class form, no load-time side effects, nothing defined outside Dexpace::. The rule's stated motivation is Zeitwerk, which ../notes/module-organization.md already records this port as not using — lib/dexpace.rb requires every file explicitly, so nothing mechanical depends on the mapping and the convention it protected is protected instead by the runtime surface snapshot. The styleguide-amendment alternative (scoping rule 12.2's filename clause to autoloaded projects) was considered and not taken; this is recorded as an SDK deviation instead (phase 1, P1-1). review · docs/work/mvp/phase1/2026-09-05-phase1-core-http-domain-model-design.md · high · sha:manual-phase1-flat-constants
  • Require-time seam self-registration is the discovery substrate, and it is the one load-time side effect this repository permits. Resolves module-organization/c84bf75e. The styleguide rule forbids a require from doing anything but define — no network call, no database query, no puts, and specifically no "global registry mutation" — and docs/sdk-design-ruby/03-seam-by-seam-idiomatic-mapping.md §3.6 contradicts it head-on: Ruby has no classpath to scan, so SEAM-5's "the runtime auto-discovers providers registered on the plugin registry" is implemented by an adapter registering itself as a side effect of being required — Dexpace::Transport.register(:net_http, klass, core: "~> 0.0") called from lib/dexpace/transport/net_http.rb — and "discoverable" means "the application has required this adapter, directly or through a Bundler group". The design wins, and the reason it is safe is that the rule's four named hazards are absent while its purpose is preserved: the mutation is of an in-process Hash this gem owns, not of a shared external system; it performs no I/O, opens no connection and prints nothing; it is idempotent, because re-registering the equal? factory under the same key is a no-op, so a double require is quiet; and it cannot fail an unrelated require, because a different factory under an occupied key and a version-skewed adapter both raise at that adapter's own require, naming both sides, which is docs/sdk-design-ruby/02-gem-and-workspace-layout.md §2.3's version-skew guard doing exactly what the styleguide's "expose an explicit Commerce.configure { } block instead" is trying to buy — a loud, attributable failure rather than a mystery at first use. What the SDK does instead of a blanket ban: core itself keeps the rule unweakened — lib/dexpace.rb and every file it requires define constants and nothing else, and dexpace-core's own require mutates no registry, because the three registries ship empty and core never auto-requires an optional gem (which is what keeps SEAM-1 true); the permitted side effect belongs to adapter gems only, and only into a registry core owns. The explicit-configuration path the rule asks for also exists and outranks discovery: Dexpace::Transport.install(instance) is SEAM-5's "an explicitly installed provider always wins", so an application that wants no discovery at all never has to rely on it. Everything else chapter 12 asks for is kept: one public constant per file, nested module/class form, no top-level constants outside Dexpace::, and the explicit requires of ../notes/module-organization.md's first entry. The styleguide-amendment alternative (scoping rule 12.4's registry clause to registries the process does not own) was considered and not taken; this is recorded as an SDK deviation instead (phase 2, and design §10 item 8 already carries the substitution). review · docs/work/mvp/phase2/2026-09-06-phase2-seam-foundations-design.md · high · sha:manual-phase2-require-time-registration