PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
 
Loading...
Searching...
No Matches
Functions | Variables
audit_subsystem_lifecycle Namespace Reference

Functions

dict page_index ()
 Every documentation page id with the anchors it defines.
 
tuple required_obligations (dict record)
 The obligation ids a record owes.
 
list check_satisfaction (str context, str key, spec, dict pages, set published, bool public)
 Verify one obligation or concern is genuinely answered.
 
list validate (list records, dict pages, dict families, set published)
 Validate every subsystem record against the lifecycle contract.
 
list validate_value_ownership (list records, dict families)
 Check that every capability value has an owning subsystem it does not outrank.
 
int main ()
 Report subsystem lifecycle violations.
 

Variables

 REPO_ROOT = Path(__file__).resolve().parents[2]
 
str RECORDS = REPO_ROOT / "tests" / "tooling" / "subsystem_records.json"
 
str PAGE_TYPES = REPO_ROOT / "tests" / "tooling" / "page_types.json"
 
str FAMILIES = REPO_ROOT / "tests" / "tooling" / "capability_families.json"
 
tuple PAGE_DIRS = ("docs/pages", "docs")
 
tuple LADDER = ("planned", "internal", "experimental", "supported")
 
dict LADDER_OBLIGATIONS
 
dict TERMINAL_OBLIGATIONS
 
tuple NON_INHERITED = ("not_implemented_status",)
 
tuple NEEDS_PEAK = ("known-defective", "deprecated", "removed")
 
tuple INHERITS_LADDER = ("known-defective", "deprecated")
 
 VALID_STATUSES = tuple(LADDER) + tuple(TERMINAL_OBLIGATIONS)
 
dict TRANSITIONS
 
dict DEMOTIONS = {("supported", "experimental"), ("known-defective", "planned")}
 
tuple VALID_VISIBILITY = ("internal", "public")
 
tuple VALID_CONCERNS
 
dict RECORD_KEYS
 
int MIN_REASON_CHARS = 30
 
dict FILLER_REASONS = {"n/a", "na", "none", "not applicable", "no", "-", "tbd"}
 

Detailed Description

Enforce the documentation obligations each subsystem lifecycle status carries.

Function Documentation

◆ page_index()

dict audit_subsystem_lifecycle.page_index ( )

Every documentation page id with the anchors it defines.

Returns
Mapping of page id to the set of @section, @subsection, and @anchor names.

Definition at line 104 of file audit_subsystem_lifecycle.py.

104def page_index() -> dict:
105 """!
106 @brief Every documentation page id with the anchors it defines.
107 @return Mapping of page id to the set of `@section`, `@subsection`, and `@anchor` names.
108 """
109 index: dict = {}
110 for directory in PAGE_DIRS:
111 for markdown in sorted((REPO_ROOT / directory).glob("*.md")):
112 text = markdown.read_text(encoding="utf-8")
113 match = re.search(r"^@page\s+(\S+)", text, re.M)
114 if not match or match.group(1).startswith("<"):
115 continue
116 anchors = set(re.findall(r"^@(?:section|subsection|subsubsection|anchor)\s+(\S+)",
117 text, re.M))
118 index[match.group(1)] = anchors
119 return index
120
121
Here is the caller graph for this function:

◆ required_obligations()

tuple audit_subsystem_lifecycle.required_obligations ( dict  record)

The obligation ids a record owes.

A record may declare a proposed_status above its claimed one. That is how a subsystem documented to a higher bar waits for the owner to decide whether it has actually earned it: obligations are checked against the proposal, so the writing is held to the higher standard, while the status the documentation publishes stays conservative until a human agrees.

Parameters
[in]recordOne subsystem record.
Returns
Ordered tuple of obligation ids.

Definition at line 122 of file audit_subsystem_lifecycle.py.

122def required_obligations(record: dict) -> tuple:
123 """!
124 @brief The obligation ids a record owes.
125
126 @details A record may declare a `proposed_status` above its claimed one. That is
127 how a subsystem documented to a higher bar waits for the owner to decide
128 whether it has actually earned it: obligations are checked against the
129 proposal, so the writing is held to the higher standard, while the status
130 the documentation publishes stays conservative until a human agrees.
131 @param[in] record One subsystem record.
132 @return Ordered tuple of obligation ids.
133 """
134 status = record.get("proposed_status") or record.get("status")
135 owed: list = []
136 if status in LADDER:
137 for rung in LADDER[: LADDER.index(status) + 1]:
138 owed.extend(LADDER_OBLIGATIONS[rung])
139 else:
140 if status in INHERITS_LADDER:
141 peak = record.get("peak_status")
142 if peak in LADDER:
143 for rung in LADDER[: LADDER.index(peak) + 1]:
144 owed.extend(LADDER_OBLIGATIONS[rung])
145 owed.extend(TERMINAL_OBLIGATIONS.get(status, ()))
146 if status != "planned":
147 owed = [key for key in owed if key not in NON_INHERITED]
148 # A status may re-owe something a lower rung already required; keep it once.
149 return tuple(dict.fromkeys(owed))
150
151
Here is the caller graph for this function:

