Class: IgniterLang::OOFFragmentRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/igniter_lang/oof_fragment_registry.rb

Constant Summary collapse

FORMAT_VERSION =
"0.1.0".freeze
REQUIRED_EXCLUDED_PREFIXES =

Namespace prefixes that must be present in excluded_namespaces.

%w[
  compiler_profile_contract.
  compiler_profile_contract_refusal.
].freeze
SUPPORT_MARKER_PATTERN =

Support marker code pattern: only PINV-* and TINV-* are support markers.

/\A(PINV|TINV)-/.freeze
GUARDED_NON_FRAGMENT_NAMES =

Fragment row names that are guarded non-fragments (must have classification_kind “not_fragment_class”).

%w[olap progression].freeze
OOF_ROW_NAME =

The special “oof” fragment row that must be non-loadable and capability-free.

"oof".freeze
SUPPORT_MARKER_STABILITY_VALUES =

Acceptable public_code_stability values for support markers (non-public).

%w[non_public_support_marker proof_only].freeze
SOURCE_ACCEPTED_MODES =

Accepted source modes for validate_source_envelope.

%w[
  proof_fixture
  caller_supplied
  profile_candidate
  pack_descriptor_candidate
].freeze
SOURCE_HELD_MODES =

Held modes: recognized but not yet authorized for helper processing.

[].freeze
SOURCE_ACCEPTED_AUTHORITY_KINDS =

Accepted authority kinds for source envelope.

%w[proof_only design_accepted].freeze
SOURCE_ACCEPTED_CANON_STATUSES =

Accepted (non-canon) canon_status values.

%w[non_canon accepted_design].freeze
SOURCE_DIAG_WRONG_KIND =

Source-envelope helper diagnostic codes. These are internal helper diagnostics. They are NOT language OOF codes and are NOT central IgniterLang::Diagnostics entries.

"oof_registry.source.validation.wrong_kind".freeze
SOURCE_DIAG_UNSUPPORTED_FORMAT_VERSION =
"oof_registry.source.validation.unsupported_format_version".freeze
SOURCE_DIAG_UNSUPPORTED_SOURCE_MODE =
"oof_registry.source.validation.unsupported_source_mode".freeze
SOURCE_DIAG_HELD_SOURCE_MODE =
"oof_registry.source.validation.held_source_mode".freeze
SOURCE_DIAG_INVALID_AUTHORITY_KIND =
"oof_registry.source.validation.invalid_authority_kind".freeze
SOURCE_DIAG_CANON_STATUS_FORBIDDEN =
"oof_registry.source.validation.canon_status_forbidden".freeze
SOURCE_DIAG_MISSING_AUTHORITY =
"oof_registry.source.validation.missing_authority".freeze
SOURCE_DIAG_MISSING_AUTHORITY_REF =
"oof_registry.source.validation.missing_authority_ref".freeze
SOURCE_DIAG_MISSING_REGISTRY =
"oof_registry.source.validation.missing_registry".freeze
SOURCE_DIAG_SURFACE_OPEN =
"oof_registry.source.validation.surface_open".freeze
SOURCE_DIAG_MISSING_PACK_REF =
"oof_registry.source.validation.missing_pack_ref".freeze
SOURCE_DIAG_MISSING_PROFILE_REF =
"oof_registry.source.validation.missing_profile_ref".freeze
SOURCE_DIAG_MISSING_SELECTED_PACK_REF =
"oof_registry.source.validation.missing_selected_pack_ref".freeze
SOURCE_DIAG_MISSING_PACK_DESCRIPTOR =
"oof_registry.source.validation.missing_pack_descriptor".freeze
SOURCE_DIAG_ROW_OWNER_MISMATCH =
"oof_registry.source.validation.row_owner_mismatch".freeze
SOURCE_DIAG_DUPLICATE_ROW_OWNERSHIP =
"oof_registry.source.validation.duplicate_row_ownership".freeze
SOURCE_DIAG_DUPLICATE_ALIAS_OWNERSHIP =
"oof_registry.source.validation.duplicate_alias_ownership".freeze
SOURCE_DIAG_EXCLUDED_NAMESPACE_CLAIM =
"oof_registry.source.validation.excluded_namespace_claim".freeze
SOURCE_DIAG_PROFILE_OVERRIDE_FORBIDDEN =
"oof_registry.source.validation.profile_override_forbidden".freeze
SOURCE_DIAG_INVALID_CONFLICT_POLICY =
"oof_registry.source.validation.invalid_conflict_policy".freeze
SOURCE_DIAG_INVALID_PACK_ORDER =
"oof_registry.source.validation.invalid_pack_order".freeze
DIAG_MISSING_SECTION =

