This document contains key context, nuances, and troubleshooting tips specifically designed to help AI agents (and human developers) quickly understand and contribute to this repository, avoiding common pitfalls.
- Environment: This project primarily uses uv for dependency management and locking.
- External Schemas: Many UTM standards implementations (such as the ASTM F3548 schemas) are provided by the external
uas_standardspackage instead of living directly within the local./monitoringor./schemasdirectories. - Agent Tip: Since external packages reside in the virtual environment, you cannot explore them directly with standard local file
grepsearches. To inspect an external schema's properties (e.g.,OperationalIntentReference), it is much faster to run a Python introspection script throughuv:uv run python -c "from uas_standards.astm.f3548.v21.api import OperationalIntentReference; print(OperationalIntentReference.__annotations__)" - uv run Troubleshooting: If running commands via
uv runfails due to multi-platform dependency resolution issues (e.g. missing upload dates/wheels in custom package registries), you can force it to use standard PyPI by specifying the--indexoption:PYTHONPATH=. uv run --index https://pypi.org/simple pytest monitoring/uss_qualifier/reports/obfuscation_test.py
- Linter and Formatting: To verify stylistic correctness/consistency in the monitoring project, run
make format(to auto-format when possible) ormake lint(to check correctness/type check) from the root of themonitoringdirectory. Do not runrufforbasedpyrightdirectly if they fail due to environment/index configuration issues. - Jsonnet
native_callbacksParameter Names: In_jsonnet(jsonnetv0.22.0), parameter names in thenative_callbackstuple passed to_jsonnet.evaluate_snippetmust be single-character ASCII strings (e.g.,("y", "x", "l")instead of("lat", "lng", "level")). Due to a use-after-free bug in_jsonnet's C extension (handle_native_callbacks; see google/jsonnet#1321 and google/jsonnet#1333), multi-bytePyBytesobjects returned byPyUnicode_AsUTF8Stringare prematurelyPy_DECREFed and freed inside the parameter loop beforejsonnet_native_callbackis called, causing subsequent parameter strings to reuse the same memory address and fail at runtime withRUNTIME ERROR: binding parameter a second time: <param>. Single-bytePyBytesobjects are immortal singletons in CPython and are not freed.
- Resource base-class imports:
configurations.configurationimports resource definitions through the resources package, whose initializer loads theResourcebase class. ImportParticipantIDfrom configuration underTYPE_CHECKINGwith postponed annotations inresources/resource.pyto avoid a circular import when scenarios are imported first. - Generic method annotations: With postponed annotations,
typing.get_type_hints(SomeGenericClass.__init__)cannot resolve class-scoped PEP 695 type parameters automatically (verified on Python 3.13 and 3.14). Usemonitoring.monitorlib.typing.get_method_type_hintsto supply the declaring class's namespace, including for inherited methods and generic return types. Regression tests should exercise resource construction and selector resolution with postponed annotations enabled. - Implicit Types: Many schema objects inherit from
ImplicitDict. This means that reading their raw Python class definitions may not reveal all their expected structure. Rely on their__annotations__or their OpenAPI documentation. - Optional
ImplicitDictFields:ImplicitDictfields annotated with| None(orOptional[...]) indicate optional dictionary keys. In implicitdict 5.0.0, accessing a missing optional attribute returnsNonewithout inserting a key; use"field" in objto distinguish absence from an explicitly stored null. Constructor keyword arguments set toNonenormally omit optional values, but class defaults may still populate the key; assigningobj.field = Noneorobj["field"] = Nonestores an explicit null. Use dictionary membership rather thanhasattrwhen key presence matters. - implicitdict 5.0.0 Typing: Its unannotated
__getattribute__introducesNoneinto the inferred type of undeclared attributes (Unknown | Any | Nonein basedpyright 1.40.1), while declared fields and properties retain their types. New optional-access diagnostics may expose a nonexistent member or the wrong schema class rather than a missing optional value. Check the receiver's declaration before adding a None guard or suppressing the diagnostic. An explicit-> Anyreturn annotation on the accessor restores the previous permissive fallback without changing runtime behavior, but also hides these pre-existing member-access mistakes. - ImplicitDict field access: Much of the existing codebase first checks ImplicitDict field presence by string before checking the field for a non-None value (e.g.,
if "bar" in foo and foo.bar). Since implicitdict 5.0.0, this is no longer necessary andif foo.baris preferred unless checking for field presence specifically. - Hidden Schema Nuances: Certain F3548 properties intuitively behave differently than standard logic might predict (e.g., F3548's
OperationalIntentReferencedoes not represent 4Daltitudeextents, whereasVolume4Ddetails do). Always verify property existence programmatically instead of relying on assumptions. - Datetime Types: Fields annotated as
StringBasedDateTime(or genericTimestructures wrapping it) inherently expose a.datetimeproperty mapping directly to Python's built-indatetime.datetimetype. Always rely on this.datetimeattribute for date-math instead of manually parsing string strings. - DSS Base URL Suffixes: When configuring DSS instances, the base URL for ASTM F3411-22a (NetRID v2) requires the
/rid/v2suffix path (e.g.http://dss1.uss1.localutm/rid/v2), whereas F3411-19 and SCD (F3548) typically use the host base URL directly without that suffix.
- Markdown Documentation is Mandatory: Every check (e.g.,
self._scenario.check(...)) added to a Python test scenario must be meticulously documented in the corresponding Markdown documentation file for that specific test scenario or fragment. - Documentation Traceability: All documented test checks must trace back to exactly one or more requirements using a specific bold format, and feature a severity emoji prefix (e.g.,
## 🛑 Correct operational intent details check). You must refer tomonitoring/uss_qualifier/scenarios/README.mdfor specific markup details before modifying test steps. - Resource name shortcuts: The shortcuts for resource names added to int.py (e.g.,
from .planning_area import PlanningAreaResource as PlanningAreaResource) should not be continued. All future development should use only the canonical resource location (e.g.,resources.planning_area.PlanningAreaResource). - Acceptable findings and continuation:
do_not_stop_fast_for_acceptable_findingsonly prevents severity escalation; findings with documented High or Critical severity still stop execution. Use Medium severity for checks whose failure permits subsequent activities. Exit-code validation is independent of tested-requirements reporting;failed_checks.is_acceptable: falseexcludes declared acceptable findings from a validation criterion.
- Unit-test working directory: Run
uss_qualifierunit tests frommonitoring/uss_qualifier/with the repository root onPYTHONPATH(for example,PYTHONPATH=../.. ../../.venv/bin/python -m pytest scenarios/scenario_test resources/flight_planning). Some resource fixtures resolve test-data paths relative to the working directory and fail when run from the repository root. - Qualifier Working Directory: Run resource-construction checks and qualifier resource tests from
monitoring/uss_qualifierwith the repository root onPYTHONPATH. External resource paths such asfile://./test_data/...resolve relative to the current working directory, as they do inrun_locally.sh. - Local Python 3.14 artifact generation: Python 3.14 defaults to
forkserveron Linux, which cannot pickle the local worker functions inreports/artifacts.py. If a local qualifier run fails there withPicklingError, use the project's Docker runtime or a local launcher that callsmultiprocessing.set_start_method("fork")before runningmonitoring.uss_qualifier.main. - Docker Dependency: Mock USS and DSS environments require active Docker containers. Standard testing commands are typically structured via bash scripts like
./monitoring/uss_qualifier/run_locally.sh <config>. If container-building fails due toAuthenticationor package registry issues in the agent's environment, gracefully halt and ask the human user to run the script instead.
- Pay It Forward: As an AI agent, your ability to acquire context quickly is critical. If, during your work, you find yourself spending significant time overcoming a misunderstanding, discovering a hidden project nuance, or writing introspection scripts to understand a schema, please proactively update this
AGENTS.mdfile. Add concise tips or warnings to help future agents (including yourself) avoid the same friction, alongside completing your core task. - Correcting Mistakes: Documentation can become outdated or contain errors over time. If your core work reveals that information in this
AGENTS.mdfile is mistaken or missing critical context, please take the initiative to fix those errors while completing your primary objectives!
- Tagging Unit Tests: When creating new unit tests, please tag each new test with the comment
# This test is AI-generated and has not been closely inspected by a human.above the test definition (one comment per test_* function). Your user may remove this annotation if they closely inspect it, but this is not generally necessary and pull requests should not generally be rejected because of these annotations.