◆ check_satisfaction()

list audit_subsystem_lifecycle.check_satisfaction ( str  context,
str  key,
  spec,
dict  pages,
set  published,
bool  public 
)

Verify one obligation or concern is genuinely answered.

An answer is a documentation reference that resolves, or a stated reason for non-applicability, or a literal value where the obligation is a fact rather than prose. An empty or filler answer is a violation.

Parameters
[in]contextRecord id, for messages.
[in]keyObligation or concern id.
[in]specThe declared answer.
[in]pagesPage index from page_index().
[in]publishedIds of the pages the site publishes.
[in]publicWhether the subsystem is publicly visible.
Returns
List of violation strings.

Definition at line 152 of file audit_subsystem_lifecycle.py.

153 public: bool) -> list:
154 """!
155 @brief Verify one obligation or concern is genuinely answered.
156
157 @details An answer is a documentation reference that resolves, or a stated reason
158 for non-applicability, or a literal value where the obligation is a fact
159 rather than prose. An empty or filler answer is a violation.
160 @param[in] context Record id, for messages.
161 @param[in] key Obligation or concern id.
162 @param[in] spec The declared answer.
163 @param[in] pages Page index from page_index().
164 @param[in] published Ids of the pages the site publishes.
165 @param[in] public Whether the subsystem is publicly visible.
166 @return List of violation strings.
167 """
168 if not isinstance(spec, dict):
169 return [f"{context}: '{key}' must be an object, got {type(spec).__name__}"]
170 problems = []
171 if "not_applicable" in spec:
172 reason = str(spec["not_applicable"]).strip()
173 if reason.lower().rstrip(".") in FILLER_REASONS or len(reason) < MIN_REASON_CHARS:
174 problems.append(
175 f"{context}: '{key}' is declared not applicable without a stated reason "
176 f"({reason!r}). A reasoned N/A is accepted; a bare one is not"
177 )
178 return problems
179 if "value" in spec:
180 if not str(spec["value"]).strip():
181 problems.append(f"{context}: '{key}' declares an empty value")
182 return problems
183 page = spec.get("page")
184 if not page:
185 problems.append(
186 f"{context}: '{key}' is unsatisfied - give it a page reference, a value, or a "
187 f"reasoned not_applicable"
188 )
189 return problems
190 if page not in pages:
191 problems.append(f"{context}: '{key}' cites page '{page}', which does not exist")
192 return problems
193 anchor = spec.get("anchor")
194 if anchor and anchor not in pages[page]:
195 problems.append(
196 f"{context}: '{key}' cites anchor '{anchor}' on page '{page}', which does not "
197 f"define it"
198 )
199 if public and page not in published:
200 problems.append(
201 f"{context}: '{key}' cites '{page}', which is not a published page, but the "
202 f"subsystem is publicly visible"
203 )
204 return problems
205
206
Here is the caller graph for this function:

◆ validate()

list audit_subsystem_lifecycle.validate ( list  records,
dict  pages,
dict  families,
set  published 
)

Validate every subsystem record against the lifecycle contract.

Parameters
[in]recordsSubsystem records.
[in]pagesPage index from page_index().
[in]familiesCapability family metadata, keyed by family id.
[in]publishedIds of the pages the site publishes.
Returns
List of violation strings; empty means the contract holds.

Definition at line 207 of file audit_subsystem_lifecycle.py.