Internal validator diagnostic codes. These are NOT public language OOF codes and are NOT central IgniterLang::Diagnostics entries.

"oof_registry.validation.missing_section".freeze
DIAG_WRONG_KIND =
"oof_registry.validation.wrong_kind".freeze
DIAG_DUPLICATE_CODE =
"oof_registry.validation.duplicate_code".freeze
DIAG_ALIAS_COLLISION =
"oof_registry.validation.alias_collision".freeze
DIAG_ALIAS_MISSING_REPLACEMENT =
"oof_registry.validation.alias_missing_replacement".freeze
DIAG_EXCLUDED_NAMESPACE_COLLISION =
"oof_registry.validation.excluded_namespace_collision".freeze
DIAG_SUPPORT_MARKER_IN_DESCRIPTORS =
"oof_registry.validation.support_marker_in_oof_descriptors".freeze
DIAG_SUPPORT_MARKER_PUBLIC =
"oof_registry.validation.support_marker_public".freeze
DIAG_SUPPORT_MARKER_EMITTED =
"oof_registry.validation.support_marker_emitted".freeze
DIAG_SUPPORT_MARKER_CODE_COLLISION =
"oof_registry.validation.support_marker_code_collision".freeze
DIAG_OOF_PROJECTION_LOADABLE =
"oof_registry.validation.oof_projection_loadable".freeze
DIAG_OOF_PROJECTION_CAPABILITY =
"oof_registry.validation.oof_projection_capability".freeze
DIAG_GUARDED_NON_FRAGMENT =
"oof_registry.validation.guarded_non_fragment_violation".freeze
DIAG_OWNER_BOUNDARY_ABSENT =
"oof_registry.validation.owner_boundary_absent".freeze

Instance Method Summary collapse

Instance Method Details

#validate(registry, installed_boundaries: nil) ⇒ Hash

Validate a registry hash against the R101 forward bucket shape.

Parameters:

  • registry (Hash)

    The registry object to validate (caller-supplied).

  • installed_boundaries (Array<String>, nil) (defaults to: nil)

    When supplied, rows owned by a boundary not in this list are recorded as inactive rows. Inactive rows are NOT silently skipped — they are recorded in the result. Inactive rows do not flip valid: false. When nil, boundary-absence checks are skipped.

Returns:

  • (Hash)

    Internal validation result. NEVER touches compiler state, reports, or public surfaces.



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/igniter_lang/oof_fragment_registry.rb', line 129

def validate(registry, installed_boundaries: nil)
  diags        = []
  inactive_rows = []

  # Step 1 — top-level shape
  shape_diags = check_top_level_shape(registry)
  diags.concat(shape_diags)
  return build_result(false, diags, inactive_rows) unless shape_diags.empty?

  oof_descriptors     = Array(registry["oof_descriptors"])
  fragment_rows       = Array(registry["fragment_rows"])
  support_markers_arr = Array(registry.dig("support_markers", "invariant_support_markers"))
  excluded_namespaces = Array(registry["excluded_namespaces"])
  excluded_prefixes   = excluded_namespaces.map { |n| n["prefix"] }.compact

  # Pre-collect all canonical OOF codes + aliases for cross-collision detection
  all_oof_canonical = oof_descriptors.map { |d| d["code"] }.compact.to_set
  all_oof_aliases   = oof_descriptors.flat_map { |d| Array(d["aliases"]) }.to_set
  all_oof_code_set  = all_oof_canonical | all_oof_aliases

  # Step 2 — OOF descriptors
  diags.concat(check_oof_descriptors(oof_descriptors, excluded_prefixes, all_oof_canonical))

  # Step 3 — fragment rows
  diags.concat(check_fragment_rows(fragment_rows))

  # Step 4 — support markers
  diags.concat(check_support_markers(support_markers_arr, all_oof_code_set))

  # Step 5 — excluded namespaces
  diags.concat(check_excluded_namespaces(excluded_namespaces))

  # Step 6 — absent-owner inactive rows (recorded, not silently skipped)
  if installed_boundaries
    boundaries_set = installed_boundaries.to_set
    candidates = [
      *oof_descriptors.map   { |row| ["oof_descriptor",  row["code"] || row["name"],  row] },
      *fragment_rows.map     { |row| ["fragment_row",    row["name"],                  row] },
      *support_markers_arr.map { |row| ["support_marker", row["code"] || row["name"],  row] }
    ]
    candidates.each do |section_kind, row_id, row|
      owner = row["owner_pack_or_boundary"]
      next unless owner
      next if boundaries_set.include?(owner)

      inactive_rows << {
        "section"    => section_kind,
        "row_id"     => row_id,
        "owner"      => owner,
        "reason"     => "owner_pack_or_boundary_absent_from_installed_boundaries"
      }
    end
  end

  build_result(diags.empty?, diags, inactive_rows)
end

#validate_source_envelope(source_envelope, installed_boundaries: nil) ⇒ Hash

Validate a source envelope and, if valid, validate its nested registry.

This is an internal helper only. It is NOT a public API, NOT a loader, NOT a compiler pass, and NOT a report surface. It is callable only from proof-local harnesses via direct require of this file.

Authorized by: LANG-R110-A Design: oof-fragment-registry-source-envelope-helper-boundary-design-v0 (LANG-R109-D1)

Parameters:

  • source_envelope (Hash)

    A source envelope describing where the registry hash comes from. Must have kind, format_version, source_mode, authority, registry.

  • installed_boundaries (Array<String>, nil) (defaults to: nil)

    Forwarded to the nested registry validate call when source envelope passes.

Returns:

  • (Hash)

    Internal source-envelope validation result.

    • valid: true only when source-envelope validation AND nested registry validation pass.

    • source_mode: the source_mode from the envelope (or nil if envelope is malformed).

    • registry_present: whether the envelope contained a registry hash.

    • source_diagnostics: internal source-envelope diagnostics only.

    • registry_validation: the nested registry validation result, or nil if source invalid.

    • closed_surface_assertions: all false (machine-assertable).

    NEVER touches compiler state, reports, or public surfaces.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/igniter_lang/oof_fragment_registry.rb', line 208