207def validate(records: list, pages: dict, families: dict, published: set) -> list:
208 """!
209 @brief Validate every subsystem record against the lifecycle contract.
210 @param[in] records Subsystem records.
211 @param[in] pages Page index from page_index().
212 @param[in] families Capability family metadata, keyed by family id.
213 @param[in] published Ids of the pages the site publishes.
214 @return List of violation strings; empty means the contract holds.
215 """
216 problems: list = []
217 seen: set = set()
218 for record in records:
219 identifier = record.get("id")
220 if not identifier:
221 problems.append("a record declares no id")
222 continue
223 if identifier in seen:
224 problems.append(f"{identifier}: declared more than once")
225 seen.add(identifier)
226
227 unknown = set(record) - RECORD_KEYS
228 if unknown:
229 problems.append(f"{identifier}: unknown field(s) {sorted(unknown)}")
230
231 status = record.get("status")
232 if status not in VALID_STATUSES:
233 problems.append(
234 f"{identifier}: status {status!r} is not one of {list(VALID_STATUSES)}"
235 )
236 continue
237
238 visibility = record.get("visibility")
239 if visibility not in VALID_VISIBILITY:
240 problems.append(
241 f"{identifier}: visibility {visibility!r} is not one of "
242 f"{list(VALID_VISIBILITY)}"
243 )
244 continue
245 if status == "internal" and visibility != "internal":
246 problems.append(
247 f"{identifier}: status 'internal' contradicts visibility 'public'; a "
248 f"subsystem the user can reach is at least experimental"
249 )
250
251 previous = record.get("previous_status", None)
252 if previous is not None and previous not in VALID_STATUSES:
253 problems.append(f"{identifier}: previous_status {previous!r} is not a valid status")
254 elif status not in TRANSITIONS[previous]:
255 problems.append(
256 f"{identifier}: {previous or 'a new record'} -> '{status}' is not a valid "
257 f"lifecycle transition (allowed: {sorted(TRANSITIONS[previous])})"
258 )
259
260 reason = record.get("demotion_reason")
261 if (previous, status) in DEMOTIONS:
262 text = (reason or "").strip()
263 if text.lower().rstrip(".") in FILLER_REASONS or len(text) < MIN_REASON_CHARS:
264 problems.append(
265 f"{identifier}: {previous} -> '{status}' is a demotion and needs a "
266 f"demotion_reason saying what the earlier claim did not establish"
267 )
268 elif reason is not None:
269 problems.append(
270 f"{identifier}: demotion_reason applies only to a demotion "
271 f"({sorted(DEMOTIONS)}), not {previous or 'a new record'} -> '{status}'"
272 )
273
274 proposed = record.get("proposed_status")
275 if proposed is not None:
276 if proposed not in LADDER:
277 problems.append(
278 f"{identifier}: proposed_status {proposed!r} must name a rung of "
279 f"{list(LADDER)}"
280 )
281 elif status not in LADDER or LADDER.index(proposed) <= LADDER.index(status):
282 problems.append(
283 f"{identifier}: proposed_status '{proposed}' is not above the claimed "
284 f"status '{status}'; a proposal that is not a promotion is noise"
285 )
286 elif not record.get("promotion_rationale"):
287 problems.append(
288 f"{identifier}: proposes '{proposed}' but gives no promotion_rationale. "
289 f"Say what the owner is being asked to confirm"
290 )
291
292 if status in NEEDS_PEAK:
293 peak = record.get("peak_status")
294 if peak not in LADDER:
295 problems.append(
296 f"{identifier}: status '{status}' requires peak_status naming the highest "
297 f"rung it reached, one of {list(LADDER)}"
298 )
299 elif record.get("peak_status") is not None:
300 problems.append(
301 f"{identifier}: peak_status applies only to {list(NEEDS_PEAK)}, not '{status}'"
302 )
303
304 obligations = record.get("obligations") or {}
305 owed = required_obligations(record)
306 for key in owed:
307 if key not in obligations:
308 problems.append(
309 f"{identifier}: status '{status}' owes '{key}', which is not declared"
310 )
311 else:
312 problems.extend(
313 check_satisfaction(identifier, key, obligations[key], pages, published,
314 visibility == "public")
315 )
316 for key in sorted(set(obligations) - set(owed)):
317 problems.append(
318 f"{identifier}: declares obligation '{key}', which status '{status}' does not "
319 f"owe; remove it or claim the status that owes it"
320 )
321
322 concerns = record.get("concerns") or {}
323 for key in sorted(concerns):
324 if key not in VALID_CONCERNS:
325 problems.append(
326 f"{identifier}: concern '{key}' is not in the concern vocabulary of "
327 f"64_Documentation_Extension_Framework"
328 )
329 continue
330 problems.extend(
331 check_satisfaction(identifier, key, concerns[key], pages, published,
332 visibility == "public")
333 )
334
335 # A planned subsystem must not already be presented as working behavior.
336 for family_id in record.get("capability_families", []):
337 family = families.get(family_id)
338 if family is None:
339 problems.append(
340 f"{identifier}: cites capability family '{family_id}', which is not "
341 f"registered"
342 )
343 continue
344 if status != "planned":
345 continue
346 live = sorted(
347 name for name, meta in family.get("value_metadata", {}).items()
348 if (meta or {}).get("status") == "supported"
349 )
350 if live:
351 problems.append(
352 f"{identifier}: is 'planned' but family '{family_id}' already offers "
353 f"supported value(s) {live}; a planned subsystem must not appear as "
354 f"supported behavior"
355 )
356 return problems
357
358
Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_value_ownership()