def validate_source_envelope(source_envelope, installed_boundaries: nil)
  source_diags = []

  # Step 1 — envelope must be a Hash with correct kind
  unless source_envelope.is_a?(Hash)
    source_diags << source_diag(SOURCE_DIAG_WRONG_KIND,
      "source envelope must be a Hash, got #{source_envelope.class}")
    return build_source_result(false, nil, false, source_diags, nil)
  end

  if source_envelope["kind"] != "oof_fragment_registry_source"
    source_diags << source_diag(SOURCE_DIAG_WRONG_KIND,
      "source envelope kind must be 'oof_fragment_registry_source', " \
      "got #{source_envelope["kind"].inspect}")
  end

  # Step 2 — format version
  unless source_envelope["format_version"] == "0.1.0"
    source_diags << source_diag(SOURCE_DIAG_UNSUPPORTED_FORMAT_VERSION,
      "source envelope format_version must be '0.1.0', " \
      "got #{source_envelope["format_version"].inspect}")
  end

  # Step 3 — source mode
  source_mode = source_envelope["source_mode"]
  if SOURCE_HELD_MODES.include?(source_mode)
    source_diags << source_diag(SOURCE_DIAG_HELD_SOURCE_MODE,
      "source_mode #{source_mode.inspect} is known but held; " \
      "only 'proof_fixture' and 'caller_supplied' are accepted in this helper")
  elsif !SOURCE_ACCEPTED_MODES.include?(source_mode)
    source_diags << source_diag(SOURCE_DIAG_UNSUPPORTED_SOURCE_MODE,
      "source_mode #{source_mode.inspect} is not supported; " \
      "accepted: proof_fixture, caller_supplied")
  end

  # Step 4 — authority object
  authority = source_envelope["authority"]
  if authority.is_a?(Hash)
    # authority_ref must be present
    if authority["authority_ref"].to_s.strip.empty?
      source_diags << source_diag(SOURCE_DIAG_MISSING_AUTHORITY_REF,
        "authority.authority_ref is required and must be non-empty")
    end

    # authority_kind must be within proof/design scope
    authority_kind = authority["authority_kind"]
    unless SOURCE_ACCEPTED_AUTHORITY_KINDS.include?(authority_kind)
      source_diags << source_diag(SOURCE_DIAG_INVALID_AUTHORITY_KIND,
        "authority.authority_kind #{authority_kind.inspect} is outside proof/design scope; " \
        "accepted: proof_only, design_accepted")
    end

    # canon_status must not be canon
    canon_status = authority["canon_status"]
    if canon_status == "canon"
      source_diags << source_diag(SOURCE_DIAG_CANON_STATUS_FORBIDDEN,
        "canon-status source envelopes are forbidden in this helper; " \
        "authority.canon_status must not be 'canon'")
    elsif !SOURCE_ACCEPTED_CANON_STATUSES.include?(canon_status)
      source_diags << source_diag(SOURCE_DIAG_CANON_STATUS_FORBIDDEN,
        "authority.canon_status #{canon_status.inspect} is not an accepted non-canon status; " \
        "accepted: non_canon, accepted_design")
    end
  else
    source_diags << source_diag(SOURCE_DIAG_MISSING_AUTHORITY,
      "source envelope authority object is missing or not a Hash")
  end

  # Step 5 — nested registry must be present for direct registry sources.
  registry_present = source_envelope["registry"].is_a?(Hash)
  direct_registry_source = %w[proof_fixture caller_supplied].include?(source_mode)
  if direct_registry_source && !registry_present
    source_diags << source_diag(SOURCE_DIAG_MISSING_REGISTRY,
      "source envelope must contain a 'registry' Hash; nested registry is missing or invalid")
  end

  # Step 6 — closed-surface assertions must all be false
  envelope_assertions = source_envelope.fetch("closed_surface_assertions", nil)
  if envelope_assertions.is_a?(Hash) && !envelope_assertions.values.all?(false)
    open_keys = envelope_assertions.select { |_k, v| v }.keys
    source_diags << source_diag(SOURCE_DIAG_SURFACE_OPEN,
      "source envelope closed_surface_assertions must all be false; " \
      "open assertions: #{open_keys.inspect}")
  end

  # If source envelope has any diagnostics, do NOT call nested registry validator.
  if source_diags.any?
    return build_source_result(false, source_mode, registry_present, source_diags, nil,
      source_authority_summary(source_envelope))
  end

  case source_mode
  when "profile_candidate"
    return validate_profile_candidate_source(source_envelope, installed_boundaries: installed_boundaries)
  when "pack_descriptor_candidate"
    return validate_pack_descriptor_candidate_source(source_envelope,
      installed_boundaries: installed_boundaries)
  end

  # Source envelope passed — call existing nested registry validator.
  registry_result = validate(source_envelope["registry"], installed_boundaries: installed_boundaries)
  source_valid = registry_result.fetch("valid")

  build_source_result(source_valid, source_mode, true, [], registry_result,
    source_authority_summary(source_envelope))
end