list audit_subsystem_lifecycle.validate_value_ownership ( list  records,
dict  families 
)

Check that every capability value has an owning subsystem it does not outrank.

A value's status and its subsystem's status used to be independent axes, which let a value read supported under a subsystem still experimental: the Newton-Krylov solver value, the periodic handlers, and every storage policy all did. The subsystem status is now a ceiling. The rules need the whole registry, so they are kept out of the per-record validate():

  • every registered family is listed by at least one subsystem record;
  • a family listed by several subsystems names each canonical value's owner in value_metadata[*].subsystem, and that owner must list the family;
  • a value may not claim a ladder rung above its owner's, and under an owner that is off the ladder it must share the owner's status or be removed;
  • off_switch: true exempts the single value per family that disables the owning subsystem, since selecting it claims nothing about it.

Accepted spellings and deprecated aliases inherit their target's owner and are not checked separately.

Parameters
[in]recordsEvery subsystem record.
[in]familiesCapability family metadata, keyed by family id.
Returns
List of violation strings; empty means every value sits under its owner.

Definition at line 359 of file audit_subsystem_lifecycle.py.

359def validate_value_ownership(records: list, families: dict) -> list:
360 """!
361 @brief Check that every capability value has an owning subsystem it does not outrank.
362
363 @details A value's status and its subsystem's status used to be independent axes,
364 which let a value read `supported` under a subsystem still `experimental`:
365 the Newton-Krylov solver value, the periodic handlers, and every storage
366 policy all did. The subsystem status is now a ceiling. The rules need the
367 whole registry, so they are kept out of the per-record `validate()`:
368
369 - every registered family is listed by at least one subsystem record;
370 - a family listed by several subsystems names each canonical value's owner
371 in `value_metadata[*].subsystem`, and that owner must list the family;
372 - a value may not claim a ladder rung above its owner's, and under an owner
373 that is off the ladder it must share the owner's status or be removed;
374 - `off_switch: true` exempts the single value per family that disables
375 the owning subsystem, since selecting it claims nothing about it.
376
377 Accepted spellings and deprecated aliases inherit their target's owner and
378 are not checked separately.
379 @param[in] records Every subsystem record.
380 @param[in] families Capability family metadata, keyed by family id.
381 @return List of violation strings; empty means every value sits under its owner.
382 """
383 problems: list = []
384 status_of = {record.get("id"): record.get("status") for record in records}
385 listed_by: dict = {}
386 for record in records:
387 for family_id in record.get("capability_families", []):
388 listed_by.setdefault(family_id, []).append(record.get("id"))
389
390 for family_id, family in sorted(families.items()):
391 owners = listed_by.get(family_id, [])
392 if not owners:
393 problems.append(
394 f"{family_id}: no subsystem lists this family, so its values have no "
395 f"lifecycle above them; add it to the owning record's capability_families"
396 )
397 continue
398 off_switches = []
399 for name, meta in sorted(family.get("value_metadata", {}).items()):
400 meta = meta or {}
401 if meta.get("spelling_of") or meta.get("alias_of"):
402 continue
403 owner = meta.get("subsystem")
404 if owner is None:
405 if len(owners) > 1:
406 problems.append(
407 f"{family_id}: '{name}' belongs to a family listed by {sorted(owners)}; "
408 f"name its owner in value_metadata.subsystem"
409 )
410 continue
411 owner = owners[0]
412 elif owner not in owners:
413 problems.append(
414 f"{family_id}: '{name}' names subsystem '{owner}', which does not list "
415 f"this family"
416 )
417 continue
418 if "off_switch" in meta:
419 if meta["off_switch"] is not True:
420 problems.append(
421 f"{family_id}: '{name}' declares off_switch {meta['off_switch']!r}; "
422 f"it is either true or absent"
423 )
424 off_switches.append(name)
425 continue
426 owner_status = status_of.get(owner)
427 value_status = meta.get("status")
428 if value_status in LADDER and owner_status in LADDER:
429 if LADDER.index(value_status) > LADDER.index(owner_status):
430 problems.append(
431 f"{family_id}: '{name}' claims '{value_status}' but its subsystem "
432 f"'{owner}' is '{owner_status}'; a value cannot outrank the "
433 f"subsystem it belongs to"
434 )
435 elif owner_status not in LADDER and value_status not in (owner_status, "removed"):
436 problems.append(
437 f"{family_id}: '{name}' is '{value_status}' under '{owner}', which is "
438 f"'{owner_status}'; under an owner off the ladder a value shares its "
439 f"status or is removed"
440 )
441 if len(off_switches) > 1:
442 problems.append(
443 f"{family_id}: {off_switches} are all marked off_switch; a family has at "
444 f"most one value that disables its subsystem"
445 )
446 return problems
447
448
Here is the caller graph for this function:

◆ main()

int audit_subsystem_lifecycle.main ( )

Report subsystem lifecycle violations.

Returns
Process status code.

Definition at line 449 of file audit_subsystem_lifecycle.py.

449def main() -> int:
450 """!
451 @brief Report subsystem lifecycle violations.
452 @return Process status code.
453 """
454 document = json.loads(RECORDS.read_text(encoding="utf-8"))
455 records = document["subsystems"]
456 published = set(json.loads(PAGE_TYPES.read_text(encoding="utf-8"))["assignments"])
457 families = {
458 family["id"]: family
459 for family in json.loads(FAMILIES.read_text(encoding="utf-8"))["families"]
460 }
461 problems = validate(records, page_index(), families, published)
462 problems += validate_value_ownership(records, families)
463 if problems:
464 print("Subsystem lifecycle violations:", file=sys.stderr)
465 for problem in problems:
466 print(f" {problem}", file=sys.stderr)
467 print(
468 "\nObligations grow with the status a subsystem claims. See\n"
469 "64_Documentation_Extension_Framework section 4. Lower the claimed status, or\n"
470 "write the documentation that status owes - do not add empty prose to pass.",
471 file=sys.stderr,
472 )
473 return 1
474
475 from collections import Counter
476 spread = Counter(record["status"] for record in records)
477 summary = ", ".join(f"{count} {status}" for status, count in sorted(spread.items()))
478 print(f"Subsystem lifecycle audit passed: {len(records)} subsystem(s) ({summary}).")
479 proposals = [r for r in records if r.get("proposed_status")]
480 if proposals:
481 print(f"\n{len(proposals)} promotion(s) awaiting the owner's decision. The "
482 f"documentation meets the higher bar; whether the subsystem has earned "
483 f"the status is a human judgement this gate cannot make:")
484 for record in proposals:
485 print(f" {record['id']}: {record['status']} -> {record['proposed_status']}")
486 print(f" {record['promotion_rationale']}")
487 return 0
488
489
int main(int argc, char **argv)
Entry point for the postprocessor executable.
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ REPO_ROOT

audit_subsystem_lifecycle.REPO_ROOT = Path(__file__).resolve().parents[2]

Definition at line 12 of file audit_subsystem_lifecycle.py.

◆ RECORDS

str audit_subsystem_lifecycle.RECORDS = REPO_ROOT / "tests" / "tooling" / "subsystem_records.json"

Definition at line 13 of file audit_subsystem_lifecycle.py.

◆ PAGE_TYPES

str audit_subsystem_lifecycle.PAGE_TYPES = REPO_ROOT / "tests" / "tooling" / "page_types.json"

Definition at line 14 of file audit_subsystem_lifecycle.py.

◆ FAMILIES

str audit_subsystem_lifecycle.FAMILIES = REPO_ROOT / "tests" / "tooling" / "capability_families.json"

Definition at line 15 of file audit_subsystem_lifecycle.py.

◆ PAGE_DIRS

tuple audit_subsystem_lifecycle.PAGE_DIRS = ("docs/pages", "docs")

Definition at line 16 of file audit_subsystem_lifecycle.py.

◆ LADDER

tuple audit_subsystem_lifecycle.LADDER = ("planned", "internal", "experimental", "supported")

Definition at line 21 of file audit_subsystem_lifecycle.py.

◆ LADDER_OBLIGATIONS

dict audit_subsystem_lifecycle.LADDER_OBLIGATIONS
Initial value:
1= {
2 "planned": ("purpose", "intended_scope", "design_owner", "not_implemented_status"),
3 "internal": ("scope_boundary", "architecture_boundary", "dependencies",
4 "developer_entry_points"),
5 "experimental": ("configuration", "selection_guidance", "observability", "limitations",
6 "safe_use_boundaries"),
7 "supported": ("evidence", "lifecycle_and_restart", "operations", "troubleshooting",
8 "examples", "complete_reference"),
9}

Definition at line 23 of file audit_subsystem_lifecycle.py.

◆ TERMINAL_OBLIGATIONS

dict audit_subsystem_lifecycle.TERMINAL_OBLIGATIONS
Initial value:
1= {
2 "known-defective": ("defect_disclosure", "defect_scope_record", "safe_use_boundaries",
3 "limitations"),
4 "deprecated": ("migration_path", "replacement", "compatibility_period", "removal_policy"),
5 "removed": ("history_record", "rejection_behavior"),
6}

Definition at line 35 of file audit_subsystem_lifecycle.py.

◆ NON_INHERITED

tuple audit_subsystem_lifecycle.NON_INHERITED = ("not_implemented_status",)

Definition at line 43 of file audit_subsystem_lifecycle.py.

◆ NEEDS_PEAK

tuple audit_subsystem_lifecycle.NEEDS_PEAK = ("known-defective", "deprecated", "removed")

Definition at line 44 of file audit_subsystem_lifecycle.py.

◆ INHERITS_LADDER

tuple audit_subsystem_lifecycle.INHERITS_LADDER = ("known-defective", "deprecated")

Definition at line 46 of file audit_subsystem_lifecycle.py.

◆ VALID_STATUSES

audit_subsystem_lifecycle.VALID_STATUSES = tuple(LADDER) + tuple(TERMINAL_OBLIGATIONS)

Definition at line 48 of file audit_subsystem_lifecycle.py.

◆ TRANSITIONS

dict audit_subsystem_lifecycle.TRANSITIONS
Initial value:
1= {
2 None: set(VALID_STATUSES) - {"removed"},
3 "planned": {"planned", "internal", "experimental", "supported", "removed"},
4 "internal": {"internal", "experimental", "supported", "known-defective", "deprecated"},
5 "experimental": {"experimental", "supported", "known-defective", "deprecated"},
6 "supported": {"supported", "experimental", "known-defective", "deprecated"},
7 "known-defective": {"known-defective", "planned", "experimental", "supported", "deprecated", "removed"},
8 "deprecated": {"deprecated", "removed"},
9 "removed": {"removed"},
10}

Definition at line 68 of file audit_subsystem_lifecycle.py.

◆ DEMOTIONS

dict audit_subsystem_lifecycle.DEMOTIONS = {("supported", "experimental"), ("known-defective", "planned")}

Definition at line 82 of file audit_subsystem_lifecycle.py.

◆ VALID_VISIBILITY

tuple audit_subsystem_lifecycle.VALID_VISIBILITY = ("internal", "public")

Definition at line 84 of file audit_subsystem_lifecycle.py.

◆ VALID_CONCERNS

tuple audit_subsystem_lifecycle.VALID_CONCERNS
Initial value:
1= (
2 "numerical_method", "user_selector", "units_and_nondimensionalization",
3 "artifact_topology", "persistent_restart_state", "determinism_and_reproducibility",
4 "mpi_distributed_execution", "external_service", "security_credentials",
5 "generated_artifact", "file_format", "destructive_scope", "backward_compatibility",
6 "scientific_verification",
7)

Definition at line 87 of file audit_subsystem_lifecycle.py.

◆ RECORD_KEYS

dict audit_subsystem_lifecycle.RECORD_KEYS
Initial value:
1= {"id", "title", "status", "visibility", "previous_status", "peak_status",
2 "proposed_status", "promotion_rationale", "demotion_reason",
3 "capability_families",
4 "obligations", "concerns", "note"}

Definition at line 95 of file audit_subsystem_lifecycle.py.

◆ MIN_REASON_CHARS

int audit_subsystem_lifecycle.MIN_REASON_CHARS = 30

Definition at line 100 of file audit_subsystem_lifecycle.py.

◆ FILLER_REASONS

dict audit_subsystem_lifecycle.FILLER_REASONS = {"n/a", "na", "none", "not applicable", "no", "-", "tbd"}

Definition at line 101 of file audit_subsystem_lifecycle.py.