From cc4ad6dda5ae111edcf9d4c070e04204c8eadc73 Mon Sep 17 00:00:00 2001 From: krital Date: Tue, 24 Feb 2026 10:15:32 +0200 Subject: [PATCH 01/12] feat(skills): add complete MAPS skill collection --- skills/install-all.sh | 104 ++++++ .../maps-aggregator-config-engineer/SKILL.md | 75 ++++ .../agents/openai.yaml | 4 + .../references/aggregator-design-guide.md | 76 ++++ .../references/output-contract.md | 44 +++ .../references/user-guide.md | 105 ++++++ ...ggregator_config_engineer_runtime_smoke.sh | 95 +++++ ..._aggregator_config_engineer_skill_smoke.sh | 12 + .../SKILL.md | 74 ++++ .../agents/openai.yaml | 4 + .../references/execution-catalog.md | 85 +++++ .../references/output-contract.md | 48 +++ .../scenarios/default-matrix.md | 11 + .../scripts/run_artifact_smoke.sh | 277 ++++++++++++++ ...t_execution_smoke_harness_runtime_smoke.sh | 95 +++++ ...act_execution_smoke_harness_skill_smoke.sh | 12 + .../scripts/run_matrix.sh | 204 +++++++++++ skills/maps-canbus-ingestion-builder/SKILL.md | 73 ++++ .../agents/openai.yaml | 4 + .../references/canbus-mapping-guide.md | 55 +++ .../references/output-contract.md | 44 +++ ..._canbus_ingestion_builder_runtime_smoke.sh | 95 +++++ ...ps_canbus_ingestion_builder_skill_smoke.sh | 12 + skills/maps-deployment-packager/SKILL.md | 108 ++++++ .../agents/openai.yaml | 4 + .../references/deployment-targets.md | 143 ++++++++ .../references/output-contract.md | 89 +++++ ..._maps_deployment_packager_runtime_smoke.sh | 95 +++++ ...un_maps_deployment_packager_skill_smoke.sh | 12 + .../maps-geospatial-routing-builder/SKILL.md | 72 ++++ .../agents/openai.yaml | 4 + .../examples/advanced-geospatial-output.md | 78 ++++ .../examples/simple-geospatial-output.md | 74 ++++ .../references/geospatial-patterns.md | 48 +++ .../references/output-contract.md | 44 +++ .../scripts/run_geospatial_mqtt_smoke.sh | 82 +++++ .../scripts/run_geospatial_skill_smoke.sh | 13 + .../scripts/run_geospatial_vectors.py | 97 +++++ ...eospatial_routing_builder_runtime_smoke.sh | 95 +++++ .../scripts/validate_geospatial_artifacts.py | 71 ++++ .../maps-ml-model-lifecycle-playbook/SKILL.md | 79 ++++ .../agents/openai.yaml | 4 + .../examples/advanced-ml-lifecycle-output.md | 93 +++++ .../examples/model-artifact-sample.json | 7 + .../examples/model-metrics-sample.csv | 5 + .../examples/simple-ml-lifecycle-output.md | 83 +++++ .../references/lifecycle-patterns.md | 50 +++ .../references/output-contract.md | 43 +++ .../scripts/run_ml_lifecycle_mqtt_smoke.sh | 75 ++++ .../scripts/run_ml_lifecycle_runtime_smoke.sh | 95 +++++ .../scripts/run_ml_lifecycle_skill_smoke.sh | 13 + .../scripts/run_ml_lifecycle_vectors.py | 54 +++ .../validate_ml_lifecycle_artifacts.py | 70 ++++ skills/maps-ml-stream-configurator/SKILL.md | 75 ++++ .../agents/openai.yaml | 4 + .../references/ml-pipeline-patterns.md | 51 +++ .../references/output-contract.md | 45 +++ ...ps_ml_stream_configurator_runtime_smoke.sh | 95 +++++ ...maps_ml_stream_configurator_skill_smoke.sh | 15 + skills/maps-protocol-bridge-tester/SKILL.md | 67 ++++ .../agents/openai.yaml | 4 + .../references/bridge-test-catalog.md | 54 +++ .../references/output-contract.md | 40 ++ ...ps_protocol_bridge_tester_runtime_smoke.sh | 95 +++++ ...maps_protocol_bridge_tester_skill_smoke.sh | 12 + .../maps-release-readiness-checker/SKILL.md | 76 ++++ .../agents/openai.yaml | 4 + .../references/output-contract.md | 44 +++ .../references/release-gate-catalog.md | 67 ++++ ...release_readiness_checker_runtime_smoke.sh | 95 +++++ ...s_release_readiness_checker_skill_smoke.sh | 12 + skills/maps-runtime-diagnostics/SKILL.md | 71 ++++ .../agents/openai.yaml | 4 + .../references/output-contract.md | 43 +++ .../startup-gates-and-bind-checks.md | 55 +++ ..._maps_runtime_diagnostics_runtime_smoke.sh | 95 +++++ ...un_maps_runtime_diagnostics_skill_smoke.sh | 12 + skills/maps-satellite-gateway-config/SKILL.md | 84 +++++ .../agents/openai.yaml | 4 + .../references/output-contract.md | 49 +++ .../references/satellite-config-map.md | 65 ++++ .../references/satellite-pubsub-patterns.md | 61 ++++ ..._satellite_gateway_config_runtime_smoke.sh | 95 +++++ ...ps_satellite_gateway_config_skill_smoke.sh | 16 + skills/maps-scenario-composer/SKILL.md | 81 ++++ .../maps-scenario-composer/agents/openai.yaml | 4 + .../references/composition-patterns.md | 55 +++ .../examples/composed-deliverable-example.md | 47 +++ .../references/output-contract.md | 47 +++ .../scripts/compose_scenarios.py | 345 ++++++++++++++++++ ...un_maps_scenario_composer_runtime_smoke.sh | 95 +++++ .../run_scenario_composer_skill_smoke.sh | 67 ++++ skills/maps-schema-pipeline-builder/SKILL.md | 74 ++++ .../agents/openai.yaml | 4 + .../references/output-contract.md | 40 ++ .../references/schema-mapping-guide.md | 54 +++ ...s_schema_pipeline_builder_runtime_smoke.sh | 95 +++++ ...aps_schema_pipeline_builder_skill_smoke.sh | 12 + skills/maps-selector-rule-engineer/SKILL.md | 71 ++++ .../agents/openai.yaml | 4 + .../examples/advanced-selector-output.md | 83 +++++ .../examples/simple-selector-output.md | 69 ++++ .../references/output-contract.md | 44 +++ .../references/selector-patterns.md | 44 +++ ...ps_selector_rule_engineer_runtime_smoke.sh | 95 +++++ .../scripts/run_selector_mqtt_smoke.sh | 99 +++++ .../scripts/run_selector_skill_smoke.sh | 12 + .../scripts/validate_selector_artifacts.py | 72 ++++ skills/maps-skill-suite-orchestrator/SKILL.md | 212 +++++++++++ .../agents/openai.yaml | 4 + ..._skill_suite_orchestrator_runtime_smoke.sh | 95 +++++ ...ps_skill_suite_orchestrator_skill_smoke.sh | 14 + skills/maps-transform-chain-designer/SKILL.md | 66 ++++ .../agents/openai.yaml | 4 + .../references/output-contract.md | 39 ++ .../references/transform-chain-patterns.md | 50 +++ ..._transform_chain_designer_runtime_smoke.sh | 95 +++++ ...ps_transform_chain_designer_skill_smoke.sh | 12 + skills/mapsmessaging-config-builder/SKILL.md | 79 ++++ .../agents/openai.yaml | 4 + .../references/output-contract.md | 46 +++ .../references/protocol-and-routing-map.md | 86 +++++ .../references/test-scenario-01-output.md | 56 +++ .../references/test-scenario-02-output.md | 44 +++ ...smessaging_config_builder_runtime_smoke.sh | 95 +++++ ...apsmessaging_config_builder_skill_smoke.sh | 12 + skills/smoke/README.md | 30 ++ skills/smoke/ensure_mqtt_listener.py | 101 +++++ .../artifact.md | 51 +++ .../artifact.md | 49 +++ .../maps-canbus-ingestion-builder/artifact.md | 51 +++ .../maps-deployment-packager/artifact.md | 84 +++++ .../artifact.md | 51 +++ .../artifact.md | 51 +++ .../maps-ml-stream-configurator/artifact.md | 51 +++ .../maps-protocol-bridge-tester/artifact.md | 44 +++ .../artifact.md | 43 +++ .../maps-runtime-diagnostics/artifact.md | 40 ++ .../maps-satellite-gateway-config/artifact.md | 58 +++ .../maps-scenario-composer/artifact.md | 51 +++ .../maps-schema-pipeline-builder/artifact.md | 48 +++ .../maps-selector-rule-engineer/artifact.md | 51 +++ .../maps-skill-suite-orchestrator/artifact.md | 32 ++ .../maps-transform-chain-designer/artifact.md | 48 +++ .../mapsmessaging-config-builder/artifact.md | 52 +++ skills/smoke/run.sh | 5 + skills/smoke/run_skill_combination.sh | 66 ++++ skills/smoke/validate_skills_smoke.py | 280 ++++++++++++++ 148 files changed, 8880 insertions(+) create mode 100755 skills/install-all.sh create mode 100644 skills/maps-aggregator-config-engineer/SKILL.md create mode 100644 skills/maps-aggregator-config-engineer/agents/openai.yaml create mode 100644 skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md create mode 100644 skills/maps-aggregator-config-engineer/references/output-contract.md create mode 100644 skills/maps-aggregator-config-engineer/references/user-guide.md create mode 100755 skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh create mode 100755 skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh create mode 100644 skills/maps-artifact-execution-smoke-harness/SKILL.md create mode 100644 skills/maps-artifact-execution-smoke-harness/agents/openai.yaml create mode 100644 skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md create mode 100644 skills/maps-artifact-execution-smoke-harness/references/output-contract.md create mode 100644 skills/maps-artifact-execution-smoke-harness/scenarios/default-matrix.md create mode 100755 skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh create mode 100755 skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh create mode 100755 skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh create mode 100755 skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh create mode 100644 skills/maps-canbus-ingestion-builder/SKILL.md create mode 100644 skills/maps-canbus-ingestion-builder/agents/openai.yaml create mode 100644 skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md create mode 100644 skills/maps-canbus-ingestion-builder/references/output-contract.md create mode 100755 skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh create mode 100755 skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh create mode 100644 skills/maps-deployment-packager/SKILL.md create mode 100644 skills/maps-deployment-packager/agents/openai.yaml create mode 100644 skills/maps-deployment-packager/references/deployment-targets.md create mode 100644 skills/maps-deployment-packager/references/output-contract.md create mode 100755 skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh create mode 100755 skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh create mode 100644 skills/maps-geospatial-routing-builder/SKILL.md create mode 100644 skills/maps-geospatial-routing-builder/agents/openai.yaml create mode 100644 skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md create mode 100644 skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md create mode 100644 skills/maps-geospatial-routing-builder/references/geospatial-patterns.md create mode 100644 skills/maps-geospatial-routing-builder/references/output-contract.md create mode 100755 skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh create mode 100755 skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh create mode 100755 skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py create mode 100755 skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh create mode 100755 skills/maps-geospatial-routing-builder/scripts/validate_geospatial_artifacts.py create mode 100644 skills/maps-ml-model-lifecycle-playbook/SKILL.md create mode 100644 skills/maps-ml-model-lifecycle-playbook/agents/openai.yaml create mode 100644 skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md create mode 100644 skills/maps-ml-model-lifecycle-playbook/references/examples/model-artifact-sample.json create mode 100644 skills/maps-ml-model-lifecycle-playbook/references/examples/model-metrics-sample.csv create mode 100644 skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md create mode 100644 skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md create mode 100644 skills/maps-ml-model-lifecycle-playbook/references/output-contract.md create mode 100755 skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh create mode 100755 skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh create mode 100755 skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh create mode 100755 skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py create mode 100755 skills/maps-ml-model-lifecycle-playbook/scripts/validate_ml_lifecycle_artifacts.py create mode 100644 skills/maps-ml-stream-configurator/SKILL.md create mode 100644 skills/maps-ml-stream-configurator/agents/openai.yaml create mode 100644 skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md create mode 100644 skills/maps-ml-stream-configurator/references/output-contract.md create mode 100755 skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh create mode 100755 skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh create mode 100644 skills/maps-protocol-bridge-tester/SKILL.md create mode 100644 skills/maps-protocol-bridge-tester/agents/openai.yaml create mode 100644 skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md create mode 100644 skills/maps-protocol-bridge-tester/references/output-contract.md create mode 100755 skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh create mode 100755 skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_skill_smoke.sh create mode 100644 skills/maps-release-readiness-checker/SKILL.md create mode 100644 skills/maps-release-readiness-checker/agents/openai.yaml create mode 100644 skills/maps-release-readiness-checker/references/output-contract.md create mode 100644 skills/maps-release-readiness-checker/references/release-gate-catalog.md create mode 100755 skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh create mode 100755 skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh create mode 100644 skills/maps-runtime-diagnostics/SKILL.md create mode 100644 skills/maps-runtime-diagnostics/agents/openai.yaml create mode 100644 skills/maps-runtime-diagnostics/references/output-contract.md create mode 100644 skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md create mode 100755 skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh create mode 100755 skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh create mode 100644 skills/maps-satellite-gateway-config/SKILL.md create mode 100644 skills/maps-satellite-gateway-config/agents/openai.yaml create mode 100644 skills/maps-satellite-gateway-config/references/output-contract.md create mode 100644 skills/maps-satellite-gateway-config/references/satellite-config-map.md create mode 100644 skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md create mode 100755 skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh create mode 100755 skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh create mode 100644 skills/maps-scenario-composer/SKILL.md create mode 100644 skills/maps-scenario-composer/agents/openai.yaml create mode 100644 skills/maps-scenario-composer/references/composition-patterns.md create mode 100644 skills/maps-scenario-composer/references/examples/composed-deliverable-example.md create mode 100644 skills/maps-scenario-composer/references/output-contract.md create mode 100755 skills/maps-scenario-composer/scripts/compose_scenarios.py create mode 100755 skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh create mode 100755 skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh create mode 100644 skills/maps-schema-pipeline-builder/SKILL.md create mode 100644 skills/maps-schema-pipeline-builder/agents/openai.yaml create mode 100644 skills/maps-schema-pipeline-builder/references/output-contract.md create mode 100644 skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md create mode 100755 skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh create mode 100755 skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_skill_smoke.sh create mode 100644 skills/maps-selector-rule-engineer/SKILL.md create mode 100644 skills/maps-selector-rule-engineer/agents/openai.yaml create mode 100644 skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md create mode 100644 skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md create mode 100644 skills/maps-selector-rule-engineer/references/output-contract.md create mode 100644 skills/maps-selector-rule-engineer/references/selector-patterns.md create mode 100755 skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh create mode 100755 skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh create mode 100755 skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh create mode 100755 skills/maps-selector-rule-engineer/scripts/validate_selector_artifacts.py create mode 100644 skills/maps-skill-suite-orchestrator/SKILL.md create mode 100644 skills/maps-skill-suite-orchestrator/agents/openai.yaml create mode 100755 skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh create mode 100755 skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh create mode 100644 skills/maps-transform-chain-designer/SKILL.md create mode 100644 skills/maps-transform-chain-designer/agents/openai.yaml create mode 100644 skills/maps-transform-chain-designer/references/output-contract.md create mode 100644 skills/maps-transform-chain-designer/references/transform-chain-patterns.md create mode 100755 skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh create mode 100755 skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_skill_smoke.sh create mode 100644 skills/mapsmessaging-config-builder/SKILL.md create mode 100644 skills/mapsmessaging-config-builder/agents/openai.yaml create mode 100644 skills/mapsmessaging-config-builder/references/output-contract.md create mode 100644 skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md create mode 100644 skills/mapsmessaging-config-builder/references/test-scenario-01-output.md create mode 100644 skills/mapsmessaging-config-builder/references/test-scenario-02-output.md create mode 100755 skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh create mode 100755 skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_skill_smoke.sh create mode 100644 skills/smoke/README.md create mode 100755 skills/smoke/ensure_mqtt_listener.py create mode 100644 skills/smoke/fixtures/maps-aggregator-config-engineer/artifact.md create mode 100644 skills/smoke/fixtures/maps-artifact-execution-smoke-harness/artifact.md create mode 100644 skills/smoke/fixtures/maps-canbus-ingestion-builder/artifact.md create mode 100644 skills/smoke/fixtures/maps-deployment-packager/artifact.md create mode 100644 skills/smoke/fixtures/maps-geospatial-routing-builder/artifact.md create mode 100644 skills/smoke/fixtures/maps-ml-model-lifecycle-playbook/artifact.md create mode 100644 skills/smoke/fixtures/maps-ml-stream-configurator/artifact.md create mode 100644 skills/smoke/fixtures/maps-protocol-bridge-tester/artifact.md create mode 100644 skills/smoke/fixtures/maps-release-readiness-checker/artifact.md create mode 100644 skills/smoke/fixtures/maps-runtime-diagnostics/artifact.md create mode 100644 skills/smoke/fixtures/maps-satellite-gateway-config/artifact.md create mode 100644 skills/smoke/fixtures/maps-scenario-composer/artifact.md create mode 100644 skills/smoke/fixtures/maps-schema-pipeline-builder/artifact.md create mode 100644 skills/smoke/fixtures/maps-selector-rule-engineer/artifact.md create mode 100644 skills/smoke/fixtures/maps-skill-suite-orchestrator/artifact.md create mode 100644 skills/smoke/fixtures/maps-transform-chain-designer/artifact.md create mode 100644 skills/smoke/fixtures/mapsmessaging-config-builder/artifact.md create mode 100755 skills/smoke/run.sh create mode 100755 skills/smoke/run_skill_combination.sh create mode 100755 skills/smoke/validate_skills_smoke.py diff --git a/skills/install-all.sh b/skills/install-all.sh new file mode 100755 index 000000000..0ad315ce1 --- /dev/null +++ b/skills/install-all.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat <<'EOF' +Install all skills from this repository into Codex using the system skill installer. + +Usage: + skills/install-all.sh --repo [--ref ] [--dest ] [--dry-run] + +Examples: + skills/install-all.sh --repo acme/maps-skills + skills/install-all.sh --repo acme/maps-skills --ref main + skills/install-all.sh --repo acme/maps-skills --ref v1.2.0 --dry-run +EOF +} + +REPO="" +REF="main" +DEST="" +DRY_RUN=0 + +while [[ $# -gt 0 ]]; do + case "$1" in + --repo) + REPO="${2:-}" + shift 2 + ;; + --ref) + REF="${2:-}" + shift 2 + ;; + --dest) + DEST="${2:-}" + shift 2 + ;; + --dry-run) + DRY_RUN=1 + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + usage + exit 1 + ;; + esac +done + +if [[ -z "${REPO}" ]]; then + echo "Missing required argument: --repo " >&2 + usage + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SKILL_INSTALLER="${HOME}/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py" + +if [[ ! -f "${SKILL_INSTALLER}" ]]; then + echo "Skill installer not found at: ${SKILL_INSTALLER}" >&2 + echo "Ensure Codex system skills are installed on this machine." >&2 + exit 1 +fi + +SKILL_PATHS=() +for dir in "${SCRIPT_DIR}"/*; do + [[ -d "${dir}" ]] || continue + if [[ -f "${dir}/SKILL.md" ]]; then + SKILL_PATHS+=("skills/$(basename "${dir}")") + fi +done +IFS=$'\n' SKILL_PATHS=($(printf '%s\n' "${SKILL_PATHS[@]}" | sort)) + +if [[ ${#SKILL_PATHS[@]} -eq 0 ]]; then + echo "No installable skills found under ${SCRIPT_DIR}" >&2 + exit 1 +fi + +CMD=(python3 "${SKILL_INSTALLER}" --repo "${REPO}" --ref "${REF}") +if [[ -n "${DEST}" ]]; then + CMD+=(--dest "${DEST}") +fi +for path in "${SKILL_PATHS[@]}"; do + CMD+=(--path "${path}") +done + +echo "Repository: ${REPO}" +echo "Ref: ${REF}" +echo "Skills to install: ${#SKILL_PATHS[@]}" +printf ' - %s\n' "${SKILL_PATHS[@]}" + +if [[ "${DRY_RUN}" -eq 1 ]]; then + echo + echo "Dry run command:" + printf '%q ' "${CMD[@]}" + echo + exit 0 +fi + +"${CMD[@]}" +echo "Install complete. Restart Codex to pick up new skills." diff --git a/skills/maps-aggregator-config-engineer/SKILL.md b/skills/maps-aggregator-config-engineer/SKILL.md new file mode 100644 index 000000000..cbe4b5372 --- /dev/null +++ b/skills/maps-aggregator-config-engineer/SKILL.md @@ -0,0 +1,75 @@ +--- +name: maps-aggregator-config-engineer +description: Design and validate MAPS AggregatorManager configurations for windowed multi-input aggregation. Use when requirements involve windowDurationMs, timeoutMs, maxEventsPerTopic, contribution modes (FIRST or LAST), topic selectors, output transformers, scheduler controls, or aggregate summary payload behavior and require deployable YAML with verification steps. +--- + +# MAPS Aggregator Config Engineer + +Convert aggregation requirements into deployable `AggregatorManager.yaml` entities with deterministic window behavior and measurable validation. + +## Workflow + +1. Normalize aggregator contract. +- Extract input topics, output topic, window duration, timeout, contribution mode per input, selector rules, and expected aggregate output shape. +- Capture throughput constraints that drive `maxEventsPerTopic`, `maxBatchPerAggregator`, `mailboxCapacity`, and `stripeCount`. + +2. Map to concrete AggregatorManager fields. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md`. +- Update `/Users/krital/dev/starsense/mapsmessaging_server/AggregatorManager.yaml` as primary source. +- Include related destination/schema/transform config only when aggregation output requires it. + +3. Build deployable config. +- Prefer minimal diffs and deterministic naming for aggregators. +- Preserve field casing and DTO-compatible keys exactly. +- Keep contribution policy explicit for each input. + +4. Validate semantics before finalizing. +- Verify each aggregator has non-empty inputs and output topic. +- Check timing consistency: `timeoutMs >= windowDurationMs` unless explicitly justified. +- Check resource and fairness guardrails: `maxEventsPerTopic`, `maxBatchPerAggregator`, `mailboxCapacity`, `stripeCount`. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh` +- Run checks: +```bash +rg -n "aggregatorConfigList|windowDurationMs|timeoutMs|maxEventsPerTopic|contributionMode|outputTopic" /Users/krital/dev/starsense/mapsmessaging_server/AggregatorManager.yaml +``` + +5. Return output using contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/references/output-contract.md`. +- Always include assumptions, deployable YAML, apply steps, and verification with pass/fail criteria. + +## Aggregator-Specific Rules + +- Treat this as a unique MAPS capability, not a generic stream processor template. +- Do not simplify away per-input contribution modes. +- Keep aggregator window model explicit: arrival-time window + timeout closure behavior. +- Include expected summary payload assertions when requirements mention statistics (`timeStart`, `timeEnd`, `duration`, `sampleCount`, per-field stats). +- If requested behavior relies on unavailable stats/transform providers, state the limitation and provide nearest valid config. + +## Scenario Modes + +- `Simple Local Default`: + - Create one aggregator with 2 inputs, `LAST` contribution mode, and conservative window/timeout defaults. + - Include a minimal publish/consume verification for a single completed window. +- `Advanced Combination Matrix`: + - Generate 3 to 5 aggregator variants across contribution policies, window sizes, timeout sensitivity, and output transformer usage. + - Include operational tradeoffs for drop risk, latency, and fairness settings. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed: +- Aggregator semantics and patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md` +- Final response contract: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/references/output-contract.md` diff --git a/skills/maps-aggregator-config-engineer/agents/openai.yaml b/skills/maps-aggregator-config-engineer/agents/openai.yaml new file mode 100644 index 000000000..ee0f73874 --- /dev/null +++ b/skills/maps-aggregator-config-engineer/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Aggregator Config Engineer" + short_description: "Design and validate MAPS aggregator configs" + default_prompt: "Use $maps-aggregator-config-engineer to build deployable AggregatorManager configuration with windowing, contribution modes, and verification commands." diff --git a/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md b/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md new file mode 100644 index 000000000..7bdd0a5b3 --- /dev/null +++ b/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md @@ -0,0 +1,76 @@ +# Aggregator Design Guide + +## Core Config Surface + +Primary file: +- `/Users/krital/dev/starsense/mapsmessaging_server/AggregatorManager.yaml` + +Important root controls: +- `maxAggregators` +- `maxBatchPerAggregator` +- `mailboxCapacity` +- `idleSleepMs` +- `stripeCount` + +Per-aggregator controls (`aggregatorConfigList[]`): +- `enabled` +- `name` +- `inputs[]` +- `outputTopic` +- `windowDurationMs` +- `timeoutMs` +- `maxEventsPerTopic` +- `outputTransformers[]` + +Per-input controls (`inputs[]`): +- `topicName` +- `selector` +- `contributionMode` (`FIRST` or `LAST`) +- `transformer[]` + +## Design Patterns + +1. Multi-sensor window join +- Use one input per topic. +- Set `contributionMode: LAST` for latest-value semantics. +- Set `windowDurationMs` to expected telemetry cadence bucket. + +2. Strict first-event capture +- Use `contributionMode: FIRST` for race-free first-observation behavior. +- Keep `maxEventsPerTopic` low to bound memory. + +3. Partial-window tolerance +- Use `timeoutMs` to close windows when not all inputs arrive. +- Document how missing inputs should be interpreted downstream. + +4. Output shaping +- Use `outputTransformers` when aggregate envelope needs format adjustments. +- Verify destination contentType/schema expectations separately. + +## Validation Heuristics + +- `windowDurationMs` and `timeoutMs` must be positive. +- Default safety pattern: `timeoutMs >= windowDurationMs`. +- `maxEventsPerTopic` should scale with burst profile but remain bounded. +- High `stripeCount` without sufficient load may add scheduling overhead. + +## Verification Patterns + +1. Startup and load checks +```bash +docker logs 2>&1 | rg -n "AGGREGATOR_MANAGER_TASK_CREATED|AGGREGATOR_STARTED|AGGREGATOR_EXCEPTION|AGGREGATOR_EVENT_DROPPED" +``` + +2. Input publication checks +- Publish to each input topic with same correlation ID and close timestamps. + +3. Output assertions +- Confirm output topic receives aggregate payload. +- When stats are required, assert expected fields exist (for example `timeStart`, `timeEnd`, `duration`, `sampleCount`, and per-field aggregates) based on configured pipeline behavior. + +## Failure Classes + +- Window mismatch: events outside bucket not co-aggregated. +- Timeout too aggressive: windows close before full input set arrives. +- Contribution mismatch: FIRST vs LAST produces wrong representative values. +- Backpressure/drop: `maxEventsPerTopic` too small for ingress bursts. diff --git a/skills/maps-aggregator-config-engineer/references/output-contract.md b/skills/maps-aggregator-config-engineer/references/output-contract.md new file mode 100644 index 000000000..c56cb0780 --- /dev/null +++ b/skills/maps-aggregator-config-engineer/references/output-contract.md @@ -0,0 +1,44 @@ +# Output Contract + +Always return in this order. + +1. `Aggregation Requirement Mapping` +- Requirement phrase -> exact fields and absolute file paths. + +2. `Window Model` +- Explain windowDurationMs, timeoutMs, and contribution mode semantics for this design. + +3. `Assumptions` +- List all defaults and inferred values. + +4. `Deployable Config Entity` +- Patch blocks or full YAML implementing `AggregatorManager` changes. + +5. `Apply Steps` +- Exact commands to apply and reload/restart runtime. + +6. `Verification Plan` +- Input publish commands for each configured input topic. +- Output consume/assert commands with success criteria. +- Include aggregate summary field checks when required. + +7. `Risk Notes` +- Highlight likely operational risks (drop risk, timeout sensitivity, ordering assumptions). + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never omit contributionMode per input. +- Never omit both windowDurationMs and timeoutMs. +- Never claim aggregator correctness without output-topic evidence. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-aggregator-config-engineer/references/user-guide.md b/skills/maps-aggregator-config-engineer/references/user-guide.md new file mode 100644 index 000000000..0fa2685f6 --- /dev/null +++ b/skills/maps-aggregator-config-engineer/references/user-guide.md @@ -0,0 +1,105 @@ +# MAPS Aggregator Config Engineer - User Guide + +## What this skill does + +`maps-aggregator-config-engineer` generates and validates deployable `AggregatorManager.yaml` entities for MAPS windowed aggregation flows. + +Use it when you need: +- multiple input topics aggregated into one output topic +- explicit `windowDurationMs` / `timeoutMs` behavior +- per-input `contributionMode` (`FIRST` or `LAST`) +- verification commands, metrics, dashboards, and C4 diagrams + +## Installation + +### Option A: Install this one skill + +```bash +python3 ~/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py \ + --repo / \ + --path skills/maps-aggregator-config-engineer +``` + +### Option B: Install multiple skills in one command + +You do not need to install one at a time. The installer accepts multiple `--path` entries: + +```bash +python3 ~/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py \ + --repo / \ + --path skills/maps-aggregator-config-engineer \ + --path skills/maps-runtime-diagnostics \ + --path skills/maps-release-readiness-checker +``` + +### Option C: Install a full skill pack + +If your repository groups many skills under `skills/`, users can install each included skill path in one installer run (as in Option B). This is the cleanest "bundle" approach. + +After install: restart Codex so newly installed skills are available. + +## Usage pattern + +Prompt format that works well: + +```text +Use maps-aggregator-config-engineer in . +Goal: +Inputs: +Output requirements: deployable YAML, apply commands, runtime verification, metrics/dashboard, C4. +``` + +Example: + +```text +Use maps-aggregator-config-engineer in Simple Local Default mode. +Goal: Aggregate telemetry from /veh/a and /veh/b to /veh/agg every 5 seconds. +windowDurationMs: 5000 +timeoutMs: 7000 +contributionMode: LAST +maxEventsPerTopic: 100 +``` + +## Deployment model: individual skills vs a "master" skill + +Short answer: +- You can install skills individually. +- You can also deploy many skills together in one installer command. +- A "master" skill does not auto-install other skills by itself. + +Details: +- Skills are discovered as separate directories under `~/.codex/skills/`. +- A master/orchestrator skill can document and coordinate workflows, but Codex still needs each dependent skill directory installed to trigger those skills directly. +- For team rollout, prefer a single repository with all skills plus one install command containing multiple `--path` arguments. + +## Operational checks + +1. Validate skill files exist: + +```bash +test -f ~/.codex/skills/maps-aggregator-config-engineer/SKILL.md +``` + +2. Validate skill definition: + +```bash +bash ~/.codex/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh +``` + +3. In Codex, run a small Simple Local Default request and confirm it returns: +- `Aggregation Requirement Mapping` +- `Deployable Config Entity` +- `Apply Steps` +- `Verification Plan` +- `Scenario Metrics and Dashboard` +- `C4 Architecture Diagram` + +## Troubleshooting + +- Skill not appearing: + - Confirm folder path is `~/.codex/skills/maps-aggregator-config-engineer`. + - Restart Codex. +- Install script fails on private repo: + - set `GITHUB_TOKEN`/`GH_TOKEN` or ensure git credentials are configured. +- Runtime checks fail: + - verify MAPS container name, mounted config path, and MQTT listener ports. diff --git a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh new file mode 100755 index 000000000..5926f6edb --- /dev/null +++ b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-aggregator-config-engineer-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-aggregator-config-engineer-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-aggregator-config-engineer-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-aggregator-config-engineer runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_aggregator_config_engineer_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-aggregator-config-engineer-runtime-smoke.out 2>/tmp/maps-aggregator-config-engineer-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-aggregator-config-engineer-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_aggregator_config_engineer_runtime_smoke path." +fi + +echo "maps-aggregator-config-engineer runtime smoke PASS" diff --git a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh new file mode 100755 index 000000000..a9048365b --- /dev/null +++ b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh" +fi +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/aggregator-design-guide.md"; rg -n "contributionMode|windowDurationMs|timeoutMs" "${ROOT}/references/output-contract.md" >/dev/null +echo "maps-aggregator-config-engineer skill smoke PASS" diff --git a/skills/maps-artifact-execution-smoke-harness/SKILL.md b/skills/maps-artifact-execution-smoke-harness/SKILL.md new file mode 100644 index 000000000..5f4ea8ff4 --- /dev/null +++ b/skills/maps-artifact-execution-smoke-harness/SKILL.md @@ -0,0 +1,74 @@ +--- +name: maps-artifact-execution-smoke-harness +description: Execute generated MAPS artifacts end-to-end as smoke gates. Use when validating that skill-generated deployable YAML, deployment bundles, and command sets actually boot, bind listeners, route data, and satisfy runtime assertions in local or Docker environments. +--- + +# MAPS Artifact Execution Smoke Harness + +Run executable smoke gates against generated artifacts, not only document-level contract checks. + +## Workflow + +1. Normalize smoke target contract. +- Extract artifact source (skill output, file bundle, generated patch set). +- Identify runtime mode (local JVM or Docker). +- Identify expected listeners, namespaces, routes, and success markers. + +2. Build execution plan. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md`. +- Define phases: setup, apply, startup, listener verification, traffic verification, teardown. +- Require explicit timeout and fail-fast conditions per phase. +- Prefer bundled scripts when direct execution is requested: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh` + +3. Execute smoke phases. +- Setup: ensure ports are free and prior containers/processes are cleaned up safely. +- Apply: write or mount artifact set exactly as generated. +- Startup: launch MAPS and capture startup logs. +- Listener verification: prove required listeners are bound. +- Traffic verification: run protocol publish/consume or route assertions. +- Teardown: stop containers/processes and collect logs/artifacts. + +4. Evaluate and classify failures. +- Classify as apply, startup gate, bind, routing, transform/schema, or protocol egress failures. +- Separate environment issues from artifact defects. + +5. Return using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/references/output-contract.md`. +- Include exact commands, observed outcomes, and minimal rerun command set. + +## Rules + +- Never mark smoke PASS without startup plus listener plus traffic evidence. +- Never skip teardown commands. +- Prefer deterministic command blocks with bounded timeouts. +- Include absolute paths for all applied artifacts. + +## Scenario Modes + +- `Simple Local Default`: + - Run one local or Docker artifact with one protocol verification path. + - Return one PASS/FAIL decision and minimal remediation path. +- `Advanced Combination Matrix`: + - Run 3 to 6 artifact variants across protocol/deployment/connectivity profiles. + - Provide comparative outcome matrix and recommended promotion candidate. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to smoke execution (startup time, bind success rate, route success rate, error counts, retry/recovery timings). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-phase and per-protocol smoke metrics. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the executed flow and test harness boundaries. + +## Reference Loading + +Load only what is needed: +- Execution phases and commands: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md` +- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/references/output-contract.md` diff --git a/skills/maps-artifact-execution-smoke-harness/agents/openai.yaml b/skills/maps-artifact-execution-smoke-harness/agents/openai.yaml new file mode 100644 index 000000000..08f90ac0d --- /dev/null +++ b/skills/maps-artifact-execution-smoke-harness/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Artifact Execution Smoke" + short_description: "Run executable artifact smoke gates" + default_prompt: "Use $maps-artifact-execution-smoke-harness to execute generated MAPS artifacts end-to-end and return startup, listener, and traffic smoke evidence." diff --git a/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md b/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md new file mode 100644 index 000000000..f496f2872 --- /dev/null +++ b/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md @@ -0,0 +1,85 @@ +# Execution Catalog + +## Phase 1: Setup + +- Validate target files exist and paths are absolute. +- Confirm expected ports are not occupied before startup. +- For Docker mode, remove stale test containers by explicit name. + +Example checks: + +```bash +rg -n "NetworkManager|DestinationManager|routing|SchemaManager" /Users/krital/dev/starsense/mapsmessaging_server/*.yaml +(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | rg "1883|5672|8080|9001" || true +``` + +## Phase 2: Apply + +- Apply generated files exactly as delivered. +- For Docker, mount generated files under `/opt/maps/conf`. + +## Phase 3: Startup + +- Start process/container and capture logs. +- Detect blockers: license, missing provider, Consul mismatch, malformed YAML, bind failure. + +## Phase 4: Listener Verification + +- Validate all required protocol listeners are bound. +- For Docker mode, verify both host publish and in-container bind state. + +## Phase 5: Traffic Verification + +- Run ingress/egress checks with correlation IDs. +- Always subscribe before publish for MQTT checks; wait for subscriber readiness before sending test payload. +- For bridging paths, verify destination-side evidence only marks PASS. + +## Phase 6: Teardown + +- Stop and remove test process/container. +- Keep log snippets and command outputs for evidence. + +## Failure Classes + +- `apply_failure` +- `startup_gate_failure` +- `listener_bind_failure` +- `traffic_path_failure` +- `environment_failure` + +## Runnable Scripts + +- Single scenario runner: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh` +- Two-scenario matrix runner: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh` + +Example: + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel release --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --base-mqtt-port 2883 --base-http-port 28080 +``` + +Snapshot example (latest requested snapshot version): + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel snapshot --version 4.3.1-snapshot --arch arm64 --platform linux/arm64 --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --base-mqtt-port 3883 --base-http-port 38080 +``` + +x86 release example: + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel release --arch amd64 --platform linux/amd64 --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --base-mqtt-port 2883 --base-http-port 28080 +``` + +Auth-enabled MQTT example: + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel snapshot --version 4.3.1-snapshot --arch arm64 --platform linux/arm64 --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --mqtt-username maps-user --mqtt-password maps-pass --base-mqtt-port 4883 --base-http-port 48080 +``` + +Listener-only example for artifacts with non-MQTT flows: + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh --image mapsmessaging/server_daemon:latest --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --skip-mqtt --required-listeners 8080 --platform linux/amd64 --mqtt-port 5883 --http-port 58080 --force-clean +``` diff --git a/skills/maps-artifact-execution-smoke-harness/references/output-contract.md b/skills/maps-artifact-execution-smoke-harness/references/output-contract.md new file mode 100644 index 000000000..3a6cd8b47 --- /dev/null +++ b/skills/maps-artifact-execution-smoke-harness/references/output-contract.md @@ -0,0 +1,48 @@ +# Output Contract + +Always return in this order. + +1. `Smoke Scope` +- Artifact source, runtime mode, expected listeners/routes, and pass criteria. + +2. `Execution Plan` +- Numbered phases with exact commands and timeouts. + +3. `Applied Artifact Manifest` +- Absolute paths and mounted/applied file map. + +4. `Startup Evidence` +- Startup command outputs summary and blocker scan findings. + +5. `Listener Evidence` +- Bind checks and explicit pass/fail for each required listener. + +6. `Traffic Evidence` +- Producer/consumer or route verification outcomes with correlation markers. + +7. `Failure Classification` +- Failure class and root-cause notes when failing. + +8. `Remediation and Re-run` +- Exact fix commands and minimal rerun command set. + +9. `Teardown Evidence` +- Cleanup commands and final environment state check. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific smoke metrics with collection points and expected ranges. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the executed flow: + - Context and Container required. + - Component required when multiple test stages or protocol routes are involved. +- Include Mermaid source. + +## Guardrails + +- Never report PASS without startup, listener, and traffic evidence. +- Never omit teardown commands. +- Never omit absolute artifact paths. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-artifact-execution-smoke-harness/scenarios/default-matrix.md b/skills/maps-artifact-execution-smoke-harness/scenarios/default-matrix.md new file mode 100644 index 000000000..aceaddbb9 --- /dev/null +++ b/skills/maps-artifact-execution-smoke-harness/scenarios/default-matrix.md @@ -0,0 +1,11 @@ +# Default Matrix Scenarios + +1. `default-image-config` +- Start MAPS image with baked configuration. +- Verify startup and listeners. +- Verify MQTT publish/subscribe smoke. + +2. `mounted-artifacts` +- Mount artifact directory manager YAML files into `/opt/maps/conf`. +- Verify startup and listeners with mounted config. +- Verify MQTT publish/subscribe smoke. diff --git a/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh b/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh new file mode 100755 index 000000000..ffc743dc4 --- /dev/null +++ b/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh @@ -0,0 +1,277 @@ +#!/usr/bin/env bash +set -euo pipefail + +IMAGE="mapsmessaging/server_daemon:latest" +CONTAINER_NAME="maps-artifact-smoke" +ARTIFACT_DIR="" +HOST_MQTT_PORT="1883" +HOST_HTTP_PORT="8080" +TOPIC="/skill/artifact/smoke" +SKIP_MQTT=0 +FORCE_CLEAN=0 +CONTAINER_CONF_DIR="/message_daemon-3.3.0/conf" +TARGET_PLATFORM="" +MQTT_USERNAME="" +MQTT_PASSWORD="" +REQUIRED_LISTENERS="" + +usage() { + cat < Docker image (default: ${IMAGE}) + --container-name Container name (default: ${CONTAINER_NAME}) + --artifact-dir Directory containing MAPS manager YAML artifacts to mount + --mqtt-port Host MQTT port (default: ${HOST_MQTT_PORT}) + --http-port Host HTTP port (default: ${HOST_HTTP_PORT}) + --topic MQTT smoke topic (default: ${TOPIC}) + --container-conf-dir Config directory inside container (default: ${CONTAINER_CONF_DIR}) + --platform Docker target platform (for example linux/amd64, linux/arm64) + --mqtt-username MQTT username for smoke publish/subscribe (optional) + --mqtt-password MQTT password for smoke publish/subscribe (optional) + --required-listeners Required container listener ports (for example 1883,8080) + --skip-mqtt Skip MQTT publish/subscribe smoke check + --force-clean Remove existing container with same name before run + -h, --help Show this help +USAGE +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --image) + IMAGE="$2"; shift 2 ;; + --container-name) + CONTAINER_NAME="$2"; shift 2 ;; + --artifact-dir) + ARTIFACT_DIR="$2"; shift 2 ;; + --mqtt-port) + HOST_MQTT_PORT="$2"; shift 2 ;; + --http-port) + HOST_HTTP_PORT="$2"; shift 2 ;; + --topic) + TOPIC="$2"; shift 2 ;; + --container-conf-dir) + CONTAINER_CONF_DIR="$2"; shift 2 ;; + --platform) + TARGET_PLATFORM="$2"; shift 2 ;; + --mqtt-username) + MQTT_USERNAME="$2"; shift 2 ;; + --mqtt-password) + MQTT_PASSWORD="$2"; shift 2 ;; + --required-listeners) + REQUIRED_LISTENERS="$2"; shift 2 ;; + --skip-mqtt) + SKIP_MQTT=1; shift ;; + --force-clean) + FORCE_CLEAN=1; shift ;; + -h|--help) + usage; exit 0 ;; + *) + echo "Unknown argument: $1" >&2 + usage + exit 2 ;; + esac +done + +require_cmd() { + if ! command -v "$1" >/dev/null 2>&1; then + echo "Missing required command: $1" >&2 + exit 1 + fi +} + +port_in_use() { + local port="$1" + if command -v lsof >/dev/null 2>&1; then + lsof -nP -iTCP:"${port}" -sTCP:LISTEN >/dev/null 2>&1 + return $? + fi + if command -v ss >/dev/null 2>&1; then + ss -lnt | awk '{print $4}' | grep -E "[:.]${port}$" >/dev/null 2>&1 + return $? + fi + if command -v netstat >/dev/null 2>&1; then + netstat -lnt 2>/dev/null | awk '{print $4}' | grep -E "[:.]${port}$" >/dev/null 2>&1 + return $? + fi + echo "No supported socket tool found (lsof/ss/netstat)." >&2 + exit 1 +} + +cleanup() { + docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true +} + +require_cmd docker +if ! docker info >/dev/null 2>&1; then + echo "Docker daemon is not accessible from this environment." >&2 + exit 1 +fi + +if [[ "${FORCE_CLEAN}" -eq 1 ]]; then + cleanup +fi + +if [[ -z "${REQUIRED_LISTENERS}" ]]; then + if [[ "${SKIP_MQTT}" -eq 0 ]]; then + REQUIRED_LISTENERS="1883" + else + REQUIRED_LISTENERS="" + fi +fi + +if docker ps -a --format '{{.Names}}' | grep -Fx "${CONTAINER_NAME}" >/dev/null 2>&1; then + echo "Container ${CONTAINER_NAME} already exists. Use --force-clean to replace it." >&2 + exit 1 +fi + +if port_in_use "${HOST_MQTT_PORT}"; then + echo "Port ${HOST_MQTT_PORT} is already in use; refusing to start smoke run." >&2 + exit 1 +fi +if port_in_use "${HOST_HTTP_PORT}"; then + echo "Port ${HOST_HTTP_PORT} is already in use; refusing to start smoke run." >&2 + exit 1 +fi + +RUN_ARGS=( + run -d + --name "${CONTAINER_NAME}" + -p "${HOST_MQTT_PORT}:1883/tcp" + -p "${HOST_HTTP_PORT}:8080/tcp" +) +if [[ -n "${TARGET_PLATFORM}" ]]; then + RUN_ARGS+=( --platform "${TARGET_PLATFORM}" ) +fi + +if [[ -n "${ARTIFACT_DIR}" ]]; then + if [[ ! -d "${ARTIFACT_DIR}" ]]; then + echo "Artifact directory does not exist: ${ARTIFACT_DIR}" >&2 + exit 1 + fi + for f in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ARTIFACT_DIR}/${f}" ]]; then + RUN_ARGS+=( -v "${ARTIFACT_DIR}/${f}:${CONTAINER_CONF_DIR}/${f}:ro" ) + fi + done +fi + +RUN_ARGS+=("${IMAGE}") + +echo "Starting container ${CONTAINER_NAME} using image ${IMAGE}" +docker "${RUN_ARGS[@]}" >/dev/null +trap cleanup EXIT + +sleep 4 + +if [[ "$(docker inspect -f '{{.State.Running}}' "${CONTAINER_NAME}")" != "true" ]]; then + echo "Container exited during startup" >&2 + docker logs "${CONTAINER_NAME}" 2>&1 | sed -n '1,200p' >&2 + exit 1 +fi + +echo "Checking startup logs for hard blockers" +if docker logs "${CONTAINER_NAME}" 2>&1 | rg -n "Address already in use|BindException|Failed to bind|Protocol not available|Cannot assign requested address" >/tmp/${CONTAINER_NAME}-errors.log; then + echo "Startup blockers detected:" >&2 + sed -n '1,120p' /tmp/${CONTAINER_NAME}-errors.log >&2 + exit 1 +fi + +if docker logs "${CONTAINER_NAME}" 2>&1 | rg -n "ConsulManagerFactory|Consol Server is not responding" >/tmp/${CONTAINER_NAME}-consul.warn; then + echo "Non-blocking warning: Consul unavailable, expecting file-based fallback." + sed -n '1,80p' /tmp/${CONTAINER_NAME}-consul.warn +fi + +echo "Verifying listeners inside container" +docker exec "${CONTAINER_NAME}" sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | sed -n "1,120p"' >/tmp/${CONTAINER_NAME}-listeners.log || true +if [[ -n "${REQUIRED_LISTENERS}" ]]; then + attempt=0 + while true; do + missing=0 + IFS=',' read -r -a ports <<< "${REQUIRED_LISTENERS}" + for p in "${ports[@]}"; do + p_trimmed="$(echo "${p}" | tr -d '[:space:]')" + if [[ -z "${p_trimmed}" ]]; then + continue + fi + if ! grep -q ":${p_trimmed}" /tmp/${CONTAINER_NAME}-listeners.log; then + missing=1 + break + fi + done + if [[ "${missing}" -eq 0 ]]; then + break + fi + attempt=$((attempt + 1)) + if [[ "${attempt}" -ge 30 ]]; then + echo "Listener check failed: expected listeners [${REQUIRED_LISTENERS}] were not all bound" >&2 + sed -n '1,120p' /tmp/${CONTAINER_NAME}-listeners.log >&2 || true + exit 1 + fi + sleep 1 + docker exec "${CONTAINER_NAME}" sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | sed -n "1,120p"' >/tmp/${CONTAINER_NAME}-listeners.log || true + done +fi + +if ! docker exec "${CONTAINER_NAME}" sh -lc 'echo ok' >/dev/null 2>&1; then + echo "Listener check failed" >&2 + exit 1 +fi + +if [[ "${SKIP_MQTT}" -eq 0 ]]; then + require_cmd mosquitto_pub + require_cmd mosquitto_sub + + CORR="artifact-smoke-$(date +%s)" + success=0 + for attempt in 1 2 3; do + SUB_OUT="/tmp/${CONTAINER_NAME}-mqtt-${attempt}.out" + SUB_ERR="/tmp/${CONTAINER_NAME}-mqtt-sub-${attempt}.err" + PUB_ERR="/tmp/${CONTAINER_NAME}-mqtt-pub-${attempt}.err" + : >"${SUB_OUT}" + : >"${SUB_ERR}" + : >"${PUB_ERR}" + + echo "Running MQTT round-trip smoke check (attempt ${attempt}/3) on topic ${TOPIC}" + SUB_CMD=(timeout 12 mosquitto_sub -d -V mqttv311 -h 127.0.0.1 -p "${HOST_MQTT_PORT}" -t "${TOPIC}" -C 1) + if [[ -n "${MQTT_USERNAME}" ]]; then SUB_CMD+=( -u "${MQTT_USERNAME}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then SUB_CMD+=( -P "${MQTT_PASSWORD}" ); fi + "${SUB_CMD[@]}" >"${SUB_OUT}" 2>"${SUB_ERR}" & + SUB_PID=$! + for _ in 1 2 3 4 5; do + if ! kill -0 "${SUB_PID}" 2>/dev/null; then + break + fi + if rg -n "CONNACK|SUBACK|Subscribed" "${SUB_ERR}" >/dev/null 2>&1; then + break + fi + sleep 1 + done + + PUB_CMD=(mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${HOST_MQTT_PORT}" -t "${TOPIC}" -q 1 -m "${CORR}") + if [[ -n "${MQTT_USERNAME}" ]]; then PUB_CMD+=( -u "${MQTT_USERNAME}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then PUB_CMD+=( -P "${MQTT_PASSWORD}" ); fi + if ! "${PUB_CMD[@]}" 2>"${PUB_ERR}"; then + wait "${SUB_PID}" || true + sleep 1 + continue + fi + + if wait "${SUB_PID}" && grep -F "${CORR}" "${SUB_OUT}" >/dev/null 2>&1; then + success=1 + break + fi + sleep 1 + done + + if [[ "${success}" -ne 1 ]]; then + echo "MQTT smoke failed after retries" >&2 + sed -n '1,80p' /tmp/${CONTAINER_NAME}-mqtt-sub-3.err >&2 || true + sed -n '1,80p' /tmp/${CONTAINER_NAME}-mqtt-pub-3.err >&2 || true + docker logs "${CONTAINER_NAME}" 2>&1 | tail -n 120 >&2 || true + exit 1 + fi +fi + +echo "Artifact smoke PASS" diff --git a/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh new file mode 100755 index 000000000..c48d2c0f6 --- /dev/null +++ b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-artifact-execution-smoke-harness-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-artifact-execution-smoke-harness-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-artifact-execution-smoke-harness-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-artifact-execution-smoke-harness runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_artifact_execution_smoke_harness_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-artifact-execution-smoke-harness-runtime-smoke.out 2>/tmp/maps-artifact-execution-smoke-harness-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-artifact-execution-smoke-harness-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_artifact_execution_smoke_harness_runtime_smoke path." +fi + +echo "maps-artifact-execution-smoke-harness runtime smoke PASS" diff --git a/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh new file mode 100755 index 000000000..d49521e2b --- /dev/null +++ b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh" +fi +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/execution-catalog.md"; bash -n "${ROOT}/scripts/run_artifact_smoke.sh"; bash -n "${ROOT}/scripts/run_matrix.sh" +echo "maps-artifact-execution-smoke-harness skill smoke PASS" diff --git a/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh b/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh new file mode 100755 index 000000000..baec39bf1 --- /dev/null +++ b/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh @@ -0,0 +1,204 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +RUNNER="${SCRIPT_DIR}/run_artifact_smoke.sh" + +IMAGE="" +ARTIFACT_DIR="${ROOT_DIR}" +BASE_MQTT_PORT="1883" +BASE_HTTP_PORT="8080" +INCLUDE_DEFAULT_IMAGE=0 +INCLUDE_UNPATCHED=0 +CHANNEL="release" +VERSION="4.3.1-snapshot" +ARCH="auto" +PLATFORM="" +SKIP_MQTT=0 +MQTT_USERNAME="" +MQTT_PASSWORD="" + +detect_arch() { + local machine + machine="$(uname -m || true)" + case "${machine}" in + arm64|aarch64) echo "arm64" ;; + x86_64|amd64) echo "amd64" ;; + *) echo "amd64" ;; + esac +} + +resolve_image() { + local selected_arch="$1" + if [[ "${CHANNEL}" == "snapshot" ]]; then + if [[ "${selected_arch}" == "arm64" ]]; then + echo "mapsmessaging/server_daemon_arm_${VERSION}:latest" + else + echo "mapsmessaging/server_daemon_${VERSION}:latest" + fi + else + echo "mapsmessaging/server_daemon:latest" + fi +} + +usage() { + cat < Docker image to test (overrides channel/version resolution) + --channel Image channel (default: ${CHANNEL}) + --version Snapshot version (default: ${VERSION}; used when channel=snapshot) + --arch Architecture selector for snapshot image tags (default: ${ARCH}) + --platform Docker run target platform (default: derived from --arch) + --skip-mqtt Skip MQTT traffic smoke and run startup/listener-only checks + --mqtt-username MQTT username for smoke checks (optional) + --mqtt-password MQTT password for smoke checks (optional) + --artifact-dir Artifact directory for mounted-artifacts scenario (default: repo root) + --base-mqtt-port Base host MQTT port (default: ${BASE_MQTT_PORT}) + --base-http-port Base host HTTP port (default: ${BASE_HTTP_PORT}) + --include-default-image Also run baked image config scenario (may require Consul) + --include-unpatched Also run mounted-artifacts scenario without Consul patch + -h, --help Show this help +USAGE +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --image) + IMAGE="$2"; shift 2 ;; + --channel) + CHANNEL="$2"; shift 2 ;; + --version) + VERSION="$2"; shift 2 ;; + --arch) + ARCH="$2"; shift 2 ;; + --platform) + PLATFORM="$2"; shift 2 ;; + --skip-mqtt) + SKIP_MQTT=1; shift ;; + --mqtt-username) + MQTT_USERNAME="$2"; shift 2 ;; + --mqtt-password) + MQTT_PASSWORD="$2"; shift 2 ;; + --artifact-dir) + ARTIFACT_DIR="$2"; shift 2 ;; + --base-mqtt-port) + BASE_MQTT_PORT="$2"; shift 2 ;; + --base-http-port) + BASE_HTTP_PORT="$2"; shift 2 ;; + --include-default-image) + INCLUDE_DEFAULT_IMAGE=1; shift ;; + --include-unpatched) + INCLUDE_UNPATCHED=1; shift ;; + -h|--help) + usage; exit 0 ;; + *) + echo "Unknown argument: $1" >&2 + usage + exit 2 ;; + esac +done + +if [[ "${CHANNEL}" != "release" && "${CHANNEL}" != "snapshot" ]]; then + echo "Invalid --channel: ${CHANNEL} (expected release or snapshot)" >&2 + exit 2 +fi +if [[ "${ARCH}" != "auto" && "${ARCH}" != "amd64" && "${ARCH}" != "arm64" ]]; then + echo "Invalid --arch: ${ARCH} (expected auto, amd64, or arm64)" >&2 + exit 2 +fi + +if [[ -z "${IMAGE}" ]]; then + SELECTED_ARCH="${ARCH}" + if [[ "${SELECTED_ARCH}" == "auto" ]]; then + SELECTED_ARCH="$(detect_arch)" + fi + IMAGE="$(resolve_image "${SELECTED_ARCH}")" +fi +if [[ -z "${PLATFORM}" ]]; then + EFFECTIVE_ARCH="${ARCH}" + if [[ "${EFFECTIVE_ARCH}" == "auto" ]]; then + EFFECTIVE_ARCH="$(detect_arch)" + fi + PLATFORM="linux/${EFFECTIVE_ARCH}" +fi + +EXTRA_ARGS=() +if [[ "${SKIP_MQTT}" -eq 1 ]]; then + EXTRA_ARGS+=( --skip-mqtt ) +fi +if [[ -n "${MQTT_USERNAME}" ]]; then + EXTRA_ARGS+=( --mqtt-username "${MQTT_USERNAME}" ) +fi +if [[ -n "${MQTT_PASSWORD}" ]]; then + EXTRA_ARGS+=( --mqtt-password "${MQTT_PASSWORD}" ) +fi + +FIRST_MQTT_PORT="${BASE_MQTT_PORT}" +FIRST_HTTP_PORT="${BASE_HTTP_PORT}" +SECOND_MQTT_PORT="$((BASE_MQTT_PORT + 1))" +SECOND_HTTP_PORT="$((BASE_HTTP_PORT + 1))" +THIRD_MQTT_PORT="$((BASE_MQTT_PORT + 2))" +THIRD_HTTP_PORT="$((BASE_HTTP_PORT + 2))" + +TMP_DIR="$(mktemp -d /tmp/maps-artifact-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for f in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ARTIFACT_DIR}/${f}" ]]; then + cp "${ARTIFACT_DIR}/${f}" "${TMP_DIR}/${f}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi + +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${INCLUDE_DEFAULT_IMAGE}" -eq 1 ]]; then + echo "Scenario 1/3: default image config" + bash "${RUNNER}" \ + --image "${IMAGE}" \ + --container-name maps-artifact-smoke-default \ + --platform "${PLATFORM}" \ + --mqtt-port "${FIRST_MQTT_PORT}" \ + --http-port "${FIRST_HTTP_PORT}" \ + --topic /skill/artifact/smoke/default \ + "${EXTRA_ARGS[@]}" \ + --force-clean +fi + +echo "Scenario 2/3: mounted artifacts (consul-optional patch)" +bash "${RUNNER}" \ + --image "${IMAGE}" \ + --container-name maps-artifact-smoke-mounted-patched \ + --platform "${PLATFORM}" \ + --artifact-dir "${TMP_DIR}" \ + --mqtt-port "${SECOND_MQTT_PORT}" \ + --http-port "${SECOND_HTTP_PORT}" \ + --topic /skill/artifact/smoke/mounted/patched \ + "${EXTRA_ARGS[@]}" \ + --force-clean + +if [[ "${INCLUDE_UNPATCHED}" -eq 1 ]]; then + echo "Scenario 3/3: mounted artifacts (as-is)" + bash "${RUNNER}" \ + --image "${IMAGE}" \ + --container-name maps-artifact-smoke-mounted-unpatched \ + --platform "${PLATFORM}" \ + --artifact-dir "${ARTIFACT_DIR}" \ + --mqtt-port "${THIRD_MQTT_PORT}" \ + --http-port "${THIRD_HTTP_PORT}" \ + --topic /skill/artifact/smoke/mounted/unpatched \ + "${EXTRA_ARGS[@]}" \ + --force-clean +fi + +echo "Matrix smoke PASS" diff --git a/skills/maps-canbus-ingestion-builder/SKILL.md b/skills/maps-canbus-ingestion-builder/SKILL.md new file mode 100644 index 000000000..9018a0eeb --- /dev/null +++ b/skills/maps-canbus-ingestion-builder/SKILL.md @@ -0,0 +1,73 @@ +--- +name: maps-canbus-ingestion-builder +description: Build deployable MAPS CAN bus ingestion configurations for canbus endpoints and N2K protocol processing. Use when requirements include SocketCAN or vcan device setup, J1939 or N2K parsing behavior, topic template mapping, JSON conversion settings, raw frame forwarding, and protocol fan-out verification. +--- + +# MAPS CAN Bus Ingestion Builder + +Convert CAN ingestion requirements into deployable MAPS configs with deterministic verification for vcan and native interfaces. + +## Workflow + +1. Normalize CAN contract. +- Extract interface mode (vcan or native), device name (`can0`, `vcan0`, etc.), protocol behavior (`n2k` decode vs raw canbus), topic naming requirements, parse-to-JSON expectations, and schema/database source. + +2. Map to config surfaces. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md`. +- Update `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` for endpoint and protocol binding. +- Update destination/schema mappings only when requested by pipeline behavior. + +3. Build deployable entities. +- Prefer minimal diffs. +- Keep endpoint and protocol alignment explicit (`endPointConfig.type: canbus`, `protocolConfigs[].type: n2k` when decoding N2K). +- Use deterministic interface naming (`canbus--`). + +4. Validate before finalizing. +- Verify endpoint/protocol consistency and topic templates. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh` +- Include runtime checks: +```bash +rg -n "type: canbus|type: n2k|deviceName|topicNameTemplate|parseToJson" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "N2K_PROTOCOL|canbus" /Users/krital/dev/starsense/mapsmessaging_server/src/main/java/io/mapsmessaging/network/protocol/impl/n2k /Users/krital/dev/starsense/mapsmessaging_server/src/main/java/io/mapsmessaging/network/io/impl/canbus +``` + +5. Return using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/references/output-contract.md`. +- Include assumptions, deployable YAML, apply steps, and vcan/native verification. + +## CAN-Specific Rules + +- Treat vcan and native CAN as separate operational profiles. +- Include `deviceName` and protocol mode explicitly for every generated endpoint. +- Keep parser mode explicit: decoded N2K JSON vs raw canbus frame flow. +- If N2K database path/content is required, state source and fallback behavior. +- Do not claim hardware parity from vcan-only validation. + +## Scenario Modes + +- `Simple Local Default`: + - Use a vcan profile with one device and one decode mode for fast local validation. + - Include one injection path and one mapped-topic assertion. +- `Advanced Combination Matrix`: + - Provide 3 to 5 variants across vcan/native, raw/decode mode, topic templates, and downstream routing targets. + - Include hardware-specific caveats and recommended rollout order. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed: +- Mapping and runtime checks: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md` +- Response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/references/output-contract.md` diff --git a/skills/maps-canbus-ingestion-builder/agents/openai.yaml b/skills/maps-canbus-ingestion-builder/agents/openai.yaml new file mode 100644 index 000000000..4da8830f7 --- /dev/null +++ b/skills/maps-canbus-ingestion-builder/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS CAN Bus Ingestion Builder" + short_description: "Build MAPS CAN/J1939/N2K ingestion configs" + default_prompt: "Use $maps-canbus-ingestion-builder to convert CAN/J1939/N2K ingestion requirements into deployable MAPS configuration and verification commands." diff --git a/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md b/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md new file mode 100644 index 000000000..3953c4342 --- /dev/null +++ b/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md @@ -0,0 +1,55 @@ +# CAN Bus Mapping Guide + +## Primary Config Surface + +- `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + - `endPointConfig.type: canbus` + - `endPointConfig.deviceName` + - `protocolConfigs[].type: n2k` for decoded N2K workflows + +## Protocol/Endpoint Alignment + +1. Raw CAN ingestion +- Endpoint type: `canbus` +- Protocol: can remain raw path if no N2K decode required +- Content type typically `canbus` + +2. N2K decode path +- Endpoint type: `canbus` +- Protocol config type: `n2k` +- Configure N2K options: + - `topicNameTemplate` + - `unknownPacketTopic` + - `parseToJson` + - database source (`databasePath` or embedded base64) + +## Environment Profiles + +1. vcan profile +- Use `vcan0` (or similar) for reproducible local tests. +- Suitable for parser and routing validation. + +2. Native CAN profile +- Use physical interface (`can0`, `can1`) and hardware-specific setup. +- Validate throughput and timing characteristics separately from vcan. + +## Validation Commands + +```bash +rg -n "type: canbus|type: n2k|deviceName|topicNameTemplate|unknownPacketTopic|parseToJson" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "N2K_PROTOCOL_CREATED_AND_BOUND|N2K_PROTOCOL_PARSING_PACKET|N2K_PROTOCOL_PARSED" /Users/krital/dev/starsense/mapsmessaging_server/src/main/java/io/mapsmessaging/logging/ServerLogMessages.java +``` + +## Verification Skeleton + +- Start with listener/startup diagnostics. +- Inject CAN frames (vcan or hardware). +- Verify expected mapped MAPS topics receive decoded or raw events. +- Confirm metadata markers (for example `protocol: n2k`) when decode path is enabled. + +## Failure Classes + +- Endpoint bound to wrong `deviceName`. +- N2K config references missing database definitions. +- parseToJson mismatch with expected downstream content type. +- Raw and decoded topic templates conflicting. diff --git a/skills/maps-canbus-ingestion-builder/references/output-contract.md b/skills/maps-canbus-ingestion-builder/references/output-contract.md new file mode 100644 index 000000000..c32877bf1 --- /dev/null +++ b/skills/maps-canbus-ingestion-builder/references/output-contract.md @@ -0,0 +1,44 @@ +# Output Contract + +Always return in this order. + +1. `CAN Requirement Mapping` +- Requirement phrase -> exact fields and absolute file paths. + +2. `Interface Profile` +- State vcan or native profile and device names used. + +3. `Assumptions` +- List inferred protocol/decode choices and database defaults. + +4. `Deployable Config Entity` +- Patch blocks or full YAML implementing canbus and protocol changes. + +5. `Apply Steps` +- Exact commands to apply changes and restart/reload runtime. + +6. `Verification` +- Startup checks. +- vcan/native injection commands or harness instructions. +- Output topic assertions with expected markers. + +7. `Limits and Risks` +- Mention differences between vcan validation and physical bus behavior. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never omit `deviceName` for canbus endpoints. +- Never omit protocol mode (raw or n2k decode). +- Never claim success without destination topic evidence. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh new file mode 100755 index 000000000..9d9550019 --- /dev/null +++ b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-canbus-ingestion-builder-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-canbus-ingestion-builder-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-canbus-ingestion-builder-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-canbus-ingestion-builder runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_canbus_ingestion_builder_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-canbus-ingestion-builder-runtime-smoke.out 2>/tmp/maps-canbus-ingestion-builder-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-canbus-ingestion-builder-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_canbus_ingestion_builder_runtime_smoke path." +fi + +echo "maps-canbus-ingestion-builder runtime smoke PASS" diff --git a/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh new file mode 100755 index 000000000..170a61b27 --- /dev/null +++ b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh" +fi +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/canbus-mapping-guide.md" +echo "maps-canbus-ingestion-builder skill smoke PASS" diff --git a/skills/maps-deployment-packager/SKILL.md b/skills/maps-deployment-packager/SKILL.md new file mode 100644 index 000000000..573daf8f1 --- /dev/null +++ b/skills/maps-deployment-packager/SKILL.md @@ -0,0 +1,108 @@ +--- +name: maps-deployment-packager +description: Package MAPS Messaging manager configurations into deployable artifacts for local runtime, Docker-based deployments, and cloud targets including Fly.io, AWS, Google Cloud, and Microsoft Azure, including air-gapped, degraded-connectivity, and delay-tolerant buffer-and-forward scenarios. Use when requirements ask for environment-specific packaging, authentication profiles, storage and volume options, file or Consul configuration source modes, startup command sets, container mounts, offline artifact bundles, or repeatable apply and validation procedures. +--- + +# MAPS Deployment Packager + +Convert MAPS manager YAML and runtime settings into deployable packaging outputs with deterministic apply and verification steps. + +## Workflow + +1. Normalize deployment target contract. +- Identify target mode: local process, Docker container, Kubernetes-style config bundle, or cloud target (Fly.io, AWS, Google Cloud, Microsoft Azure). +- Extract required manager files, environment variables, port mappings, and runtime dependencies. +- Identify connectivity profile: connected, air-gapped, degraded/intermittent, or delay-tolerant store-and-forward. +- Extract deployment control dimensions: + - authentication mode (any supported MAPS mechanism for this deployment) + - storage and volume profile (ephemeral vs persistent, file/memory/tier choices) + - configuration source mode (local file-based vs Consul-based) + - state/config backend option details where applicable: + - Fly.io KV default profile (no cluster required) + - optional dedicated Consul cluster mode (HCP Consul or self-managed Consul) + - object storage provider option details where applicable: + - AWS S3 + - S3-compatible object storage (including Cloudflare R2) + +2. Build environment packaging plan. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/deployment-targets.md`. +- Generate artifact set for the selected target with minimal duplication. +- Keep config and runtime command paths explicit. + +3. Materialize deployable entities. +- Local: resolved manager YAML set + start command sequence. +- Docker: bind-mount plan, `docker run` command, image tag, exposed ports. +- Kubernetes-style: ConfigMap-ready YAML payload blocks and container args/env. +- Cloud-target packaging: + - Fly.io deployment bundle and service config, including optional Fly KV mapping profile when selected + - AWS deployment bundle (container/task/service profile) + - Google Cloud deployment bundle (container/service profile) + - Microsoft Azure deployment bundle (container/app service profile) + - optional dedicated Consul cluster profile for edge/cloud: + - HCP Consul + - self-managed Consul + - optional object storage profile: + - AWS S3 + - S3-compatible endpoints (for example Cloudflare R2) +- Air-gapped/degraded profile: offline image and dependency manifest, local config bundle, and replay/retry startup strategy with explicit buffer storage paths. + +4. Validate packaging integrity. +- Ensure all referenced files exist. +- Check config mount paths and runtime env coherence (`MAPS_HOME`, `MAPS_CONF`, `MAPS_DATA`). +- Include startup diagnostics and listener checks. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh` +- Validate store-and-forward readiness (persistent destination paths, queue/backlog expectations, and recovery behavior after reconnect). +- Validate auth, storage, and config-source alignment: + - auth manager configuration matches selected authentication mode + - storage/volume mappings match persistence expectations + - config source mode is explicit (file or Consul) and startup flags/env align + - when Fly.io is selected with KV mode, no Consul cluster dependency is required + - when Consul mode is selected, deployment specifies dedicated Consul topology (HCP or self-managed) + - when object storage is selected, provider, endpoint, bucket, and credentials mapping are explicit + +5. Return using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/output-contract.md`. +- Include artifacts, apply commands, validation, and rollback hints. + +## Rules + +- Prefer repository-native startup scripts and layout conventions. +- Keep generated artifacts environment-specific and explicit. +- Never omit absolute file paths in package manifests. +- Include both startup diagnostics and protocol listener checks. +- For air-gapped profiles, avoid steps requiring live external dependency fetch at deploy time. +- For delay-tolerant profiles, include explicit buffering assumptions and replay verification steps. +- Always include at least one simple local deployment profile and one advanced cloud profile in matrix mode. +- Always include auth mode, storage mode, and config source mode in generated deployment profiles. +- Always include backend option details when relevant: Fly KV usage, Consul topology choice, and object storage provider choice. + +## Scenario Modes + +- `Simple Local Default`: + - Package one local runtime profile and one minimal Docker run profile with working defaults. + - Include one default auth mode, one default persistent storage mode, and one default file-based config mode for quick local testing. + - Include shortest apply/verify path for local smoke execution. +- `Advanced Combination Matrix`: + - Provide 4 to 8 packaging variants across local, Docker, Kubernetes-style, Fly.io, AWS, Google Cloud, Azure, air-gapped, degraded, and delay-tolerant profiles. + - Include auth/storage/config-source combinations in each variant. + - Include artifact differences, operational tradeoffs, and recommended profile. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed: +- Target packaging patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/deployment-targets.md` +- Final response structure: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/output-contract.md` diff --git a/skills/maps-deployment-packager/agents/openai.yaml b/skills/maps-deployment-packager/agents/openai.yaml new file mode 100644 index 000000000..56b5000da --- /dev/null +++ b/skills/maps-deployment-packager/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Deployment Packager" + short_description: "Package MAPS configs for deployment targets" + default_prompt: "Use $maps-deployment-packager to turn MAPS manager configs into deployable local, Docker, or Kubernetes packaging artifacts with apply and validation steps." diff --git a/skills/maps-deployment-packager/references/deployment-targets.md b/skills/maps-deployment-packager/references/deployment-targets.md new file mode 100644 index 000000000..00f7fe2c9 --- /dev/null +++ b/skills/maps-deployment-packager/references/deployment-targets.md @@ -0,0 +1,143 @@ +# Deployment Targets + +## Deployment Dimension Matrix + +Every deployment profile must declare all dimensions: +- Platform: local, Docker, Kubernetes-style, Fly.io, AWS, Google Cloud, Azure +- Connectivity: connected, air-gapped, degraded, delay-tolerant +- Authentication: selected MAPS-supported auth mechanism(s) for this deployment (for example htpasswd, LDAP, JWT, Auth0, token-based) +- Storage and volumes: ephemeral or persistent; file/memory/tier mix; volume mount strategy +- Config source: local file-based config or Consul-based config +- Backend option: Fly KV, no dedicated backend, or dedicated Consul cluster +- Consul topology (if Consul mode): HCP Consul or self-managed Consul +- Object storage option (if used): AWS S3 or S3-compatible provider (for example Cloudflare R2) + +## Local Runtime Packaging + +Inputs: +- manager YAML files in repo root or `src/main/resources` +- runtime env: `MAPS_HOME`, `MAPS_CONF`, `MAPS_DATA` +- explicit auth/storage/config-source selections + +Execution references: +- `/Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/start.sh` +- `/Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/start.bat` + +Output expectations: +- complete file set for conf directory +- startup command block +- post-start diagnostics + +## Docker Packaging + +Execution references: +- `/Users/krital/dev/starsense/mapsmessaging_server/buildDocker.sh` +- `/Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/startDocker.sh` +- `/Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/docker_run.sh` + +Output expectations: +- image tag and run command +- mounted config map (host path -> `/opt/maps/conf/...`) +- port mappings and env vars +- auth and storage env/volume mappings +- startup diagnostics (`docker logs`, listener checks) + +## Cloud Target Packaging + +### Fly.io +- Generate app and service deployment bundle with mapped ports, env, volumes, and config source mode. +- Offer Fly.io KV profile as a first-class default for lightweight state/config needs without running a Consul cluster. +- If Consul-based mode is selected, treat it as an explicit override and include dedicated Consul topology choice. + +### AWS +- Generate container deployment profile (task/service style) including volume/storage class and auth/config parameters. + +### Google Cloud +- Generate container service profile with runtime env, mounts, and config source wiring. + +### Microsoft Azure +- Generate container app/service profile with env, volumes, and config-source mode. + +For all cloud targets: +- include authentication profile mapping +- include storage/volume profile mapping +- include file vs Consul configuration mode mapping +- include backend option mapping (Fly KV, dedicated Consul, or none) +- if dedicated Consul is used, include topology (HCP or self-managed), addresses, and bootstrap/join details +- if object storage is used, include provider, endpoint style, bucket strategy, and credentials mapping +- include startup and listener diagnostics commands adapted to target runtime + +## Consul Cluster Options + +Dedicated Consul may be offered for any edge or cloud deployment target. + +### HCP Consul +- Use managed control plane endpoints and ACL/bootstrap parameters from HashiCorp Cloud. +- Include datacenter, token handling, TLS settings, and agent/client connectivity details. + +### Self-Managed Consul +- Include server count/profile, gossip/LAN/WAN ports, bootstrap-expect, and storage placement. +- Include upgrade and failure-domain assumptions (edge single-site vs regional multi-site). + +## Object Storage Options + +Use when deployment requires durable off-box artifacts, archives, or replay staging. + +- AWS S3 + - native AWS auth path and region-aware bucket configuration +- S3-compatible providers (for example Cloudflare R2) + - explicit endpoint URL, signature compatibility assumptions, and credential variables + +## Air-Gapped Packaging + +Generate an offline-ready bundle containing: +- manager YAML files +- startup scripts and env file +- prebuilt image reference and load instructions (no remote pull at deploy time) +- dependency manifest with checksums + +Operational expectations: +- deployment must succeed without internet connectivity +- all runtime references must resolve locally + +## Degraded / Delay-Tolerant Packaging + +Design for intermittent links and temporal delivery: +- configure persistent storage and buffering paths in destination-related manager files +- document backlog and retry expectations +- include reconnect and replay verification commands + +Recommended checks: +- simulate producer while downstream path is unavailable +- restore path and verify buffered events are forwarded + +## Kubernetes-Style Packaging + +No native Helm manifests are required for this skill. +Generate: +- ConfigMap-ready YAML sections for manager files +- container env/args aligned with MAPS startup conventions +- auth/storage/config-source explicit values +- apply/check commands for config-only deployment bundles + +## Validation Checklist + +```bash +rg -n "MAPS_HOME|MAPS_CONF|MAPS_DATA|java.security.auth.login.config|Consul" /Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/start.sh /Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/startDocker.sh +rg -n "NetworkManager|DestinationManager|routing|AggregatorManager|AuthManager" /Users/krital/dev/starsense/mapsmessaging_server/*.yaml +rg -n "directory:|storageConfig:|type: File|type: Memory|autoPauseTimeout" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +``` + +## Failure Classes + +- Missing manager file in package bundle. +- Mount path mismatch causes runtime to use baked-in defaults. +- Port mapping mismatch between container and host checks. +- Environment variables unresolved at startup. +- Air-gapped install references remote artifact endpoints. +- Buffer-and-forward profile uses non-persistent storage where persistence is required. +- Authentication profile declared but not wired in deployment env/config. +- File vs Consul mode mismatch between deployment commands and runtime flags/env. +- Fly KV mode selected but deployment still depends on unavailable Consul endpoint. +- Consul mode selected without explicit topology (HCP vs self-managed) and connection details. +- Object storage selected without provider endpoint and credential mapping details. diff --git a/skills/maps-deployment-packager/references/output-contract.md b/skills/maps-deployment-packager/references/output-contract.md new file mode 100644 index 000000000..e55414874 --- /dev/null +++ b/skills/maps-deployment-packager/references/output-contract.md @@ -0,0 +1,89 @@ +# Output Contract + +Always return in this order. + +1. `Deployment Target Matrix` +- Include target platform options used or considered: + - local, Docker, Kubernetes-style, Fly.io, AWS, Google Cloud, Azure +- Include connectivity profile: connected, air-gapped, degraded, delay-tolerant. + +2. `Authentication Profile` +- Selected auth mechanism(s) and exact deployment wiring points. +- Include fallback/default behavior if auth details are omitted. + +3. `Storage and Volume Profile` +- Selected storage mode (ephemeral/persistent) and destination/storage type expectations. +- Include exact volume/mount mappings per target. + +4. `Configuration Source Mode` +- File-based or Consul-based configuration mode. +- Include exact env/flags/paths required by selected mode. + +5. `State and Config Backend Choice` +- Declare backend selection: + - Fly KV (especially for Fly.io lightweight deployments, no cluster required), or + - dedicated Consul cluster, or + - none/local only. +- If Consul is selected, include `Consul Topology Option`. + +6. `Consul Topology Option` +- Required only when Consul mode is selected. +- Must be one of: + - HCP Consul + - self-managed Consul +- Include addresses/endpoints, auth/TLS assumptions, and deployment placement (edge/cloud). + +7. `Object Storage Option` +- Required when object storage is used. +- Include provider selection: + - AWS S3 + - S3-compatible provider (for example Cloudflare R2) +- Include endpoint/bucket/credential wiring details. + +8. `Artifact Manifest` +- Absolute file paths and generated artifact list. + +9. `Deployable Entity` +- Full files, patch blocks, command scripts, or ConfigMap YAML blocks. + +10. `Apply Steps` +- Exact commands to apply/deploy artifacts. +- For air-gapped bundles, include offline image/artifact load steps. + +11. `Startup Diagnostics` +- Commands to confirm process/container startup and config load. + +12. `Listener Verification` +- Commands proving expected protocol listeners are bound. + +13. `Buffer-and-Forward Verification` +- Commands that validate queueing/buffering during outage and forward-on-recovery behavior. + +14. `Rollback` +- Minimal rollback commands or file restoration path. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never omit absolute paths in manifest. +- Never omit startup and listener checks. +- Never claim deployment readiness without diagnostics. +- Never omit connectivity-profile assumptions. +- Never omit outage/recovery verification steps for delay-tolerant scenarios. +- Never omit authentication profile mapping. +- Never omit storage and volume mapping. +- Never omit file-vs-Consul config source declaration. +- Never omit backend choice declaration (Fly KV vs dedicated Consul vs none). +- Never omit Consul topology details when Consul mode is selected. +- Never omit object storage provider/endpoint/credential mapping when object storage is selected. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh new file mode 100755 index 000000000..4e8f9f6cd --- /dev/null +++ b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-deployment-packager-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-deployment-packager-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-deployment-packager-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-deployment-packager runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_deployment_packager_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-deployment-packager-runtime-smoke.out 2>/tmp/maps-deployment-packager-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-deployment-packager-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_deployment_packager_runtime_smoke path." +fi + +echo "maps-deployment-packager runtime smoke PASS" diff --git a/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh new file mode 100755 index 000000000..9f72624bd --- /dev/null +++ b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_deployment_packager_runtime_smoke.sh" +fi +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/deployment-targets.md"; rg -n "Fly KV|HCP Consul|self-managed|Cloudflare R2|Object Storage Option" "${ROOT}/references/output-contract.md" >/dev/null +echo "maps-deployment-packager skill smoke PASS" diff --git a/skills/maps-geospatial-routing-builder/SKILL.md b/skills/maps-geospatial-routing-builder/SKILL.md new file mode 100644 index 000000000..45a208f8d --- /dev/null +++ b/skills/maps-geospatial-routing-builder/SKILL.md @@ -0,0 +1,72 @@ +--- +name: maps-geospatial-routing-builder +description: Build MAPS geospatial routing configurations using geohash, GPS coordinates, and distance-based decision logic. Use when requirements include geohash topic partitioning, geofence-like routing, GPS payload normalization, proximity thresholds, or distance-function-driven route selection. +--- + +# MAPS Geospatial Routing Builder + +Translate location-aware requirements into deployable MAPS routing and transformation configurations with deterministic verification. + +## Workflow + +1. Normalize geospatial contract. +- Extract coordinate format, geohash precision requirements, distance thresholds, target destinations, and fallback rules. +- Identify whether routing is geohash-bucketed, distance-driven, or both. + +2. Design geospatial routing model. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md`. +- Define coordinate normalization and unit assumptions. +- Define precision strategy (coarse vs fine geohash) and route fan-out behavior. + +3. Map to MAPS config surfaces. +- Update relevant manager YAML for routing, destination mapping, and transformations. +- Keep geospatial computations deterministic and explicit. + +4. Validate semantics. +- Include known-coordinate test vectors. +- Validate geohash output paths and distance threshold transitions. +- Verify destination evidence for in-range and out-of-range cases. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh` + +5. Return using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/output-contract.md`. +- Include deployable config, apply steps, and geospatial verification commands. + +## Rules + +- Always declare coordinate reference assumptions and units. +- Always include at least one known-distance sanity check. +- Prefer MAPS-native transform/routing capabilities (for example GeoHash resolver behavior where available). +- Never omit fallback path for invalid or missing GPS fields. + +## Scenario Modes + +- `Simple Local Default`: + - One geohash route and one proximity threshold route with minimal test vectors. +- `Advanced Combination Matrix`: + - Provide 3 to 6 variants across geohash precision, distance thresholds, and multi-zone routing. + - Include one recommended variant balancing accuracy and operational simplicity. + +## Observability and Architecture Outputs + +- Always generate scenario-specific geospatial metrics (geohash distribution, distance-eval count, in-range/out-of-range split, invalid-coordinate rate, routing latency). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification. +- Support both quick and deep observability: + - Simple mode: one geospatial health panel and 3 to 6 metrics. + - Advanced mode: per-zone and per-threshold drill-down with alerts. +- Always generate C4 diagrams (Context and Container minimum; Component when multiple geo stages are used). + +## Reference Loading + +Load only what is needed: +- Geospatial patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md` +- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/output-contract.md` +- Example artifacts: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md` diff --git a/skills/maps-geospatial-routing-builder/agents/openai.yaml b/skills/maps-geospatial-routing-builder/agents/openai.yaml new file mode 100644 index 000000000..aef241ff2 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Geospatial Routing Builder" + short_description: "Build geohash and distance routing" + default_prompt: "Use $maps-geospatial-routing-builder to build MAPS geohash and GPS distance-based routing with deployable config and known-coordinate verification." diff --git a/skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md b/skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md new file mode 100644 index 000000000..7a1fd8460 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md @@ -0,0 +1,78 @@ +# Advanced Geospatial Output Example + +## Geospatial Requirement Mapping +- Stage 1 geohash region bucketing. +- Stage 2 per-region distance thresholds for routing. +- Invalid coordinate quarantine and fallback delivery path. +- File targets: + - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + +## Geo Model +- Coordinate system: WGS84. +- Units: kilometers. +- Geohash precision: 6 (region split) with fallback to precision 4 for sparse regions. +- Thresholds: + - region A: 10 km + - region B: 25 km + +## Assumptions +- Payload fields: `lat`, `lon`, `regionHint`. +- Unknown regionHint defaults to global threshold profile. + +## Deployable Config Entity +```yaml +routes: + - source: /geo/in + selector: "isValidGps(lat, lon)" + destination: /geo/intermediate/${geohash(lat, lon, 6)} + - source: /geo/in + selector: "!isValidGps(lat, lon)" + destination: /geo/out/invalid +# stage-2 selectors apply per intermediate region with distance thresholds +``` + +## Apply Steps +```bash +cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml.bak +# apply staged geospatial routing patch and restart runtime +``` + +## Verification +- Distance checks: + - known-distance vectors and threshold transition assertions. +- Geohash checks: + - precision 6 and fallback precision 4 behavior. +- Invalid checks: + - missing lat/lon and out-of-range values go to quarantine. +```bash +python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh --source-topic /geo/in --near-topic /geo/out/near --far-topic /geo/out/far --invalid-topic /geo/out/invalid +``` + +## Risk Notes +- Higher precision geohash increases route cardinality. +- Region-specific thresholds add operational complexity. +- GPS quality variance may increase fallback usage. + +## Scenario Metrics and Dashboard +- Metrics: + - per-region geohash cardinality + - distance-threshold crossing count + - invalid and missing GPS rate + - fallback profile usage + - per-stage routing latency +- Grafana: region map + threshold crossing alert panels. +- MAPS-hosted dashboard: per-zone throughput and invalid-route stream. + +## C4 Architecture Diagram +```mermaid +graph LR + A[GPS Publisher] --> B[Stage1 geohash bucket] + B --> C[/geo/intermediate/] + C --> D[Stage2 distance selectors] + D --> E[/geo/out/near] + D --> F[/geo/out/far] + B --> G[/geo/out/invalid] +``` diff --git a/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md b/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md new file mode 100644 index 000000000..3aa22dbc7 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md @@ -0,0 +1,74 @@ +# Simple Geospatial Output Example + +## Geospatial Requirement Mapping +- Route incoming GPS messages by geohash prefix and proximity threshold. +- Route invalid coordinates to quarantine path. +- File targets: + - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + +## Geo Model +- Coordinate system: WGS84 latitude/longitude. +- Units: kilometers. +- Geohash precision: 5. +- Distance threshold: 20 km from reference point. + +## Assumptions +- Payload fields: `lat`, `lon`. +- Invalid coordinate ranges route to `/geo/out/invalid`. + +## Deployable Config Entity +```yaml +routes: + - source: /geo/in + selector: "isValidGps(lat, lon) && distanceKm(lat, lon, 51.5074, -0.1278) <= 20" + destination: /geo/out/near + - source: /geo/in + selector: "isValidGps(lat, lon) && distanceKm(lat, lon, 51.5074, -0.1278) > 20" + destination: /geo/out/far + - source: /geo/in + selector: "!isValidGps(lat, lon)" + destination: /geo/out/invalid +``` + +## Apply Steps +```bash +cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml.bak +# apply geospatial route patch and reload runtime +``` + +## Verification +- Distance vector checks (known-distance sanity): + - London->Paris near known value. +- Geohash checks: + - known geohash prefix for London/NYC at precision 5. +- Invalid GPS checks: + - out-of-range latitude and longitude values route to invalid path. +```bash +python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh --source-topic /geo/in --near-topic /geo/out/near --far-topic /geo/out/far --invalid-topic /geo/out/invalid +``` + +## Risk Notes +- Precision tradeoff: geohash-5 may be coarse near boundary edges. +- GPS jitter may cause near/far oscillation close to threshold. + +## Scenario Metrics and Dashboard +- Metrics: + - geohash bucket distribution + - distance evaluation count + - near/far split rate + - invalid-coordinate count + - geospatial route latency +- Grafana: geohash heat bucket + near/far ratio panel. +- MAPS-hosted dashboard: invalid-GPS trend and threshold crossing counters. + +## C4 Architecture Diagram +```mermaid +graph LR + A[GPS Publisher] --> B[MAPS geospatial route] + B --> C[/geo/out/near] + B --> D[/geo/out/far] + B --> E[/geo/out/invalid] +``` diff --git a/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md b/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md new file mode 100644 index 000000000..02939dd55 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md @@ -0,0 +1,48 @@ +# Geospatial Patterns + +## Pattern A: Geohash Bucket Routing + +- Normalize incoming GPS coordinates. +- Compute geohash at configured precision. +- Route into hierarchy paths using geohash segments. + +## Pattern B: Distance Threshold Routing + +- Compute distance between message coordinate and reference point. +- Route to `near` or `far` destinations based on threshold. + +## Pattern C: Hybrid Geohash + Distance + +- First route by geohash region. +- Then apply distance threshold within region. + +## Input Quality Handling + +- Handle invalid lat/lon range. +- Handle missing coordinates. +- Route invalid data to explicit quarantine path. + +## Verification Vectors + +- Include known coordinate pairs with expected distance order. +- Include expected geohash values for chosen precision. + +## Runnable Smoke Commands + +Skill smoke gate: + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh +``` + +Deterministic vector checks: + +```bash +python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py +``` + +Runtime geospatial route smoke: + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh --source-topic /geo/in --near-topic /geo/out/near --far-topic /geo/out/far --invalid-topic /geo/out/invalid +``` diff --git a/skills/maps-geospatial-routing-builder/references/output-contract.md b/skills/maps-geospatial-routing-builder/references/output-contract.md new file mode 100644 index 000000000..48cd40ee9 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/references/output-contract.md @@ -0,0 +1,44 @@ +# Output Contract + +Always return in this order. + +1. `Geospatial Requirement Mapping` +- Requirement phrase -> fields and absolute file paths. + +2. `Geo Model` +- Coordinate assumptions, units, geohash precision, and threshold model. + +3. `Assumptions` +- Defaults and inferred geospatial behavior. + +4. `Deployable Config Entity` +- Patch blocks or full YAML implementing geospatial routing behavior. + +5. `Apply Steps` +- Exact commands to apply and restart/reload runtime. + +6. `Verification` +- Known coordinate vectors. +- Geohash path assertions. +- Distance-threshold pass/fail assertions. + +7. `Risk Notes` +- Precision tradeoffs, GPS quality risks, and fallback behavior. + +`Scenario Metrics and Dashboard` +- Provide geospatial metrics with collection points and expected ranges. +- Provide Grafana dashboard and MAPS-hosted dashboard definitions. + +`C4 Architecture Diagram` +- Provide C4 diagrams for geospatial flow: + - Context and Container required. + - Component required for hybrid/multi-stage geo pipelines. +- Include Mermaid source. + +## Guardrails + +- Never omit units and coordinate assumptions. +- Never omit at least one known-distance verification. +- Never omit invalid-GPS fallback route. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh b/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh new file mode 100755 index 000000000..bb4165b80 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +set -euo pipefail + +HOST="127.0.0.1" +PORT="1883" +SOURCE_TOPIC="/geo/in" +NEAR_TOPIC="/geo/out/near" +FAR_TOPIC="/geo/out/far" +INVALID_TOPIC="/geo/out/invalid" +NEAR_PAYLOAD='{"lat":51.5074,"lon":-0.1278}' +FAR_PAYLOAD='{"lat":40.7128,"lon":-74.0060}' +INVALID_PAYLOAD='{"lat":123.45,"lon":8.3}' +USERNAME="" +PASSWORD="" + +usage() { + cat < Broker host (default: ${HOST}) + --port Broker port (default: ${PORT}) + --source-topic Source publish topic (default: ${SOURCE_TOPIC}) + --near-topic Expected near route topic (default: ${NEAR_TOPIC}) + --far-topic Expected far route topic (default: ${FAR_TOPIC}) + --invalid-topic Expected invalid route topic (default: ${INVALID_TOPIC}) + --near-payload Near-route payload + --far-payload Far-route payload + --invalid-payload Invalid-route payload + --username MQTT username (optional) + --password MQTT password (optional) + -h, --help Show this help +USAGE +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --host) HOST="$2"; shift 2 ;; + --port) PORT="$2"; shift 2 ;; + --source-topic) SOURCE_TOPIC="$2"; shift 2 ;; + --near-topic) NEAR_TOPIC="$2"; shift 2 ;; + --far-topic) FAR_TOPIC="$2"; shift 2 ;; + --invalid-topic) INVALID_TOPIC="$2"; shift 2 ;; + --near-payload) NEAR_PAYLOAD="$2"; shift 2 ;; + --far-payload) FAR_PAYLOAD="$2"; shift 2 ;; + --invalid-payload) INVALID_PAYLOAD="$2"; shift 2 ;; + --username) USERNAME="$2"; shift 2 ;; + --password) PASSWORD="$2"; shift 2 ;; + -h|--help) usage; exit 0 ;; + *) echo "Unknown argument: $1" >&2; usage; exit 2 ;; + esac +done + +AUTH=() +if [[ -n "${USERNAME}" ]]; then AUTH+=( -u "${USERNAME}" ); fi +if [[ -n "${PASSWORD}" ]]; then AUTH+=( -P "${PASSWORD}" ); fi + +# near case: subscribe first, then publish. +timeout 10 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${NEAR_TOPIC}" -C 1 "${AUTH[@]}" >/tmp/geo-near.out 2>/tmp/geo-near.err & +PID_NEAR=$! +sleep 1 +mosquitto_pub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${SOURCE_TOPIC}" -m "${NEAR_PAYLOAD}" "${AUTH[@]}" +wait "${PID_NEAR}" +[[ -s /tmp/geo-near.out ]] || { echo "near route failed" >&2; exit 1; } + +# far case +timeout 10 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${FAR_TOPIC}" -C 1 "${AUTH[@]}" >/tmp/geo-far.out 2>/tmp/geo-far.err & +PID_FAR=$! +sleep 1 +mosquitto_pub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${SOURCE_TOPIC}" -m "${FAR_PAYLOAD}" "${AUTH[@]}" +wait "${PID_FAR}" +[[ -s /tmp/geo-far.out ]] || { echo "far route failed" >&2; exit 1; } + +# invalid case +timeout 10 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${INVALID_TOPIC}" -C 1 "${AUTH[@]}" >/tmp/geo-invalid.out 2>/tmp/geo-invalid.err & +PID_INV=$! +sleep 1 +mosquitto_pub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${SOURCE_TOPIC}" -m "${INVALID_PAYLOAD}" "${AUTH[@]}" +wait "${PID_INV}" +[[ -s /tmp/geo-invalid.out ]] || { echo "invalid route failed" >&2; exit 1; } + +echo "geospatial mqtt smoke PASS" diff --git a/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh b/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh new file mode 100755 index 000000000..c9fd3adb3 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" + +python3 "${VALIDATOR}" "${ROOT}" +python3 "${ROOT}/scripts/validate_geospatial_artifacts.py" +python3 "${ROOT}/scripts/run_geospatial_vectors.py" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh" +fi +echo "geospatial skill smoke PASS" diff --git a/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py b/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py new file mode 100755 index 000000000..d01d1b3e9 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import math + +BASE32 = '0123456789bcdefghjkmnpqrstuvwxyz' + + +def geohash_encode(lat: float, lon: float, precision: int = 5) -> str: + lat_interval = [-90.0, 90.0] + lon_interval = [-180.0, 180.0] + bits = [16, 8, 4, 2, 1] + bit = 0 + ch = 0 + even = True + out = [] + + while len(out) < precision: + if even: + mid = (lon_interval[0] + lon_interval[1]) / 2 + if lon >= mid: + ch |= bits[bit] + lon_interval[0] = mid + else: + lon_interval[1] = mid + else: + mid = (lat_interval[0] + lat_interval[1]) / 2 + if lat >= mid: + ch |= bits[bit] + lat_interval[0] = mid + else: + lat_interval[1] = mid + even = not even + + if bit < 4: + bit += 1 + else: + out.append(BASE32[ch]) + bit = 0 + ch = 0 + + return ''.join(out) + + +def haversine_km(lat1: float, lon1: float, lat2: float, lon2: float) -> float: + r = 6371.0088 + p1 = math.radians(lat1) + p2 = math.radians(lat2) + dlat = p2 - p1 + dlon = math.radians(lon2 - lon1) + a = math.sin(dlat / 2) ** 2 + math.cos(p1) * math.cos(p2) * math.sin(dlon / 2) ** 2 + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) + return r * c + + +def check_vectors() -> int: + # Known geohash prefixes (stable at low precision) + london = geohash_encode(51.5074, -0.1278, precision=5) + nyc = geohash_encode(40.7128, -74.0060, precision=5) + if not london.startswith('gcp'): + print(f'geohash check failed for London: {london}') + return 1 + if not nyc.startswith('dr5'): + print(f'geohash check failed for NYC: {nyc}') + return 1 + + # Known distance sanity: London <-> Paris about 344 km (+/- 20 km bound) + d_lp = haversine_km(51.5074, -0.1278, 48.8566, 2.3522) + if not (324 <= d_lp <= 364): + print(f'distance check failed for London-Paris: {d_lp:.2f} km') + return 1 + + # Order sanity: London->Paris < London->Berlin + d_lb = haversine_km(51.5074, -0.1278, 52.52, 13.4050) + if not (d_lp < d_lb): + print(f'distance order check failed: LP={d_lp:.2f}, LB={d_lb:.2f}') + return 1 + + # Invalid coordinate checks + invalid_cases = [ + (95.0, 0.0), + (-95.0, 0.0), + (0.0, 190.0), + (0.0, -190.0), + ] + for lat, lon in invalid_cases: + if -90 <= lat <= 90 and -180 <= lon <= 180: + print(f'invalid vector check failed for ({lat}, {lon})') + return 1 + + print('geospatial vector smoke PASS') + print(f'london geohash(5)={london}, nyc geohash(5)={nyc}, london-paris={d_lp:.2f} km') + return 0 + + +if __name__ == '__main__': + raise SystemExit(check_vectors()) diff --git a/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh b/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh new file mode 100755 index 000000000..bca683e54 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-geospatial-routing-builder-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-geospatial-routing-builder-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-geospatial-routing-builder-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-geospatial-routing-builder runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_geospatial_routing_builder_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-geospatial-routing-builder-runtime-smoke.out 2>/tmp/maps-geospatial-routing-builder-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-geospatial-routing-builder-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_geospatial_routing_builder_runtime_smoke path." +fi + +echo "maps-geospatial-routing-builder runtime smoke PASS" diff --git a/skills/maps-geospatial-routing-builder/scripts/validate_geospatial_artifacts.py b/skills/maps-geospatial-routing-builder/scripts/validate_geospatial_artifacts.py new file mode 100755 index 000000000..c0dc6e1a5 --- /dev/null +++ b/skills/maps-geospatial-routing-builder/scripts/validate_geospatial_artifacts.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import re +from pathlib import Path + +ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder') +CONTRACT = ROOT / 'references' / 'output-contract.md' +EXAMPLES = [ + ROOT / 'references' / 'examples' / 'simple-geospatial-output.md', + ROOT / 'references' / 'examples' / 'advanced-geospatial-output.md', +] + + +def parse_sections(text: str) -> list[str]: + sections: list[str] = [] + seen: set[str] = set() + for line in text.splitlines(): + line = line.strip() + m = re.match(r'^\d+\.\s+`([^`]+)`', line) + if not m: + m = re.match(r'^`([^`]+)`$', line) + if m: + val = m.group(1).strip() + if val not in seen: + seen.add(val) + sections.append(val) + return sections + + +def main() -> int: + if not CONTRACT.exists(): + print(f'missing contract: {CONTRACT}') + return 1 + + sections = parse_sections(CONTRACT.read_text(encoding='utf-8')) + if not sections: + print('no sections parsed from contract') + return 1 + + errors: list[str] = [] + for ex in EXAMPLES: + if not ex.exists(): + errors.append(f'missing example: {ex}') + continue + txt = ex.read_text(encoding='utf-8') + for section in sections: + if f'## {section}' not in txt: + errors.append(f'{ex.name}: missing section {section}') + for marker in ['distance', 'geohash', 'invalid']: + if marker not in txt.lower(): + errors.append(f'{ex.name}: missing {marker} verification marker') + if '```bash' not in txt: + errors.append(f'{ex.name}: missing bash command block') + if '```mermaid' not in txt: + errors.append(f'{ex.name}: missing mermaid diagram block') + if '/Users/krital/dev/starsense/mapsmessaging_server' not in txt: + errors.append(f'{ex.name}: missing absolute path reference') + + if errors: + print('geospatial artifact validation failed:') + for e in errors: + print(f'- {e}') + return 1 + + print('geospatial artifact validation passed.') + return 0 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/skills/maps-ml-model-lifecycle-playbook/SKILL.md b/skills/maps-ml-model-lifecycle-playbook/SKILL.md new file mode 100644 index 000000000..5fed798d4 --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/SKILL.md @@ -0,0 +1,79 @@ +--- +name: maps-ml-model-lifecycle-playbook +description: Guide MAPS-native ML model lifecycle workflows from streamed data training to externally trained model ingestion for streaming inference. Use when requirements include model creation from event streams, model store strategy, retraining policy, external model onboarding, staged inference, and production-safe validation. +--- + +# MAPS ML Model Lifecycle Playbook + +Provide clear, executable guidance for both model creation from streaming data and online inference with externally trained models, always within MAPS capabilities. + +## Workflow + +1. Normalize lifecycle contract. +- Extract objective (classification, anomaly, clustering, regression), source streams, schema IDs, training window assumptions, retraining triggers, and inference outputs. +- Classify mode: + - stream-trained model pipeline + - externally trained model ingestion pipeline + - hybrid lifecycle + +2. Design lifecycle blueprint. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md`. +- Build simple baseline first, then advanced staged variant when requested. +- Keep model-store type explicit (`file`, `nexus`, `s3`, `maps`). + +3. Map to deployable config. +- Primary ML stream config in `/Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml`. +- Include destination/schema/routing changes when staged inference or quarantine flows are required. +- Include external model artifact ingest mapping for portable formats only. + +4. Validate lifecycle behavior. +- Validate training and inference stage boundaries. +- Validate model-store and artifact metadata wiring. +- Validate retrain threshold semantics and rollback behavior. +- Include stage-by-stage runtime verification commands. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh` + +5. Return using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/output-contract.md`. +- Include simple baseline and advanced option(s) when requested. + +## ML Lifecycle Rules + +- Always present a simple working lifecycle first. +- Keep advanced chains bounded by default (2 to 3 passes) unless user requests more. +- Use portable model artifacts; do not use Java object serialization. +- Include Smile 4.3.0 compatibility assumptions in model-related guidance. +- For external model ingestion, include artifact format checks and compatibility fallback notes. + +## Scenario Modes + +- `Simple Local Default`: + - One stream-trained or external-model inference flow with one output topic and one verification path. +- `Advanced Combination Matrix`: + - Provide 3 to 6 variants across training/inference split, retraining policy, staged selectors, and model-store options. + - Recommend one operationally simplest production path. + +## Observability and Architecture Outputs + +- Always generate scenario-specific ML lifecycle metrics: + - train event count, retrain trigger frequency, model load success rate, inference latency, selector hit rate, outlier rate. +- Always provide two dashboard options: + - Grafana-ready panel/query definitions. + - MAPS-hosted dashboard view specification. +- Support both quick and deep observability: + - Simple mode: one lifecycle health panel and 3 to 6 core metrics. + - Advanced mode: per-stage training/inference lifecycle dashboard with drift alerts. +- Always generate C4 diagrams (Context and Container minimum; Component for multi-stage or hybrid lifecycle). + +## Reference Loading + +Load only what is needed: +- Lifecycle patterns and constraints: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md` +- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/output-contract.md` +- Example artifacts: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md` diff --git a/skills/maps-ml-model-lifecycle-playbook/agents/openai.yaml b/skills/maps-ml-model-lifecycle-playbook/agents/openai.yaml new file mode 100644 index 000000000..2d0cf8a40 --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS ML Lifecycle Playbook" + short_description: "Model lifecycle from stream to inference" + default_prompt: "Use $maps-ml-model-lifecycle-playbook to produce MAPS-native guidance for stream-trained models and externally trained model ingestion with staged verification." diff --git a/skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md b/skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md new file mode 100644 index 000000000..a68eeda1d --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md @@ -0,0 +1,93 @@ +# Advanced ML Lifecycle Output Example + +## Lifecycle Requirement Mapping +- Hybrid lifecycle: + - external model bootstrap + - stream-based retrain thresholds + - staged inference pass-1 and pass-2 with intermediate destination +- File targets: + - `/Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + +## Lifecycle Shape +- Simple baseline retained. +- Advanced lifecycle option: + 1. external-model load + 2. stage-1 selector `/ml/in` -> `/ml/intermediate` + 3. stage-2 selector `/ml/intermediate` -> `/ml/final` or `/ml/outlier` + 4. retrain trigger path from stream counters + +## Model and Store Assumptions +- Model type: `RandomForest` (external bootstrap), optional downstream `DecisionTree` retrain. +- Store mode: `s3` or `maps` in advanced mode; `file` fallback in local mode. +- Artifact formats: portable json/csv only. +- Smile 4.3.0 compatibility assumptions required before activation. +- Incompatible external artifacts route to fallback model and emit warning. + +## Deployable Config Entity +```yaml +MLModelManager: + type: MLModelManagerConfigDTO + modelStore: + type: maps + eventStreams: + - id: ml-advanced-stage1 + topicFilter: /ml/in + schemaId: ml-schema-v2 + selector: "featureA > 0.4" + outputTopic: /ml/intermediate + maxTrainEvents: 5000 + retrainThreshold: 0.08 + - id: ml-advanced-stage2 + topicFilter: /ml/intermediate + schemaId: ml-schema-v2 + selector: "confidence >= 0.7" + outputTopic: /ml/final + outlierTopic: /ml/outlier +``` + +## Apply Steps +```bash +cp /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml.bak +# apply advanced lifecycle patch and restart runtime +``` + +## Verification +- Stage-by-stage checks: + - model load + - stage1 and stage2 output + - retrain trigger observation +- External-model negative check: + - incompatible artifact should fail validation and fallback. +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh --source-topic /ml/in --stage1-topic /ml/intermediate --final-topic /ml/final --outlier-topic /ml/outlier +``` + +## Risk and Operational Notes +- Multi-stage lifecycle increases operational complexity. +- Drift and retrain instability can increase false positives. +- Always retain rollback model reference and cutoff criteria. + +## Scenario Metrics and Dashboard +- Metrics: + - per-stage inference latency + - model cache hit ratio + - retrain trigger frequency + - fallback model usage + - outlier queue size +- Grafana: per-stage lifecycle dashboard with drift alerts. +- MAPS-hosted dashboard: retrain/fallback event stream. + +## C4 Architecture Diagram +```mermaid +graph LR + A[Input Stream] --> B[External Model Load] + B --> C[Stage1 Inference] + C --> D[/ml/intermediate] + D --> E[Stage2 Inference] + E --> F[/ml/final] + E --> G[/ml/outlier] + C --> H[Retrain Trigger] +``` diff --git a/skills/maps-ml-model-lifecycle-playbook/references/examples/model-artifact-sample.json b/skills/maps-ml-model-lifecycle-playbook/references/examples/model-artifact-sample.json new file mode 100644 index 000000000..7698f3581 --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/references/examples/model-artifact-sample.json @@ -0,0 +1,7 @@ +{ + "modelType": "DecisionTree", + "format": "portable-json", + "smileVersion": "4.3.0", + "features": ["featureA", "featureB"], + "target": "label" +} diff --git a/skills/maps-ml-model-lifecycle-playbook/references/examples/model-metrics-sample.csv b/skills/maps-ml-model-lifecycle-playbook/references/examples/model-metrics-sample.csv new file mode 100644 index 000000000..e915ec4ed --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/references/examples/model-metrics-sample.csv @@ -0,0 +1,5 @@ +metric,value +accuracy,0.91 +f1,0.88 +precision,0.90 +recall,0.86 diff --git a/skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md b/skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md new file mode 100644 index 000000000..1436c52c9 --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md @@ -0,0 +1,83 @@ +# Simple ML Lifecycle Output Example + +## Lifecycle Requirement Mapping +- Stream-trained baseline with one selector stage and one output destination. +- Optional external model artifact load for warm start. +- File targets: + - `/Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` + +## Lifecycle Shape +- Simple baseline: + - Input stream `/ml/in` + - Selector stage output `/ml/stage1` + - Final output `/ml/final` +- Advanced options not enabled in this profile. + +## Model and Store Assumptions +- Model type: `DecisionTree`. +- Store mode: `file`. +- Artifact format: portable json/csv. +- Smile 4.3.0 compatibility assumptions are explicitly required. +- External model ingestion allowed from: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/examples/model-artifact-sample.json` + +## Deployable Config Entity +```yaml +MLModelManager: + type: MLModelManagerConfigDTO + modelStore: + type: file + path: /Users/krital/dev/starsense/mapsmessaging_server/models + eventStreams: + - id: ml-simple-stage1 + topicFilter: /ml/in + schemaId: ml-schema-v1 + selector: "featureA > 0.5" + outputTopic: /ml/stage1 + - id: ml-simple-final + topicFilter: /ml/stage1 + schemaId: ml-schema-v1 + selector: "label != null" + outputTopic: /ml/final +``` + +## Apply Steps +```bash +cp /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml.bak +# apply lifecycle patch and restart runtime +``` + +## Verification +- Stream verification: + - publish to `/ml/in`, expect event at `/ml/stage1` and `/ml/final`. +- External-model compatibility verification: + - validate artifact metadata and portable format. +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh --source-topic /ml/in --stage1-topic /ml/stage1 --final-topic /ml/final --outlier-topic /ml/outlier +``` + +## Risk and Operational Notes +- Retrain trigger frequency should be bounded to avoid thrashing. +- Drift monitoring required for sustained external-model accuracy. +- Rollback to previous model artifact on compatibility or quality failure. + +## Scenario Metrics and Dashboard +- Metrics: + - train event count + - model load success rate + - stage latency + - selector hit rate + - outlier rate +- Grafana: lifecycle health + stage latency panel. +- MAPS-hosted dashboard: load/retrain timeline and anomaly counters. + +## C4 Architecture Diagram +```mermaid +graph LR + A[Input Stream] --> B[Stage1 Selector] + B --> C[Final Inference] + C --> D[/ml/final] + B --> E[/ml/outlier] +``` diff --git a/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md b/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md new file mode 100644 index 000000000..e3984336c --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md @@ -0,0 +1,50 @@ +# ML Lifecycle Patterns + +## Pattern A: Stream-Trained Baseline + +- Input stream feeds training event collection. +- Model updates at configured thresholds. +- Inference output goes to one downstream topic. + +## Pattern B: External Model Ingestion + +- External portable model artifact is loaded into MAPS model store. +- Inference runs on live stream with selector/output routing. +- Include compatibility checks and fallback behavior. + +## Pattern C: Hybrid Lifecycle + +- Start with external model. +- Enable MAPS retraining from stream once confidence thresholds are met. +- Preserve rollback to prior model version. + +## Artifact and Compatibility Rules + +- Use portable artifact formats only. +- Validate Smile 4.3.0 compatibility assumptions. +- Avoid Java serialization formats. + +## Verification Guidance + +- Stage-wise verification: model load, inference output, retrain trigger, post-retrain inference. +- Include negative case for incompatible model artifact. + +## Runnable Smoke Commands + +Skill smoke gate: + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh +``` + +Vector checks (portable format + serialization constraints): + +```bash +python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py +``` + +Runtime staged ML smoke: + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh --source-topic /ml/in --stage1-topic /ml/stage1 --final-topic /ml/final --outlier-topic /ml/outlier +``` diff --git a/skills/maps-ml-model-lifecycle-playbook/references/output-contract.md b/skills/maps-ml-model-lifecycle-playbook/references/output-contract.md new file mode 100644 index 000000000..95cc215d1 --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/references/output-contract.md @@ -0,0 +1,43 @@ +# Output Contract + +Always return in this order. + +1. `Lifecycle Requirement Mapping` +- Requirement phrase -> fields and absolute file paths. + +2. `Lifecycle Shape` +- Simple baseline lifecycle. +- Advanced lifecycle option(s) when requested. + +3. `Model and Store Assumptions` +- Model type, store mode, artifact format, Smile 4.3.0 compatibility assumptions. + +4. `Deployable Config Entity` +- Patch blocks or full YAML implementing lifecycle configuration. + +5. `Apply Steps` +- Exact commands to apply and restart/reload runtime. + +6. `Verification` +- Stage-by-stage checks for model load, inference output, and retrain behavior. + +7. `Risk and Operational Notes` +- Drift, retrain instability, rollback plan, compatibility limits. + +`Scenario Metrics and Dashboard` +- Provide ML lifecycle metrics with collection points and expected ranges. +- Provide Grafana dashboard and MAPS-hosted dashboard definitions. + +`C4 Architecture Diagram` +- Provide C4 diagrams for lifecycle flow: + - Context and Container required. + - Component required for hybrid or multi-stage lifecycle. +- Include Mermaid source. + +## Guardrails + +- Never omit simple baseline lifecycle. +- Never omit model-store assumptions and artifact format constraints. +- Never omit external-model compatibility checks when external ingestion is requested. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh new file mode 100755 index 000000000..5c564f185 --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +set -euo pipefail + +HOST="127.0.0.1" +PORT="1883" +SOURCE_TOPIC="/ml/in" +STAGE1_TOPIC="/ml/stage1" +FINAL_TOPIC="/ml/final" +OUTLIER_TOPIC="/ml/outlier" +PAYLOAD='{"featureA":1.2,"featureB":3.4,"label":"normal"}' +USERNAME="" +PASSWORD="" + +usage() { + cat < Broker host (default: ${HOST}) + --port Broker port (default: ${PORT}) + --source-topic Input stream topic (default: ${SOURCE_TOPIC}) + --stage1-topic Stage-1 output topic (default: ${STAGE1_TOPIC}) + --final-topic Final output topic (default: ${FINAL_TOPIC}) + --outlier-topic Outlier output topic (default: ${OUTLIER_TOPIC}) + --payload Test payload + --username MQTT username (optional) + --password MQTT password (optional) + -h, --help Show this help +USAGE +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --host) HOST="$2"; shift 2 ;; + --port) PORT="$2"; shift 2 ;; + --source-topic) SOURCE_TOPIC="$2"; shift 2 ;; + --stage1-topic) STAGE1_TOPIC="$2"; shift 2 ;; + --final-topic) FINAL_TOPIC="$2"; shift 2 ;; + --outlier-topic) OUTLIER_TOPIC="$2"; shift 2 ;; + --payload) PAYLOAD="$2"; shift 2 ;; + --username) USERNAME="$2"; shift 2 ;; + --password) PASSWORD="$2"; shift 2 ;; + -h|--help) usage; exit 0 ;; + *) echo "Unknown argument: $1" >&2; usage; exit 2 ;; + esac +done + +AUTH=() +if [[ -n "${USERNAME}" ]]; then AUTH+=( -u "${USERNAME}" ); fi +if [[ -n "${PASSWORD}" ]]; then AUTH+=( -P "${PASSWORD}" ); fi + +# Stage-1 check: subscribe before publish +timeout 12 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${STAGE1_TOPIC}" -C 1 "${AUTH[@]}" >/tmp/ml-stage1.out 2>/tmp/ml-stage1.err & +PID_S1=$! +sleep 1 +mosquitto_pub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${SOURCE_TOPIC}" -m "${PAYLOAD}" "${AUTH[@]}" +wait "${PID_S1}" +[[ -s /tmp/ml-stage1.out ]] || { echo "stage1 inference output missing" >&2; exit 1; } + +# Final stage check: final OR outlier must receive one event +timeout 10 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${FINAL_TOPIC}" -C 1 "${AUTH[@]}" >/tmp/ml-final.out 2>/tmp/ml-final.err & +PID_F=$! +timeout 10 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${OUTLIER_TOPIC}" -C 1 "${AUTH[@]}" >/tmp/ml-outlier.out 2>/tmp/ml-outlier.err & +PID_O=$! +sleep 1 +mosquitto_pub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${SOURCE_TOPIC}" -m "${PAYLOAD}" "${AUTH[@]}" +wait "${PID_F}" || true +wait "${PID_O}" || true + +if [[ ! -s /tmp/ml-final.out && ! -s /tmp/ml-outlier.out ]]; then + echo "neither final nor outlier stream received output" >&2 + exit 1 +fi + +echo "ml lifecycle mqtt smoke PASS" diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh new file mode 100755 index 000000000..b5372887b --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-ml-lifecycle-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/ml-lifecycle-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/ml-lifecycle-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-ml-model-lifecycle-playbook runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="ml_lifecycle_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/ml-lifecycle-runtime-smoke.out 2>/tmp/ml-lifecycle-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/ml-lifecycle-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without ml_lifecycle_runtime_smoke path." +fi + +echo "maps-ml-model-lifecycle-playbook runtime smoke PASS" diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh new file mode 100755 index 000000000..979f020d7 --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" + +python3 "${VALIDATOR}" "${ROOT}" +python3 "${ROOT}/scripts/validate_ml_lifecycle_artifacts.py" +python3 "${ROOT}/scripts/run_ml_lifecycle_vectors.py" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_ml_lifecycle_runtime_smoke.sh" +fi +echo "ml lifecycle skill smoke PASS" diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py new file mode 100755 index 000000000..aeec355b1 --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +from pathlib import Path + +ALLOWED_EXTS = {'.json', '.csv'} +BANNED_EXTS = {'.ser', '.bin', '.obj'} +ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server') + + +def check_portable_extensions() -> list[str]: + errors: list[str] = [] + sample_artifacts = [ + ROOT / 'skills' / 'maps-ml-model-lifecycle-playbook' / 'references' / 'examples' / 'model-artifact-sample.json', + ROOT / 'skills' / 'maps-ml-model-lifecycle-playbook' / 'references' / 'examples' / 'model-metrics-sample.csv', + ] + for p in sample_artifacts: + if p.suffix.lower() not in ALLOWED_EXTS: + errors.append(f'non-portable extension: {p}') + + for banned in BANNED_EXTS: + if list((ROOT / 'skills' / 'maps-ml-model-lifecycle-playbook').rglob(f'*{banned}')): + errors.append(f'found banned artifact extension {banned} under skill tree') + + return errors + + +def check_no_java_serialization_markers() -> list[str]: + errors: list[str] = [] + for p in (ROOT / 'skills' / 'maps-ml-model-lifecycle-playbook').rglob('*.md'): + txt = p.read_text(encoding='utf-8') + if 'ObjectInputStream' in txt or 'ObjectOutputStream' in txt: + errors.append(f'java serialization marker found in {p}') + return errors + + +def main() -> int: + errors = [] + errors.extend(check_portable_extensions()) + errors.extend(check_no_java_serialization_markers()) + + if errors: + print('ml lifecycle vectors failed:') + for e in errors: + print(f'- {e}') + return 1 + + print('ml lifecycle vector smoke PASS') + print('portable formats: json/csv; no Java serialization markers detected') + return 0 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/validate_ml_lifecycle_artifacts.py b/skills/maps-ml-model-lifecycle-playbook/scripts/validate_ml_lifecycle_artifacts.py new file mode 100755 index 000000000..887f92972 --- /dev/null +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/validate_ml_lifecycle_artifacts.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import re +from pathlib import Path + +ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook') +CONTRACT = ROOT / 'references' / 'output-contract.md' +EXAMPLES = [ + ROOT / 'references' / 'examples' / 'simple-ml-lifecycle-output.md', + ROOT / 'references' / 'examples' / 'advanced-ml-lifecycle-output.md', +] + + +def parse_sections(text: str) -> list[str]: + sections: list[str] = [] + seen: set[str] = set() + for line in text.splitlines(): + line = line.strip() + m = re.match(r'^\d+\.\s+`([^`]+)`', line) + if not m: + m = re.match(r'^`([^`]+)`$', line) + if m: + v = m.group(1).strip() + if v not in seen: + seen.add(v) + sections.append(v) + return sections + + +def main() -> int: + if not CONTRACT.exists(): + print(f'missing contract: {CONTRACT}') + return 1 + sections = parse_sections(CONTRACT.read_text(encoding='utf-8')) + if not sections: + print('no sections parsed from contract') + return 1 + + errors: list[str] = [] + for ex in EXAMPLES: + if not ex.exists(): + errors.append(f'missing example: {ex}') + continue + txt = ex.read_text(encoding='utf-8') + for section in sections: + if f'## {section}' not in txt: + errors.append(f'{ex.name}: missing section {section}') + for marker in ['stream', 'external', 'smile 4.3.0', 'portable', 'verification']: + if marker not in txt.lower(): + errors.append(f'{ex.name}: missing marker {marker}') + if '```bash' not in txt: + errors.append(f'{ex.name}: missing bash command block') + if '```mermaid' not in txt: + errors.append(f'{ex.name}: missing mermaid diagram block') + if '/Users/krital/dev/starsense/mapsmessaging_server' not in txt: + errors.append(f'{ex.name}: missing absolute path reference') + + if errors: + print('ml lifecycle artifact validation failed:') + for e in errors: + print(f'- {e}') + return 1 + + print('ml lifecycle artifact validation passed.') + return 0 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/skills/maps-ml-stream-configurator/SKILL.md b/skills/maps-ml-stream-configurator/SKILL.md new file mode 100644 index 000000000..a8ca266a2 --- /dev/null +++ b/skills/maps-ml-stream-configurator/SKILL.md @@ -0,0 +1,75 @@ +--- +name: maps-ml-stream-configurator +description: Build deployable MAPS ML stream configurations for selector-driven event processing, model store integration, and multi-pass inference pipelines. Use when requirements include ML selectors on streams, intermediate destination passes, staged model chaining, retraining thresholds, and production-safe verification with simple and advanced modes. +--- + +# MAPS ML Stream Configurator + +Design ML-enabled MAPS stream pipelines that stay understandable: one simple baseline path first, then optional advanced multi-pass model chaining. + +## Workflow + +1. Normalize ML stream contract. +- Extract source topics, schema IDs, selector expressions, outlier or decision topics, model store type, caching policy, and retraining thresholds. +- Detect whether user needs single-pass or multi-pass model chaining. + +2. Build pipeline shape in two layers. +- Layer A (simple): one model selector on one stream, one output topic. +- Layer B (advanced): staged passes using intermediate MAPS destinations with one model per pass. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md`. + +3. Map to deployable config. +- Primary file: `/Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml`. +- Link to destination/schema config when intermediate stages or schema checks are required. +- Keep model-store type explicit (`file`, `nexus`, `s3`, `maps`) and include required config block details. + +4. Validate before finalizing. +- Ensure each event stream has `id`, `topicFilter`, `schemaId`, `selector`, and output topic. +- Validate multi-pass chains have clear stage boundaries and deterministic topic handoff. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh` +- Include static checks: +```bash +rg -n "MLModelManager|eventStreams|selector|topicFilter|schemaId|outlierTopic|maxTrainEvents|retrainThreshold|modelStore" /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml +``` + +5. Return with output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/references/output-contract.md`. +- Include simple baseline and advanced option when requested. + +## ML-Specific Rules + +- Keep model pipelines deterministic and explain each stage in plain language. +- Always present a simple working baseline before advanced chain variants. +- For advanced pipelines, cap complexity by default (2 to 3 passes) unless user asks for more. +- Explicitly label each pass with input topic, selector model, and output topic. +- Keep serialization portable; do not rely on Java object serialization. +- Respect runtime constraints and mention Smile 4.3.0 compatibility assumptions for model-related guidance. + +## Scenario Modes + +- `Simple Local Default`: + - One event stream selector and one output topic. + - One locally testable publish/observe flow with minimal configuration. +- `Advanced Combination Matrix`: + - Provide 3 to 6 variants across selector/model choice, pass count, intermediate topic design, and retraining behavior. + - Include one recommended staged pipeline and explain why it is easier to operate. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to ML stream behavior: + - selector hit rate, outlier rate, false-positive review queue size, stage latency, model cache hit ratio, retrain trigger frequency. +- Always provide two dashboard options: + - Grafana-ready panel/query definitions. + - MAPS-hosted dashboard view specification. +- Support both quick and deep observability: + - Simple mode: one health panel plus 3 to 6 core ML stream metrics. + - Advanced mode: per-stage pipeline dashboard with alerts for drift or anomaly spikes. +- Always generate C4 diagrams (Context and Container minimum; Component for multi-pass) for the deployed ML flow. + +## Reference Loading + +Load only what is needed: +- Pipeline patterns and simplification guidance: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md` +- Final response structure: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/references/output-contract.md` diff --git a/skills/maps-ml-stream-configurator/agents/openai.yaml b/skills/maps-ml-stream-configurator/agents/openai.yaml new file mode 100644 index 000000000..36c21a5cc --- /dev/null +++ b/skills/maps-ml-stream-configurator/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS ML Stream Configurator" + short_description: "Design MAPS ML stream and selector pipelines" + default_prompt: "Use $maps-ml-stream-configurator to build a deployable MAPS ML stream pipeline with simple and advanced multi-pass model options plus verification commands." diff --git a/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md b/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md new file mode 100644 index 000000000..1eef1a6f8 --- /dev/null +++ b/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md @@ -0,0 +1,51 @@ +# ML Pipeline Patterns + +## Core Principle + +Always propose a simple baseline first, then advanced chained variants. + +## Baseline Pattern + +Single-pass stream: +- Input topic filter +- One selector with one model expression +- One output topic (for outliers/decisions) + +Use when: +- fast local validation is needed +- model behavior must be easy to explain + +## Advanced Multi-Pass Pattern + +Stage-by-stage chain using intermediate MAPS destinations: +- Stage 1: broad anomaly or classification filter to intermediate topic +- Stage 2: refinement model on intermediate topic +- Stage 3 (optional): specialized model or policy selector to final action topic + +Guidance: +- keep stages explicit and named +- ensure each stage has a deterministic topic contract +- do not hide transformations between stages + +## Example Chaining Skeleton + +- `stage1-input`: `/sensor/raw/#` +- `stage1-output`: `/ml/intermediate/stage1` +- `stage2-input`: `/ml/intermediate/stage1` +- `stage2-output`: `/ml/intermediate/stage2` +- `stage3-input`: `/ml/intermediate/stage2` +- `stage3-output`: `/ml/final/actions` + +## Validation Checklist + +```bash +rg -n "eventStreams|selector|topicFilter|outlierTopic|schemaId|retrainThreshold" /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml +rg -n "namespace: |namespaceMapping:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +``` + +## Failure Classes + +- Selector expression does not match stream schema. +- Intermediate topics not provisioned/mapped. +- Multi-pass chain loops back unintentionally. +- Retraining threshold too sensitive and causes churn. diff --git a/skills/maps-ml-stream-configurator/references/output-contract.md b/skills/maps-ml-stream-configurator/references/output-contract.md new file mode 100644 index 000000000..29e1508d6 --- /dev/null +++ b/skills/maps-ml-stream-configurator/references/output-contract.md @@ -0,0 +1,45 @@ +# Output Contract + +Always return in this order. + +1. `ML Stream Requirement Mapping` +- Requirement phrase -> exact fields and absolute file paths. + +2. `Pipeline Shape` +- Simple baseline pipeline. +- Advanced multi-pass option(s) when requested. + +3. `Model and Store Assumptions` +- Model type assumptions and store mode (`file`, `nexus`, `s3`, `maps`). +- Include compatibility notes (Smile 4.3.0 and portable model artifacts). + +4. `Deployable Config Entity` +- Patch blocks or full YAML implementing ML stream configuration. + +5. `Apply Steps` +- Exact commands to apply and restart/reload runtime. + +6. `Verification` +- Publish/observe steps per stage. +- For multi-pass, include stage-by-stage evidence checks. + +7. `Risk and Complexity Notes` +- Operational complexity, drift risk, retrain sensitivity, fallback behavior. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific ML metrics with collection points and expected ranges. +- Provide Grafana dashboard definition and MAPS-hosted dashboard definition. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the ML flow: + - Context and Container required. + - Component required for multi-pass pipelines. +- Include Mermaid source. + +## Guardrails + +- Never omit the simple baseline. +- Never present advanced chain without explicit stage boundaries. +- Never omit model-store assumptions. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh new file mode 100755 index 000000000..13e7ed011 --- /dev/null +++ b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-ml-stream-configurator-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-ml-stream-configurator-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-ml-stream-configurator-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-ml-stream-configurator runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_ml_stream_configurator_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-ml-stream-configurator-runtime-smoke.out 2>/tmp/maps-ml-stream-configurator-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-ml-stream-configurator-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_ml_stream_configurator_runtime_smoke path." +fi + +echo "maps-ml-stream-configurator runtime smoke PASS" diff --git a/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh new file mode 100755 index 000000000..ff4f97920 --- /dev/null +++ b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" + +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh" +fi +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/ml-pipeline-patterns.md" +rg -n "simple baseline" "${ROOT}/references/output-contract.md" >/dev/null +echo "maps-ml-stream-configurator skill smoke PASS" diff --git a/skills/maps-protocol-bridge-tester/SKILL.md b/skills/maps-protocol-bridge-tester/SKILL.md new file mode 100644 index 000000000..f70e30833 --- /dev/null +++ b/skills/maps-protocol-bridge-tester/SKILL.md @@ -0,0 +1,67 @@ +--- +name: maps-protocol-bridge-tester +description: Build and execute MAPS Messaging protocol bridge test plans. Use when validating protocol ingress and egress behavior, cross-protocol routing (for example MQTT to AMQP, MQTT to WS, CoAP to MQTT), namespace mapping correctness, and end-to-end delivery with reproducible producer and consumer commands and pass-fail criteria. +--- + +# MAPS Protocol Bridge Tester + +Create deterministic bridge tests for MAPS protocol flows and verify end-to-end delivery with explicit evidence. + +## Workflow + +1. Define bridge matrix. +- Identify source protocol, destination protocol, namespace/topic mapping, payload format, QoS/retain expectations. +- Resolve missing details only when they change verification behavior. + +2. Validate runtime readiness first. +- Confirm listener binds and provider availability before generating traffic. +- Use `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md` startup checks. + +3. Execute layered tests. +- Layer 1: source ingress test (producer -> source listener). +- Layer 2: destination egress visibility test (consumer on destination side). +- Layer 3: full bridge test with correlation marker in payload. +- For executable runtime smoke, use: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh` + +4. Evaluate with strict pass/fail markers. +- Pass only when destination receives expected payload on mapped namespace within timeout. +- Separate failures into ingress, routing, transform, or egress categories. + +5. Return using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/references/output-contract.md`. +- Include exact commands, expected outputs, and remediation path for each failed layer. + +## Rules + +- Do not run end-to-end bridge tests before listener and startup diagnostics are clean. +- Use MAPS-native protocol paths; avoid introducing external brokers unless already in target architecture. +- Prefer reproducible CLI commands with bounded timeouts. +- Always include correlation IDs in payload to prove message continuity across protocol boundaries. + +## Scenario Modes + +- `Simple Local Default`: + - Run one baseline bridge path with minimal setup (single ingress, single egress, one correlation ID). + - Provide one pass/fail assertion set. +- `Advanced Combination Matrix`: + - Generate 3 to 6 bridge variants across protocol pairs and namespace mappings. + - Include per-variant ingress, routing, transform/schema, and egress test gates. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed: +- Test patterns and commands: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md` +- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/references/output-contract.md` diff --git a/skills/maps-protocol-bridge-tester/agents/openai.yaml b/skills/maps-protocol-bridge-tester/agents/openai.yaml new file mode 100644 index 000000000..4fba896d8 --- /dev/null +++ b/skills/maps-protocol-bridge-tester/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Protocol Bridge Tester" + short_description: "Test MAPS protocol bridging end-to-end" + default_prompt: "Use $maps-protocol-bridge-tester to generate and run a protocol bridge test plan with producer/consumer commands and pass/fail criteria." diff --git a/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md b/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md new file mode 100644 index 000000000..474a194e2 --- /dev/null +++ b/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md @@ -0,0 +1,54 @@ +# Bridge Test Catalog + +## Preconditions + +1. Container/process healthy and listeners bound. +```bash +docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' +docker logs 2>&1 | rg -n "ERROR|Startup aborted|Protocol not available|BindException|Address already in use" +docker exec sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | rg "1883|5672|8080|9001"' +``` + +2. Namespace mapping and routing present in config. +```bash +rg -n "namespace: |namespaceMapping:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "predefinedServers|enabled|autoDiscovery" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +``` + +## Core Test Patterns + +### MQTT -> MQTT (baseline) +```bash +mosquitto_sub -h localhost -p 1883 -t /bridge/test/# -C 1 -W 8 -d +mosquitto_pub -h localhost -p 1883 -t /bridge/test/in -m '{"cid":"b1","v":1}' -d +``` + +### MQTT -> WS (encapsulated path readiness) +```bash +timeout 8 mosquitto_sub -L ws://127.0.0.1:9001/ -t /bridge/ws/# -C 1 -d -W 5 +mosquitto_pub -h localhost -p 1883 -t /bridge/ws/in -m '{"cid":"b2","v":2}' -d +``` + +### MQTT -> AMQP (bridge verification scaffold) +- Use MQTT producer command as ingress. +- Use AMQP consumer matching deployment tooling (qpid-proton, rhea, or project test harness). +- Require correlation ID match between source and destination payloads. + +### CoAP -> MQTT (gateway path) +- Publish CoAP payload to configured CoAP endpoint. +- Consume expected mapped MQTT namespace. +- Validate contentType/schema handling where configured. + +## Failure Classification + +- Ingress failure: source producer cannot connect (`CONNACK` missing, timeout, refused). +- Routing failure: ingress accepted but no delivery to mapped namespace. +- Transform/schema failure: destination receives payload with invalid shape/contentType/schemaId. +- Egress failure: destination protocol consumer cannot connect or receive. + +## Recommended Markers + +- Always include: + - `cid` (correlation id) + - `ts` (epoch millis) + - `route` (expected namespace or bridge path) diff --git a/skills/maps-protocol-bridge-tester/references/output-contract.md b/skills/maps-protocol-bridge-tester/references/output-contract.md new file mode 100644 index 000000000..1fac8971a --- /dev/null +++ b/skills/maps-protocol-bridge-tester/references/output-contract.md @@ -0,0 +1,40 @@ +# Output Contract + +Always return test outputs in this order. + +1. `Bridge Matrix` +- Source protocol -> destination protocol, ports/listeners, namespace mapping, payload format. + +2. `Preflight` +- Startup and bind checks with clear pass/fail state. + +3. `Test Commands` +- Numbered command list for each layer: ingress, egress, end-to-end. +- Include timeouts and expected success markers. + +4. `Results` +- For each layer: pass/fail, evidence summary, and observed output markers. + +5. `Failure Classification` +- Identify failure domain: ingress, routing, transform/schema, egress. + +6. `Remediation and Re-test` +- Exact config/runtime fixes and minimal re-test command set. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never report pass without destination-side evidence. +- Never skip preflight checks. +- Never omit correlation IDs in test payload examples. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh new file mode 100755 index 000000000..948f79a36 --- /dev/null +++ b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-protocol-bridge-tester-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-protocol-bridge-tester-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-protocol-bridge-tester-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-protocol-bridge-tester runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_protocol_bridge_tester_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-protocol-bridge-tester-runtime-smoke.out 2>/tmp/maps-protocol-bridge-tester-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-protocol-bridge-tester-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_protocol_bridge_tester_runtime_smoke path." +fi + +echo "maps-protocol-bridge-tester runtime smoke PASS" diff --git a/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_skill_smoke.sh b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_skill_smoke.sh new file mode 100755 index 000000000..9cbb4504b --- /dev/null +++ b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/bridge-test-catalog.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh" +fi +echo "maps-protocol-bridge-tester skill smoke PASS" diff --git a/skills/maps-release-readiness-checker/SKILL.md b/skills/maps-release-readiness-checker/SKILL.md new file mode 100644 index 000000000..d91774ad0 --- /dev/null +++ b/skills/maps-release-readiness-checker/SKILL.md @@ -0,0 +1,76 @@ +--- +name: maps-release-readiness-checker +description: Assess MAPS Messaging release readiness using evidence-based operational gates. Use when preparing a release candidate, validating snapshot or release artifacts, confirming Docker image availability, running Docker image smoke tests, checking protocol and manager startup health, and producing pass-fail findings with remediation and rerun criteria. +--- + +# MAPS Release Readiness Checker + +Run a structured release gate review and return a defensible release decision with concrete evidence. + +## Workflow + +1. Define release scope. +- Identify candidate type: snapshot, RC, or final release. +- Identify deployment targets and mandatory protocol/feature coverage. + +2. Execute build and test gates. +- Validate build pipeline commands and unit/integration test expectations. +- Capture failing gates with exact evidence. + +3. Execute image availability and container smoke gates. +- Confirm required Docker image tags are available (local or registry-accessible per release scope). +- Start a container from the candidate image and run smoke checks for startup logs and listener binds. +- Capture image-level failures separately from application configuration failures. + +4. Execute runtime startup gates. +- Check startup abort blockers (license, Consul/config gating, provider availability). +- Check listener binds and core protocol availability. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh` + +5. Execute feature-specific operational gates. +- Run checks for configured unique features (aggregator, satellite, schema/transform, CAN, etc.) based on release scope. +- Require destination-side evidence for protocol paths. + +6. Evaluate deployment readiness. +- Confirm packaging artifacts and deployment commands are complete and reproducible. +- Confirm rollback procedure is present and minimal. + +7. Return readiness decision. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/references/output-contract.md`. +- Provide PASS, CONDITIONAL PASS, or FAIL with blocking/non-blocking findings. + +## Rules + +- Never mark PASS without evidence from build, Docker image smoke, startup, and runtime checks. +- Separate blockers from warnings. +- Prefer reproducible command evidence over narrative claims. +- Include explicit rerun criteria after remediation. + +## Scenario Modes + +- `Simple Local Default`: + - Run one compact readiness sweep (build command, one Docker smoke container, one protocol smoke check). + - Return a concise PASS/FAIL with minimal rerun set. +- `Advanced Combination Matrix`: + - Run 3 to 5 readiness profiles by release scope (snapshot/RC/final, protocol sets, feature gates). + - Provide comparative gate outcomes and recommended release decision. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed: +- Gate catalog and commands: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/references/release-gate-catalog.md` +- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/references/output-contract.md` diff --git a/skills/maps-release-readiness-checker/agents/openai.yaml b/skills/maps-release-readiness-checker/agents/openai.yaml new file mode 100644 index 000000000..efb44a251 --- /dev/null +++ b/skills/maps-release-readiness-checker/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Release Readiness Checker" + short_description: "Gate MAPS releases with operational checks" + default_prompt: "Use $maps-release-readiness-checker to assess MAPS release readiness and return pass-fail findings with remediation and rerun checks." diff --git a/skills/maps-release-readiness-checker/references/output-contract.md b/skills/maps-release-readiness-checker/references/output-contract.md new file mode 100644 index 000000000..255dd7b15 --- /dev/null +++ b/skills/maps-release-readiness-checker/references/output-contract.md @@ -0,0 +1,44 @@ +# Output Contract + +Always return in this order. + +1. `Release Scope` +- Candidate type, target environment, mandatory features/protocols. +- Include required Docker image tags for this release decision. + +2. `Gate Results` +- Numbered gate results with pass/fail and concise evidence. +- Include explicit Docker image availability and container smoke evidence. + +3. `Blocking Findings` +- Blocking issues with impact and exact remediation steps. + +4. `Non-Blocking Findings` +- Warnings, risk notes, and mitigation owners. + +5. `Readiness Decision` +- PASS, CONDITIONAL PASS, or FAIL. + +6. `Rerun Criteria` +- Exact command list to rerun after remediation. + +7. `Rollback Confidence` +- Rollback commands and residual risk statement. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never issue PASS without evidence across build, Docker image smoke, startup, and runtime checks. +- Never mix blockers with warnings. +- Never omit rerun criteria. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-release-readiness-checker/references/release-gate-catalog.md b/skills/maps-release-readiness-checker/references/release-gate-catalog.md new file mode 100644 index 000000000..52d432d15 --- /dev/null +++ b/skills/maps-release-readiness-checker/references/release-gate-catalog.md @@ -0,0 +1,67 @@ +# Release Gate Catalog + +## Gate 1: Build and Test + +Core checks: +```bash +cd /Users/krital/dev/starsense/mapsmessaging_server +./build.sh +``` + +If scoped checks are needed, include targeted test commands and capture pass/fail. + +## Gate 2: Docker Image Availability and Smoke + +Image availability checks: +```bash +docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}' +``` + +Container smoke checks: +```bash +docker run -d --name maps-release-smoke -p 1883:1883/tcp -p 8080:8080/tcp +docker logs maps-release-smoke 2>&1 | rg -n "Startup aborted|Protocol not available|ERROR" +docker exec maps-release-smoke sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | rg "1883|8080|5672|9001"' +docker rm -f maps-release-smoke +``` + +## Gate 3: Startup Integrity + +Check for startup blockers: +```bash +docker logs 2>&1 | rg -n "Startup aborted|Protocol not available|Consul|license|ERROR" +``` + +Check listener state: +```bash +docker exec sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | rg "1883|5672|8080|9001"' +``` + +## Gate 4: Protocol Smoke Coverage + +At minimum, run protocol checks required by release scope. +Example MQTT smoke: +```bash +mosquitto_pub -h localhost -p 1883 -t /release/smoke -m ok -d +``` + +Require destination-side confirmation where applicable. + +## Gate 5: Feature-Specific Checks + +Use release scope to include targeted checks: +- Aggregator: aggregator startup and output evidence +- Satellite: provider startup, publish boundary checks +- CAN/N2K: endpoint bind and mapped topic evidence +- Schema/Transform: contentType/schemaId alignment and transformed output + +## Gate 6: Packaging and Rollback + +Confirm deploy artifact completeness and rollback instructions. +For dockerized packaging, include image tag, run command, mounts, and revert command. + +## Decision Criteria + +- PASS: all blocking gates pass with evidence. +- CONDITIONAL PASS: only non-blocking issues remain with mitigation and owner. +- FAIL: any blocking gate fails or evidence is missing. diff --git a/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh new file mode 100755 index 000000000..84cd1f332 --- /dev/null +++ b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-release-readiness-checker-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-release-readiness-checker-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-release-readiness-checker-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-release-readiness-checker runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_release_readiness_checker_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-release-readiness-checker-runtime-smoke.out 2>/tmp/maps-release-readiness-checker-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-release-readiness-checker-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_release_readiness_checker_runtime_smoke path." +fi + +echo "maps-release-readiness-checker runtime smoke PASS" diff --git a/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh new file mode 100755 index 000000000..fcbd66836 --- /dev/null +++ b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_release_readiness_checker_runtime_smoke.sh" +fi +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/release-gate-catalog.md"; rg -n "Docker image" "${ROOT}/references/output-contract.md" >/dev/null +echo "maps-release-readiness-checker skill smoke PASS" diff --git a/skills/maps-runtime-diagnostics/SKILL.md b/skills/maps-runtime-diagnostics/SKILL.md new file mode 100644 index 000000000..9af8db11e --- /dev/null +++ b/skills/maps-runtime-diagnostics/SKILL.md @@ -0,0 +1,71 @@ +--- +name: maps-runtime-diagnostics +description: Diagnose MAPS Messaging Server runtime failures and degraded startup behavior. Use when listeners do not bind, protocol endpoints are unavailable, MQTT/AMQP publish-subscribe tests fail, container startup aborts, licensing or provider issues appear, or configuration changes need root-cause analysis with exact remediation and verification steps. +--- + +# MAPS Runtime Diagnostics + +Diagnose MAPS instance health from startup to protocol smoke tests. Produce actionable root-cause findings and exact commands to verify the fix. + +## Workflow + +1. Capture runtime context. +- Identify deployment mode (local JVM, Docker, Kubernetes). +- Collect target config files and expected listeners (for example `1883`, `5672`, `8080`). +- Record the precise failing operation and timestamp. + +2. Run startup-gate checks first. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md`. +- Detect hard blockers: license validation, Consul bootstrap abort, missing protocol providers, malformed YAML. +- Detect bind blockers: address in use, unsupported endpoint transport, invalid URL scheme. + +3. Verify listener state. +- Compare expected listener matrix vs actual bound sockets. +- Validate container port publishing and in-container bind simultaneously. +- Confirm protocol adapter availability before smoke tests. + +4. Execute protocol smoke tests. +- Run producer/consumer checks only after startup gates are clean. +- For cross-protocol paths, test ingress and egress independently before end-to-end routing. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh` + +5. Return diagnostics using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/references/output-contract.md`. +- Include root cause, evidence commands, exact remediation, and post-fix verification. + +## Diagnostic Rules + +- Prioritize root-cause evidence from logs and bind state over assumptions. +- Do not attribute failures to port collisions unless logs or socket tables prove it. +- Separate startup failures from protocol-data-path failures. +- Prefer MAPS-native fixes (config/runtime flags/image compatibility) over external system substitutions. +- Include concrete success criteria (listener bound, CONNACK received, end-to-end route observed). + +## Scenario Modes + +- `Simple Local Default`: + - Run minimal triage: startup logs, listener bind check, one protocol smoke command. + - Return one likely fix path plus one rerun command set. +- `Advanced Combination Matrix`: + - Evaluate 3 to 5 possible failure domains (startup gate, provider mismatch, bind, routing, transform). + - Rank by confidence and provide targeted diagnostics/remediation per domain. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed: +- Startup and bind triage: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md` +- Final response shape: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/references/output-contract.md` diff --git a/skills/maps-runtime-diagnostics/agents/openai.yaml b/skills/maps-runtime-diagnostics/agents/openai.yaml new file mode 100644 index 000000000..f81bca694 --- /dev/null +++ b/skills/maps-runtime-diagnostics/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Runtime Diagnostics" + short_description: "Diagnose MAPS startup and listener failures" + default_prompt: "Use $maps-runtime-diagnostics to diagnose why this MAPS instance did not start listeners and provide exact fixes and verification commands." diff --git a/skills/maps-runtime-diagnostics/references/output-contract.md b/skills/maps-runtime-diagnostics/references/output-contract.md new file mode 100644 index 000000000..87b9c01af --- /dev/null +++ b/skills/maps-runtime-diagnostics/references/output-contract.md @@ -0,0 +1,43 @@ +# Output Contract + +Always return diagnostics in this order. + +1. `Observed Failure` +- One paragraph: what failed, where, and when. + +2. `Evidence` +- Exact command outputs (summarized) with concrete indicators. +- Include at least one startup-log check and one bind-state check. + +3. `Root Cause` +- Primary root cause plus contributing factors. +- Separate confirmed facts from inference. + +4. `Remediation` +- Exact commands and config edits to resolve the issue. +- Use absolute file paths. + +5. `Post-Fix Verification` +- Listener verification command(s). +- Protocol smoke commands and expected success markers. + +6. `Residual Risks` +- Any unresolved uncertainties or dependencies (image tags, provider plugins, external services). + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never claim port collision without explicit bind-error evidence. +- Never stop at symptoms; provide a concrete fix path. +- Never omit exact verification commands. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md b/skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md new file mode 100644 index 000000000..28c068400 --- /dev/null +++ b/skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md @@ -0,0 +1,55 @@ +# Startup Gates and Bind Checks + +## Primary Triage Sequence + +1. Confirm process/container is actually running. +```bash +docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' +``` + +2. Capture startup errors. +```bash +docker logs 2>&1 | rg -n "ERROR|Exception|Startup aborted|Consul|license|Protocol not available|Address already in use|BindException" +``` + +3. Verify in-container listeners. +```bash +docker exec sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | rg "1883|5672|8080|9001"' +``` + +4. Verify host published ports. +```bash +docker ps --format 'table {{.Names}}\t{{.Ports}}' | rg '' +``` + +5. Run smoke publish/subscribe only if listener is bound. +```bash +mosquitto_pub -h localhost -p 1883 -t /diag/smoke -m ok -d +mosquitto_sub -h localhost -p 1883 -t /diag/smoke -C 1 -W 5 -d +``` + +## Evidence Patterns + +- `Startup aborted ... Consul`: runtime gate failure before full listener init. +- `Protocol not available`: provider missing from build/image; config may reference unsupported protocol. +- `Address already in use` or `BindException`: confirmed port collision. +- `CONNACK (0)` from `mosquitto_pub`: MQTT ingress path is alive. +- Listener only on `8080` but not `1883`: REST came up while messaging listeners failed. + +## Known Pitfall Classes + +1. Image/runtime mismatch +- Symptom: protocol provider errors after startup. +- Check: image tag compatibility with configuration files. + +2. Config gate failures +- Symptom: startup abort before listener bind. +- Check: Consul/file-config expectations, license validity windows, invalid manager YAML. + +3. Port publishing confusion +- Symptom: listener bound in container but unreachable from host. +- Check: `docker run -p` mapping and host firewall. + +4. False port-collision diagnosis +- Symptom: suspected collision but no bind errors. +- Check: prove with log evidence and socket table before concluding collision. diff --git a/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh new file mode 100755 index 000000000..77eda1af0 --- /dev/null +++ b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-runtime-diagnostics-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-runtime-diagnostics-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-runtime-diagnostics-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-runtime-diagnostics runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_runtime_diagnostics_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-runtime-diagnostics-runtime-smoke.out 2>/tmp/maps-runtime-diagnostics-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-runtime-diagnostics-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_runtime_diagnostics_runtime_smoke path." +fi + +echo "maps-runtime-diagnostics runtime smoke PASS" diff --git a/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh new file mode 100755 index 000000000..ab5252eec --- /dev/null +++ b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh" +fi +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/startup-gates-and-bind-checks.md" +echo "maps-runtime-diagnostics skill smoke PASS" diff --git a/skills/maps-satellite-gateway-config/SKILL.md b/skills/maps-satellite-gateway-config/SKILL.md new file mode 100644 index 000000000..09b766ba1 --- /dev/null +++ b/skills/maps-satellite-gateway-config/SKILL.md @@ -0,0 +1,84 @@ +--- +name: maps-satellite-gateway-config +description: Build deployable MAPS satellite gateway configurations for Iridium-style pub-sub service patterns using Orbcomm or Viasat provider profiles and flexible protocol ingress and egress options. Use when requirements include satellite endpoint setup, polling lifecycle, fragmentation and reassembly, priority handling, namespace publish boundaries, and multi-protocol delivery choices with verification and diagnostics. +--- + +# MAPS Satellite Gateway Config + +Generate Iridium-like pub-sub service patterns using MAPS satellite capabilities, with Orbcomm and Viasat-oriented profiles plus selectable protocol endpoints. + +## Workflow + +1. Normalize satellite service contract. +- Extract provider profile (Orbcomm or Viasat), traffic direction (uplink, downlink, bidirectional), polling intervals, message lifetime, priority policy, payload size assumptions, and namespace boundary. +- Capture required ingress and egress protocol options (MQTT, MQTT-SN, AMQP, STOMP, NATS, CoAP, WS, REST). +- Capture encoding mode. If encoding is CBC, enable SIN/MIN hierarchy routing policy. + +2. Build protocol option matrix. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md`. +- Produce at least 2 viable pattern variants when user asks for "more choices". +- For each variant, specify source and destination protocol path, mapping namespace, and operational tradeoffs. + +3. Map selected variant to MAPS config surfaces. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/satellite-config-map.md`. +- Update `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` satellite endpoint and protocol blocks. +- Update `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` and `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` only when required by chosen pattern. + +4. Build deployable entities. +- Prefer minimal diffs. +- Keep endpoint and protocol `type: satellite` aligned. +- Use deterministic interface naming (`sat---`). + +5. Validate before finalizing. +- Confirm provider-profile assumptions, poll cadence bounds, and protocol listener compatibility. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh` +- Include startup/provider checks: +```bash +rg -n "type: satellite|satellite://|Inmarsat|Orbcomm|Viasat" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +docker logs 2>&1 | rg -n "satellite|OGWS|Inmarsat|Viasat|Protocol not available|Startup aborted" +``` + +6. Return with output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/output-contract.md`. +- Include pattern matrix, selected profile, deployable YAML, diagnostics, and verification. + +## Satellite-Specific Rules + +- Treat satellite as a publish boundary into MAPS namespaces. +- Keep polling lifecycle explicit (incoming and outgoing cadence). +- Preserve fragmentation and reassembly expectations; do not claim large-payload success without configured support. +- Include priority-path costs/tradeoffs where high-priority bypass behavior is enabled. +- If requested provider profile is not runtime-supported, emit nearest valid MAPS config with explicit fallback note. +- Prefer MAPS-native bridging over external message brokers. +- Enforce CBC auto-routing policy: when CBC-encoded messages carry unsigned SIN or MIN values under `127`, route to individual SIN/MIN topic hierarchies (for example `.../{sin}/{min}` paths) instead of generic shared topics. +- Include explicit namespace path templates for CBC routing outputs and corresponding verification commands. + +## Scenario Modes + +- `Simple Local Default`: + - Produce one minimal satellite profile with one downstream protocol path and one publish-boundary verification. + - Use conservative polling and queue defaults suitable for local validation. +- `Advanced Combination Matrix`: + - Provide 3 to 6 variants across provider profile, directionality, encoding (including CBC), and downstream protocol fan-out options. + - Include fallback behavior per variant when provider/protocol support is unavailable. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed: +- Service-pattern variants: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md` +- Config mapping and diagnostics: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/satellite-config-map.md` +- Output format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/output-contract.md` diff --git a/skills/maps-satellite-gateway-config/agents/openai.yaml b/skills/maps-satellite-gateway-config/agents/openai.yaml new file mode 100644 index 000000000..7a34911bd --- /dev/null +++ b/skills/maps-satellite-gateway-config/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Satellite Gateway Config" + short_description: "Configure MAPS satellite gateway pipelines" + default_prompt: "Use $maps-satellite-gateway-config to build deployable MAPS satellite gateway configuration with verification commands." diff --git a/skills/maps-satellite-gateway-config/references/output-contract.md b/skills/maps-satellite-gateway-config/references/output-contract.md new file mode 100644 index 000000000..0b9f0ecfa --- /dev/null +++ b/skills/maps-satellite-gateway-config/references/output-contract.md @@ -0,0 +1,49 @@ +# Output Contract + +Always return in this order. + +1. `Satellite Service Pattern Matrix` +- At least 2 variants when user asks for alternatives. +- Each variant: provider profile, ingress protocol, egress protocol(s), namespace boundary, and tradeoffs. + +2. `Selected Pattern` +- State chosen variant and why. + +3. `Provider and Protocol Assumptions` +- List inferred provider/runtime constraints and protocol availability assumptions. +- Include encoding assumptions and whether CBC SIN/MIN auto-routing is active. + +4. `Deployable Config Entity` +- Patch blocks or full YAML implementing satellite plus protocol fan-out changes. + +5. `Apply Steps` +- Exact commands to apply and restart or reload runtime. + +6. `Diagnostics` +- Provider startup checks, protocol listener checks, and bind checks. + +7. `Verification` +- Commands proving satellite-boundary ingest and downstream pub-sub delivery for chosen protocol paths. +- Include one check proving CBC messages with SIN/MIN values under `127` are published into individual `.../{sin}/{min}` hierarchy topics. + +8. `Fallback Notes` +- Explicit fallback behavior when requested provider or protocol path is not currently runtime-supported. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never omit variant matrix when alternatives are requested. +- Never claim provider support without diagnostics. +- Never omit protocol listener verification for each chosen downstream protocol. +- Never omit CBC `<127` SIN/MIN hierarchy routing behavior when CBC encoding is requested. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-satellite-gateway-config/references/satellite-config-map.md b/skills/maps-satellite-gateway-config/references/satellite-config-map.md new file mode 100644 index 000000000..6138fc6ae --- /dev/null +++ b/skills/maps-satellite-gateway-config/references/satellite-config-map.md @@ -0,0 +1,65 @@ +# Satellite Config Map + +## Primary Surface + +- `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + - satellite endpoint entries under `endPointServerConfigList[]` + - protocol block `protocolConfigs[].type: satellite` + +Secondary surfaces for pub-sub pattern realization: +- `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` +- `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + +## Provider Profiles + +1. Orbcomm profile +- Map to OGWS-oriented runtime paths. +- Emphasize queue and polling reliability settings. + +2. Viasat profile +- Treat as provider profile requirements mapped into available satellite DTO fields. +- If a dedicated Viasat adapter is unavailable in runtime, emit a fallback profile note and configure the nearest supported satellite path. + +## Protocol Choice Mapping + +Satellite publish boundary may fan out to one or more protocols depending on request: +- MQTT / MQTT-SN +- AMQP +- STOMP +- NATS +- CoAP +- WS encapsulation +- REST-facing access paths + +For each selected protocol path: +- ensure listener exists in `NetworkManager.yaml` +- ensure namespace mapping exists in `DestinationManager.yaml` +- ensure routing entry exists when cross-server delivery is required + +## CBC Encoding and SIN/MIN Auto-Routing + +When payload encoding mode is CBC, apply this routing rule in generated patterns: +- Treat SIN and MIN as unsigned bytes. +- If SIN or MIN is less than `127`, auto-route to individual SIN/MIN hierarchy paths. +- Preferred inbound topic template: + - `/{deviceId}/common/in/{sin}/{min}` +- Keep per-SIN/MIN routing explicit in namespace mapping output so downstream protocol fan-out can subscribe to deterministic branches. + +For non-CBC or unsupported payload encodings: +- keep fallback to configured generic inbound namespace and note the limitation. + +## Validation Commands + +```bash +rg -n "type: satellite|satellite://|Orbcomm|Viasat|Inmarsat" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "type: mqtt|type: mqtt-sn|type: amqp|type: stomp|type: nats|type: coap|type: ws" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "namespace: |namespaceMapping:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "\\{sin\\}|\\{min\\}|common/in" /Users/krital/dev/starsense/mapsmessaging_server/src/main/java/io/mapsmessaging/network/protocol/impl/satellite +``` + +## Failure Classes + +- Provider profile mismatch against available runtime adapters. +- Protocol fan-out configured without corresponding listeners. +- Polling cadence too aggressive causing queue churn. +- Fragmentation and reassembly assumptions not aligned with payload profile. diff --git a/skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md b/skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md new file mode 100644 index 000000000..12fddcad1 --- /dev/null +++ b/skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md @@ -0,0 +1,61 @@ +# Satellite Pub-Sub Patterns + +## Goal + +Generate Iridium-style service patterns using MAPS satellite ingress and multi-protocol egress. + +## Pattern Templates + +1. `orbcomm-uplink-mqtt-amqp` +- Provider profile: Orbcomm +- Ingress: satellite endpoint +- Egress: MQTT and AMQP fan-out +- Good for: command and telemetry consumers with mixed broker clients + +2. `orbcomm-bidirectional-mqtt-nats` +- Provider profile: Orbcomm +- Ingress and command return path via satellite +- Egress: MQTT and NATS +- Good for: low-latency command distribution with event-stream consumers + +3. `viasat-uplink-mqtt-ws-rest` +- Provider profile: Viasat (profile mapping) +- Ingress: satellite endpoint +- Egress: MQTT plus WS plus REST visibility +- Good for: web clients and operational dashboards + +4. `viasat-bidirectional-amqp-stomp-coap` +- Provider profile: Viasat (profile mapping) +- Ingress and command return path +- Egress: AMQP, STOMP, CoAP +- Good for: heterogeneous device and enterprise integrations + +5. `orbcomm-cbc-sinmin-mqtt-nats` +- Provider profile: Orbcomm +- Encoding: CBC +- Routing rule: auto-route SIN/MIN values less than `127` into `/{deviceId}/common/in/{sin}/{min}` +- Egress: MQTT and NATS branches subscribed to SIN/MIN hierarchy +- Good for: fine-grained device command and telemetry streams keyed by SIN/MIN + +6. `viasat-cbc-sinmin-amqp-ws-rest` +- Provider profile: Viasat (profile mapping) +- Encoding: CBC +- Routing rule: auto-route SIN/MIN values less than `127` into per-SIN/MIN hierarchy +- Egress: AMQP, WS, REST +- Good for: operations platforms needing protocol diversity and SIN/MIN-specific subscriptions + +## Variant Selection Heuristics + +- Prefer fewer protocols for reliability-first deployments. +- Add WS or REST when operator-facing observability is required. +- Use AMQP or NATS when downstream systems need queue/stream semantics. +- Use CoAP only when constrained-device consumers are explicit. + +## Verification Skeleton + +For each chosen protocol path: +- verify listener bound +- publish correlated test message at satellite boundary namespace +- consume at each downstream protocol endpoint +- assert correlation ID and expected route tags +- for CBC patterns, include at least one message where SIN and MIN are below `127` and assert arrival on the exact `.../{sin}/{min}` topic path diff --git a/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh new file mode 100755 index 000000000..43749ed83 --- /dev/null +++ b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-satellite-gateway-config-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-satellite-gateway-config-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-satellite-gateway-config-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-satellite-gateway-config runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_satellite_gateway_config_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-satellite-gateway-config-runtime-smoke.out 2>/tmp/maps-satellite-gateway-config-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-satellite-gateway-config-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_satellite_gateway_config_runtime_smoke path." +fi + +echo "maps-satellite-gateway-config runtime smoke PASS" diff --git a/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh new file mode 100755 index 000000000..a3059166b --- /dev/null +++ b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" + +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh" +fi +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/satellite-pubsub-patterns.md" +test -f "${ROOT}/references/satellite-config-map.md" +rg -n "CBC" "${ROOT}/SKILL.md" >/dev/null +echo "maps-satellite-gateway-config skill smoke PASS" diff --git a/skills/maps-scenario-composer/SKILL.md b/skills/maps-scenario-composer/SKILL.md new file mode 100644 index 000000000..56f76031c --- /dev/null +++ b/skills/maps-scenario-composer/SKILL.md @@ -0,0 +1,81 @@ +--- +name: maps-scenario-composer +description: Combine scenarios from multiple MAPS skills into one unified deliverable. Use when requirements span multiple domains (for example deployment + selectors + geospatial + ML + satellite) and need one coherent deployable entity with merged apply steps, verification, metrics/dashboard outputs, and C4 diagrams. +--- + +# MAPS Scenario Composer + +Compose multi-skill scenario outputs into one deployable, testable, and conflict-resolved delivery package. + +## Workflow + +1. Normalize composition contract. +- Extract requested scenario blocks and source skills. +- Capture dependencies, ordering constraints, and shared config surfaces. +- Identify conflicts (port reuse, topic collisions, incompatible auth/storage assumptions, duplicate routes). + +2. Build composition plan. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/references/composition-patterns.md`. +- Define per-skill scenario slices and merge strategy. +- Decide composition mode: + - additive (independent scenarios merged) + - staged (scenario outputs feed downstream scenarios) + - hybrid (subset staged, subset additive) + +3. Merge deployable entities. +- Produce one unified artifact manifest and merged deployable config blocks. +- Keep source ownership annotations per merged section. +- Resolve collisions deterministically (explicit precedence and fallback paths). +- When concrete artifacts are available, use composer script inputs: + - `--artifact =` for each source scenario output. + - `--out-dir ` to emit concrete merged YAML files. +- Select conflict policy explicitly for deterministic behavior: + - `--conflict-policy strict-fail` + - `--conflict-policy override` + - `--conflict-policy rename` + +4. Build unified execution plan. +- One apply sequence covering all merged artifacts. +- One integrated startup/listener verification sequence. +- One integrated runtime smoke and cross-scenario verification sequence. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh` + +5. Return using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/references/output-contract.md`. +- Include composition matrix, merged deployable entity, and consolidated verification. + +## Rules + +- Never return disconnected per-skill outputs; always produce one coherent deliverable. +- Always declare conflict-resolution decisions explicitly. +- Always preserve traceability: merged section -> source skill(s). +- Always include cross-scenario verification, not only per-scenario checks. + +## Scenario Modes + +- `Simple Local Default`: + - Combine 2 scenarios from different skills into one local deployable profile. + - Include minimal unified apply and smoke sequence. +- `Advanced Combination Matrix`: + - Combine 3 to 8 scenario slices across skills. + - Provide 2 to 4 composition variants and recommend one. + +## Observability and Architecture Outputs + +- Always generate combined scenario metrics across all included scenario slices. +- Always provide two dashboard options: + - Grafana-ready combined dashboard definition. + - MAPS-hosted combined dashboard definition. +- Support both quick and deep observability: + - Simple mode: one combined health dashboard and 5 to 8 core metrics. + - Advanced mode: per-scenario panes plus cross-scenario dependency health. +- Always generate C4 diagrams (Context + Container required, Component required for staged/hybrid composition). + +## Reference Loading + +Load only what is needed: +- Composition design patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/references/composition-patterns.md` +- Final response structure: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/references/output-contract.md` +- Optional generator script: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/scripts/compose_scenarios.py` diff --git a/skills/maps-scenario-composer/agents/openai.yaml b/skills/maps-scenario-composer/agents/openai.yaml new file mode 100644 index 000000000..55813892a --- /dev/null +++ b/skills/maps-scenario-composer/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Scenario Composer" + short_description: "Compose multi-skill deliverables" + default_prompt: "Use $maps-scenario-composer to combine scenarios from multiple MAPS skills into one merged deployable with unified apply and verification steps." diff --git a/skills/maps-scenario-composer/references/composition-patterns.md b/skills/maps-scenario-composer/references/composition-patterns.md new file mode 100644 index 000000000..60f19b56a --- /dev/null +++ b/skills/maps-scenario-composer/references/composition-patterns.md @@ -0,0 +1,55 @@ +# Composition Patterns + +## Pattern A: Additive Composition + +- Merge independent scenarios with minimal overlap. +- Keep apply steps sequential but isolated by section. +- Use when scenarios share runtime but not data path. + +## Pattern B: Staged Composition + +- Output of scenario A becomes input of scenario B. +- Requires explicit intermediate topics/destinations. +- Use when chaining transformations/selectors/ML stages. + +## Pattern C: Hybrid Composition + +- Mix additive and staged sections. +- Group by dependency and failure domain. +- Use when combining deployment/runtime concerns with pipeline concerns. + +## Conflict Resolution Guide + +Resolve in this order: + +1. listener/port conflicts +2. namespace/topic conflicts +3. auth/storage/config-source conflicts +4. selector/route precedence conflicts +5. verification ownership conflicts + +## Conflict Policy Profiles + +- `strict-fail` + - Any scalar/type conflict aborts composition. + - Use for high-integrity release pipelines. +- `override` + - Later skill in `--skills` order overrides conflicting scalar/type values. + - Use for fast iteration and deterministic precedence. +- `rename` + - Conflicting scalar/type keys are preserved by renaming incoming key with source suffix. + - Use when preserving both variants is required for review. + +## Runnable Composer + +Generate a unified deliverable with concrete merged YAML: + +```bash +python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/scripts/compose_scenarios.py \ + --skills maps-deployment-packager,maps-selector-rule-engineer,maps-geospatial-routing-builder \ + --mode hybrid \ + --conflict-policy override \ + --artifact maps-selector-rule-engineer=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md \ + --artifact maps-geospatial-routing-builder=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md \ + --out-dir /tmp/maps-composed +``` diff --git a/skills/maps-scenario-composer/references/examples/composed-deliverable-example.md b/skills/maps-scenario-composer/references/examples/composed-deliverable-example.md new file mode 100644 index 000000000..8010e31f3 --- /dev/null +++ b/skills/maps-scenario-composer/references/examples/composed-deliverable-example.md @@ -0,0 +1,47 @@ +# Composed Deliverable Example + +## Composition Matrix +- mode: hybrid +- sources: + - maps-deployment-packager + - maps-selector-rule-engineer + - maps-geospatial-routing-builder + +## Unified Assumptions +- one runtime, shared config surfaces, explicit precedence. + +## Merged Deployable Entity +```yaml +mergedArtifacts: + - sourceSkill: maps-deployment-packager + - sourceSkill: maps-selector-rule-engineer + - sourceSkill: maps-geospatial-routing-builder +``` + +## Unified Apply Sequence +```bash +# apply merged artifacts, restart once, verify startup +``` + +## Integrated Verification +- startup/listener checks +- selector checks +- geospatial near/far/invalid checks +- cross-scenario route checks + +## Failure Domain and Rollback +- per-slice failure map with merged rollback steps. + +## Traceability Map +- merged section -> `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/SKILL.md` +- merged section -> `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/SKILL.md` +- merged section -> `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/SKILL.md` + +## Scenario Metrics and Dashboard +- combined metrics and cross-scenario health pane. + +## C4 Architecture Diagram +```mermaid +graph LR + A[Ingress] --> B[Composed Runtime] --> C[Egress] +``` diff --git a/skills/maps-scenario-composer/references/output-contract.md b/skills/maps-scenario-composer/references/output-contract.md new file mode 100644 index 000000000..a8a9fc50a --- /dev/null +++ b/skills/maps-scenario-composer/references/output-contract.md @@ -0,0 +1,47 @@ +# Output Contract + +Always return in this order. + +1. `Composition Matrix` +- Source skill/scenario -> merged section mapping. +- Include composition mode (additive/staged/hybrid). +- Include conflict policy used (strict-fail/override/rename). + +2. `Unified Assumptions` +- Shared assumptions and explicit conflict-resolution decisions. + +3. `Merged Deployable Entity` +- One merged artifact set (patches/full files/scripts) with source trace tags. + +4. `Unified Apply Sequence` +- One ordered command plan to apply all merged sections. + +5. `Integrated Verification` +- Startup and listener checks. +- Per-scenario checks. +- Cross-scenario checks proving integration behavior. + +6. `Failure Domain and Rollback` +- Failure split by scenario slice and integrated rollback path. + +7. `Traceability Map` +- For each merged section, list source skills and rationale. + +`Scenario Metrics and Dashboard` +- Provide combined metrics with per-scenario and cross-scenario views. +- Provide Grafana and MAPS-hosted combined dashboard definitions. + +`C4 Architecture Diagram` +- Provide C4 diagrams for composed flow: + - Context and Container required. + - Component required for staged/hybrid composition. +- Include Mermaid source. + +## Guardrails + +- Never output disjoint per-skill artifacts without a merged apply plan. +- Never omit conflict-resolution decisions. +- Never omit cross-scenario verification. +- Never omit traceability from merged sections to source skills. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the composed flow. diff --git a/skills/maps-scenario-composer/scripts/compose_scenarios.py b/skills/maps-scenario-composer/scripts/compose_scenarios.py new file mode 100755 index 000000000..6e726c0ae --- /dev/null +++ b/skills/maps-scenario-composer/scripts/compose_scenarios.py @@ -0,0 +1,345 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import argparse +import re +from collections import defaultdict +from pathlib import Path +from typing import Any + +import yaml + +ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server') +SKILLS_ROOT = ROOT / 'skills' + +MANAGER_FILE_MAP = { + 'NetworkManager': 'NetworkManager.yaml', + 'DestinationManager': 'DestinationManager.yaml', + 'SchemaManager': 'SchemaManager.yaml', + 'AggregatorManager': 'AggregatorManager.yaml', + 'MLModelManager': 'MLModelManager.yaml', + 'AuthManager': 'AuthManager.yaml', + 'SecurityManager': 'SecurityManager.yaml', + 'DeviceManager': 'DeviceManager.yaml', + 'DiscoveryManager': 'DiscoveryManager.yaml', + 'NetworkConnectionManager': 'NetworkConnectionManager.yaml', + 'RestApi': 'RestApi.yaml', + 'TenantManagement': 'TenantManagement.yaml', + 'MessageDaemon': 'MessageDaemon.yaml', + 'LoRaDevice': 'LoRaDevice.yaml', + 'License': 'License.yaml', + 'routing': 'routing.yaml', + 'Routing': 'routing.yaml', +} + + +def parse_csv(raw: str) -> list[str]: + return [x.strip() for x in raw.split(',') if x.strip()] + + +def parse_artifact_arg(raw: str) -> tuple[str, Path]: + if '=' not in raw: + raise ValueError(f'invalid --artifact value `{raw}`; expected skill=path') + skill, path = raw.split('=', 1) + return skill.strip(), Path(path.strip()) + + +def extract_yaml_blocks(path: Path) -> list[str]: + if path.suffix.lower() in {'.yaml', '.yml'}: + return [path.read_text(encoding='utf-8')] + + text = path.read_text(encoding='utf-8') + blocks = re.findall(r"```yaml\n(.*?)```", text, flags=re.DOTALL | re.IGNORECASE) + return [b.strip() for b in blocks if b.strip()] + + +def detect_target_file(obj: Any, skill: str, index: int) -> str: + if isinstance(obj, dict) and len(obj) == 1: + top_key = next(iter(obj.keys())) + if top_key in MANAGER_FILE_MAP: + return MANAGER_FILE_MAP[top_key] + + if isinstance(obj, dict): + keys = set(obj.keys()) + if {'routes', 'predefinedServers', 'autoDiscovery'} & keys: + return 'routing.yaml' + + return f'composed-{skill}-{index}.yaml' + + +def sanitize_id(raw: str) -> str: + return re.sub(r'[^a-zA-Z0-9_]+', '_', raw).strip('_') or 'source' + + +def deep_merge( + base: Any, + incoming: Any, + path: str, + conflicts: list[str], + policy: str, + source_tag: str, + blocking_conflicts: list[str], +) -> Any: + if base is None: + return incoming + + if isinstance(base, dict): + out = dict(base) + for k, v in incoming.items(): + child_path = f'{path}.{k}' if path else str(k) + if k in out: + existing = out[k] + if type(existing) != type(v): + msg = f'{child_path}: type conflict {type(existing).__name__} -> {type(v).__name__}' + if policy == 'strict-fail': + conflicts.append(msg + '; blocked') + blocking_conflicts.append(msg) + elif policy == 'rename': + renamed_key = f'{k}__from_{sanitize_id(source_tag)}' + out[renamed_key] = v + conflicts.append(msg + f'; renamed to {path}.{renamed_key}') + else: + out[k] = v + conflicts.append(msg + '; incoming wins') + elif isinstance(existing, (dict, list)): + out[k] = deep_merge(existing, v, child_path, conflicts, policy, source_tag, blocking_conflicts) + else: + if existing != v: + msg = f'{child_path}: value conflict `{existing}` -> `{v}`' + if policy == 'strict-fail': + conflicts.append(msg + '; blocked') + blocking_conflicts.append(msg) + elif policy == 'rename': + renamed_key = f'{k}__from_{sanitize_id(source_tag)}' + out[renamed_key] = v + conflicts.append(msg + f'; renamed to {path}.{renamed_key}') + else: + out[k] = v + conflicts.append(msg + '; incoming wins') + else: + out[k] = v + return out + + if isinstance(base, list): + out = list(base) + existing = {yaml.safe_dump(item, sort_keys=True).strip() for item in out} + for item in incoming: + sig = yaml.safe_dump(item, sort_keys=True).strip() + if sig not in existing: + out.append(item) + existing.add(sig) + else: + conflicts.append(f'{path}: duplicate list entry ignored') + return out + + if base == incoming: + return base + + msg = f'{path}: value conflict `{base}` -> `{incoming}`' + if policy == 'strict-fail': + conflicts.append(msg + '; blocked') + blocking_conflicts.append(msg) + return base + if policy == 'rename': + conflicts.append(msg + '; rename not possible at scalar root, incoming wins') + return incoming + + conflicts.append(msg + '; incoming wins') + return incoming + + +def collect_artifacts( + skill_order: list[str], + artifact_specs: list[tuple[str, Path]], + policy: str, +) -> tuple[dict[str, Any], dict[str, list[str]], dict[str, list[str]], list[str]]: + merged_by_file: dict[str, Any] = {} + trace_by_file: dict[str, list[str]] = defaultdict(list) + conflicts_by_file: dict[str, list[str]] = defaultdict(list) + blocking_conflicts: list[str] = [] + + order_index = {s: i for i, s in enumerate(skill_order)} + ordered_specs = sorted( + artifact_specs, + key=lambda t: (order_index.get(t[0], 10_000), t[0], str(t[1])), + ) + + for skill, path in ordered_specs: + blocks = extract_yaml_blocks(path) + if not blocks: + conflicts_by_file['global'].append(f'{skill}:{path} produced no YAML blocks') + continue + + for i, block in enumerate(blocks, start=1): + try: + obj = yaml.safe_load(block) + except Exception as ex: + conflicts_by_file['global'].append(f'{skill}:{path} block#{i} YAML parse error: {ex}') + continue + + if obj is None: + continue + + target = detect_target_file(obj, skill, i) + merged_existing = merged_by_file.get(target) + merged_by_file[target] = deep_merge( + merged_existing, + obj, + target, + conflicts_by_file[target], + policy, + skill, + blocking_conflicts, + ) + if skill not in trace_by_file[target]: + trace_by_file[target].append(skill) + + return merged_by_file, trace_by_file, conflicts_by_file, blocking_conflicts + + +def emit_apply_sequence(target_files: list[str], out_dir: Path | None) -> str: + lines = ['```bash'] + if out_dir: + lines.append(f'mkdir -p {out_dir}') + for f in target_files: + lines.append(f'cp {out_dir / f} {ROOT / f}') + else: + lines.append('# Write merged YAML blocks to target files in repo root') + for f in target_files: + lines.append(f'# target: {ROOT / f}') + lines.append('# restart MAPS runtime once after all files are updated') + lines.append('```') + return '\n'.join(lines) + + +def write_output_files(merged_by_file: dict[str, Any], out_dir: Path) -> None: + out_dir.mkdir(parents=True, exist_ok=True) + for file_name, obj in merged_by_file.items(): + (out_dir / file_name).write_text( + yaml.safe_dump(obj, sort_keys=False, allow_unicode=False), + encoding='utf-8', + ) + + +def main() -> int: + parser = argparse.ArgumentParser(description='Compose multi-skill scenario deliverable with concrete merged YAML') + parser.add_argument('--skills', required=True, help='Comma-separated skill names') + parser.add_argument('--mode', default='hybrid', choices=['additive', 'staged', 'hybrid']) + parser.add_argument( + '--conflict-policy', + default='override', + choices=['strict-fail', 'override', 'rename'], + help='Conflict policy for merge collisions', + ) + parser.add_argument('--artifact', action='append', default=[], help='Per-skill artifact input in form skill=path (repeatable)') + parser.add_argument('--out-dir', default='', help='Optional output directory for merged YAML files') + args = parser.parse_args() + + skills = parse_csv(args.skills) + missing = [s for s in skills if not (SKILLS_ROOT / s / 'SKILL.md').exists()] + if missing: + print('Missing skills: ' + ', '.join(missing)) + return 1 + + artifact_specs: list[tuple[str, Path]] = [] + for raw in args.artifact: + try: + skill, path = parse_artifact_arg(raw) + except ValueError as ex: + print(str(ex)) + return 1 + if skill not in skills: + print(f'Artifact skill `{skill}` not in --skills list') + return 1 + if not path.exists(): + print(f'Artifact path does not exist: {path}') + return 1 + artifact_specs.append((skill, path)) + + merged_by_file, trace_by_file, conflicts_by_file, blocking_conflicts = collect_artifacts( + skills, artifact_specs, args.conflict_policy + ) + if args.conflict_policy == 'strict-fail' and blocking_conflicts: + print('Composition failed due to strict-fail conflicts:') + for c in blocking_conflicts: + print(f'- {c}') + return 1 + out_dir = Path(args.out_dir) if args.out_dir else None + if out_dir: + write_output_files(merged_by_file, out_dir) + + print('# Composed Scenario Deliverable') + print() + print('## Composition Matrix') + print(f'- composition mode: {args.mode}') + print(f'- conflict policy: {args.conflict_policy}') + print('- source skills:') + for s in skills: + print(f' - {s}') + if artifact_specs: + print('- source artifacts:') + for skill, path in artifact_specs: + print(f' - {skill}: {path}') + + print('\n## Unified Assumptions') + print('- Shared runtime and config surfaces merged by skill order as precedence.') + print('- Conflicts resolved deterministically; incoming skill in order overrides scalar conflicts.') + print('- Lists are merged with deduplication by YAML signature.') + + print('\n## Merged Deployable Entity') + if not merged_by_file: + print('No merged YAML artifacts were produced. Provide --artifact skill=path inputs.') + else: + for file_name in sorted(merged_by_file.keys()): + print(f'### {ROOT / file_name}') + print('```yaml') + print(yaml.safe_dump(merged_by_file[file_name], sort_keys=False, allow_unicode=False).rstrip()) + print('```') + + print('\n## Unified Apply Sequence') + print(emit_apply_sequence(sorted(merged_by_file.keys()), out_dir)) + + print('\n## Integrated Verification') + print('- Startup diagnostics and listener checks for expected endpoints.') + print('- Per-skill verification paths preserved from source scenarios.') + print('- Cross-scenario checks for staged flows and dependency boundaries.') + + print('\n## Failure Domain and Rollback') + print('- Rollback by restoring target manager files from backups before compose apply.') + print('- Isolate failures by merged file and source-skill ownership.') + + print('\n## Traceability Map') + if not trace_by_file: + print('- No trace entries (no merged artifacts).') + else: + for file_name in sorted(trace_by_file.keys()): + src = ', '.join(trace_by_file[file_name]) + print(f'- {ROOT / file_name} <- {src}') + + print('\n## Conflict Resolution Log') + has_conflicts = False + for file_name in sorted(conflicts_by_file.keys()): + entries = [e for e in conflicts_by_file[file_name] if e] + if not entries: + continue + has_conflicts = True + print(f'- {file_name}:') + for e in entries: + print(f' - {e}') + if not has_conflicts: + print('- No merge conflicts detected.') + + print('\n## Scenario Metrics and Dashboard') + print('- Combined metrics across included skills plus per-skill panes.') + print('- Grafana and MAPS-hosted combined dashboard definitions.') + + print('\n## C4 Architecture Diagram') + print('```mermaid') + print('graph LR') + print(' A[Input Scenario Artifacts] --> B[Scenario Composer Merge] --> C[Unified MAPS Deployable]') + print('```') + return 0 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh b/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh new file mode 100755 index 000000000..44676c5e4 --- /dev/null +++ b/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-scenario-composer-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-scenario-composer-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-scenario-composer-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-scenario-composer runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_scenario_composer_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-scenario-composer-runtime-smoke.out 2>/tmp/maps-scenario-composer-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-scenario-composer-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_scenario_composer_runtime_smoke path." +fi + +echo "maps-scenario-composer runtime smoke PASS" diff --git a/skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh b/skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh new file mode 100755 index 000000000..88c4cd0fd --- /dev/null +++ b/skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +OUT="/tmp/maps-scenario-composer.out" +MERGED_DIR="/tmp/maps-scenario-composer-merged" +TMP_A="/tmp/maps-scenario-composer-a.yaml" +TMP_B="/tmp/maps-scenario-composer-b.yaml" +TMP_RENAME="/tmp/maps-scenario-composer-rename.out" +TMP_OVERRIDE="/tmp/maps-scenario-composer-override.out" + +python3 "${VALIDATOR}" "${ROOT}" +python3 "${ROOT}/scripts/compose_scenarios.py" \ + --skills maps-deployment-packager,maps-selector-rule-engineer,maps-geospatial-routing-builder \ + --mode hybrid \ + --artifact maps-deployment-packager=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/output-contract.md \ + --artifact maps-selector-rule-engineer=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md \ + --artifact maps-geospatial-routing-builder=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md \ + --conflict-policy override \ + --out-dir "${MERGED_DIR}" >"${OUT}" +rg -n "Composition Matrix|Unified Assumptions|Merged Deployable Entity|Unified Apply Sequence|Integrated Verification|Traceability Map|Conflict Resolution Log|Scenario Metrics and Dashboard|C4 Architecture Diagram" "${OUT}" >/dev/null +test -f "${MERGED_DIR}/routing.yaml" + +cat >"${TMP_A}" <"${TMP_B}" </tmp/maps-scenario-composer-strict.out; then + echo "strict-fail policy did not fail on conflict" >&2 + exit 1 +fi + +# rename must preserve incoming conflict with suffix +python3 "${ROOT}/scripts/compose_scenarios.py" \ + --skills maps-selector-rule-engineer,maps-geospatial-routing-builder \ + --mode additive \ + --conflict-policy rename \ + --artifact maps-selector-rule-engineer="${TMP_A}" \ + --artifact maps-geospatial-routing-builder="${TMP_B}" >"${TMP_RENAME}" +rg -n "autoDiscovery__from_maps_geospatial_routing_builder" "${TMP_RENAME}" >/dev/null + +# override must prefer later skill value +python3 "${ROOT}/scripts/compose_scenarios.py" \ + --skills maps-selector-rule-engineer,maps-geospatial-routing-builder \ + --mode additive \ + --conflict-policy override \ + --artifact maps-selector-rule-engineer="${TMP_A}" \ + --artifact maps-geospatial-routing-builder="${TMP_B}" >"${TMP_OVERRIDE}" +rg -n "autoDiscovery: true" "${TMP_OVERRIDE}" >/dev/null + +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_scenario_composer_runtime_smoke.sh" +fi + +echo "scenario composer skill smoke PASS" diff --git a/skills/maps-schema-pipeline-builder/SKILL.md b/skills/maps-schema-pipeline-builder/SKILL.md new file mode 100644 index 000000000..eabb97a70 --- /dev/null +++ b/skills/maps-schema-pipeline-builder/SKILL.md @@ -0,0 +1,74 @@ +--- +name: maps-schema-pipeline-builder +description: Build schema-aware MAPS Messaging configuration pipelines. Use when requirements include schema registration, schemaId assignment, validation and transformation behavior, content-type normalization, or format conversion across JSON, Protobuf, Avro, CSV, raw binary, and raw text with deployable manager YAML changes. +--- + +# MAPS Schema Pipeline Builder + +Translate schema and format requirements into deployable MAPS configuration entities with deterministic verification. + +## Workflow + +1. Normalize schema contract. +- Extract payload formats, schema source, namespace mapping, required schemaId behavior, validation strictness, and transformation order. +- Resolve missing details only when schema behavior would change. + +2. Map contract to configuration surfaces. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md`. +- Map schema-aware message behavior to: + - `/Users/krital/dev/starsense/mapsmessaging_server/SchemaManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +- If required, include relevant transformation manager config paths. + +3. Build deployable entities. +- Prefer minimal file diffs. +- For deployment packaging requests, emit full YAML bodies or ConfigMap manifests. +- Keep deterministic IDs and names for schema entities. + +4. Validate before finalizing. +- Check key fields and linkage consistency (`schemaId`, `contentType`, namespace mapping). +- Run targeted checks: +```bash +rg -n "schemaId|contentType|messageOverride|qualityOfService" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "SchemaManager|schema|type:" /Users/krital/dev/starsense/mapsmessaging_server/SchemaManager.yaml +rg -n "protocolConfigs|messageDefaults|contentType" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +``` + +5. Return output using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/references/output-contract.md`. +- Always include assumptions, deployable YAML, apply steps, and validation commands. + +## Rules + +- Keep transformations deterministic and ordered. +- Preserve existing DTO naming/casing and manager structure. +- Use MAPS-native schema and transformation paths before suggesting external systems. +- Explicitly state unsupported or unavailable schema providers and output nearest valid config. + +## Scenario Modes + +- `Simple Local Default`: + - Produce one schema registration plus one namespace schemaId/contentType mapping. + - Include minimal producer/consumer verification. +- `Advanced Combination Matrix`: + - Provide 3 to 5 schema pipeline variants across JSON/Protobuf/Avro/CSV/raw pathways. + - Include compatibility notes for schema linkage, transformation order, and destination expectations. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed: +- Schema mapping details: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md` +- Response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/references/output-contract.md` diff --git a/skills/maps-schema-pipeline-builder/agents/openai.yaml b/skills/maps-schema-pipeline-builder/agents/openai.yaml new file mode 100644 index 000000000..ffe060f64 --- /dev/null +++ b/skills/maps-schema-pipeline-builder/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Schema Pipeline Builder" + short_description: "Build schema-aware MAPS message pipelines" + default_prompt: "Use $maps-schema-pipeline-builder to convert schema and transformation requirements into deployable MAPS configuration and verification steps." diff --git a/skills/maps-schema-pipeline-builder/references/output-contract.md b/skills/maps-schema-pipeline-builder/references/output-contract.md new file mode 100644 index 000000000..27b1f30e4 --- /dev/null +++ b/skills/maps-schema-pipeline-builder/references/output-contract.md @@ -0,0 +1,40 @@ +# Output Contract + +Always return outputs in this order. + +1. `Schema Requirement Mapping` +- Requirement phrase -> config fields and absolute file paths. + +2. `Assumptions` +- List all defaulted schema/content-type choices. + +3. `Deployable Config Entity` +- Provide patch blocks, full YAML bodies, or ConfigMap manifests. +- Include exact `schemaId` and `contentType` values. + +4. `Apply Steps` +- Exact commands to apply YAML changes in this repo. + +5. `Validation` +- Commands that verify schema linkage and content-type alignment. + +6. `Runtime Verification` +- Producer/consumer checks showing payload acceptance on expected namespace. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never omit absolute file paths. +- Never leave unresolved placeholders. +- Never provide schema behavior without exact implementing YAML. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md b/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md new file mode 100644 index 000000000..61fa1bb4c --- /dev/null +++ b/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md @@ -0,0 +1,54 @@ +# Schema Mapping Guide + +## Scope + +Use this guide when a request requires schema registration, schema assignment, content-type controls, validation, or format conversion. + +Supported payload families in MAPS context: +- JSON +- Protobuf +- Avro +- CSV +- Raw binary +- Raw text + +## Configuration Surfaces + +- `/Users/krital/dev/starsense/mapsmessaging_server/SchemaManager.yaml` + - schema catalog and registration behavior. +- `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` + - namespace-level message overrides (`schemaId`, `contentType`, QoS, retain). +- `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + - protocol-level message defaults and content-type baselines. + +## Mapping Patterns + +1. Schema registration request +- Target `SchemaManager.yaml` entries. +- Ensure schema IDs are deterministic and referenced where needed. + +2. Namespace-specific schema enforcement +- Target `DestinationManager.data[].messageOverride.schemaId`. +- Pair with `contentType` when format is explicit. + +3. Protocol ingress default format +- Target `NetworkManager...protocolConfigs[].messageDefaults.contentType`. +- Keep this as protocol default; override at destination only when required. + +4. Format conversion pipeline +- Use configured transformation chain in explicit order. +- Validate resulting `contentType` and `schemaId` at egress destination. + +## Validation Checklist + +```bash +rg -n "schemaId:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "contentType:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "schema|Schema" /Users/krital/dev/starsense/mapsmessaging_server/SchemaManager.yaml +``` + +## Common Failure Classes + +- Schema reference present but not registered in schema manager. +- Content type mismatch between ingress default and destination override. +- Transformation order mismatch causes invalid payload shape at destination. diff --git a/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh new file mode 100755 index 000000000..235dc151d --- /dev/null +++ b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-schema-pipeline-builder-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-schema-pipeline-builder-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-schema-pipeline-builder-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-schema-pipeline-builder runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_schema_pipeline_builder_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-schema-pipeline-builder-runtime-smoke.out 2>/tmp/maps-schema-pipeline-builder-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-schema-pipeline-builder-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_schema_pipeline_builder_runtime_smoke path." +fi + +echo "maps-schema-pipeline-builder runtime smoke PASS" diff --git a/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_skill_smoke.sh b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_skill_smoke.sh new file mode 100755 index 000000000..a4fa1d24b --- /dev/null +++ b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/schema-mapping-guide.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh" +fi +echo "maps-schema-pipeline-builder skill smoke PASS" diff --git a/skills/maps-selector-rule-engineer/SKILL.md b/skills/maps-selector-rule-engineer/SKILL.md new file mode 100644 index 000000000..6a8a31ed8 --- /dev/null +++ b/skills/maps-selector-rule-engineer/SKILL.md @@ -0,0 +1,71 @@ +--- +name: maps-selector-rule-engineer +description: Design and validate MAPS selector logic for routing rules and subscriber selectors. Use when requirements include conditional routing, selector expressions, multi-stage filter chains, selector performance tuning, or conflict resolution across destination routing and subscriber-level selection. +--- + +# MAPS Selector Rule Engineer + +Build clear, testable selector configurations for routing and subscriptions, from simple filters to advanced chained selection logic. + +## Workflow + +1. Normalize selector contract. +- Extract selector intent, source topics, output destinations, subscriber selector behavior, and expected match/non-match outcomes. +- Identify whether selectors apply at routing layer, subscription layer, or both. + +2. Build selector design. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/selector-patterns.md`. +- Create explicit selector evaluation order. +- Define conflict policy (first-match, priority-based, or layered pass). + +3. Map to MAPS config surfaces. +- Update manager YAML files relevant to routing and destination/subscription behavior. +- Keep selector expressions and routing paths deterministic and explicit. + +4. Validate selector semantics. +- Include positive and negative test vectors. +- Verify no contradictory selector overlap unless intentionally prioritized. +- Include runtime verification commands with correlation payload markers. +- Prefer bundled scripts for repeatable validation: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh` + +5. Return using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/output-contract.md`. +- Include selector matrix, deployable config, apply steps, and verification. + +## Rules + +- Always show selector evaluation order. +- Never claim correctness without both match and non-match evidence. +- Prefer MAPS-native selector/routing mechanisms over external filtering services. +- Include complexity notes for selectors likely to impact throughput. + +## Scenario Modes + +- `Simple Local Default`: + - One routing selector and one subscriber selector with clear pass/fail examples. +- `Advanced Combination Matrix`: + - Provide 3 to 6 variants across routing-level, subscriber-level, and chained selector patterns. + - Include one recommended operationally simple variant. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to selector behavior (selector hit rate, miss rate, route divergence, dropped-on-filter count, selector latency). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification. +- Support both quick and deep observability: + - Simple mode: one minimal selector health panel and 3 to 6 metrics. + - Advanced mode: per-selector and per-route breakdown with alerts. +- Always generate C4 diagrams (Context and Container minimum; Component for multi-stage selectors). + +## Reference Loading + +Load only what is needed: +- Selector design patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/selector-patterns.md` +- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/output-contract.md` +- Example artifacts: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md` diff --git a/skills/maps-selector-rule-engineer/agents/openai.yaml b/skills/maps-selector-rule-engineer/agents/openai.yaml new file mode 100644 index 000000000..322650947 --- /dev/null +++ b/skills/maps-selector-rule-engineer/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Selector Rule Engineer" + short_description: "Design routing and subscriber selectors" + default_prompt: "Use $maps-selector-rule-engineer to design MAPS routing and subscriber selectors with deployable config and positive/negative verification vectors." diff --git a/skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md b/skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md new file mode 100644 index 000000000..ccc4c2030 --- /dev/null +++ b/skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md @@ -0,0 +1,83 @@ +# Advanced Selector Output Example + +## Selector Requirement Mapping +- Stage 1 route by `vehicleType` to intermediate topics. +- Stage 2 subscriber selectors split high-priority alerts and normal events. +- File targets: + - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + +## Selector Evaluation Model +- Routing selector order: + 1. `vehicleType == "emergency"` -> `/selector/intermediate/emergency` + 2. `vehicleType == "public"` -> `/selector/intermediate/public` + 3. fallback -> `/selector/intermediate/other` +- Subscriber selector order on each intermediate topic: + 1. `priority >= 8` -> `/selector/final/high` + 2. `priority < 8` -> `/selector/final/normal` +- Conflict policy: strict stage order, first-match per stage. + +## Assumptions +- Payload fields: `vehicleType`, `priority`. +- Unknown `vehicleType` uses fallback path. + +## Deployable Config Entity +```yaml +# example staged selector routes +routes: + - source: /selector/in + selector: "vehicleType == 'emergency'" + destination: /selector/intermediate/emergency + - source: /selector/in + selector: "vehicleType == 'public'" + destination: /selector/intermediate/public + - source: /selector/in + selector: "true" + destination: /selector/intermediate/other +``` + +## Apply Steps +```bash +cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml.bak +# apply staged selector patch and restart runtime +``` + +## Verification +- Positive vectors: + - `{ "vehicleType":"emergency", "priority":9 }` -> `/selector/final/high` + - `{ "vehicleType":"public", "priority":6 }` -> `/selector/final/normal` +- Negative vectors: + - `{ "vehicleType":"other", "priority":9 }` should not appear in emergency-only subscriber stream. + - `{ "vehicleType":"public", "priority":2 }` should not appear in high-priority stream. +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh --source-topic /selector/in --match-topic /selector/final/high --nonmatch-topic /selector/final/normal +``` + +## Performance and Risk Notes +- Two-stage selection increases evaluation count. +- Risk: overlapping selector terms can cause unintended fan-out if precedence is altered. +- Mitigation: keep explicit stage boundaries and fallback routes. + +## Scenario Metrics and Dashboard +- Metrics: + - per-stage selector hit/miss + - stage-1 to stage-2 transfer latency + - dropped-on-filter count + - selector conflict count +- Grafana: stage heatmap + selector latency percentiles. +- MAPS-hosted dashboard: per-stage throughput and conflict alerts. + +## C4 Architecture Diagram +```mermaid +graph LR + A[Publisher] --> B[Stage1 routing selectors] + B --> C[/selector/intermediate/emergency] + B --> D[/selector/intermediate/public] + B --> E[/selector/intermediate/other] + C --> F[Stage2 subscriber selectors] + D --> F + E --> F + F --> G[/selector/final/high] + F --> H[/selector/final/normal] +``` diff --git a/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md b/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md new file mode 100644 index 000000000..09e005638 --- /dev/null +++ b/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md @@ -0,0 +1,69 @@ +# Simple Selector Output Example + +## Selector Requirement Mapping +- Route `priority >= 5` messages to `/selector/match` and others to `/selector/nonmatch`. +- File targets: + - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` + - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + +## Selector Evaluation Model +- Routing selector order: + 1. `priority >= 5` -> `/selector/match` + 2. fallback -> `/selector/nonmatch` +- Subscriber selector order: + 1. subscriber A: `priority >= 5` + 2. subscriber B: `priority < 5` +- Conflict policy: first-match then fallback. + +## Assumptions +- JSON payload has numeric `priority`. +- Missing `priority` treated as non-match. + +## Deployable Config Entity +```yaml +# example patch fragment +routes: + - source: /selector/in + selector: "priority >= 5" + destination: /selector/match + - source: /selector/in + selector: "true" + destination: /selector/nonmatch +``` + +## Apply Steps +```bash +cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml.bak +# apply selector route patch +``` + +## Verification +- Positive vector: + - payload: `{ "priority": 9 }` should route to `/selector/match`. +- Negative vector: + - payload: `{ "priority": 1 }` should route to `/selector/nonmatch`. +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh --source-topic /selector/in --match-topic /selector/match --nonmatch-topic /selector/nonmatch +``` + +## Performance and Risk Notes +- Simple expression has low selector latency. +- Risk: malformed payloads without `priority` route to fallback. + +## Scenario Metrics and Dashboard +- Metrics: + - selector match rate + - selector miss rate + - route divergence count + - selector evaluation latency +- Grafana panel: selector hit/miss time series. +- MAPS-hosted dashboard: per-selector counters and last-evaluation errors. + +## C4 Architecture Diagram +```mermaid +graph LR + A[Publisher] --> B[MAPS selector route] + B --> C[/selector/match] + B --> D[/selector/nonmatch] +``` diff --git a/skills/maps-selector-rule-engineer/references/output-contract.md b/skills/maps-selector-rule-engineer/references/output-contract.md new file mode 100644 index 000000000..e693c4819 --- /dev/null +++ b/skills/maps-selector-rule-engineer/references/output-contract.md @@ -0,0 +1,44 @@ +# Output Contract + +Always return in this order. + +1. `Selector Requirement Mapping` +- Requirement phrase -> selector field/path and absolute file path. + +2. `Selector Evaluation Model` +- Routing selector order and subscriber selector order. +- Conflict/precedence policy. + +3. `Assumptions` +- Defaults and inferred selector constraints. + +4. `Deployable Config Entity` +- Patch blocks or full YAML implementing selectors and routes. + +5. `Apply Steps` +- Exact commands to apply and restart/reload runtime. + +6. `Verification` +- Positive and negative test vectors. +- Runtime publish/consume commands with pass/fail assertions. + +7. `Performance and Risk Notes` +- Complexity notes, likely hot paths, and fallback guidance. + +`Scenario Metrics and Dashboard` +- Provide selector-specific metrics list with collection points and expected ranges. +- Provide Grafana dashboard and MAPS-hosted dashboard definitions. + +`C4 Architecture Diagram` +- Provide C4 diagrams for selector-enabled flow: + - Context and Container required. + - Component required for chained selectors. +- Include Mermaid source. + +## Guardrails + +- Never omit selector order. +- Never omit non-match evidence. +- Never omit absolute file paths. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-selector-rule-engineer/references/selector-patterns.md b/skills/maps-selector-rule-engineer/references/selector-patterns.md new file mode 100644 index 000000000..cfe1015a7 --- /dev/null +++ b/skills/maps-selector-rule-engineer/references/selector-patterns.md @@ -0,0 +1,44 @@ +# Selector Patterns + +## Pattern A: Simple Routing Selector + +- One source topic. +- One condition. +- Two destination paths: matched and unmatched. + +## Pattern B: Subscriber Selector + +- Shared source topic. +- Distinct selectors per subscriber class. +- Verify each subscriber receives only intended messages. + +## Pattern C: Chained Selectors + +- Selector stage 1 routes into intermediate destination. +- Selector stage 2 refines output to final destinations. +- Keep stage boundaries explicit and testable. + +## Conflict Handling + +- Define precedence when selectors overlap. +- Document expected behavior for ambiguous payloads. + +## Verification Guidance + +- Provide positive vectors (should pass). +- Provide negative vectors (should fail). +- Include timeout-bound consume checks. + +## Runnable Smoke Commands + +Skill smoke gate: + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh +``` + +Runtime selector smoke (subscribe before publish): + +```bash +bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh --source-topic /selector/in --match-topic /selector/match --nonmatch-topic /selector/nonmatch +``` diff --git a/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh b/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh new file mode 100755 index 000000000..81f19476e --- /dev/null +++ b/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-selector-rule-engineer-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-selector-rule-engineer-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-selector-rule-engineer-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-selector-rule-engineer runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_selector_rule_engineer_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-selector-rule-engineer-runtime-smoke.out 2>/tmp/maps-selector-rule-engineer-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-selector-rule-engineer-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_selector_rule_engineer_runtime_smoke path." +fi + +echo "maps-selector-rule-engineer runtime smoke PASS" diff --git a/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh b/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh new file mode 100755 index 000000000..d60fe6f95 --- /dev/null +++ b/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +set -euo pipefail + +HOST="127.0.0.1" +PORT="1883" +SOURCE_TOPIC="/selector/in" +MATCH_TOPIC="/selector/match" +NON_MATCH_TOPIC="/selector/nonmatch" +POSITIVE_PAYLOAD='{"kind":"priority","priority":9}' +NEGATIVE_PAYLOAD='{"kind":"normal","priority":1}' +USERNAME="" +PASSWORD="" + +usage() { + cat < Broker host (default: ${HOST}) + --port Broker port (default: ${PORT}) + --source-topic Source publish topic (default: ${SOURCE_TOPIC}) + --match-topic Expected match topic (default: ${MATCH_TOPIC}) + --nonmatch-topic Expected non-match topic (default: ${NON_MATCH_TOPIC}) + --positive-payload Payload expected to hit match selector + --negative-payload Payload expected to hit non-match selector + --username MQTT username (optional) + --password MQTT password (optional) + -h, --help Show this help +USAGE +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --host) HOST="$2"; shift 2 ;; + --port) PORT="$2"; shift 2 ;; + --source-topic) SOURCE_TOPIC="$2"; shift 2 ;; + --match-topic) MATCH_TOPIC="$2"; shift 2 ;; + --nonmatch-topic) NON_MATCH_TOPIC="$2"; shift 2 ;; + --positive-payload) POSITIVE_PAYLOAD="$2"; shift 2 ;; + --negative-payload) NEGATIVE_PAYLOAD="$2"; shift 2 ;; + --username) USERNAME="$2"; shift 2 ;; + --password) PASSWORD="$2"; shift 2 ;; + -h|--help) usage; exit 0 ;; + *) echo "Unknown argument: $1" >&2; usage; exit 2 ;; + esac +done + +MQTT_AUTH_ARGS=() +if [[ -n "${USERNAME}" ]]; then MQTT_AUTH_ARGS+=( -u "${USERNAME}" ); fi +if [[ -n "${PASSWORD}" ]]; then MQTT_AUTH_ARGS+=( -P "${PASSWORD}" ); fi + +POS_MATCH="/tmp/selector-pos-match.out" +POS_NONMATCH="/tmp/selector-pos-nonmatch.out" +NEG_MATCH="/tmp/selector-neg-match.out" +NEG_NONMATCH="/tmp/selector-neg-nonmatch.out" + +: >"${POS_MATCH}"; : >"${POS_NONMATCH}"; : >"${NEG_MATCH}"; : >"${NEG_NONMATCH}" + +# Subscribe before publish. +timeout 12 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${MATCH_TOPIC}" -C 1 "${MQTT_AUTH_ARGS[@]}" >"${POS_MATCH}" 2>/tmp/selector-pos-match.err & +PID_PM=$! +timeout 4 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${NON_MATCH_TOPIC}" -C 1 "${MQTT_AUTH_ARGS[@]}" >"${POS_NONMATCH}" 2>/tmp/selector-pos-nonmatch.err & +PID_PN=$! +sleep 1 +mosquitto_pub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${SOURCE_TOPIC}" -m "${POSITIVE_PAYLOAD}" "${MQTT_AUTH_ARGS[@]}" + +wait "${PID_PM}" +wait "${PID_PN}" || true + +if [[ ! -s "${POS_MATCH}" ]]; then + echo "positive case failed: no match-topic message" >&2 + exit 1 +fi +if [[ -s "${POS_NONMATCH}" ]]; then + echo "positive case failed: unexpected nonmatch-topic message" >&2 + exit 1 +fi + +# Negative payload should route to non-match. +timeout 4 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${MATCH_TOPIC}" -C 1 "${MQTT_AUTH_ARGS[@]}" >"${NEG_MATCH}" 2>/tmp/selector-neg-match.err & +PID_NM=$! +timeout 12 mosquitto_sub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${NON_MATCH_TOPIC}" -C 1 "${MQTT_AUTH_ARGS[@]}" >"${NEG_NONMATCH}" 2>/tmp/selector-neg-nonmatch.err & +PID_NN=$! +sleep 1 +mosquitto_pub -V mqttv311 -h "${HOST}" -p "${PORT}" -t "${SOURCE_TOPIC}" -m "${NEGATIVE_PAYLOAD}" "${MQTT_AUTH_ARGS[@]}" + +wait "${PID_NM}" || true +wait "${PID_NN}" + +if [[ -s "${NEG_MATCH}" ]]; then + echo "negative case failed: unexpected match-topic message" >&2 + exit 1 +fi +if [[ ! -s "${NEG_NONMATCH}" ]]; then + echo "negative case failed: no nonmatch-topic message" >&2 + exit 1 +fi + +echo "selector mqtt smoke PASS" diff --git a/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh b/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh new file mode 100755 index 000000000..04e2214eb --- /dev/null +++ b/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" + +python3 "${VALIDATOR}" "${ROOT}" +python3 "${ROOT}/scripts/validate_selector_artifacts.py" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh" +fi +echo "selector skill smoke PASS" diff --git a/skills/maps-selector-rule-engineer/scripts/validate_selector_artifacts.py b/skills/maps-selector-rule-engineer/scripts/validate_selector_artifacts.py new file mode 100755 index 000000000..f0be21e59 --- /dev/null +++ b/skills/maps-selector-rule-engineer/scripts/validate_selector_artifacts.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import re +import sys +from pathlib import Path + +ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer') +CONTRACT = ROOT / 'references' / 'output-contract.md' +EXAMPLES = [ + ROOT / 'references' / 'examples' / 'simple-selector-output.md', + ROOT / 'references' / 'examples' / 'advanced-selector-output.md', +] + + +def parse_sections(text: str) -> list[str]: + sections: list[str] = [] + seen: set[str] = set() + for line in text.splitlines(): + line = line.strip() + m = re.match(r'^\d+\.\s+`([^`]+)`', line) + if not m: + m = re.match(r'^`([^`]+)`$', line) + if m: + val = m.group(1).strip() + if val not in seen: + seen.add(val) + sections.append(val) + return sections + + +def main() -> int: + if not CONTRACT.exists(): + print(f'missing contract: {CONTRACT}') + return 1 + + sections = parse_sections(CONTRACT.read_text(encoding='utf-8')) + if not sections: + print('no sections parsed from contract') + return 1 + + errors: list[str] = [] + for ex in EXAMPLES: + if not ex.exists(): + errors.append(f'missing example: {ex}') + continue + txt = ex.read_text(encoding='utf-8') + for section in sections: + if f'## {section}' not in txt: + errors.append(f'{ex.name}: missing section {section}') + for marker in ['positive', 'negative']: + if marker not in txt.lower(): + errors.append(f'{ex.name}: missing {marker} verification marker') + if '```bash' not in txt: + errors.append(f'{ex.name}: missing bash command block') + if '```mermaid' not in txt: + errors.append(f'{ex.name}: missing mermaid diagram block') + if '/Users/krital/dev/starsense/mapsmessaging_server' not in txt: + errors.append(f'{ex.name}: missing absolute path reference') + + if errors: + print('selector artifact validation failed:') + for e in errors: + print(f'- {e}') + return 1 + + print('selector artifact validation passed.') + return 0 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/skills/maps-skill-suite-orchestrator/SKILL.md b/skills/maps-skill-suite-orchestrator/SKILL.md new file mode 100644 index 000000000..9f2d768c9 --- /dev/null +++ b/skills/maps-skill-suite-orchestrator/SKILL.md @@ -0,0 +1,212 @@ +--- +name: maps-skill-suite-orchestrator +description: Master index and invocation orchestrator for the MAPS skill suite. Use when selecting which MAPS skill to run, composing multi-skill workflows, or generating standardized quick-start and advanced prompts that map requirements to deployable outputs with diagnostics, metrics dashboards, and C4 diagrams. +--- + +# MAPS Skill Suite Orchestrator + +Use this as the entrypoint index for all MAPS skills in this repository. + +## Purpose + +- Route a request to the correct skill quickly. +- Provide consistent prompt templates for `Quick Start` and `Advanced` usage. +- Keep outputs aligned with deployment readiness: deployable config artifacts, verification commands, scenario metrics/dashboard specs, and C4 diagrams. + +## Skill Index + +1. `mapsmessaging-config-builder` +- Build deployable MAPS manager YAML from protocol, encoding, topology, schema, and routing intent. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/SKILL.md` + +2. `maps-runtime-diagnostics` +- Diagnose startup/runtime failures, bind issues, provider/config blockers, and smoke-test failures. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/SKILL.md` + +3. `maps-protocol-bridge-tester` +- Design and run layered ingress/egress/end-to-end bridge tests with strict pass/fail markers. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/SKILL.md` + +4. `maps-satellite-gateway-config` +- Generate satellite pub/sub patterns using Orbcomm or Viasat with broad protocol fan-out and CBC SIN/MIN routing. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/SKILL.md` + +5. `maps-schema-pipeline-builder` +- Build schema-aware pipelines across JSON/Protobuf/Avro/CSV/raw with schemaId/contentType mapping. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/SKILL.md` + +6. `maps-transform-chain-designer` +- Design deterministic ordered transform chains (CloudEvent, mutate, convert, enrich). +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/SKILL.md` + +7. `maps-aggregator-config-engineer` +- Configure unique MAPS windowed aggregation behavior and validate window/timeout/fairness semantics. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/SKILL.md` + +8. `maps-canbus-ingestion-builder` +- Build CAN/N2K ingestion profiles for `vcan` and native interfaces with deterministic topic mapping. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/SKILL.md` + +9. `maps-deployment-packager` +- Package deployables for local, Docker, Kubernetes-style bundles, Fly.io, AWS, GCP, and Azure. +- Includes auth, storage, file-vs-Consul mode, Fly KV options, optional Consul (HCP/self-managed), and object storage (S3/R2). +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/SKILL.md` + +10. `maps-release-readiness-checker` +- Run evidence-based release gates with Docker image availability and smoke checks. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/SKILL.md` + +11. `maps-ml-stream-configurator` +- Build simple-to-advanced ML selector stream pipelines with staged intermediate destinations and model chaining. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/SKILL.md` + +12. `maps-artifact-execution-smoke-harness` +- Execute generated artifacts end-to-end and return startup, listener, and traffic smoke evidence. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/SKILL.md` + +13. `maps-selector-rule-engineer` +- Design selector logic for routing rules and subscriber selectors with deterministic precedence and verification. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/SKILL.md` + +14. `maps-geospatial-routing-builder` +- Build geohash and GPS/distance-driven routing behavior with deployable config and geospatial validation. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/SKILL.md` + +15. `maps-ml-model-lifecycle-playbook` +- Provide MAPS-native model lifecycle guidance from stream training to external model ingestion for inference. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/SKILL.md` + +16. `maps-scenario-composer` +- Combine scenarios from multiple skills into one merged deployable with unified apply and integrated verification. +- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/SKILL.md` + +## Selection Guide + +Use this mapping to choose a starting skill: + +- Protocol/topology to YAML: `mapsmessaging-config-builder` +- Startup failures or bind/smoke issues: `maps-runtime-diagnostics` +- Cross-protocol delivery verification: `maps-protocol-bridge-tester` +- Satellite service patterns: `maps-satellite-gateway-config` +- Schema registration and conversion: `maps-schema-pipeline-builder` +- Ordered transform design: `maps-transform-chain-designer` +- Windowed aggregate logic: `maps-aggregator-config-engineer` +- CAN/N2K ingestion: `maps-canbus-ingestion-builder` +- Deployment packaging: `maps-deployment-packager` +- Release gate decision: `maps-release-readiness-checker` +- ML selector stream orchestration: `maps-ml-stream-configurator` +- Artifact execution smoke validation: `maps-artifact-execution-smoke-harness` +- Routing/subscriber selector engineering: `maps-selector-rule-engineer` +- Geospatial (geohash/GPS/distance) routing: `maps-geospatial-routing-builder` +- Stream-trained and external-model ML lifecycle: `maps-ml-model-lifecycle-playbook` +- Multi-skill scenario composition into one deliverable: `maps-scenario-composer` + +## Standard Prompt Templates + +Use these exact templates and replace placeholders. + +### Quick Start Template + +```text +Use in Simple Local Default mode. +Goal: . +Inputs: +- protocols/features: <...> +- config files in scope: <...> +- constraints: <...> +Output requirements: +- deployable config/artifacts +- apply commands +- startup + listener/smoke verification +- scenario metrics + minimal dashboard +- C4 Context + Container diagrams +Keep it minimal and locally testable. +``` + +### Advanced Template + +```text +Use in Advanced Combination Matrix mode. +Goal: . +Generate viable variants and recommend one. +Inputs: +- protocol/topology and feature scope: <...> +- auth modes to support: <...> +- storage/volume and config source modes: <...> +- deployment targets: +- connectivity profile: +Output requirements: +- per-variant deployable config/artifacts +- tradeoffs and recommended option +- apply + diagnostics + smoke tests +- scenario-specific metrics + dashboards (Grafana + MAPS-hosted) +- C4 diagrams (Context, Container, Component if multi-stage) +``` + +## Composed Workflow Templates + +### Build then Test + +```text +1) Use mapsmessaging-config-builder in Simple Local Default mode to create deployable config. +2) Use maps-protocol-bridge-tester to verify ingress/egress and end-to-end delivery. +3) Use maps-runtime-diagnostics only if any stage fails. +``` + +### Deploy then Gate + +```text +1) Use maps-deployment-packager in Advanced Combination Matrix mode for . +2) Use maps-release-readiness-checker to produce PASS/CONDITIONAL PASS/FAIL with evidence. +3) Use maps-artifact-execution-smoke-harness to execute generated artifacts and collect runtime smoke evidence. +``` + +### Advanced Data Pipeline + +```text +1) Use maps-schema-pipeline-builder for schema linkage. +2) Use maps-transform-chain-designer for deterministic stage order. +3) Use maps-aggregator-config-engineer for windowed summary outputs. +4) Use maps-ml-stream-configurator last for selector-based multi-pass decisions. +5) Use maps-ml-model-lifecycle-playbook for stream-trained and external-model lifecycle controls. +``` + +### Selector and Geospatial Flow + +```text +1) Use maps-selector-rule-engineer for routing and subscriber selectors. +2) Use maps-geospatial-routing-builder for geohash and GPS distance-based decisions. +3) Use maps-protocol-bridge-tester for end-to-end route evidence. +``` + +### Multi-Skill Unified Deliverable + +```text +1) Build scenario slices with relevant source skills. +2) Use maps-scenario-composer to merge slices into one unified deployable. +3) Use maps-artifact-execution-smoke-harness for integrated runtime evidence. +``` + +## Output Baseline Requirements + +Every skill output should include: + +- Explicit assumptions and selected variant/profile. +- Deployable artifacts or full YAML blocks. +- Apply commands and rollback path. +- Startup diagnostics and listener/protocol verification. +- Scenario metrics + dashboard definition. +- C4 diagram source in Mermaid. + +## Validation Scripts + +- `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh` +- `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh` + +## Reference Loading + +Read only required skill files: + +- `/Users/krital/dev/starsense/mapsmessaging_server/skills//SKILL.md` + +Load reference docs only for the selected target skill and scenario mode. diff --git a/skills/maps-skill-suite-orchestrator/agents/openai.yaml b/skills/maps-skill-suite-orchestrator/agents/openai.yaml new file mode 100644 index 000000000..27b95afeb --- /dev/null +++ b/skills/maps-skill-suite-orchestrator/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Skill Suite Orchestrator" + short_description: "Index and orchestrate MAPS skills" + default_prompt: "Use $maps-skill-suite-orchestrator to select the right MAPS skill and produce a quick-start or advanced prompt for the scenario." diff --git a/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh new file mode 100755 index 000000000..9b24e16f0 --- /dev/null +++ b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-skill-suite-orchestrator-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-skill-suite-orchestrator-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-skill-suite-orchestrator-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-skill-suite-orchestrator runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_skill_suite_orchestrator_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-skill-suite-orchestrator-runtime-smoke.out 2>/tmp/maps-skill-suite-orchestrator-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-skill-suite-orchestrator-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_skill_suite_orchestrator_runtime_smoke path." +fi + +echo "maps-skill-suite-orchestrator runtime smoke PASS" diff --git a/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh new file mode 100755 index 000000000..b6574c61f --- /dev/null +++ b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-skill-suite-orchestrator" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" + +python3 "${VALIDATOR}" "${ROOT}" +rg -n "maps-scenario-composer|Quick Start Template|Advanced Template|Multi-Skill Unified Deliverable" "${ROOT}/SKILL.md" >/dev/null + +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh" +fi + +echo "maps-skill-suite-orchestrator skill smoke PASS" diff --git a/skills/maps-transform-chain-designer/SKILL.md b/skills/maps-transform-chain-designer/SKILL.md new file mode 100644 index 000000000..88adb0f7b --- /dev/null +++ b/skills/maps-transform-chain-designer/SKILL.md @@ -0,0 +1,66 @@ +--- +name: maps-transform-chain-designer +description: Design and validate deterministic MAPS transformation chains. Use when requests require ordered payload transformation (CloudEvent wrapping, JSON mutation, format conversion, enrichment), content-type transitions, schema compatibility checks, and deployable configuration updates with runtime verification. +--- + +# MAPS Transform Chain Designer + +Translate transformation requirements into ordered, deterministic MAPS configuration and verification steps. + +## Workflow + +1. Normalize transform contract. +- Extract source format, target format, required enrichment, CloudEvent wrapping needs, namespace routing, and schema constraints. +- Resolve ambiguity only when ordering or output format would differ. + +2. Design ordered chain. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/references/transform-chain-patterns.md`. +- Produce explicit stage order with input/output contentType at each step. +- Enforce deterministic, non-throwing behavior. + +3. Map chain to MAPS config. +- Apply relevant updates to manager YAML files in this repo. +- Ensure stage configuration is consistent with destination `schemaId` and `contentType` expectations. + +4. Validate chain compatibility. +- Check format handoffs between consecutive stages. +- Verify no stage expects fields absent from prior stage output. +- Include static checks and runtime smoke checks. + +5. Return using output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/references/output-contract.md`. +- Include ordered stages, deployable config, apply steps, and test commands. + +## Rules + +- Never reorder user-required stages unless impossible; if impossible, explain and provide nearest valid order. +- Keep chain minimal: no redundant transforms. +- Preserve MAPS-native transformer behavior and avoid external processing dependencies. +- Always declare expected `contentType` progression across stages. + +## Scenario Modes + +- `Simple Local Default`: + - Build one 2 to 3 stage chain with clear input/output content types and one verification flow. + - Use minimal transformations to validate baseline behavior quickly. +- `Advanced Combination Matrix`: + - Provide 3 to 6 chain variants with differing stage order constraints and format transitions. + - Include stage compatibility risk notes and recommended variant selection. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed: +- Chain patterns and checks: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/references/transform-chain-patterns.md` +- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/references/output-contract.md` diff --git a/skills/maps-transform-chain-designer/agents/openai.yaml b/skills/maps-transform-chain-designer/agents/openai.yaml new file mode 100644 index 000000000..e25ee1b76 --- /dev/null +++ b/skills/maps-transform-chain-designer/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Transform Chain Designer" + short_description: "Design deterministic MAPS transform chains" + default_prompt: "Use $maps-transform-chain-designer to convert transformation requirements into ordered deployable MAPS config and verification commands." diff --git a/skills/maps-transform-chain-designer/references/output-contract.md b/skills/maps-transform-chain-designer/references/output-contract.md new file mode 100644 index 000000000..2da5f9523 --- /dev/null +++ b/skills/maps-transform-chain-designer/references/output-contract.md @@ -0,0 +1,39 @@ +# Output Contract + +Always return in this order. + +1. `Transformation Contract` +- Source format, target format, required stages, namespace/path. + +2. `Ordered Stage Plan` +- Numbered stages with input/output contentType and purpose. + +3. `Deployable Config Entity` +- Patch blocks or full YAML/ConfigMap artifacts implementing the chain. + +4. `Apply Steps` +- Exact commands to apply config changes. + +5. `Validation` +- Static checks for stage compatibility and key settings. + +6. `Runtime Verification` +- Producer and consumer commands proving transformed output reaches destination in expected format. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never omit stage order. +- Never omit contentType transitions. +- Never claim success without destination-side transformed payload evidence. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/maps-transform-chain-designer/references/transform-chain-patterns.md b/skills/maps-transform-chain-designer/references/transform-chain-patterns.md new file mode 100644 index 000000000..6904767a7 --- /dev/null +++ b/skills/maps-transform-chain-designer/references/transform-chain-patterns.md @@ -0,0 +1,50 @@ +# Transform Chain Patterns + +## Core Principle + +Transformation chains are ordered and deterministic. Each stage must define: +- Input format / contentType +- Transformation action +- Output format / contentType +- Optional schema impact + +## Common Stage Types + +1. CloudEvent wrapper +- Wrap payload to CloudEvent 1.0.2 structure. +- Usually early in chain when downstream expects envelope semantics. + +2. JSON mutation +- Add, remove, or rename JSON fields. +- Keep idempotent where possible. + +3. Format conversion +- JSON to XML, XML to JSON, or schema-based conversion. +- Must declare target contentType explicitly. + +4. Enrichment +- Add derived fields (for example geohash). +- Requires source fields to exist before stage executes. + +## Recommended Ordering Heuristics + +- Validate/decode first. +- Envelope/wrap second. +- Mutate/enrich next. +- Final format conversion last. + +If user mandates a different order, evaluate compatibility and flag impossible handoffs. + +## Validation Commands + +```bash +rg -n "contentType|schemaId|messageDefaults|messageOverride" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "transform|Transformation|CloudEvent|JSONToXML|XMLToJSON" /Users/krital/dev/starsense/mapsmessaging_server/src/main/java +``` + +## Failure Patterns + +- contentType mismatch between stages. +- Schema validation failure after format conversion. +- Enrichment stage missing prerequisite fields. +- Destination expects transformed format but ingress defaults remain unchanged. diff --git a/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh new file mode 100755 index 000000000..ccab2ebad --- /dev/null +++ b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-transform-chain-designer-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/maps-transform-chain-designer-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/maps-transform-chain-designer-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "maps-transform-chain-designer runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="maps_transform_chain_designer_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/maps-transform-chain-designer-runtime-smoke.out 2>/tmp/maps-transform-chain-designer-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/maps-transform-chain-designer-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without maps_transform_chain_designer_runtime_smoke path." +fi + +echo "maps-transform-chain-designer runtime smoke PASS" diff --git a/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_skill_smoke.sh b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_skill_smoke.sh new file mode 100755 index 000000000..4d9420010 --- /dev/null +++ b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/transform-chain-patterns.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_maps_transform_chain_designer_runtime_smoke.sh" +fi +echo "maps-transform-chain-designer skill smoke PASS" diff --git a/skills/mapsmessaging-config-builder/SKILL.md b/skills/mapsmessaging-config-builder/SKILL.md new file mode 100644 index 000000000..335dd5463 --- /dev/null +++ b/skills/mapsmessaging-config-builder/SKILL.md @@ -0,0 +1,79 @@ +--- +name: mapsmessaging-config-builder +description: Translate protocol, encoding, topology, schema, and transformation requirements into deployable MAPS Messaging Server configuration entities. Use when a request describes protocol listeners, protocol bridging, namespace routing, schema registration/selection, transformer chains, aggregator/event-stream behavior, or link routing and needs exact MAPS YAML edits or deployable config manifests. +--- + +# MAPS Messaging Config Builder + +Build production-grade MAPS configuration output from requirements. Convert narrative protocol and topology intent into exact YAML changes for this repository layout. + +## Workflow + +1. Normalize requirements into a contract. +- Extract protocol(s), transport, bind URL/port, auth realm, namespace mapping, payload encoding, schema IDs/types, transformation order, and routing topology. +- Resolve ambiguity with one concise clarification question only when a missing field changes runtime behavior. +- Default safely when unspecified: `authenticationRealm: anon`, no payload overrides, `proxyProtocol: false`. + +2. Map contract to config surfaces. +- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md`. +- Map listeners/adapters to `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml`. +- Map namespace storage and message overrides to `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml`. +- Map federation/topology to `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml`. +- If request includes aggregator, ML, or schema behavior, target corresponding manager YAML files in this repo and keep changes minimal. + +3. Build deployable entities. +- Prefer minimal diffs against existing files. +- For deployment requests, emit full file bodies or Kubernetes `ConfigMap` manifests. +- Use deterministic names: `---`. + +4. Validate before finalizing. +- Re-open touched YAML files and match existing key casing and style. +- Run targeted checks: +```bash +rg -n "type: (mqtt|mqtt-sn|amqp|stomp|coap|ws|nats|satellite|canbus)" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "namespace: |namespaceMapping: |contentType:|schemaId:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "predefinedServers|autoDiscovery|enabled" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +``` +- For runtime checks, include startup diagnostics first, then protocol smoke checks. +- For executable runtime smoke, use: + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh` + +5. Return output using the output contract. +- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/references/output-contract.md`. +- Always include assumptions, file-by-file deployable content, apply steps, startup diagnostics, and protocol verification commands. + +## Platform Rules + +- Preserve existing architecture and DTO naming/casing (`BaseConfigDTO`, discriminator `type`, `protocolConfigs`, `messageDefaults`). +- Keep outputs compatible with Java 21 runtime and current MAPS managers. +- Prefer MAPS-native bridging/routing over introducing external brokers. +- Treat transformer chains as deterministic and ordered; never emit unordered transform behavior. +- Prefer Gson-compatible JSON handling assumptions and avoid Jackson-specific recommendations. +- If a requested feature requires unavailable plugins/providers, state the gap and output the nearest valid MAPS config plus explicit limitation notes. + +## Scenario Modes + +- `Simple Local Default`: + - Produce one minimal, locally testable configuration path (single ingress protocol, one namespace mapping, one verification pair of commands). + - Prefer existing default listener ports and anon realm unless explicitly overridden. +- `Advanced Combination Matrix`: + - Provide 3 to 6 viable variants across protocol, encoding, routing topology, and transformation/schema behavior. + - Include tradeoffs and select one recommended variant with deployable output. + +## Observability and Architecture Outputs + +- Always generate scenario-specific metrics mapped to the deployed flow (throughput, latency, error and drop counters, backlog/queue depth, and protocol- or feature-specific KPIs). +- Always provide two dashboard options: + - Grafana-ready panel and query specification (or JSON model when requested). + - MAPS-hosted dashboard view specification (REST/WS backed) for local-first operation without external dependencies. +- Support both quick and deep modes for observability: + - Simple local mode: one minimal dashboard and 3 to 6 core metrics. + - Advanced mode: multi-pane dashboard with per-protocol/component metrics, alerts, and drill-down views. +- Always generate C4 architecture diagrams (Context and Container minimum; Component when useful) that visualize the exact deployed flow, protocol boundaries, and data movement paths. +- Include one diagram suited for local test topology and one diagram for advanced/production topology when both are discussed. + +## Reference Loading + +Load only what is needed for the task: +- Protocol/link mapping: `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md` +- Final response shape: `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/references/output-contract.md` diff --git a/skills/mapsmessaging-config-builder/agents/openai.yaml b/skills/mapsmessaging-config-builder/agents/openai.yaml new file mode 100644 index 000000000..a512492e6 --- /dev/null +++ b/skills/mapsmessaging-config-builder/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "MAPS Config Builder" + short_description: "Build deployable MAPS messaging configs" + default_prompt: "Use $mapsmessaging-config-builder to convert this protocol and routing requirement into deployable MAPS configuration changes." diff --git a/skills/mapsmessaging-config-builder/references/output-contract.md b/skills/mapsmessaging-config-builder/references/output-contract.md new file mode 100644 index 000000000..976ed0e8a --- /dev/null +++ b/skills/mapsmessaging-config-builder/references/output-contract.md @@ -0,0 +1,46 @@ +# Output Contract + +Always produce final answers in this order. + +1. `Requirement Mapping` +- Table: requirement phrase -> config fields + absolute file paths. + +2. `Assumptions` +- List all defaults used because requirements omitted details. + +3. `Deployable Config Entity` +- Provide one of: + - patch blocks for in-repo YAML files, + - full YAML file bodies, or + - Kubernetes `ConfigMap` manifests embedding YAML. +- Do not leave placeholders. + +4. `Apply Steps` +- Exact commands to apply/update files in this repo. +- Include restart steps for local runtime or containerized deployment. + +5. `Startup Diagnostics` +- Commands to confirm listeners started and no fatal startup gate occurred (bind collision, missing provider, Consul/license abort). + +6. `Protocol Verification` +- Include at least one producer and one consumer/inspection command aligned to configured protocol(s). +- For bridged topology, include cross-protocol verification commands when requested. + +`Scenario Metrics and Dashboard` +- Provide scenario-specific metrics list with collection points and expected ranges for the deployed topology. +- Provide a Grafana dashboard artifact definition and a MAPS-hosted dashboard definition suitable for local-first use. + +`C4 Architecture Diagram` +- Provide C4 diagrams for the deployed flow: + - Context and Container diagrams required. + - Component diagram required when multiple internal services/transform stages are involved. +- Include diagram source in Mermaid format so it is directly renderable. + +## Guardrails + +- Never omit absolute file paths. +- Never leave `` or unresolved placeholders. +- Never describe behavior without exact YAML implementing it. +- Never suggest external brokers/services when MAPS-native bridging can satisfy the requirement. +- Never omit scenario-specific metrics and at least one testable dashboard output. +- Never omit C4 diagram source for the deployed flow. diff --git a/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md b/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md new file mode 100644 index 000000000..e2dd00de4 --- /dev/null +++ b/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md @@ -0,0 +1,86 @@ +# Protocol and Routing Map + +## Config Surfaces + +- `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml`: listener URLs, transport (`tcp`/`udp`/`ssl`/`dtls`/`hmac`/`satellite`), protocol adapters, auth realms, protocol defaults. +- `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml`: namespace storage layout, message override defaults (`contentType`, QoS, retain, `schemaId`). +- `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml`: inter-server topology and predefined peers. +- Other manager files (`AggregatorManager.yaml`, `MLModelManager.yaml`, `SchemaManager.yaml`) when request explicitly includes those capabilities. + +## Supported Protocol Targets + +When requirements mention a protocol, map to `protocolConfigs[].type` in `NetworkManager.yaml` using the closest supported adapter in this deployment: +- MQTT v3/v5 -> `mqtt` +- MQTT-SN -> `mqtt-sn` +- AMQP -> `amqp` +- STOMP -> `stomp` (if provider present in build) +- NATS / JetStream ingress-egress paths -> `nats` where provider is available +- CoAP -> `coap` +- LoRa local integration -> LoRa-specific endpoint/protocol entries present in current config set +- Satellite (Orbcomm/Inmarsat) -> `satellite` endpoint/protocol entries where enabled +- CAN bus (J1939/N2K) -> `canbus` endpoint entries where enabled +- WebSocket encapsulation for MQTT/AMQP paths -> `ws` + +If provider is absent in runtime image, output valid config plus a limitation note and startup check command. + +## Requirement to Config Mapping + +1. Listener and protocol ingress +- Request terms: "expose MQTT on 1883", "add AMQP endpoint", "enable CoAP/DTLS", "bridge NATS". +- Primary target: `NetworkManager.endPointServerConfigList[]`. +- Required fields: + - `name` + - `authenticationRealm` + - `url` (example `tcp://0.0.0.0:1883/`) + - `endPointConfig.type` + - `protocolConfigs[].type` + +2. Encoding, schema, and payload behavior +- Request terms: "JSON output", "XML payload", "Protobuf schema", "set QoS 1", "retain". +- Primary targets: + - `NetworkManager...protocolConfigs[].messageDefaults` + - `DestinationManager...messageOverride` +- Common fields: + - `contentType` + - `qualityOfService` + - `retain` + - `schemaId` + +3. Namespace and destination routing +- Request terms: "map /edge to /core", "route /telemetry to memory/file". +- Primary target: `DestinationManager.data[]`. +- Required fields: + - `namespace` + - `namespaceMapping` + - destination `type` + - `storageConfig.type` + - `directory` for file-backed storage + +4. Inter-server topology +- Request terms: "federate with site-broker", "bridge to remote MAPS". +- Primary target: `routing.predefinedServers[]`. +- Feature flags: + - `routing.enabled` + - `routing.autoDiscovery` + +5. Ordered transformation behavior +- Request terms: "apply CloudEvent wrapper then JSON mutation", "enrich with geohash". +- Target: transformation config sections in the relevant manager file. +- Rule: preserve configured order; deterministic and non-throwing behavior only. + +## Startup and Bind Diagnostics + +Include these checks in verification steps when deploying: +```bash +docker logs 2>&1 | rg -n "Address already in use|BindException|Protocol not available|Startup aborted|Consul|license" +docker exec sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | rg "1883|5672|8080|9001"' +``` + +## Practical Search Patterns + +```bash +rg -n "endPointServerConfigList|protocolConfigs|messageDefaults|url:" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "namespace: |namespaceMapping: |messageOverride|schemaId" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "routing:|predefinedServers|autoDiscovery|enabled" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +rg -n "window|timeout|maxEventsPerTopic|contribution" /Users/krital/dev/starsense/mapsmessaging_server/AggregatorManager.yaml +``` diff --git a/skills/mapsmessaging-config-builder/references/test-scenario-01-output.md b/skills/mapsmessaging-config-builder/references/test-scenario-01-output.md new file mode 100644 index 000000000..0fd550e4a --- /dev/null +++ b/skills/mapsmessaging-config-builder/references/test-scenario-01-output.md @@ -0,0 +1,56 @@ +Requirement Mapping +- "Expose MQTT over TCP on 1883" -> `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` fields: `endPointServerConfigList[].url`, `endPointConfig.type=tcp`, `protocolConfigs[].type=mqtt` +- "Default JSON payload" -> `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` field: `protocolConfigs[].messageDefaults.contentType=application/json` +- "Map /telemetry namespace" -> `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` fields: `namespace`, `namespaceMapping` +- "Add route server edge-a" -> `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` fields: `routing.predefinedServers[]`, `routing.enabled=true` + +Assumptions +- `authenticationRealm` defaults to `anon`. +- `proxyProtocol` remains `false`. +- No QoS override requested. + +Deployable Config Entity +```diff +*** /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml ++ - ++ authenticationRealm: anon ++ name: mqtt-tcp-ingress-1883 ++ endPointConfig: ++ type: tcp ++ protocolConfigs: ++ - ++ type: mqtt ++ messageDefaults: ++ contentType: application/json ++ url: tcp://0.0.0.0:1883/ + +*** /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml ++ - ++ type: Memory ++ namespace: /telemetry/ ++ namespaceMapping: /telemetry/ ++ +*** /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml ++ enabled: true ++ predefinedServers: ++ - ++ name: edge-a ++ url: https://edge-a:8080/ +``` + +Apply Steps +```bash +# apply edits in working tree +# then verify keys exist +rg -n "type: mqtt|contentType: application/json|tcp://0.0.0.0:1883/" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "namespace: /telemetry/|namespaceMapping: /telemetry/" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "enabled: true|name: edge-a|url: https://edge-a:8080/" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +``` + +Verification +```bash +# producer +mosquitto_pub -h localhost -p 1883 -t /telemetry/test -m '{"ok":true}' +# consumer +timeout 5 mosquitto_sub -h localhost -p 1883 -t /telemetry/# -C 1 +``` diff --git a/skills/mapsmessaging-config-builder/references/test-scenario-02-output.md b/skills/mapsmessaging-config-builder/references/test-scenario-02-output.md new file mode 100644 index 000000000..c8001f0f7 --- /dev/null +++ b/skills/mapsmessaging-config-builder/references/test-scenario-02-output.md @@ -0,0 +1,44 @@ +Requirement Mapping +- "Expose AMQP over TCP on 5672" -> `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml`: `url`, `endPointConfig.type=tcp`, `protocolConfigs[].type=amqp` +- "Set XML default payload" -> `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml`: `protocolConfigs[].messageDefaults.contentType=application/xml` +- "Enable server routing to core-hub" -> `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml`: `routing.enabled=true`, `predefinedServers[]` + +Assumptions +- Realm uses `anon`. +- AMQP session defaults remain unchanged except explicit contentType. + +Deployable Config Entity +```diff +*** /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml ++ - ++ authenticationRealm: anon ++ name: amqp-tcp-ingress-5672 ++ endPointConfig: ++ type: tcp ++ protocolConfigs: ++ - ++ type: amqp ++ messageDefaults: ++ contentType: application/xml ++ url: tcp://0.0.0.0:5672/ + +*** /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml ++ enabled: true ++ predefinedServers: ++ - ++ name: core-hub ++ url: https://core-hub:8080/ +``` + +Apply Steps +```bash +rg -n "type: amqp|contentType: application/xml|tcp://0.0.0.0:5672/" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "enabled: true|name: core-hub|url: https://core-hub:8080/" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +``` + +Verification +```bash +# AMQP smoke checks are environment-specific; verify listener then route entry +rg -n "amqp-tcp-ingress-5672|type: amqp" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "core-hub" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +``` diff --git a/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh new file mode 100755 index 000000000..fb0248820 --- /dev/null +++ b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +PLATFORM="${PLATFORM:-}" +MQTT_PORT="${MQTT_PORT:-1883}" +HTTP_PORT="${HTTP_PORT:-8080}" +CONTAINER_NAME="${CONTAINER_NAME:-mapsmessaging-config-builder-runtime-smoke}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/skill/mapsmessaging-config-builder-runtime-smoke/runtime}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +TOPIC="${TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}}" +MQTT_USER="${MQTT_USER:-}" +MQTT_PASSWORD="${MQTT_PASSWORD:-}" +REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" +STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" + +TMP_DIR="$(mktemp -d /tmp/mapsmessaging-config-builder-runtime-smoke.XXXXXX)" +trap 'rm -rf "${TMP_DIR}"' EXIT + +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${cfg}" ]]; then + cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" + fi +done + +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" && "${STRICT_MQTT_BASELINE}" == "1" ]]; then + cat > "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML +fi + +if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +fi + +RUNTIME_LISTENERS="8080" +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + RUNTIME_LISTENERS="8080,1883" +fi + +CMD=(bash "${HARNESS}" + --image "${IMAGE}" + --container-name "${CONTAINER_NAME}" + --artifact-dir "${TMP_DIR}" + --mqtt-port "${MQTT_PORT}" + --http-port "${HTTP_PORT}" + --topic "${TOPIC}" + --required-listeners "${RUNTIME_LISTENERS}" + --force-clean +) +if [[ "${REQUIRE_MQTT_RUNTIME}" != "1" ]]; then CMD+=(--skip-mqtt); fi +if [[ -n "${PLATFORM}" ]]; then CMD+=(--platform "${PLATFORM}"); fi +if [[ -n "${MQTT_USER}" ]]; then CMD+=(--mqtt-username "${MQTT_USER}"); fi +if [[ -n "${MQTT_PASSWORD}" ]]; then CMD+=(--mqtt-password "${MQTT_PASSWORD}"); fi + +"${CMD[@]}" + +if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then + echo "strict MQTT runtime smoke validated by harness on topic ${TOPIC}" + echo "mapsmessaging-config-builder runtime smoke PASS" + exit 0 +fi + +if timeout 3 bash -lc "echo > /dev/tcp/127.0.0.1/${MQTT_PORT}" 2>/dev/null; then + AUTH=() + if [[ -n "${MQTT_USER}" ]]; then AUTH+=( -u "${MQTT_USER}" ); fi + if [[ -n "${MQTT_PASSWORD}" ]]; then AUTH+=( -P "${MQTT_PASSWORD}" ); fi + CORR="mapsmessaging_config_builder_runtime_smoke-$(date +%s)" + timeout 8 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -C 1 "${AUTH[@]}" >/tmp/mapsmessaging-config-builder-runtime-smoke.out 2>/tmp/mapsmessaging-config-builder-runtime-smoke.err & + SPID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${TOPIC}" -m "${CORR}" "${AUTH[@]}" + wait "${SPID}" + rg -n "${CORR}" /tmp/mapsmessaging-config-builder-runtime-smoke.out >/dev/null +else + echo "MQTT listener not available on ${MQTT_PORT}; startup/listener runtime check passed without mapsmessaging_config_builder_runtime_smoke path." +fi + +echo "mapsmessaging-config-builder runtime smoke PASS" diff --git a/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_skill_smoke.sh b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_skill_smoke.sh new file mode 100755 index 000000000..3e5905067 --- /dev/null +++ b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_skill_smoke.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder" +VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +python3 "${VALIDATOR}" "${ROOT}" +test -f "${ROOT}/references/output-contract.md" +rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null +test -f "${ROOT}/references/protocol-and-routing-map.md" +if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then + bash "${ROOT}/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh" +fi +echo "mapsmessaging-config-builder skill smoke PASS" diff --git a/skills/smoke/README.md b/skills/smoke/README.md new file mode 100644 index 000000000..b1db3fc94 --- /dev/null +++ b/skills/smoke/README.md @@ -0,0 +1,30 @@ +# Skill Smoke Tests + +Run smoke coverage for: + +- all skill definitions (`SKILL.md` + `agents/openai.yaml` + `quick_validate`) +- all generated artifact fixtures (validated against each skill's `references/output-contract.md`) + +## Usage + +```bash +./skills/smoke/run.sh +``` + +Generate or refresh fixtures first: + +```bash +./skills/smoke/run.sh --bootstrap-fixtures +``` + +Run any skill combination (contract smoke): + +```bash +./skills/smoke/run_skill_combination.sh --skills maps-selector-rule-engineer,maps-geospatial-routing-builder +``` + +Run any skill combination with deep per-skill smoke (when scripts exist): + +```bash +./skills/smoke/run_skill_combination.sh --skills maps-selector-rule-engineer,maps-geospatial-routing-builder,maps-ml-model-lifecycle-playbook --deep --bootstrap-fixtures +``` diff --git a/skills/smoke/ensure_mqtt_listener.py b/skills/smoke/ensure_mqtt_listener.py new file mode 100755 index 000000000..e97bc0e4d --- /dev/null +++ b/skills/smoke/ensure_mqtt_listener.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import sys +from pathlib import Path + +import yaml + + +def has_mqtt_old(entries: list[dict]) -> bool: + for item in entries: + if not isinstance(item, dict): + continue + url = str(item.get("url", "")) + if ":1883" not in url: + continue + protocol = str(item.get("protocol", "")).lower() + if protocol in {"mqtt", "all"}: + return True + for pc in item.get("protocolConfigs", []) or []: + if isinstance(pc, dict) and str(pc.get("type", "")).lower() == "mqtt": + return True + return False + + +def has_mqtt_new(entries: list[dict]) -> bool: + for item in entries: + if not isinstance(item, dict): + continue + url = str(item.get("url", "")) + if ":1883" not in url: + continue + for pc in item.get("protocolConfigs", []) or []: + if isinstance(pc, dict) and str(pc.get("type", "")).lower() == "mqtt": + return True + return False + + +def ensure_old_data_listener(nm: dict) -> bool: + data = nm.get("data") + changed = False + if not isinstance(data, list): + data = [] + nm["data"] = data + changed = True + if not has_mqtt_old(data): + data.append( + { + "name": "runtime-smoke-mqtt-data-1883", + "url": "tcp://0.0.0.0:1883/", + "protocol": "mqtt", + "selectorThreadCount": 5, + } + ) + changed = True + return changed + + +def ensure_new_endpoint_listener(nm: dict) -> bool: + eps = nm.get("endPointServerConfigList") + if not isinstance(eps, list): + return False + if has_mqtt_new(eps): + return False + eps.append( + { + "authenticationRealm": "anon", + "backlog": 100, + "endPointConfig": {"type": "tcp", "proxyProtocolMode": "DISABLED"}, + "name": "runtime-smoke-mqtt-1883", + "protocolConfigs": [{"type": "mqtt", "proxyProtocol": False}], + "selectorTaskWait": 10, + "url": "tcp://0.0.0.0:1883/", + } + ) + return True + + +def main() -> int: + if len(sys.argv) != 2: + print("usage: ensure_mqtt_listener.py ", file=sys.stderr) + return 2 + + path = Path(sys.argv[1]) + doc = yaml.safe_load(path.read_text(encoding="utf-8")) or {} + nm = doc.setdefault("NetworkManager", {}) + + changed = False + if ensure_old_data_listener(nm): + changed = True + if ensure_new_endpoint_listener(nm): + changed = True + + if changed: + path.write_text(yaml.safe_dump(doc, sort_keys=False, allow_unicode=False), encoding="utf-8") + + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/skills/smoke/fixtures/maps-aggregator-config-engineer/artifact.md b/skills/smoke/fixtures/maps-aggregator-config-engineer/artifact.md new file mode 100644 index 000000000..199e51875 --- /dev/null +++ b/skills/smoke/fixtures/maps-aggregator-config-engineer/artifact.md @@ -0,0 +1,51 @@ +# maps-aggregator-config-engineer Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Aggregation Requirement Mapping +Smoke placeholder for `Aggregation Requirement Mapping`. + +## Window Model +Smoke placeholder for `Window Model`. + +## Assumptions +Smoke placeholder for `Assumptions`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Verification Plan +Smoke placeholder for `Verification Plan`. + +```bash +echo smoke-check +``` + +## Risk Notes +Smoke placeholder for `Risk Notes`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-artifact-execution-smoke-harness/artifact.md b/skills/smoke/fixtures/maps-artifact-execution-smoke-harness/artifact.md new file mode 100644 index 000000000..51c7825e7 --- /dev/null +++ b/skills/smoke/fixtures/maps-artifact-execution-smoke-harness/artifact.md @@ -0,0 +1,49 @@ +# maps-artifact-execution-smoke-harness Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Smoke Scope +Smoke placeholder for `Smoke Scope`. + +## Execution Plan +Smoke placeholder for `Execution Plan`. + +## Applied Artifact Manifest +Smoke placeholder for `Applied Artifact Manifest`. + +```bash +echo smoke-check +``` + +## Startup Evidence +Smoke placeholder for `Startup Evidence`. + +## Listener Evidence +Smoke placeholder for `Listener Evidence`. + +## Traffic Evidence +Smoke placeholder for `Traffic Evidence`. + +## Failure Classification +Smoke placeholder for `Failure Classification`. + +## Remediation and Re-run +Smoke placeholder for `Remediation and Re-run`. + +## Teardown Evidence +Smoke placeholder for `Teardown Evidence`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-canbus-ingestion-builder/artifact.md b/skills/smoke/fixtures/maps-canbus-ingestion-builder/artifact.md new file mode 100644 index 000000000..014d92a33 --- /dev/null +++ b/skills/smoke/fixtures/maps-canbus-ingestion-builder/artifact.md @@ -0,0 +1,51 @@ +# maps-canbus-ingestion-builder Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## CAN Requirement Mapping +Smoke placeholder for `CAN Requirement Mapping`. + +## Interface Profile +Smoke placeholder for `Interface Profile`. + +## Assumptions +Smoke placeholder for `Assumptions`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Verification +Smoke placeholder for `Verification`. + +```bash +echo smoke-check +``` + +## Limits and Risks +Smoke placeholder for `Limits and Risks`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-deployment-packager/artifact.md b/skills/smoke/fixtures/maps-deployment-packager/artifact.md new file mode 100644 index 000000000..efa41742b --- /dev/null +++ b/skills/smoke/fixtures/maps-deployment-packager/artifact.md @@ -0,0 +1,84 @@ +# maps-deployment-packager Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Deployment Target Matrix +Smoke placeholder for `Deployment Target Matrix`. + +## Authentication Profile +Smoke placeholder for `Authentication Profile`. + +## Storage and Volume Profile +Smoke placeholder for `Storage and Volume Profile`. + +## Configuration Source Mode +Smoke placeholder for `Configuration Source Mode`. + +## State and Config Backend Choice +Smoke placeholder for `State and Config Backend Choice`. + +## Consul Topology Option +Smoke placeholder for `Consul Topology Option`. + +## Object Storage Option +Smoke placeholder for `Object Storage Option`. + +## Artifact Manifest +Smoke placeholder for `Artifact Manifest`. + +```bash +echo smoke-check +``` + +## Deployable Entity +Smoke placeholder for `Deployable Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Startup Diagnostics +Smoke placeholder for `Startup Diagnostics`. + +```bash +echo smoke-check +``` + +## Listener Verification +Smoke placeholder for `Listener Verification`. + +```bash +echo smoke-check +``` + +## Buffer-and-Forward Verification +Smoke placeholder for `Buffer-and-Forward Verification`. + +```bash +echo smoke-check +``` + +## Rollback +Smoke placeholder for `Rollback`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-geospatial-routing-builder/artifact.md b/skills/smoke/fixtures/maps-geospatial-routing-builder/artifact.md new file mode 100644 index 000000000..cf3a69f5c --- /dev/null +++ b/skills/smoke/fixtures/maps-geospatial-routing-builder/artifact.md @@ -0,0 +1,51 @@ +# maps-geospatial-routing-builder Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Geospatial Requirement Mapping +Smoke placeholder for `Geospatial Requirement Mapping`. + +## Geo Model +Smoke placeholder for `Geo Model`. + +## Assumptions +Smoke placeholder for `Assumptions`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Verification +Smoke placeholder for `Verification`. + +```bash +echo smoke-check +``` + +## Risk Notes +Smoke placeholder for `Risk Notes`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-ml-model-lifecycle-playbook/artifact.md b/skills/smoke/fixtures/maps-ml-model-lifecycle-playbook/artifact.md new file mode 100644 index 000000000..5b7de3e9b --- /dev/null +++ b/skills/smoke/fixtures/maps-ml-model-lifecycle-playbook/artifact.md @@ -0,0 +1,51 @@ +# maps-ml-model-lifecycle-playbook Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Lifecycle Requirement Mapping +Smoke placeholder for `Lifecycle Requirement Mapping`. + +## Lifecycle Shape +Smoke placeholder for `Lifecycle Shape`. + +## Model and Store Assumptions +Smoke placeholder for `Model and Store Assumptions`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Verification +Smoke placeholder for `Verification`. + +```bash +echo smoke-check +``` + +## Risk and Operational Notes +Smoke placeholder for `Risk and Operational Notes`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-ml-stream-configurator/artifact.md b/skills/smoke/fixtures/maps-ml-stream-configurator/artifact.md new file mode 100644 index 000000000..8194e1226 --- /dev/null +++ b/skills/smoke/fixtures/maps-ml-stream-configurator/artifact.md @@ -0,0 +1,51 @@ +# maps-ml-stream-configurator Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## ML Stream Requirement Mapping +Smoke placeholder for `ML Stream Requirement Mapping`. + +## Pipeline Shape +Smoke placeholder for `Pipeline Shape`. + +## Model and Store Assumptions +Smoke placeholder for `Model and Store Assumptions`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Verification +Smoke placeholder for `Verification`. + +```bash +echo smoke-check +``` + +## Risk and Complexity Notes +Smoke placeholder for `Risk and Complexity Notes`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-protocol-bridge-tester/artifact.md b/skills/smoke/fixtures/maps-protocol-bridge-tester/artifact.md new file mode 100644 index 000000000..e56bc4163 --- /dev/null +++ b/skills/smoke/fixtures/maps-protocol-bridge-tester/artifact.md @@ -0,0 +1,44 @@ +# maps-protocol-bridge-tester Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Bridge Matrix +Smoke placeholder for `Bridge Matrix`. + +## Preflight +Smoke placeholder for `Preflight`. + +```bash +echo smoke-check +``` + +## Test Commands +Smoke placeholder for `Test Commands`. + +```bash +echo smoke-check +``` + +## Results +Smoke placeholder for `Results`. + +## Failure Classification +Smoke placeholder for `Failure Classification`. + +## Remediation and Re-test +Smoke placeholder for `Remediation and Re-test`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-release-readiness-checker/artifact.md b/skills/smoke/fixtures/maps-release-readiness-checker/artifact.md new file mode 100644 index 000000000..d52c12ded --- /dev/null +++ b/skills/smoke/fixtures/maps-release-readiness-checker/artifact.md @@ -0,0 +1,43 @@ +# maps-release-readiness-checker Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Release Scope +Smoke placeholder for `Release Scope`. + +## Gate Results +Smoke placeholder for `Gate Results`. + +```bash +echo smoke-check +``` + +## Blocking Findings +Smoke placeholder for `Blocking Findings`. + +## Non-Blocking Findings +Smoke placeholder for `Non-Blocking Findings`. + +## Readiness Decision +Smoke placeholder for `Readiness Decision`. + +## Rerun Criteria +Smoke placeholder for `Rerun Criteria`. + +## Rollback Confidence +Smoke placeholder for `Rollback Confidence`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-runtime-diagnostics/artifact.md b/skills/smoke/fixtures/maps-runtime-diagnostics/artifact.md new file mode 100644 index 000000000..54a877ac1 --- /dev/null +++ b/skills/smoke/fixtures/maps-runtime-diagnostics/artifact.md @@ -0,0 +1,40 @@ +# maps-runtime-diagnostics Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Observed Failure +Smoke placeholder for `Observed Failure`. + +## Evidence +Smoke placeholder for `Evidence`. + +## Root Cause +Smoke placeholder for `Root Cause`. + +## Remediation +Smoke placeholder for `Remediation`. + +## Post-Fix Verification +Smoke placeholder for `Post-Fix Verification`. + +```bash +echo smoke-check +``` + +## Residual Risks +Smoke placeholder for `Residual Risks`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-satellite-gateway-config/artifact.md b/skills/smoke/fixtures/maps-satellite-gateway-config/artifact.md new file mode 100644 index 000000000..b4d175644 --- /dev/null +++ b/skills/smoke/fixtures/maps-satellite-gateway-config/artifact.md @@ -0,0 +1,58 @@ +# maps-satellite-gateway-config Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Satellite Service Pattern Matrix +Smoke placeholder for `Satellite Service Pattern Matrix`. + +## Selected Pattern +Smoke placeholder for `Selected Pattern`. + +## Provider and Protocol Assumptions +Smoke placeholder for `Provider and Protocol Assumptions`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Diagnostics +Smoke placeholder for `Diagnostics`. + +```bash +echo smoke-check +``` + +## Verification +Smoke placeholder for `Verification`. + +```bash +echo smoke-check +``` + +## Fallback Notes +Smoke placeholder for `Fallback Notes`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-scenario-composer/artifact.md b/skills/smoke/fixtures/maps-scenario-composer/artifact.md new file mode 100644 index 000000000..aa84594a8 --- /dev/null +++ b/skills/smoke/fixtures/maps-scenario-composer/artifact.md @@ -0,0 +1,51 @@ +# maps-scenario-composer Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Composition Matrix +Smoke placeholder for `Composition Matrix`. + +## Unified Assumptions +Smoke placeholder for `Unified Assumptions`. + +## Merged Deployable Entity +Smoke placeholder for `Merged Deployable Entity`. + +```bash +echo smoke-check +``` + +## Unified Apply Sequence +Smoke placeholder for `Unified Apply Sequence`. + +```bash +echo smoke-check +``` + +## Integrated Verification +Smoke placeholder for `Integrated Verification`. + +```bash +echo smoke-check +``` + +## Failure Domain and Rollback +Smoke placeholder for `Failure Domain and Rollback`. + +## Traceability Map +Smoke placeholder for `Traceability Map`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-schema-pipeline-builder/artifact.md b/skills/smoke/fixtures/maps-schema-pipeline-builder/artifact.md new file mode 100644 index 000000000..3c284785b --- /dev/null +++ b/skills/smoke/fixtures/maps-schema-pipeline-builder/artifact.md @@ -0,0 +1,48 @@ +# maps-schema-pipeline-builder Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Schema Requirement Mapping +Smoke placeholder for `Schema Requirement Mapping`. + +## Assumptions +Smoke placeholder for `Assumptions`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Validation +Smoke placeholder for `Validation`. + +## Runtime Verification +Smoke placeholder for `Runtime Verification`. + +```bash +echo smoke-check +``` + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-selector-rule-engineer/artifact.md b/skills/smoke/fixtures/maps-selector-rule-engineer/artifact.md new file mode 100644 index 000000000..ef153e5ed --- /dev/null +++ b/skills/smoke/fixtures/maps-selector-rule-engineer/artifact.md @@ -0,0 +1,51 @@ +# maps-selector-rule-engineer Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Selector Requirement Mapping +Smoke placeholder for `Selector Requirement Mapping`. + +## Selector Evaluation Model +Smoke placeholder for `Selector Evaluation Model`. + +## Assumptions +Smoke placeholder for `Assumptions`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Verification +Smoke placeholder for `Verification`. + +```bash +echo smoke-check +``` + +## Performance and Risk Notes +Smoke placeholder for `Performance and Risk Notes`. + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/maps-skill-suite-orchestrator/artifact.md b/skills/smoke/fixtures/maps-skill-suite-orchestrator/artifact.md new file mode 100644 index 000000000..bf44bc480 --- /dev/null +++ b/skills/smoke/fixtures/maps-skill-suite-orchestrator/artifact.md @@ -0,0 +1,32 @@ +# maps-skill-suite-orchestrator Artifact Fixture + +## Quick Start Template +Use in Simple Local Default mode. + +## Advanced Template +Use in Advanced Combination Matrix mode. + +## Indexed Skills +- mapsmessaging-config-builder +- maps-runtime-diagnostics +- maps-protocol-bridge-tester +- maps-satellite-gateway-config +- maps-schema-pipeline-builder +- maps-transform-chain-designer +- maps-aggregator-config-engineer +- maps-canbus-ingestion-builder +- maps-deployment-packager +- maps-release-readiness-checker +- maps-ml-stream-configurator + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-skill-suite-orchestrator/SKILL.md` + +```bash +echo smoke-check +``` + +```mermaid +graph LR + A["Request"] --> B["Orchestrator"] --> C["Target Skill"] +``` diff --git a/skills/smoke/fixtures/maps-transform-chain-designer/artifact.md b/skills/smoke/fixtures/maps-transform-chain-designer/artifact.md new file mode 100644 index 000000000..41ea69540 --- /dev/null +++ b/skills/smoke/fixtures/maps-transform-chain-designer/artifact.md @@ -0,0 +1,48 @@ +# maps-transform-chain-designer Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Transformation Contract +Smoke placeholder for `Transformation Contract`. + +## Ordered Stage Plan +Smoke placeholder for `Ordered Stage Plan`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Validation +Smoke placeholder for `Validation`. + +## Runtime Verification +Smoke placeholder for `Runtime Verification`. + +```bash +echo smoke-check +``` + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/fixtures/mapsmessaging-config-builder/artifact.md b/skills/smoke/fixtures/mapsmessaging-config-builder/artifact.md new file mode 100644 index 000000000..d39570664 --- /dev/null +++ b/skills/smoke/fixtures/mapsmessaging-config-builder/artifact.md @@ -0,0 +1,52 @@ +# mapsmessaging-config-builder Artifact Fixture + +Synthetic output used by smoke tests to verify output-contract coverage. + +## Requirement Mapping +Smoke placeholder for `Requirement Mapping`. + +## Assumptions +Smoke placeholder for `Assumptions`. + +## Deployable Config Entity +Smoke placeholder for `Deployable Config Entity`. + +```bash +echo smoke-check +``` + +## Apply Steps +Smoke placeholder for `Apply Steps`. + +```bash +echo smoke-check +``` + +## Startup Diagnostics +Smoke placeholder for `Startup Diagnostics`. + +```bash +echo smoke-check +``` + +## Protocol Verification +Smoke placeholder for `Protocol Verification`. + +```bash +echo smoke-check +``` + +## Scenario Metrics and Dashboard +Smoke placeholder for `Scenario Metrics and Dashboard`. + +## C4 Architecture Diagram +Smoke placeholder for `C4 Architecture Diagram`. + +## Absolute Path Example +`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + +## Mermaid C4 Placeholder +```mermaid +graph LR + A["Source"] --> B["MAPS"] --> C["Destination"] +``` diff --git a/skills/smoke/run.sh b/skills/smoke/run.sh new file mode 100755 index 000000000..8b74ab3d9 --- /dev/null +++ b/skills/smoke/run.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +python3 "${ROOT_DIR}/skills/smoke/validate_skills_smoke.py" "$@" diff --git a/skills/smoke/run_skill_combination.sh b/skills/smoke/run_skill_combination.sh new file mode 100755 index 000000000..c955a7331 --- /dev/null +++ b/skills/smoke/run_skill_combination.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +SKILLS_ARG="" +DEEP=0 +BOOTSTRAP=0 + +usage() { + cat < [options] + +Options: + --skills Comma-separated skill names to test (required) + --deep Also run skill-specific deep smoke scripts when available + --bootstrap-fixtures Regenerate fixtures before contract smoke + -h, --help Show this help +USAGE +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --skills) + SKILLS_ARG="$2"; shift 2 ;; + --deep) + DEEP=1; shift ;; + --bootstrap-fixtures) + BOOTSTRAP=1; shift ;; + -h|--help) + usage; exit 0 ;; + *) + echo "Unknown argument: $1" >&2 + usage + exit 2 ;; + esac +done + +if [[ -z "${SKILLS_ARG}" ]]; then + echo "--skills is required" >&2 + usage + exit 2 +fi + +VALIDATE_CMD=(python3 "${ROOT_DIR}/skills/smoke/validate_skills_smoke.py" --skills "${SKILLS_ARG}") +if [[ "${BOOTSTRAP}" -eq 1 ]]; then + VALIDATE_CMD+=(--bootstrap-fixtures) +fi +"${VALIDATE_CMD[@]}" + +if [[ "${DEEP}" -eq 1 ]]; then + IFS=',' read -r -a SKILLS <<< "${SKILLS_ARG}" + for skill in "${SKILLS[@]}"; do + s="$(echo "${skill}" | tr -d '[:space:]')" + if [[ -z "${s}" ]]; then + continue + fi + script_path="$(find "${ROOT_DIR}/skills/${s}/scripts" -maxdepth 1 -type f -name '*skill_smoke.sh' 2>/dev/null | head -n 1 || true)" + if [[ -n "${script_path}" ]]; then + bash "${script_path}" + else + echo "No deep smoke script for ${s}; contract smoke only." + fi + done +fi + +echo "Skill combination smoke PASS (${SKILLS_ARG})" diff --git a/skills/smoke/validate_skills_smoke.py b/skills/smoke/validate_skills_smoke.py new file mode 100755 index 000000000..d574d19bf --- /dev/null +++ b/skills/smoke/validate_skills_smoke.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python3 +"""Smoke tests for MAPS skill definitions and generated artifact outputs.""" + +from __future__ import annotations + +import argparse +import re +import subprocess +import sys +from pathlib import Path +from typing import Iterable + + +REPO_ROOT = Path(__file__).resolve().parents[2] +SKILLS_DIR = REPO_ROOT / "skills" +FIXTURES_DIR = SKILLS_DIR / "smoke" / "fixtures" +DEFAULT_QUICK_VALIDATE = Path( + "/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +) + + +def iter_skill_dirs() -> Iterable[Path]: + for path in sorted(SKILLS_DIR.iterdir()): + if not path.is_dir(): + continue + if path.name in {"smoke"}: + continue + if (path / "SKILL.md").exists(): + yield path + + +def parse_skill_filter(raw: str | None) -> set[str]: + if not raw: + return set() + items = [item.strip() for item in raw.split(",")] + return {item for item in items if item} + + +def parse_contract_sections(contract_text: str) -> list[str]: + sections: list[str] = [] + seen: set[str] = set() + for raw_line in contract_text.splitlines(): + line = raw_line.strip() + numbered = re.match(r"^\d+\.\s+`([^`]+)`", line) + bare = re.match(r"^`([^`]+)`$", line) + value = None + if numbered: + value = numbered.group(1).strip() + elif bare: + value = bare.group(1).strip() + if value and value not in seen: + seen.add(value) + sections.append(value) + return sections + + +def build_fixture(skill_name: str, sections: list[str]) -> str: + lines: list[str] = [ + f"# {skill_name} Artifact Fixture", + "", + "Synthetic output used by smoke tests to verify output-contract coverage.", + "", + ] + for section in sections: + lines.extend( + [ + f"## {section}", + f"Smoke placeholder for `{section}`.", + "", + ] + ) + lowered = section.lower() + if any( + token in lowered + for token in ( + "apply", + "diagnostic", + "verification", + "test commands", + "preflight", + "gate results", + "manifest", + "deployable", + ) + ): + lines.extend( + [ + "```bash", + "echo smoke-check", + "```", + "", + ] + ) + + lines.extend( + [ + "## Absolute Path Example", + f"`{REPO_ROOT / 'NetworkManager.yaml'}`", + "", + "## Mermaid C4 Placeholder", + "```mermaid", + "graph LR", + ' A["Source"] --> B["MAPS"] --> C["Destination"]', + "```", + "", + ] + ) + return "\n".join(lines) + + +def check_contains(text: str, expected: str, errors: list[str], label: str) -> None: + if expected not in text: + errors.append(f"{label}: missing `{expected}`") + + +def validate_orchestrator_fixture(skill_dir: Path, errors: list[str]) -> None: + fixture = FIXTURES_DIR / skill_dir.name / "artifact.md" + if not fixture.exists(): + errors.append(f"{skill_dir.name}: missing fixture `{fixture}`") + return + text = fixture.read_text(encoding="utf-8") + for expected in ( + "## Quick Start Template", + "## Advanced Template", + "mapsmessaging-config-builder", + "maps-ml-stream-configurator", + ): + check_contains(text, expected, errors, skill_dir.name) + + +def validate_artifact_fixture(skill_dir: Path, errors: list[str]) -> None: + contract = skill_dir / "references" / "output-contract.md" + if not contract.exists(): + if skill_dir.name == "maps-skill-suite-orchestrator": + validate_orchestrator_fixture(skill_dir, errors) + return + + sections = parse_contract_sections(contract.read_text(encoding="utf-8")) + if not sections: + errors.append(f"{skill_dir.name}: no sections parsed from `{contract}`") + return + + fixture = FIXTURES_DIR / skill_dir.name / "artifact.md" + if not fixture.exists(): + errors.append(f"{skill_dir.name}: missing fixture `{fixture}`") + return + + fixture_text = fixture.read_text(encoding="utf-8") + for section in sections: + check_contains(fixture_text, f"## {section}", errors, skill_dir.name) + + if "```bash" not in fixture_text: + errors.append(f"{skill_dir.name}: fixture missing bash command block") + if "```mermaid" not in fixture_text: + errors.append(f"{skill_dir.name}: fixture missing mermaid block") + if str(REPO_ROOT) not in fixture_text: + errors.append(f"{skill_dir.name}: fixture missing absolute repo path") + + +def ensure_skill_definition(skill_dir: Path, quick_validate: Path, errors: list[str]) -> None: + for required in ("SKILL.md", "agents/openai.yaml"): + if not (skill_dir / required).exists(): + errors.append(f"{skill_dir.name}: missing required file `{required}`") + + cmd = [sys.executable, str(quick_validate), str(skill_dir)] + result = subprocess.run(cmd, capture_output=True, text=True, check=False) + if result.returncode != 0: + output = (result.stdout + "\n" + result.stderr).strip() + errors.append(f"{skill_dir.name}: quick_validate failed: {output}") + + +def bootstrap_fixtures(skill_dirs: list[Path]) -> None: + for skill_dir in skill_dirs: + target = FIXTURES_DIR / skill_dir.name / "artifact.md" + target.parent.mkdir(parents=True, exist_ok=True) + + contract = skill_dir / "references" / "output-contract.md" + if contract.exists(): + sections = parse_contract_sections(contract.read_text(encoding="utf-8")) + target.write_text(build_fixture(skill_dir.name, sections), encoding="utf-8") + continue + + if skill_dir.name == "maps-skill-suite-orchestrator": + target.write_text( + "\n".join( + [ + "# maps-skill-suite-orchestrator Artifact Fixture", + "", + "## Quick Start Template", + "Use in Simple Local Default mode.", + "", + "## Advanced Template", + "Use in Advanced Combination Matrix mode.", + "", + "## Indexed Skills", + "- mapsmessaging-config-builder", + "- maps-runtime-diagnostics", + "- maps-protocol-bridge-tester", + "- maps-satellite-gateway-config", + "- maps-schema-pipeline-builder", + "- maps-transform-chain-designer", + "- maps-aggregator-config-engineer", + "- maps-canbus-ingestion-builder", + "- maps-deployment-packager", + "- maps-release-readiness-checker", + "- maps-ml-stream-configurator", + "", + "## Absolute Path Example", + f"`{REPO_ROOT / 'skills' / 'maps-skill-suite-orchestrator' / 'SKILL.md'}`", + "", + "```bash", + "echo smoke-check", + "```", + "", + "```mermaid", + "graph LR", + ' A["Request"] --> B["Orchestrator"] --> C["Target Skill"]', + "```", + "", + ] + ), + encoding="utf-8", + ) + + +def main() -> int: + parser = argparse.ArgumentParser(description="Smoke test MAPS skills and artifacts") + parser.add_argument( + "--quick-validate", + type=Path, + default=DEFAULT_QUICK_VALIDATE, + help="Path to skill-creator quick_validate.py", + ) + parser.add_argument( + "--bootstrap-fixtures", + action="store_true", + help="Generate or refresh fixture outputs before validation", + ) + parser.add_argument( + "--skills", + default="", + help="Comma-separated skill names to validate (default: all skills)", + ) + args = parser.parse_args() + + requested = parse_skill_filter(args.skills) + skills = list(iter_skill_dirs()) + if requested: + skills = [s for s in skills if s.name in requested] + missing = sorted(requested - {s.name for s in skills}) + if missing: + print( + "Requested skills not found: " + ", ".join(missing), + file=sys.stderr, + ) + return 1 + if not skills: + print("No skill directories found.", file=sys.stderr) + return 1 + + if args.bootstrap_fixtures: + bootstrap_fixtures(skills) + + errors: list[str] = [] + for skill_dir in skills: + ensure_skill_definition(skill_dir, args.quick_validate, errors) + validate_artifact_fixture(skill_dir, errors) + + if errors: + print("Skill smoke test failed:") + for err in errors: + print(f"- {err}") + return 1 + + print(f"Skill smoke test passed for {len(skills)} skills.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 8e11ea4e56b5c4ceb62898f1b626f8efd8ec2031 Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 14:45:22 +0200 Subject: [PATCH 02/12] feat(skills): auto-detect platform and image defaults for runtime smokes --- .../maps-aggregator-config-engineer/SKILL.md | 1 + ...ggregator_config_engineer_runtime_smoke.sh | 51 ++- .../run_maps_aggregator_scenario_e2e.sh | 303 ++++++++++++++++++ .../scripts/run_artifact_smoke.sh | 56 +++- ...t_execution_smoke_harness_runtime_smoke.sh | 3 +- ..._canbus_ingestion_builder_runtime_smoke.sh | 3 +- ..._maps_deployment_packager_runtime_smoke.sh | 3 +- ...eospatial_routing_builder_runtime_smoke.sh | 3 +- .../scripts/run_ml_lifecycle_runtime_smoke.sh | 3 +- ...ps_ml_stream_configurator_runtime_smoke.sh | 3 +- ...ps_protocol_bridge_tester_runtime_smoke.sh | 3 +- ...release_readiness_checker_runtime_smoke.sh | 3 +- ..._maps_runtime_diagnostics_runtime_smoke.sh | 3 +- ..._satellite_gateway_config_runtime_smoke.sh | 3 +- ...un_maps_scenario_composer_runtime_smoke.sh | 3 +- ...s_schema_pipeline_builder_runtime_smoke.sh | 3 +- ...ps_selector_rule_engineer_runtime_smoke.sh | 3 +- ..._skill_suite_orchestrator_runtime_smoke.sh | 3 +- ..._transform_chain_designer_runtime_smoke.sh | 3 +- ...smessaging_config_builder_runtime_smoke.sh | 3 +- 20 files changed, 422 insertions(+), 37 deletions(-) create mode 100755 skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh diff --git a/skills/maps-aggregator-config-engineer/SKILL.md b/skills/maps-aggregator-config-engineer/SKILL.md index cbe4b5372..c866d3a8c 100644 --- a/skills/maps-aggregator-config-engineer/SKILL.md +++ b/skills/maps-aggregator-config-engineer/SKILL.md @@ -30,6 +30,7 @@ Convert aggregation requirements into deployable `AggregatorManager.yaml` entiti - Prefer bundled scripts for repeatable validation: - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh` - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh` + - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh` - Run checks: ```bash rg -n "aggregatorConfigList|windowDurationMs|timeoutMs|maxEventsPerTopic|contributionMode|outputTopic" /Users/krital/dev/starsense/mapsmessaging_server/AggregatorManager.yaml diff --git a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh index 5926f6edb..d3e37b01d 100755 --- a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh +++ b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh @@ -3,8 +3,11 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" +IMAGE_CHANNEL="${IMAGE_CHANNEL:-auto}" +IMAGE_VERSION="${IMAGE_VERSION:-4.3.1-snapshot}" +ARCH="${ARCH:-auto}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" CONTAINER_NAME="${CONTAINER_NAME:-maps-aggregator-config-engineer-runtime-smoke}" @@ -16,9 +19,51 @@ MQTT_PASSWORD="${MQTT_PASSWORD:-}" REQUIRE_MQTT_RUNTIME="${REQUIRE_MQTT_RUNTIME:-0}" STRICT_MQTT_BASELINE="${STRICT_MQTT_BASELINE:-1}" +detect_arch() { + local machine + machine="$(uname -m || true)" + case "${machine}" in + arm64|aarch64) echo "arm64" ;; + x86_64|amd64) echo "amd64" ;; + *) echo "amd64" ;; + esac +} + +resolve_image() { + local selected_arch="$1" + local selected_channel="$2" + if [[ "${selected_channel}" == "snapshot" ]]; then + if [[ "${selected_arch}" == "arm64" ]]; then + echo "mapsmessaging/server_daemon_arm_${IMAGE_VERSION}:latest" + else + echo "mapsmessaging/server_daemon_${IMAGE_VERSION}:latest" + fi + return + fi + echo "mapsmessaging/server_daemon:latest" +} + TMP_DIR="$(mktemp -d /tmp/maps-aggregator-config-engineer-runtime-smoke.XXXXXX)" trap 'rm -rf "${TMP_DIR}"' EXIT +if [[ "${ARCH}" == "auto" ]]; then + ARCH="$(detect_arch)" +fi +if [[ -z "${IMAGE}" ]]; then + EFFECTIVE_CHANNEL="${IMAGE_CHANNEL}" + if [[ "${EFFECTIVE_CHANNEL}" == "auto" ]]; then + if [[ "${ARCH}" == "arm64" ]]; then + EFFECTIVE_CHANNEL="snapshot" + else + EFFECTIVE_CHANNEL="release" + fi + fi + IMAGE="$(resolve_image "${ARCH}" "${EFFECTIVE_CHANNEL}")" +fi +if [[ -z "${PLATFORM}" ]]; then + PLATFORM="linux/${ARCH}" +fi + for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MLModelManager.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do if [[ -f "${ROOT}/${cfg}" ]]; then cp "${ROOT}/${cfg}" "${TMP_DIR}/${cfg}" @@ -46,7 +91,9 @@ YAML fi if [[ -f "${TMP_DIR}/NetworkManager.yaml" ]]; then - python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" + if python3 -c 'import yaml' >/dev/null 2>&1; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" + fi fi RUNTIME_LISTENERS="8080" diff --git a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh new file mode 100755 index 000000000..3c1c2fc89 --- /dev/null +++ b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh @@ -0,0 +1,303 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +IMAGE="${IMAGE:-}" +PLATFORM="${PLATFORM:-}" +IMAGE_CHANNEL="${IMAGE_CHANNEL:-auto}" +IMAGE_VERSION="${IMAGE_VERSION:-4.3.1-snapshot}" +ARCH="${ARCH:-auto}" +CONTAINER_NAME="${CONTAINER_NAME:-maps-agg-scenario-e2e}" +MQTT_PORT="${MQTT_PORT:-49883}" +HTTP_PORT="${HTTP_PORT:-56080}" +INPUT_A="${INPUT_A:-/veh/a}" +INPUT_B="${INPUT_B:-/veh/b}" +OUTPUT_TOPIC="${OUTPUT_TOPIC:-/veh/agg}" +TOPIC_NAMESPACE="${TOPIC_NAMESPACE:-/local/maps-aggregator-scenario-e2e}" +TEST_RUN_ID="${TEST_RUN_ID:-$(date +%s)-$$}" +SMOKE_TOPIC="${SMOKE_TOPIC:-${TOPIC_NAMESPACE}/${TEST_RUN_ID}/smoke}" +WAIT_SECS="${WAIT_SECS:-18}" + +detect_arch() { + local machine + machine="$(uname -m || true)" + case "${machine}" in + arm64|aarch64) echo "arm64" ;; + x86_64|amd64) echo "amd64" ;; + *) echo "amd64" ;; + esac +} + +resolve_image() { + local selected_arch="$1" + local selected_channel="$2" + if [[ "${selected_channel}" == "snapshot" ]]; then + if [[ "${selected_arch}" == "arm64" ]]; then + echo "mapsmessaging/server_daemon_arm_${IMAGE_VERSION}:latest" + else + echo "mapsmessaging/server_daemon_${IMAGE_VERSION}:latest" + fi + return + fi + echo "mapsmessaging/server_daemon:latest" +} + +require_cmd() { + if ! command -v "$1" >/dev/null 2>&1; then + echo "Missing required command: $1" >&2 + exit 1 + fi +} + +search_cmd() { + if command -v rg >/dev/null 2>&1; then + rg -n "$1" "$2" + else + grep -nE "$1" "$2" + fi +} + +port_in_use() { + local p="$1" + if command -v lsof >/dev/null 2>&1; then + lsof -nP -iTCP:"${p}" -sTCP:LISTEN >/dev/null 2>&1 + return $? + fi + if command -v ss >/dev/null 2>&1; then + ss -lnt | awk '{print $4}' | grep -E "[:.]${p}$" >/dev/null 2>&1 + return $? + fi + if command -v netstat >/dev/null 2>&1; then + netstat -lnt 2>/dev/null | awk '{print $4}' | grep -E "[:.]${p}$" >/dev/null 2>&1 + return $? + fi + return 1 +} + +require_cmd docker +require_cmd mosquitto_pub +require_cmd mosquitto_sub +require_cmd python3 + +if [[ "${ARCH}" == "auto" ]]; then + ARCH="$(detect_arch)" +fi + +if [[ -z "${IMAGE}" ]]; then + EFFECTIVE_CHANNEL="${IMAGE_CHANNEL}" + if [[ "${EFFECTIVE_CHANNEL}" == "auto" ]]; then + if [[ "${ARCH}" == "arm64" ]]; then + EFFECTIVE_CHANNEL="snapshot" + else + EFFECTIVE_CHANNEL="release" + fi + fi + IMAGE="$(resolve_image "${ARCH}" "${EFFECTIVE_CHANNEL}")" +fi + +if [[ -z "${PLATFORM}" ]]; then + PLATFORM="linux/${ARCH}" +fi + +TMP_DIR="$(mktemp -d /tmp/maps-agg-scenario-e2e.XXXXXX)" +cleanup() { + docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true + rm -rf "${TMP_DIR}" +} +trap cleanup EXIT + +for f in AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MessageDaemon.yaml NetworkConnectionManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${ROOT}/${f}" ]]; then + cp "${ROOT}/${f}" "${TMP_DIR}/${f}" + fi +done + +cat > "${TMP_DIR}/AggregatorManager.yaml" < "${TMP_DIR}/NetworkManager.yaml" <<'YAML' +--- +NetworkManager: + data: + - name: "Runtime MQTT 1883" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML + +if python3 -c 'import yaml' >/dev/null 2>&1; then + python3 "${ROOT}/skills/smoke/ensure_mqtt_listener.py" "${TMP_DIR}/NetworkManager.yaml" +else + # Fallback for local environments without PyYAML; keep canonical MQTT listener present. + if ! grep -Eq 'url:[[:space:]]*tcp://0\.0\.0\.0:1883/?' "${TMP_DIR}/NetworkManager.yaml"; then + cat >> "${TMP_DIR}/NetworkManager.yaml" <<'YAML' + - name: "Runtime MQTT 1883 (fallback)" + url: tcp://0.0.0.0:1883/ + protocol: mqtt +YAML + fi +fi + +if [[ -f "${TMP_DIR}/DiscoveryManager.yaml" ]]; then + sed -i.bak -E 's/hostnames:[[:space:]]*::/hostnames: "::"/g' "${TMP_DIR}/DiscoveryManager.yaml" + rm -f "${TMP_DIR}/DiscoveryManager.yaml.bak" +fi +if [[ -f "${TMP_DIR}/routing.yaml" ]]; then + sed -i.bak -E 's/autoDiscovery:[[:space:]]*true/autoDiscovery: false/g' "${TMP_DIR}/routing.yaml" + rm -f "${TMP_DIR}/routing.yaml.bak" +fi + +if port_in_use "${MQTT_PORT}"; then + echo "MQTT host port ${MQTT_PORT} is already in use" >&2 + exit 1 +fi +if port_in_use "${HTTP_PORT}"; then + echo "HTTP host port ${HTTP_PORT} is already in use" >&2 + exit 1 +fi + +RUN_ARGS=( + run -d + --name "${CONTAINER_NAME}" + -p "${MQTT_PORT}:1883/tcp" + -p "${HTTP_PORT}:8080/tcp" +) +if [[ -n "${PLATFORM}" ]]; then + RUN_ARGS+=( --platform "${PLATFORM}" ) +fi +for cfg in AggregatorManager.yaml AuthManager.yaml DestinationManager.yaml DeviceManager.yaml DiscoveryManager.yaml License.yaml LoRaDevice.yaml MessageDaemon.yaml NetworkConnectionManager.yaml NetworkManager.yaml RestApi.yaml SchemaManager.yaml SecurityManager.yaml TenantManagement.yaml jolokia.yaml routing.yaml; do + if [[ -f "${TMP_DIR}/${cfg}" ]]; then + RUN_ARGS+=( -v "${TMP_DIR}/${cfg}:/message_daemon-3.3.0/conf/${cfg}:ro" ) + fi +done +RUN_ARGS+=("${IMAGE}") + +docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true + +echo "Starting ${CONTAINER_NAME} (${IMAGE})" +docker "${RUN_ARGS[@]}" >/dev/null + +sleep 4 +if [[ "$(docker inspect -f '{{.State.Running}}' "${CONTAINER_NAME}")" != "true" ]]; then + echo "Container exited during startup" >&2 + docker logs "${CONTAINER_NAME}" 2>&1 | sed -n '1,220p' >&2 + exit 1 +fi + +LOG_ERR="/tmp/${CONTAINER_NAME}-errors.log" +if docker logs "${CONTAINER_NAME}" 2>&1 | grep -nE "Address already in use|BindException|Failed to bind|Cannot assign requested address" >"${LOG_ERR}"; then + echo "Startup blockers detected" >&2 + sed -n '1,120p' "${LOG_ERR}" >&2 + exit 1 +fi +if docker logs "${CONTAINER_NAME}" 2>&1 | grep -nE "Protocol not available" >/tmp/${CONTAINER_NAME}-protocol.warn; then + echo "Non-blocking warning: some optional protocols are unavailable in this image." >&2 + sed -n '1,80p' /tmp/${CONTAINER_NAME}-protocol.warn >&2 || true +fi + +LISTENERS="/tmp/${CONTAINER_NAME}-listeners.log" +attempt=0 +while true; do + docker exec "${CONTAINER_NAME}" sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | sed -n "1,120p"' >"${LISTENERS}" || true + if search_cmd ':1883' "${LISTENERS}" >/dev/null 2>&1 && search_cmd ':8080' "${LISTENERS}" >/dev/null 2>&1; then + break + fi + attempt=$((attempt + 1)) + if [[ "${attempt}" -ge 30 ]]; then + echo "Listener verification failed: expected 1883/8080 inside container" >&2 + echo "Listener snapshot:" >&2 + sed -n '1,120p' "${LISTENERS}" >&2 || true + echo "Recent server logs:" >&2 + docker logs "${CONTAINER_NAME}" 2>&1 | tail -n 120 >&2 || true + exit 1 + fi + sleep 1 +done + +# Wait for aggregator workers to become active before scenario publish. +agg_ready=0 +for _ in $(seq 1 40); do + if docker logs "${CONTAINER_NAME}" 2>&1 | grep -Eq "AGGREGATOR_MANAGER_TASK_CREATED|AGGREGATOR_STARTED"; then + agg_ready=1 + break + fi + sleep 1 +done +if [[ "${agg_ready}" -ne 1 ]]; then + echo "Warning: aggregator startup marker not observed; continuing with scenario publish." >&2 +fi + +# Smoke topic check to ensure MQTT path is alive. +OUT_SMOKE="/tmp/${CONTAINER_NAME}-smoke.out" +: >"${OUT_SMOKE}" + +timeout 12 mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${SMOKE_TOPIC}" -C 1 >"${OUT_SMOKE}" 2>/tmp/${CONTAINER_NAME}-smoke.err & +SPID=$! +sleep 1 +mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${SMOKE_TOPIC}" -m "smoke-${TEST_RUN_ID}" +wait "${SPID}" + +# Aggregator scenario: subscribe before publishing both inputs. +OUT_AGG="/tmp/${CONTAINER_NAME}-agg.out" +ERR_AGG="/tmp/${CONTAINER_NAME}-agg.err" +: >"${OUT_AGG}"; : >"${ERR_AGG}" + +scenario_ok=0 +for attempt in 1 2 3; do + cid="${TEST_RUN_ID}-a${attempt}" + : >"${OUT_AGG}"; : >"${ERR_AGG}" + timeout "${WAIT_SECS}" mosquitto_sub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${OUTPUT_TOPIC}" -C 1 >"${OUT_AGG}" 2>"${ERR_AGG}" & + APID=$! + sleep 1 + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${INPUT_A}" -m "{\"src\":\"a\",\"v\":11,\"cid\":\"${cid}\"}" + mosquitto_pub -V mqttv311 -h 127.0.0.1 -p "${MQTT_PORT}" -t "${INPUT_B}" -m "{\"src\":\"b\",\"v\":22,\"cid\":\"${cid}\"}" + if wait "${APID}"; then + scenario_ok=1 + break + fi + sleep 1 +done + +if [[ "${scenario_ok}" -ne 1 ]]; then + echo "Aggregator scenario failed: no message on ${OUTPUT_TOPIC} within ${WAIT_SECS}s (3 attempts)" >&2 + echo "Subscriber stderr:" >&2 + sed -n '1,120p' "${ERR_AGG}" >&2 || true + echo "Aggregator log markers:" >&2 + docker logs "${CONTAINER_NAME}" 2>&1 | grep -nE "AGGREGATOR_MANAGER_TASK_CREATED|AGGREGATOR_STARTED|AGGREGATOR_EXCEPTION|AGGREGATOR_EVENT_DROPPED|/veh/a|/veh/b|/veh/agg" | tail -n 120 >&2 || true + echo "Recent server logs:" >&2 + docker logs "${CONTAINER_NAME}" 2>&1 | tail -n 120 >&2 || true + exit 1 +fi + +if [[ ! -s "${OUT_AGG}" ]]; then + echo "Aggregator scenario failed: output payload is empty on ${OUTPUT_TOPIC}" >&2 + exit 1 +fi + +echo "--- ${OUTPUT_TOPIC} sample ---" +sed -n '1,6p' "${OUT_AGG}" +echo "maps-aggregator-config-engineer scenario e2e PASS" diff --git a/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh b/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh index ffc743dc4..bbfe490bb 100755 --- a/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh +++ b/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -IMAGE="mapsmessaging/server_daemon:latest" +IMAGE="${IMAGE:-}" CONTAINER_NAME="maps-artifact-smoke" ARTIFACT_DIR="" HOST_MQTT_PORT="1883" @@ -14,13 +14,40 @@ TARGET_PLATFORM="" MQTT_USERNAME="" MQTT_PASSWORD="" REQUIRED_LISTENERS="" +IMAGE_CHANNEL="${IMAGE_CHANNEL:-auto}" +IMAGE_VERSION="${IMAGE_VERSION:-4.3.1-snapshot}" +ARCH="${ARCH:-auto}" + +detect_arch() { + local machine + machine="$(uname -m || true)" + case "${machine}" in + arm64|aarch64) echo "arm64" ;; + x86_64|amd64) echo "amd64" ;; + *) echo "amd64" ;; + esac +} + +resolve_image() { + local selected_arch="$1" + local selected_channel="$2" + if [[ "${selected_channel}" == "snapshot" ]]; then + if [[ "${selected_arch}" == "arm64" ]]; then + echo "mapsmessaging/server_daemon_arm_${IMAGE_VERSION}:latest" + else + echo "mapsmessaging/server_daemon_${IMAGE_VERSION}:latest" + fi + return + fi + echo "mapsmessaging/server_daemon:latest" +} usage() { cat < Docker image (default: ${IMAGE}) + --image Docker image (default: auto-selected by arch/channel unless set) --container-name Container name (default: ${CONTAINER_NAME}) --artifact-dir Directory containing MAPS manager YAML artifacts to mount --mqtt-port Host MQTT port (default: ${HOST_MQTT_PORT}) @@ -74,6 +101,24 @@ while [[ $# -gt 0 ]]; do esac done +if [[ "${ARCH}" == "auto" ]]; then + ARCH="$(detect_arch)" +fi +if [[ -z "${IMAGE}" ]]; then + EFFECTIVE_CHANNEL="${IMAGE_CHANNEL}" + if [[ "${EFFECTIVE_CHANNEL}" == "auto" ]]; then + if [[ "${ARCH}" == "arm64" ]]; then + EFFECTIVE_CHANNEL="snapshot" + else + EFFECTIVE_CHANNEL="release" + fi + fi + IMAGE="$(resolve_image "${ARCH}" "${EFFECTIVE_CHANNEL}")" +fi +if [[ -z "${TARGET_PLATFORM}" ]]; then + TARGET_PLATFORM="linux/${ARCH}" +fi + require_cmd() { if ! command -v "$1" >/dev/null 2>&1; then echo "Missing required command: $1" >&2 @@ -172,12 +217,17 @@ if [[ "$(docker inspect -f '{{.State.Running}}' "${CONTAINER_NAME}")" != "true" fi echo "Checking startup logs for hard blockers" -if docker logs "${CONTAINER_NAME}" 2>&1 | rg -n "Address already in use|BindException|Failed to bind|Protocol not available|Cannot assign requested address" >/tmp/${CONTAINER_NAME}-errors.log; then +if docker logs "${CONTAINER_NAME}" 2>&1 | rg -n "Address already in use|BindException|Failed to bind|Cannot assign requested address" >/tmp/${CONTAINER_NAME}-errors.log; then echo "Startup blockers detected:" >&2 sed -n '1,120p' /tmp/${CONTAINER_NAME}-errors.log >&2 exit 1 fi +if docker logs "${CONTAINER_NAME}" 2>&1 | rg -n "Protocol not available" >/tmp/${CONTAINER_NAME}-protocol.warn; then + echo "Non-blocking warning: optional protocols unavailable in selected image." + sed -n '1,80p' /tmp/${CONTAINER_NAME}-protocol.warn +fi + if docker logs "${CONTAINER_NAME}" 2>&1 | rg -n "ConsulManagerFactory|Consol Server is not responding" >/tmp/${CONTAINER_NAME}-consul.warn; then echo "Non-blocking warning: Consul unavailable, expecting file-based fallback." sed -n '1,80p' /tmp/${CONTAINER_NAME}-consul.warn diff --git a/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh index c48d2c0f6..fd9ca4a6b 100755 --- a/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh +++ b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh index 9d9550019..903c89082 100755 --- a/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh +++ b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh index 4e8f9f6cd..cbbf20d7e 100755 --- a/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh +++ b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh b/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh index bca683e54..6efc0fb77 100755 --- a/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh +++ b/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh index b5372887b..b6eff7d11 100755 --- a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh index 13e7ed011..e917159fa 100755 --- a/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh +++ b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh index 948f79a36..efcf56df3 100755 --- a/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh +++ b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh index 84cd1f332..a6e1084b9 100755 --- a/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh +++ b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh index 77eda1af0..2900f8b15 100755 --- a/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh +++ b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh index 43749ed83..3178e38cb 100755 --- a/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh +++ b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh b/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh index 44676c5e4..c2727b6c0 100755 --- a/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh +++ b/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh index 235dc151d..b81c2fe48 100755 --- a/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh +++ b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh b/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh index 81f19476e..f63d79910 100755 --- a/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh +++ b/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh index 9b24e16f0..0317367e5 100755 --- a/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh +++ b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh index ccab2ebad..cf1c053e1 100755 --- a/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh +++ b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" diff --git a/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh index fb0248820..bd599f650 100755 --- a/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh +++ b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT="/Users/krital/dev/starsense/mapsmessaging_server" HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" -IMAGE="${IMAGE:-mapsmessaging/server_daemon:latest}" +IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" HTTP_PORT="${HTTP_PORT:-8080}" @@ -55,7 +55,6 @@ if [[ "${REQUIRE_MQTT_RUNTIME}" == "1" ]]; then fi CMD=(bash "${HARNESS}" - --image "${IMAGE}" --container-name "${CONTAINER_NAME}" --artifact-dir "${TMP_DIR}" --mqtt-port "${MQTT_PORT}" From b9205a2809f05d1840c7b3ef6ff315e748e13bf7 Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 14:55:36 +0200 Subject: [PATCH 03/12] ci(buildkite): include pipeline and skills combo updates --- .buildkite/ml_server_pipeline.yml | 42 +++++++++++++++++++ .buildkite/ml_server_release_pipeline.yml | 42 +++++++++++++++++++ .buildkite/server_pipeline.yml | 43 ++++++++++++++++++- .buildkite/server_release_pipeline.yml | 43 ++++++++++++++++++- .buildkite/skills_combo_usage.md | 51 +++++++++++++++++++++++ 5 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 .buildkite/skills_combo_usage.md diff --git a/.buildkite/ml_server_pipeline.yml b/.buildkite/ml_server_pipeline.yml index affcb1bbb..2e77d54c0 100644 --- a/.buildkite/ml_server_pipeline.yml +++ b/.buildkite/ml_server_pipeline.yml @@ -1,4 +1,46 @@ steps: + - label: ":test_tube: Skills Smoke" + command: + - bash ./skills/smoke/run.sh + agents: + queue: "java_build_queue" + + - label: ":mag: Selector Skill Smoke" + command: + - bash ./skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":round_pushpin: Geospatial Skill Smoke" + command: + - bash ./skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":robot_face: ML Lifecycle Skill Smoke" + command: + - bash ./skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":test_tube: Skill Combo Smoke (Optional)" + command: + - | + if [ -n "${SKILL_COMBO:-}" ]; then + cmd=(bash ./skills/smoke/run_skill_combination.sh --skills "${SKILL_COMBO}") + if [ "${SKILL_COMBO_DEEP:-0}" = "1" ]; then + cmd+=(--deep) + fi + if [ "${SKILL_COMBO_BOOTSTRAP:-0}" = "1" ]; then + cmd+=(--bootstrap-fixtures) + fi + "${cmd[@]}" + else + echo "SKILL_COMBO not set, skipping optional combo smoke." + fi + agents: + queue: "java_build_queue" + - label: ":maven: Build and release to github" command: - export NVD_API_KEY=$(buildkite-agent secret get nvd_api_key) diff --git a/.buildkite/ml_server_release_pipeline.yml b/.buildkite/ml_server_release_pipeline.yml index 964713f1a..8b7f2d0a1 100644 --- a/.buildkite/ml_server_release_pipeline.yml +++ b/.buildkite/ml_server_release_pipeline.yml @@ -1,4 +1,46 @@ steps: + - label: ":test_tube: Skills Smoke" + command: + - bash ./skills/smoke/run.sh + agents: + queue: "java_build_queue" + + - label: ":mag: Selector Skill Smoke" + command: + - bash ./skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":round_pushpin: Geospatial Skill Smoke" + command: + - bash ./skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":robot_face: ML Lifecycle Skill Smoke" + command: + - bash ./skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":test_tube: Skill Combo Smoke (Optional)" + command: + - | + if [ -n "${SKILL_COMBO:-}" ]; then + cmd=(bash ./skills/smoke/run_skill_combination.sh --skills "${SKILL_COMBO}") + if [ "${SKILL_COMBO_DEEP:-0}" = "1" ]; then + cmd+=(--deep) + fi + if [ "${SKILL_COMBO_BOOTSTRAP:-0}" = "1" ]; then + cmd+=(--bootstrap-fixtures) + fi + "${cmd[@]}" + else + echo "SKILL_COMBO not set, skipping optional combo smoke." + fi + agents: + queue: "java_build_queue" + - label: ":maven: Build and release to github" command: - export NVD_API_KEY=$(buildkite-agent secret get nvd_api_key) diff --git a/.buildkite/server_pipeline.yml b/.buildkite/server_pipeline.yml index 10dc97542..c96d2cb4f 100644 --- a/.buildkite/server_pipeline.yml +++ b/.buildkite/server_pipeline.yml @@ -1,4 +1,46 @@ steps: + - label: ":test_tube: Skills Smoke" + command: + - bash ./skills/smoke/run.sh + agents: + queue: "java_build_queue" + + - label: ":mag: Selector Skill Smoke" + command: + - bash ./skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":round_pushpin: Geospatial Skill Smoke" + command: + - bash ./skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":robot_face: ML Lifecycle Skill Smoke" + command: + - bash ./skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":test_tube: Skill Combo Smoke (Optional)" + command: + - | + if [ -n "${SKILL_COMBO:-}" ]; then + cmd=(bash ./skills/smoke/run_skill_combination.sh --skills "${SKILL_COMBO}") + if [ "${SKILL_COMBO_DEEP:-0}" = "1" ]; then + cmd+=(--deep) + fi + if [ "${SKILL_COMBO_BOOTSTRAP:-0}" = "1" ]; then + cmd+=(--bootstrap-fixtures) + fi + "${cmd[@]}" + else + echo "SKILL_COMBO not set, skipping optional combo smoke." + fi + agents: + queue: "java_build_queue" + - label: ":maven: Build and release to github" command: - export SONAR_TOKEN=$(buildkite-agent secret get SONAR_TOKEN) @@ -22,4 +64,3 @@ steps: agents: queue: "java_build_queue" - diff --git a/.buildkite/server_release_pipeline.yml b/.buildkite/server_release_pipeline.yml index a7e05a7e0..645e01417 100644 --- a/.buildkite/server_release_pipeline.yml +++ b/.buildkite/server_release_pipeline.yml @@ -1,4 +1,46 @@ steps: + - label: ":test_tube: Skills Smoke" + command: + - bash ./skills/smoke/run.sh + agents: + queue: "java_build_queue" + + - label: ":mag: Selector Skill Smoke" + command: + - bash ./skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":round_pushpin: Geospatial Skill Smoke" + command: + - bash ./skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":robot_face: ML Lifecycle Skill Smoke" + command: + - bash ./skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh + agents: + queue: "java_build_queue" + + - label: ":test_tube: Skill Combo Smoke (Optional)" + command: + - | + if [ -n "${SKILL_COMBO:-}" ]; then + cmd=(bash ./skills/smoke/run_skill_combination.sh --skills "${SKILL_COMBO}") + if [ "${SKILL_COMBO_DEEP:-0}" = "1" ]; then + cmd+=(--deep) + fi + if [ "${SKILL_COMBO_BOOTSTRAP:-0}" = "1" ]; then + cmd+=(--bootstrap-fixtures) + fi + "${cmd[@]}" + else + echo "SKILL_COMBO not set, skipping optional combo smoke." + fi + agents: + queue: "java_build_queue" + - label: ":maven: Build and release to github" command: - wget https://github.com/Maps-Messaging/web-admin-client/releases/download/maps_web_client_1.0.1/webAdminClient.tgz @@ -16,4 +58,3 @@ steps: agents: queue: "java_build_queue" - diff --git a/.buildkite/skills_combo_usage.md b/.buildkite/skills_combo_usage.md new file mode 100644 index 000000000..e4e351652 --- /dev/null +++ b/.buildkite/skills_combo_usage.md @@ -0,0 +1,51 @@ +# Skill Combo Smoke Usage + +Optional Buildkite step: `:test_tube: Skill Combo Smoke (Optional)` + +This step runs only when `SKILL_COMBO` is set. + +## Environment Variables + +- `SKILL_COMBO` + - Required to activate combo smoke. + - Comma-separated skill names. + - Example: + - `maps-selector-rule-engineer,maps-geospatial-routing-builder,maps-ml-model-lifecycle-playbook` + +- `SKILL_COMBO_DEEP` + - Optional. + - `1` to run per-skill deep smoke scripts when available. + - `0` or unset for contract-only combination smoke. + +- `SKILL_COMBO_BOOTSTRAP` + - Optional. + - `1` to regenerate fixtures before combo smoke. + - `0` or unset to use existing fixtures. + +## Common Examples + +Contract-only combo smoke: + +```bash +SKILL_COMBO="maps-deployment-packager,maps-selector-rule-engineer,maps-geospatial-routing-builder" +``` + +Deep combo smoke: + +```bash +SKILL_COMBO="maps-selector-rule-engineer,maps-geospatial-routing-builder,maps-ml-model-lifecycle-playbook,maps-scenario-composer" +SKILL_COMBO_DEEP=1 +``` + +Deep combo smoke with fixture refresh: + +```bash +SKILL_COMBO="mapsmessaging-config-builder,maps-runtime-diagnostics,maps-protocol-bridge-tester,maps-satellite-gateway-config,maps-schema-pipeline-builder,maps-transform-chain-designer,maps-aggregator-config-engineer,maps-canbus-ingestion-builder,maps-deployment-packager,maps-release-readiness-checker,maps-ml-stream-configurator,maps-artifact-execution-smoke-harness,maps-selector-rule-engineer,maps-geospatial-routing-builder,maps-ml-model-lifecycle-playbook,maps-scenario-composer,maps-skill-suite-orchestrator" +SKILL_COMBO_DEEP=1 +SKILL_COMBO_BOOTSTRAP=1 +``` + +## Notes + +- The combo step is optional and does not replace the per-skill required smoke gates. +- Skill names must match folder names under `/Users/krital/dev/starsense/mapsmessaging_server/skills`. From 5aac2e5ed3f256d6e415661dd223dd1e92c31786 Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 14:58:30 +0200 Subject: [PATCH 04/12] chore(gitignore): ignore python cache artifacts --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index c37f33840..ebb5986a6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ buildNumber.properties # https://github.com/takari/maven-wrapper#usage-without-binary-jar .mvn/wrapper/maven-wrapper.jar .idea + +# Python cache artifacts (skill helper scripts) +__pycache__/ +*.py[cod] From dd8444a862454d841cff0259b509b287d60d61f3 Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 15:00:09 +0200 Subject: [PATCH 05/12] docs(readme): document skill combo smoke pipeline usage --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index dcfcb7843..3dc3fc1c6 100644 --- a/README.md +++ b/README.md @@ -95,3 +95,15 @@ For full license terms, see the [LICENSE](LICENSE) file in the repository. [![Mutable.ai Auto Wiki](https://img.shields.io/badge/Auto_Wiki-Mutable.ai-blue)](https://wiki.mutable.ai/Maps-Messaging/mapsmessaging_server) + +## Buildkite Skill Combo Smoke + +This repository includes an optional Buildkite combo smoke step (`:test_tube: Skill Combo Smoke (Optional)`) that can run any combination of skills. + +Set these environment variables on the pipeline/build: +- `SKILL_COMBO` (required to activate): comma-separated skill names +- `SKILL_COMBO_DEEP` (optional): `1` to run deep per-skill smoke scripts +- `SKILL_COMBO_BOOTSTRAP` (optional): `1` to regenerate fixtures before combo smoke + +Usage reference: +- `.buildkite/skills_combo_usage.md` From 1215acafdcb882ccffc9fe7eb3d0aa78f20c8cca Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 15:02:42 +0200 Subject: [PATCH 06/12] docs(skills): add install guide for codex claude and generic agents --- README.md | 1 + docs/skills-install.md | 76 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 docs/skills-install.md diff --git a/README.md b/README.md index 3dc3fc1c6..aee4f6ed3 100644 --- a/README.md +++ b/README.md @@ -107,3 +107,4 @@ Set these environment variables on the pipeline/build: Usage reference: - `.buildkite/skills_combo_usage.md` +- `docs/skills-install.md` diff --git a/docs/skills-install.md b/docs/skills-install.md new file mode 100644 index 000000000..6165bde2c --- /dev/null +++ b/docs/skills-install.md @@ -0,0 +1,76 @@ +# Skills Install Guide + +This guide explains how to package and install MAPS skills into Codex, Claude, and other agent runtimes. + +## What to distribute + +Distribute skill folders from `skills/` (each folder should include `SKILL.md`, `references/`, and `scripts/` as needed). + +Examples: +- `skills/mapsmessaging-config-builder` +- `skills/maps-runtime-diagnostics` +- `skills/maps-aggregator-config-engineer` + +## Install into Codex + +Codex reads skills from `$CODEX_HOME/skills` (often `~/.codex/skills`). + +Install selected skills: + +```bash +mkdir -p ~/.codex/skills +cp -R skills/mapsmessaging-config-builder ~/.codex/skills/ +cp -R skills/maps-runtime-diagnostics ~/.codex/skills/ +``` + +Install all skills: + +```bash +mkdir -p ~/.codex/skills +cp -R skills/* ~/.codex/skills/ +``` + +Open a new Codex session and invoke by name, for example: +- `$mapsmessaging-config-builder` +- `$maps-runtime-diagnostics` + +## Install into Claude + +For Claude project agents: + +1. Copy skill folders into your project (for example under `skills/` or `.claude/skills/`). +2. Register them in `AGENTS.md` with: +- skill name +- short description +- path to the skill `SKILL.md` +3. Trigger by explicit skill mention or task intent. + +## Install into other LLM agents + +If the platform has no native skill system, use one of these patterns: + +1. Prompt-pack pattern: +- load `SKILL.md` plus required reference files into system/developer context. + +2. Tool wrapper pattern: +- expose `scripts/` as callable tools for the agent. + +3. Retrieval pattern: +- index `skills/` content and inject relevant snippets into runtime context. + +## Runtime prerequisites (for MAPS smoke/runtime scripts) + +- Docker +- `bash` +- `mosquitto_pub` and `mosquitto_sub` +- `python3` (optional helper scripts may also need `PyYAML`) +- `rg` (recommended) + +## Packaging recommendation + +For internal distribution: + +1. Publish the repo branch/tag containing skill updates. +2. Keep skill docs and scripts versioned with source. +3. Prefer repo-relative paths in docs and references. +4. Include a short changelog entry for added/updated skills. From 8544c442840d3413ed2318c658e6a4a37c1d55ff Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 15:23:51 +0200 Subject: [PATCH 07/12] chore(skills): remove local checkout path leakage and normalize script roots --- .../maps-aggregator-config-engineer/SKILL.md | 18 ++++----- .../references/aggregator-design-guide.md | 2 +- ...ggregator_config_engineer_runtime_smoke.sh | 4 +- ..._aggregator_config_engineer_skill_smoke.sh | 5 ++- .../run_maps_aggregator_scenario_e2e.sh | 2 +- .../SKILL.md | 16 ++++---- .../references/execution-catalog.md | 16 ++++---- ...t_execution_smoke_harness_runtime_smoke.sh | 4 +- ...act_execution_smoke_harness_skill_smoke.sh | 5 ++- skills/maps-canbus-ingestion-builder/SKILL.md | 18 ++++----- .../references/canbus-mapping-guide.md | 6 +-- ..._canbus_ingestion_builder_runtime_smoke.sh | 4 +- ...ps_canbus_ingestion_builder_skill_smoke.sh | 5 ++- skills/maps-deployment-packager/SKILL.md | 12 +++--- .../references/deployment-targets.md | 16 ++++---- ..._maps_deployment_packager_runtime_smoke.sh | 4 +- ...un_maps_deployment_packager_skill_smoke.sh | 5 ++- .../maps-geospatial-routing-builder/SKILL.md | 20 +++++----- .../examples/advanced-geospatial-output.md | 12 +++--- .../examples/simple-geospatial-output.md | 12 +++--- .../references/geospatial-patterns.md | 6 +-- .../scripts/run_geospatial_skill_smoke.sh | 5 ++- ...eospatial_routing_builder_runtime_smoke.sh | 4 +- .../scripts/validate_geospatial_artifacts.py | 6 +-- .../maps-ml-model-lifecycle-playbook/SKILL.md | 22 +++++------ .../examples/advanced-ml-lifecycle-output.md | 12 +++--- .../examples/simple-ml-lifecycle-output.md | 14 +++---- .../references/lifecycle-patterns.md | 6 +-- .../scripts/run_ml_lifecycle_runtime_smoke.sh | 4 +- .../scripts/run_ml_lifecycle_skill_smoke.sh | 5 ++- .../scripts/run_ml_lifecycle_vectors.py | 2 +- .../validate_ml_lifecycle_artifacts.py | 6 +-- skills/maps-ml-stream-configurator/SKILL.md | 16 ++++---- .../references/ml-pipeline-patterns.md | 4 +- ...ps_ml_stream_configurator_runtime_smoke.sh | 4 +- ...maps_ml_stream_configurator_skill_smoke.sh | 5 ++- skills/maps-protocol-bridge-tester/SKILL.md | 10 ++--- .../references/bridge-test-catalog.md | 4 +- ...ps_protocol_bridge_tester_runtime_smoke.sh | 4 +- ...maps_protocol_bridge_tester_skill_smoke.sh | 5 ++- .../maps-release-readiness-checker/SKILL.md | 10 ++--- .../references/release-gate-catalog.md | 2 +- ...release_readiness_checker_runtime_smoke.sh | 4 +- ...s_release_readiness_checker_skill_smoke.sh | 5 ++- skills/maps-runtime-diagnostics/SKILL.md | 12 +++--- ..._maps_runtime_diagnostics_runtime_smoke.sh | 4 +- ...un_maps_runtime_diagnostics_skill_smoke.sh | 5 ++- skills/maps-satellite-gateway-config/SKILL.md | 22 +++++------ .../references/satellite-config-map.md | 14 +++---- ..._satellite_gateway_config_runtime_smoke.sh | 4 +- ...ps_satellite_gateway_config_skill_smoke.sh | 5 ++- skills/maps-scenario-composer/SKILL.md | 14 +++---- .../references/composition-patterns.md | 6 +-- .../examples/composed-deliverable-example.md | 6 +-- .../scripts/compose_scenarios.py | 2 +- ...un_maps_scenario_composer_runtime_smoke.sh | 4 +- .../run_scenario_composer_skill_smoke.sh | 11 +++--- skills/maps-schema-pipeline-builder/SKILL.md | 20 +++++----- .../references/schema-mapping-guide.md | 12 +++--- ...s_schema_pipeline_builder_runtime_smoke.sh | 4 +- ...aps_schema_pipeline_builder_skill_smoke.sh | 5 ++- skills/maps-selector-rule-engineer/SKILL.md | 18 ++++----- .../examples/advanced-selector-output.md | 10 ++--- .../examples/simple-selector-output.md | 10 ++--- .../references/selector-patterns.md | 4 +- ...ps_selector_rule_engineer_runtime_smoke.sh | 4 +- .../scripts/run_selector_skill_smoke.sh | 5 ++- .../scripts/validate_selector_artifacts.py | 6 +-- skills/maps-skill-suite-orchestrator/SKILL.md | 38 +++++++++---------- ..._skill_suite_orchestrator_runtime_smoke.sh | 4 +- ...ps_skill_suite_orchestrator_skill_smoke.sh | 5 ++- skills/maps-transform-chain-designer/SKILL.md | 8 ++-- .../references/transform-chain-patterns.md | 4 +- ..._transform_chain_designer_runtime_smoke.sh | 4 +- ...ps_transform_chain_designer_skill_smoke.sh | 5 ++- skills/mapsmessaging-config-builder/SKILL.md | 22 +++++------ .../references/protocol-and-routing-map.md | 14 +++---- .../references/test-scenario-01-output.md | 20 +++++----- .../references/test-scenario-02-output.md | 18 ++++----- ...smessaging_config_builder_runtime_smoke.sh | 4 +- ...apsmessaging_config_builder_skill_smoke.sh | 5 ++- .../artifact.md | 2 +- .../artifact.md | 2 +- .../maps-canbus-ingestion-builder/artifact.md | 2 +- .../maps-deployment-packager/artifact.md | 2 +- .../artifact.md | 2 +- .../artifact.md | 2 +- .../maps-ml-stream-configurator/artifact.md | 2 +- .../maps-protocol-bridge-tester/artifact.md | 2 +- .../artifact.md | 2 +- .../maps-runtime-diagnostics/artifact.md | 2 +- .../maps-satellite-gateway-config/artifact.md | 2 +- .../maps-scenario-composer/artifact.md | 2 +- .../maps-schema-pipeline-builder/artifact.md | 2 +- .../maps-selector-rule-engineer/artifact.md | 2 +- .../maps-skill-suite-orchestrator/artifact.md | 2 +- .../maps-transform-chain-designer/artifact.md | 2 +- .../mapsmessaging-config-builder/artifact.md | 2 +- skills/smoke/validate_skills_smoke.py | 2 +- 99 files changed, 381 insertions(+), 364 deletions(-) diff --git a/skills/maps-aggregator-config-engineer/SKILL.md b/skills/maps-aggregator-config-engineer/SKILL.md index c866d3a8c..c14d1dc20 100644 --- a/skills/maps-aggregator-config-engineer/SKILL.md +++ b/skills/maps-aggregator-config-engineer/SKILL.md @@ -14,8 +14,8 @@ Convert aggregation requirements into deployable `AggregatorManager.yaml` entiti - Capture throughput constraints that drive `maxEventsPerTopic`, `maxBatchPerAggregator`, `mailboxCapacity`, and `stripeCount`. 2. Map to concrete AggregatorManager fields. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md`. -- Update `/Users/krital/dev/starsense/mapsmessaging_server/AggregatorManager.yaml` as primary source. +- Read `skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md`. +- Update `AggregatorManager.yaml` as primary source. - Include related destination/schema/transform config only when aggregation output requires it. 3. Build deployable config. @@ -28,16 +28,16 @@ Convert aggregation requirements into deployable `AggregatorManager.yaml` entiti - Check timing consistency: `timeoutMs >= windowDurationMs` unless explicitly justified. - Check resource and fairness guardrails: `maxEventsPerTopic`, `maxBatchPerAggregator`, `mailboxCapacity`, `stripeCount`. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh` + - `skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh` + - `skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh` + - `skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh` - Run checks: ```bash -rg -n "aggregatorConfigList|windowDurationMs|timeoutMs|maxEventsPerTopic|contributionMode|outputTopic" /Users/krital/dev/starsense/mapsmessaging_server/AggregatorManager.yaml +rg -n "aggregatorConfigList|windowDurationMs|timeoutMs|maxEventsPerTopic|contributionMode|outputTopic" AggregatorManager.yaml ``` 5. Return output using contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/references/output-contract.md`. +- Follow `skills/maps-aggregator-config-engineer/references/output-contract.md`. - Always include assumptions, deployable YAML, apply steps, and verification with pass/fail criteria. ## Aggregator-Specific Rules @@ -72,5 +72,5 @@ rg -n "aggregatorConfigList|windowDurationMs|timeoutMs|maxEventsPerTopic|contrib ## Reference Loading Load only what is needed: -- Aggregator semantics and patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md` -- Final response contract: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/references/output-contract.md` +- Aggregator semantics and patterns: `skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md` +- Final response contract: `skills/maps-aggregator-config-engineer/references/output-contract.md` diff --git a/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md b/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md index 7bdd0a5b3..6ed85feef 100644 --- a/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md +++ b/skills/maps-aggregator-config-engineer/references/aggregator-design-guide.md @@ -3,7 +3,7 @@ ## Core Config Surface Primary file: -- `/Users/krital/dev/starsense/mapsmessaging_server/AggregatorManager.yaml` +- `AggregatorManager.yaml` Important root controls: - `maxAggregators` diff --git a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh index d3e37b01d..07c5ffc28 100755 --- a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh +++ b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" IMAGE_CHANNEL="${IMAGE_CHANNEL:-auto}" diff --git a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh index a9048365b..fdd6b68e8 100755 --- a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh +++ b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_config_engineer_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then diff --git a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh index 3c1c2fc89..9616690a4 100755 --- a/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh +++ b/skills/maps-aggregator-config-engineer/scripts/run_maps_aggregator_scenario_e2e.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" IMAGE_CHANNEL="${IMAGE_CHANNEL:-auto}" diff --git a/skills/maps-artifact-execution-smoke-harness/SKILL.md b/skills/maps-artifact-execution-smoke-harness/SKILL.md index 5f4ea8ff4..f79c30ccb 100644 --- a/skills/maps-artifact-execution-smoke-harness/SKILL.md +++ b/skills/maps-artifact-execution-smoke-harness/SKILL.md @@ -15,14 +15,14 @@ Run executable smoke gates against generated artifacts, not only document-level - Identify expected listeners, namespaces, routes, and success markers. 2. Build execution plan. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md`. +- Read `skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md`. - Define phases: setup, apply, startup, listener verification, traffic verification, teardown. - Require explicit timeout and fail-fast conditions per phase. - Prefer bundled scripts when direct execution is requested: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh` + - `skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh` + - `skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh` + - `skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh` + - `skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh` 3. Execute smoke phases. - Setup: ensure ports are free and prior containers/processes are cleaned up safely. @@ -37,7 +37,7 @@ Run executable smoke gates against generated artifacts, not only document-level - Separate environment issues from artifact defects. 5. Return using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/references/output-contract.md`. +- Follow `skills/maps-artifact-execution-smoke-harness/references/output-contract.md`. - Include exact commands, observed outcomes, and minimal rerun command set. ## Rules @@ -70,5 +70,5 @@ Run executable smoke gates against generated artifacts, not only document-level ## Reference Loading Load only what is needed: -- Execution phases and commands: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md` -- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/references/output-contract.md` +- Execution phases and commands: `skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md` +- Final response format: `skills/maps-artifact-execution-smoke-harness/references/output-contract.md` diff --git a/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md b/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md index f496f2872..7b6625010 100644 --- a/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md +++ b/skills/maps-artifact-execution-smoke-harness/references/execution-catalog.md @@ -9,7 +9,7 @@ Example checks: ```bash -rg -n "NetworkManager|DestinationManager|routing|SchemaManager" /Users/krital/dev/starsense/mapsmessaging_server/*.yaml +rg -n "NetworkManager|DestinationManager|routing|SchemaManager" *.yaml (ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null || netstat -an 2>/dev/null) | rg "1883|5672|8080|9001" || true ``` @@ -50,36 +50,36 @@ rg -n "NetworkManager|DestinationManager|routing|SchemaManager" /Users/krital/de ## Runnable Scripts - Single scenario runner: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh` + - `skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh` - Two-scenario matrix runner: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh` + - `skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh` Example: ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel release --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --base-mqtt-port 2883 --base-http-port 28080 +bash skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel release --artifact-dir --base-mqtt-port 2883 --base-http-port 28080 ``` Snapshot example (latest requested snapshot version): ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel snapshot --version 4.3.1-snapshot --arch arm64 --platform linux/arm64 --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --base-mqtt-port 3883 --base-http-port 38080 +bash skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel snapshot --version 4.3.1-snapshot --arch arm64 --platform linux/arm64 --artifact-dir --base-mqtt-port 3883 --base-http-port 38080 ``` x86 release example: ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel release --arch amd64 --platform linux/amd64 --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --base-mqtt-port 2883 --base-http-port 28080 +bash skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel release --arch amd64 --platform linux/amd64 --artifact-dir --base-mqtt-port 2883 --base-http-port 28080 ``` Auth-enabled MQTT example: ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel snapshot --version 4.3.1-snapshot --arch arm64 --platform linux/arm64 --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --mqtt-username maps-user --mqtt-password maps-pass --base-mqtt-port 4883 --base-http-port 48080 +bash skills/maps-artifact-execution-smoke-harness/scripts/run_matrix.sh --channel snapshot --version 4.3.1-snapshot --arch arm64 --platform linux/arm64 --artifact-dir --mqtt-username maps-user --mqtt-password maps-pass --base-mqtt-port 4883 --base-http-port 48080 ``` Listener-only example for artifacts with non-MQTT flows: ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh --image mapsmessaging/server_daemon:latest --artifact-dir /Users/krital/dev/starsense/mapsmessaging_server --skip-mqtt --required-listeners 8080 --platform linux/amd64 --mqtt-port 5883 --http-port 58080 --force-clean +bash skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh --image mapsmessaging/server_daemon:latest --artifact-dir --skip-mqtt --required-listeners 8080 --platform linux/amd64 --mqtt-port 5883 --http-port 58080 --force-clean ``` diff --git a/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh index fd9ca4a6b..1c64457f1 100755 --- a/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh +++ b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh index d49521e2b..45a94f541 100755 --- a/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh +++ b/skills/maps-artifact-execution-smoke-harness/scripts/run_maps_artifact_execution_smoke_harness_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then diff --git a/skills/maps-canbus-ingestion-builder/SKILL.md b/skills/maps-canbus-ingestion-builder/SKILL.md index 9018a0eeb..941d00c2d 100644 --- a/skills/maps-canbus-ingestion-builder/SKILL.md +++ b/skills/maps-canbus-ingestion-builder/SKILL.md @@ -13,8 +13,8 @@ Convert CAN ingestion requirements into deployable MAPS configs with determinist - Extract interface mode (vcan or native), device name (`can0`, `vcan0`, etc.), protocol behavior (`n2k` decode vs raw canbus), topic naming requirements, parse-to-JSON expectations, and schema/database source. 2. Map to config surfaces. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md`. -- Update `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` for endpoint and protocol binding. +- Read `skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md`. +- Update `NetworkManager.yaml` for endpoint and protocol binding. - Update destination/schema mappings only when requested by pipeline behavior. 3. Build deployable entities. @@ -25,16 +25,16 @@ Convert CAN ingestion requirements into deployable MAPS configs with determinist 4. Validate before finalizing. - Verify endpoint/protocol consistency and topic templates. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh` + - `skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh` + - `skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh` - Include runtime checks: ```bash -rg -n "type: canbus|type: n2k|deviceName|topicNameTemplate|parseToJson" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "N2K_PROTOCOL|canbus" /Users/krital/dev/starsense/mapsmessaging_server/src/main/java/io/mapsmessaging/network/protocol/impl/n2k /Users/krital/dev/starsense/mapsmessaging_server/src/main/java/io/mapsmessaging/network/io/impl/canbus +rg -n "type: canbus|type: n2k|deviceName|topicNameTemplate|parseToJson" NetworkManager.yaml +rg -n "N2K_PROTOCOL|canbus" src/main/java/io/mapsmessaging/network/protocol/impl/n2k src/main/java/io/mapsmessaging/network/io/impl/canbus ``` 5. Return using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/references/output-contract.md`. +- Follow `skills/maps-canbus-ingestion-builder/references/output-contract.md`. - Include assumptions, deployable YAML, apply steps, and vcan/native verification. ## CAN-Specific Rules @@ -69,5 +69,5 @@ rg -n "N2K_PROTOCOL|canbus" /Users/krital/dev/starsense/mapsmessaging_server/src ## Reference Loading Load only what is needed: -- Mapping and runtime checks: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md` -- Response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/references/output-contract.md` +- Mapping and runtime checks: `skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md` +- Response format: `skills/maps-canbus-ingestion-builder/references/output-contract.md` diff --git a/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md b/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md index 3953c4342..77d601a05 100644 --- a/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md +++ b/skills/maps-canbus-ingestion-builder/references/canbus-mapping-guide.md @@ -2,7 +2,7 @@ ## Primary Config Surface -- `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +- `NetworkManager.yaml` - `endPointConfig.type: canbus` - `endPointConfig.deviceName` - `protocolConfigs[].type: n2k` for decoded N2K workflows @@ -36,8 +36,8 @@ ## Validation Commands ```bash -rg -n "type: canbus|type: n2k|deviceName|topicNameTemplate|unknownPacketTopic|parseToJson" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "N2K_PROTOCOL_CREATED_AND_BOUND|N2K_PROTOCOL_PARSING_PACKET|N2K_PROTOCOL_PARSED" /Users/krital/dev/starsense/mapsmessaging_server/src/main/java/io/mapsmessaging/logging/ServerLogMessages.java +rg -n "type: canbus|type: n2k|deviceName|topicNameTemplate|unknownPacketTopic|parseToJson" NetworkManager.yaml +rg -n "N2K_PROTOCOL_CREATED_AND_BOUND|N2K_PROTOCOL_PARSING_PACKET|N2K_PROTOCOL_PARSED" src/main/java/io/mapsmessaging/logging/ServerLogMessages.java ``` ## Verification Skeleton diff --git a/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh index 903c89082..4e2a99341 100755 --- a/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh +++ b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh index 170a61b27..a7d8960c2 100755 --- a/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh +++ b/skills/maps-canbus-ingestion-builder/scripts/run_maps_canbus_ingestion_builder_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then diff --git a/skills/maps-deployment-packager/SKILL.md b/skills/maps-deployment-packager/SKILL.md index 573daf8f1..f15c96bd9 100644 --- a/skills/maps-deployment-packager/SKILL.md +++ b/skills/maps-deployment-packager/SKILL.md @@ -25,7 +25,7 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs - S3-compatible object storage (including Cloudflare R2) 2. Build environment packaging plan. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/deployment-targets.md`. +- Read `skills/maps-deployment-packager/references/deployment-targets.md`. - Generate artifact set for the selected target with minimal duplication. - Keep config and runtime command paths explicit. @@ -51,8 +51,8 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs - Check config mount paths and runtime env coherence (`MAPS_HOME`, `MAPS_CONF`, `MAPS_DATA`). - Include startup diagnostics and listener checks. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh` + - `skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh` + - `skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh` - Validate store-and-forward readiness (persistent destination paths, queue/backlog expectations, and recovery behavior after reconnect). - Validate auth, storage, and config-source alignment: - auth manager configuration matches selected authentication mode @@ -63,7 +63,7 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs - when object storage is selected, provider, endpoint, bucket, and credentials mapping are explicit 5. Return using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/output-contract.md`. +- Follow `skills/maps-deployment-packager/references/output-contract.md`. - Include artifacts, apply commands, validation, and rollback hints. ## Rules @@ -104,5 +104,5 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs ## Reference Loading Load only what is needed: -- Target packaging patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/deployment-targets.md` -- Final response structure: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/output-contract.md` +- Target packaging patterns: `skills/maps-deployment-packager/references/deployment-targets.md` +- Final response structure: `skills/maps-deployment-packager/references/output-contract.md` diff --git a/skills/maps-deployment-packager/references/deployment-targets.md b/skills/maps-deployment-packager/references/deployment-targets.md index 00f7fe2c9..213ecb6d3 100644 --- a/skills/maps-deployment-packager/references/deployment-targets.md +++ b/skills/maps-deployment-packager/references/deployment-targets.md @@ -20,8 +20,8 @@ Inputs: - explicit auth/storage/config-source selections Execution references: -- `/Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/start.sh` -- `/Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/start.bat` +- `src/main/scripts/start.sh` +- `src/main/scripts/start.bat` Output expectations: - complete file set for conf directory @@ -31,9 +31,9 @@ Output expectations: ## Docker Packaging Execution references: -- `/Users/krital/dev/starsense/mapsmessaging_server/buildDocker.sh` -- `/Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/startDocker.sh` -- `/Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/docker_run.sh` +- `buildDocker.sh` +- `src/main/scripts/startDocker.sh` +- `src/main/scripts/docker_run.sh` Output expectations: - image tag and run command @@ -123,9 +123,9 @@ Generate: ## Validation Checklist ```bash -rg -n "MAPS_HOME|MAPS_CONF|MAPS_DATA|java.security.auth.login.config|Consul" /Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/start.sh /Users/krital/dev/starsense/mapsmessaging_server/src/main/scripts/startDocker.sh -rg -n "NetworkManager|DestinationManager|routing|AggregatorManager|AuthManager" /Users/krital/dev/starsense/mapsmessaging_server/*.yaml -rg -n "directory:|storageConfig:|type: File|type: Memory|autoPauseTimeout" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "MAPS_HOME|MAPS_CONF|MAPS_DATA|java.security.auth.login.config|Consul" src/main/scripts/start.sh src/main/scripts/startDocker.sh +rg -n "NetworkManager|DestinationManager|routing|AggregatorManager|AuthManager" *.yaml +rg -n "directory:|storageConfig:|type: File|type: Memory|autoPauseTimeout" DestinationManager.yaml ``` ## Failure Classes diff --git a/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh index cbbf20d7e..91a9f5fa0 100755 --- a/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh +++ b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh index 9f72624bd..c65044cfc 100755 --- a/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh +++ b/skills/maps-deployment-packager/scripts/run_maps_deployment_packager_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then diff --git a/skills/maps-geospatial-routing-builder/SKILL.md b/skills/maps-geospatial-routing-builder/SKILL.md index 45a208f8d..ade44f928 100644 --- a/skills/maps-geospatial-routing-builder/SKILL.md +++ b/skills/maps-geospatial-routing-builder/SKILL.md @@ -14,7 +14,7 @@ Translate location-aware requirements into deployable MAPS routing and transform - Identify whether routing is geohash-bucketed, distance-driven, or both. 2. Design geospatial routing model. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md`. +- Read `skills/maps-geospatial-routing-builder/references/geospatial-patterns.md`. - Define coordinate normalization and unit assumptions. - Define precision strategy (coarse vs fine geohash) and route fan-out behavior. @@ -27,13 +27,13 @@ Translate location-aware requirements into deployable MAPS routing and transform - Validate geohash output paths and distance threshold transitions. - Verify destination evidence for in-range and out-of-range cases. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh` + - `skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh` + - `skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh` + - `skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py` + - `skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh` 5. Return using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/output-contract.md`. +- Follow `skills/maps-geospatial-routing-builder/references/output-contract.md`. - Include deployable config, apply steps, and geospatial verification commands. ## Rules @@ -65,8 +65,8 @@ Translate location-aware requirements into deployable MAPS routing and transform ## Reference Loading Load only what is needed: -- Geospatial patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md` -- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/output-contract.md` +- Geospatial patterns: `skills/maps-geospatial-routing-builder/references/geospatial-patterns.md` +- Final response format: `skills/maps-geospatial-routing-builder/references/output-contract.md` - Example artifacts: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md` + - `skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md` + - `skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md` diff --git a/skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md b/skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md index 7a1fd8460..6814714d5 100644 --- a/skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md +++ b/skills/maps-geospatial-routing-builder/references/examples/advanced-geospatial-output.md @@ -5,9 +5,9 @@ - Stage 2 per-region distance thresholds for routing. - Invalid coordinate quarantine and fallback delivery path. - File targets: - - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + - `NetworkManager.yaml` + - `DestinationManager.yaml` + - `routing.yaml` ## Geo Model - Coordinate system: WGS84. @@ -35,7 +35,7 @@ routes: ## Apply Steps ```bash -cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml.bak +cp routing.yaml routing.yaml.bak # apply staged geospatial routing patch and restart runtime ``` @@ -47,8 +47,8 @@ cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/d - Invalid checks: - missing lat/lon and out-of-range values go to quarantine. ```bash -python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh --source-topic /geo/in --near-topic /geo/out/near --far-topic /geo/out/far --invalid-topic /geo/out/invalid +python3 skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py +bash skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh --source-topic /geo/in --near-topic /geo/out/near --far-topic /geo/out/far --invalid-topic /geo/out/invalid ``` ## Risk Notes diff --git a/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md b/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md index 3aa22dbc7..6c9cf720e 100644 --- a/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md +++ b/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md @@ -4,9 +4,9 @@ - Route incoming GPS messages by geohash prefix and proximity threshold. - Route invalid coordinates to quarantine path. - File targets: - - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + - `NetworkManager.yaml` + - `DestinationManager.yaml` + - `routing.yaml` ## Geo Model - Coordinate system: WGS84 latitude/longitude. @@ -34,7 +34,7 @@ routes: ## Apply Steps ```bash -cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml.bak +cp routing.yaml routing.yaml.bak # apply geospatial route patch and reload runtime ``` @@ -46,8 +46,8 @@ cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/d - Invalid GPS checks: - out-of-range latitude and longitude values route to invalid path. ```bash -python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh --source-topic /geo/in --near-topic /geo/out/near --far-topic /geo/out/far --invalid-topic /geo/out/invalid +python3 skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py +bash skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh --source-topic /geo/in --near-topic /geo/out/near --far-topic /geo/out/far --invalid-topic /geo/out/invalid ``` ## Risk Notes diff --git a/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md b/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md index 02939dd55..efdc0c5ca 100644 --- a/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md +++ b/skills/maps-geospatial-routing-builder/references/geospatial-patterns.md @@ -32,17 +32,17 @@ Skill smoke gate: ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh +bash skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh ``` Deterministic vector checks: ```bash -python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py +python3 skills/maps-geospatial-routing-builder/scripts/run_geospatial_vectors.py ``` Runtime geospatial route smoke: ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh --source-topic /geo/in --near-topic /geo/out/near --far-topic /geo/out/far --invalid-topic /geo/out/invalid +bash skills/maps-geospatial-routing-builder/scripts/run_geospatial_mqtt_smoke.sh --source-topic /geo/in --near-topic /geo/out/near --far-topic /geo/out/far --invalid-topic /geo/out/invalid ``` diff --git a/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh b/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh index c9fd3adb3..73f822d80 100755 --- a/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh +++ b/skills/maps-geospatial-routing-builder/scripts/run_geospatial_skill_smoke.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" python3 "${ROOT}/scripts/validate_geospatial_artifacts.py" diff --git a/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh b/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh index 6efc0fb77..712dc0075 100755 --- a/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh +++ b/skills/maps-geospatial-routing-builder/scripts/run_maps_geospatial_routing_builder_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-geospatial-routing-builder/scripts/validate_geospatial_artifacts.py b/skills/maps-geospatial-routing-builder/scripts/validate_geospatial_artifacts.py index c0dc6e1a5..ea1bee0e9 100755 --- a/skills/maps-geospatial-routing-builder/scripts/validate_geospatial_artifacts.py +++ b/skills/maps-geospatial-routing-builder/scripts/validate_geospatial_artifacts.py @@ -4,7 +4,7 @@ import re from pathlib import Path -ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder') +ROOT = Path(__file__).resolve().parents[1] CONTRACT = ROOT / 'references' / 'output-contract.md' EXAMPLES = [ ROOT / 'references' / 'examples' / 'simple-geospatial-output.md', @@ -54,8 +54,8 @@ def main() -> int: errors.append(f'{ex.name}: missing bash command block') if '```mermaid' not in txt: errors.append(f'{ex.name}: missing mermaid diagram block') - if '/Users/krital/dev/starsense/mapsmessaging_server' not in txt: - errors.append(f'{ex.name}: missing absolute path reference') + if 'skills/' not in txt: + errors.append(f'{ex.name}: missing repo-relative reference') if errors: print('geospatial artifact validation failed:') diff --git a/skills/maps-ml-model-lifecycle-playbook/SKILL.md b/skills/maps-ml-model-lifecycle-playbook/SKILL.md index 5fed798d4..338abd2a4 100644 --- a/skills/maps-ml-model-lifecycle-playbook/SKILL.md +++ b/skills/maps-ml-model-lifecycle-playbook/SKILL.md @@ -17,12 +17,12 @@ Provide clear, executable guidance for both model creation from streaming data a - hybrid lifecycle 2. Design lifecycle blueprint. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md`. +- Read `skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md`. - Build simple baseline first, then advanced staged variant when requested. - Keep model-store type explicit (`file`, `nexus`, `s3`, `maps`). 3. Map to deployable config. -- Primary ML stream config in `/Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml`. +- Primary ML stream config in `MLModelManager.yaml`. - Include destination/schema/routing changes when staged inference or quarantine flows are required. - Include external model artifact ingest mapping for portable formats only. @@ -32,13 +32,13 @@ Provide clear, executable guidance for both model creation from streaming data a - Validate retrain threshold semantics and rollback behavior. - Include stage-by-stage runtime verification commands. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh` + - `skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh` + - `skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh` + - `skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py` + - `skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh` 5. Return using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/output-contract.md`. +- Follow `skills/maps-ml-model-lifecycle-playbook/references/output-contract.md`. - Include simple baseline and advanced option(s) when requested. ## ML Lifecycle Rules @@ -72,8 +72,8 @@ Provide clear, executable guidance for both model creation from streaming data a ## Reference Loading Load only what is needed: -- Lifecycle patterns and constraints: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md` -- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/output-contract.md` +- Lifecycle patterns and constraints: `skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md` +- Final response format: `skills/maps-ml-model-lifecycle-playbook/references/output-contract.md` - Example artifacts: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md` + - `skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md` + - `skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md` diff --git a/skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md b/skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md index a68eeda1d..7371e5f00 100644 --- a/skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md +++ b/skills/maps-ml-model-lifecycle-playbook/references/examples/advanced-ml-lifecycle-output.md @@ -6,9 +6,9 @@ - stream-based retrain thresholds - staged inference pass-1 and pass-2 with intermediate destination - File targets: - - `/Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + - `MLModelManager.yaml` + - `DestinationManager.yaml` + - `routing.yaml` ## Lifecycle Shape - Simple baseline retained. @@ -49,7 +49,7 @@ MLModelManager: ## Apply Steps ```bash -cp /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml.bak +cp MLModelManager.yaml MLModelManager.yaml.bak # apply advanced lifecycle patch and restart runtime ``` @@ -61,8 +61,8 @@ cp /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml /Users/k - External-model negative check: - incompatible artifact should fail validation and fallback. ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh --source-topic /ml/in --stage1-topic /ml/intermediate --final-topic /ml/final --outlier-topic /ml/outlier +bash skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh +bash skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh --source-topic /ml/in --stage1-topic /ml/intermediate --final-topic /ml/final --outlier-topic /ml/outlier ``` ## Risk and Operational Notes diff --git a/skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md b/skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md index 1436c52c9..6284aed4d 100644 --- a/skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md +++ b/skills/maps-ml-model-lifecycle-playbook/references/examples/simple-ml-lifecycle-output.md @@ -4,8 +4,8 @@ - Stream-trained baseline with one selector stage and one output destination. - Optional external model artifact load for warm start. - File targets: - - `/Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` + - `MLModelManager.yaml` + - `DestinationManager.yaml` ## Lifecycle Shape - Simple baseline: @@ -20,7 +20,7 @@ - Artifact format: portable json/csv. - Smile 4.3.0 compatibility assumptions are explicitly required. - External model ingestion allowed from: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/references/examples/model-artifact-sample.json` + - `skills/maps-ml-model-lifecycle-playbook/references/examples/model-artifact-sample.json` ## Deployable Config Entity ```yaml @@ -28,7 +28,7 @@ MLModelManager: type: MLModelManagerConfigDTO modelStore: type: file - path: /Users/krital/dev/starsense/mapsmessaging_server/models + path: models eventStreams: - id: ml-simple-stage1 topicFilter: /ml/in @@ -44,7 +44,7 @@ MLModelManager: ## Apply Steps ```bash -cp /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml.bak +cp MLModelManager.yaml MLModelManager.yaml.bak # apply lifecycle patch and restart runtime ``` @@ -54,8 +54,8 @@ cp /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml /Users/k - External-model compatibility verification: - validate artifact metadata and portable format. ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh --source-topic /ml/in --stage1-topic /ml/stage1 --final-topic /ml/final --outlier-topic /ml/outlier +bash skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh +bash skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh --source-topic /ml/in --stage1-topic /ml/stage1 --final-topic /ml/final --outlier-topic /ml/outlier ``` ## Risk and Operational Notes diff --git a/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md b/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md index e3984336c..23e381160 100644 --- a/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md +++ b/skills/maps-ml-model-lifecycle-playbook/references/lifecycle-patterns.md @@ -34,17 +34,17 @@ Skill smoke gate: ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh +bash skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh ``` Vector checks (portable format + serialization constraints): ```bash -python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py +python3 skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py ``` Runtime staged ML smoke: ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh --source-topic /ml/in --stage1-topic /ml/stage1 --final-topic /ml/final --outlier-topic /ml/outlier +bash skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_mqtt_smoke.sh --source-topic /ml/in --stage1-topic /ml/stage1 --final-topic /ml/final --outlier-topic /ml/outlier ``` diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh index b6eff7d11..a6cf8360c 100755 --- a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh index 979f020d7..3f33a6f85 100755 --- a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_skill_smoke.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" python3 "${ROOT}/scripts/validate_ml_lifecycle_artifacts.py" diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py index aeec355b1..fd0a3d89f 100755 --- a/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/run_ml_lifecycle_vectors.py @@ -5,7 +5,7 @@ ALLOWED_EXTS = {'.json', '.csv'} BANNED_EXTS = {'.ser', '.bin', '.obj'} -ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server') +ROOT = Path(__file__).resolve().parents[3] def check_portable_extensions() -> list[str]: diff --git a/skills/maps-ml-model-lifecycle-playbook/scripts/validate_ml_lifecycle_artifacts.py b/skills/maps-ml-model-lifecycle-playbook/scripts/validate_ml_lifecycle_artifacts.py index 887f92972..ddcf90d3c 100755 --- a/skills/maps-ml-model-lifecycle-playbook/scripts/validate_ml_lifecycle_artifacts.py +++ b/skills/maps-ml-model-lifecycle-playbook/scripts/validate_ml_lifecycle_artifacts.py @@ -4,7 +4,7 @@ import re from pathlib import Path -ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook') +ROOT = Path(__file__).resolve().parents[1] CONTRACT = ROOT / 'references' / 'output-contract.md' EXAMPLES = [ ROOT / 'references' / 'examples' / 'simple-ml-lifecycle-output.md', @@ -53,8 +53,8 @@ def main() -> int: errors.append(f'{ex.name}: missing bash command block') if '```mermaid' not in txt: errors.append(f'{ex.name}: missing mermaid diagram block') - if '/Users/krital/dev/starsense/mapsmessaging_server' not in txt: - errors.append(f'{ex.name}: missing absolute path reference') + if 'skills/' not in txt: + errors.append(f'{ex.name}: missing repo-relative reference') if errors: print('ml lifecycle artifact validation failed:') diff --git a/skills/maps-ml-stream-configurator/SKILL.md b/skills/maps-ml-stream-configurator/SKILL.md index a8ca266a2..d2472ba23 100644 --- a/skills/maps-ml-stream-configurator/SKILL.md +++ b/skills/maps-ml-stream-configurator/SKILL.md @@ -16,10 +16,10 @@ Design ML-enabled MAPS stream pipelines that stay understandable: one simple bas 2. Build pipeline shape in two layers. - Layer A (simple): one model selector on one stream, one output topic. - Layer B (advanced): staged passes using intermediate MAPS destinations with one model per pass. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md`. +- Read `skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md`. 3. Map to deployable config. -- Primary file: `/Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml`. +- Primary file: `MLModelManager.yaml`. - Link to destination/schema config when intermediate stages or schema checks are required. - Keep model-store type explicit (`file`, `nexus`, `s3`, `maps`) and include required config block details. @@ -27,15 +27,15 @@ Design ML-enabled MAPS stream pipelines that stay understandable: one simple bas - Ensure each event stream has `id`, `topicFilter`, `schemaId`, `selector`, and output topic. - Validate multi-pass chains have clear stage boundaries and deterministic topic handoff. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh` + - `skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh` + - `skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh` - Include static checks: ```bash -rg -n "MLModelManager|eventStreams|selector|topicFilter|schemaId|outlierTopic|maxTrainEvents|retrainThreshold|modelStore" /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml +rg -n "MLModelManager|eventStreams|selector|topicFilter|schemaId|outlierTopic|maxTrainEvents|retrainThreshold|modelStore" MLModelManager.yaml ``` 5. Return with output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/references/output-contract.md`. +- Follow `skills/maps-ml-stream-configurator/references/output-contract.md`. - Include simple baseline and advanced option when requested. ## ML-Specific Rules @@ -71,5 +71,5 @@ rg -n "MLModelManager|eventStreams|selector|topicFilter|schemaId|outlierTopic|ma ## Reference Loading Load only what is needed: -- Pipeline patterns and simplification guidance: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md` -- Final response structure: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/references/output-contract.md` +- Pipeline patterns and simplification guidance: `skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md` +- Final response structure: `skills/maps-ml-stream-configurator/references/output-contract.md` diff --git a/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md b/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md index 1eef1a6f8..273d76392 100644 --- a/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md +++ b/skills/maps-ml-stream-configurator/references/ml-pipeline-patterns.md @@ -39,8 +39,8 @@ Guidance: ## Validation Checklist ```bash -rg -n "eventStreams|selector|topicFilter|outlierTopic|schemaId|retrainThreshold" /Users/krital/dev/starsense/mapsmessaging_server/MLModelManager.yaml -rg -n "namespace: |namespaceMapping:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +rg -n "eventStreams|selector|topicFilter|outlierTopic|schemaId|retrainThreshold" MLModelManager.yaml +rg -n "namespace: |namespaceMapping:" DestinationManager.yaml ``` ## Failure Classes diff --git a/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh index e917159fa..862122082 100755 --- a/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh +++ b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh index ff4f97920..d37693e21 100755 --- a/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh +++ b/skills/maps-ml-stream-configurator/scripts/run_maps_ml_stream_configurator_skill_smoke.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" diff --git a/skills/maps-protocol-bridge-tester/SKILL.md b/skills/maps-protocol-bridge-tester/SKILL.md index f70e30833..ab893bd76 100644 --- a/skills/maps-protocol-bridge-tester/SKILL.md +++ b/skills/maps-protocol-bridge-tester/SKILL.md @@ -15,21 +15,21 @@ Create deterministic bridge tests for MAPS protocol flows and verify end-to-end 2. Validate runtime readiness first. - Confirm listener binds and provider availability before generating traffic. -- Use `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md` startup checks. +- Use `skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md` startup checks. 3. Execute layered tests. - Layer 1: source ingress test (producer -> source listener). - Layer 2: destination egress visibility test (consumer on destination side). - Layer 3: full bridge test with correlation marker in payload. - For executable runtime smoke, use: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh` + - `skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh` 4. Evaluate with strict pass/fail markers. - Pass only when destination receives expected payload on mapped namespace within timeout. - Separate failures into ingress, routing, transform, or egress categories. 5. Return using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/references/output-contract.md`. +- Follow `skills/maps-protocol-bridge-tester/references/output-contract.md`. - Include exact commands, expected outputs, and remediation path for each failed layer. ## Rules @@ -63,5 +63,5 @@ Create deterministic bridge tests for MAPS protocol flows and verify end-to-end ## Reference Loading Load only what is needed: -- Test patterns and commands: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md` -- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/references/output-contract.md` +- Test patterns and commands: `skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md` +- Final response format: `skills/maps-protocol-bridge-tester/references/output-contract.md` diff --git a/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md b/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md index 474a194e2..df53ba00b 100644 --- a/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md +++ b/skills/maps-protocol-bridge-tester/references/bridge-test-catalog.md @@ -11,8 +11,8 @@ docker exec sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null 2. Namespace mapping and routing present in config. ```bash -rg -n "namespace: |namespaceMapping:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml -rg -n "predefinedServers|enabled|autoDiscovery" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +rg -n "namespace: |namespaceMapping:" DestinationManager.yaml +rg -n "predefinedServers|enabled|autoDiscovery" routing.yaml ``` ## Core Test Patterns diff --git a/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh index efcf56df3..0c8c18672 100755 --- a/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh +++ b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_skill_smoke.sh b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_skill_smoke.sh index 9cbb4504b..6b4ae448c 100755 --- a/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_skill_smoke.sh +++ b/skills/maps-protocol-bridge-tester/scripts/run_maps_protocol_bridge_tester_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null diff --git a/skills/maps-release-readiness-checker/SKILL.md b/skills/maps-release-readiness-checker/SKILL.md index d91774ad0..854522001 100644 --- a/skills/maps-release-readiness-checker/SKILL.md +++ b/skills/maps-release-readiness-checker/SKILL.md @@ -26,8 +26,8 @@ Run a structured release gate review and return a defensible release decision wi - Check startup abort blockers (license, Consul/config gating, provider availability). - Check listener binds and core protocol availability. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh` + - `skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh` + - `skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh` 5. Execute feature-specific operational gates. - Run checks for configured unique features (aggregator, satellite, schema/transform, CAN, etc.) based on release scope. @@ -38,7 +38,7 @@ Run a structured release gate review and return a defensible release decision wi - Confirm rollback procedure is present and minimal. 7. Return readiness decision. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/references/output-contract.md`. +- Follow `skills/maps-release-readiness-checker/references/output-contract.md`. - Provide PASS, CONDITIONAL PASS, or FAIL with blocking/non-blocking findings. ## Rules @@ -72,5 +72,5 @@ Run a structured release gate review and return a defensible release decision wi ## Reference Loading Load only what is needed: -- Gate catalog and commands: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/references/release-gate-catalog.md` -- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/references/output-contract.md` +- Gate catalog and commands: `skills/maps-release-readiness-checker/references/release-gate-catalog.md` +- Final response format: `skills/maps-release-readiness-checker/references/output-contract.md` diff --git a/skills/maps-release-readiness-checker/references/release-gate-catalog.md b/skills/maps-release-readiness-checker/references/release-gate-catalog.md index 52d432d15..efb68d528 100644 --- a/skills/maps-release-readiness-checker/references/release-gate-catalog.md +++ b/skills/maps-release-readiness-checker/references/release-gate-catalog.md @@ -4,7 +4,7 @@ Core checks: ```bash -cd /Users/krital/dev/starsense/mapsmessaging_server +cd ./build.sh ``` diff --git a/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh index a6e1084b9..3c94cb2f7 100755 --- a/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh +++ b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh index fcbd66836..117406a61 100755 --- a/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh +++ b/skills/maps-release-readiness-checker/scripts/run_maps_release_readiness_checker_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then diff --git a/skills/maps-runtime-diagnostics/SKILL.md b/skills/maps-runtime-diagnostics/SKILL.md index 9af8db11e..118482986 100644 --- a/skills/maps-runtime-diagnostics/SKILL.md +++ b/skills/maps-runtime-diagnostics/SKILL.md @@ -15,7 +15,7 @@ Diagnose MAPS instance health from startup to protocol smoke tests. Produce acti - Record the precise failing operation and timestamp. 2. Run startup-gate checks first. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md`. +- Follow `skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md`. - Detect hard blockers: license validation, Consul bootstrap abort, missing protocol providers, malformed YAML. - Detect bind blockers: address in use, unsupported endpoint transport, invalid URL scheme. @@ -28,11 +28,11 @@ Diagnose MAPS instance health from startup to protocol smoke tests. Produce acti - Run producer/consumer checks only after startup gates are clean. - For cross-protocol paths, test ingress and egress independently before end-to-end routing. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh` + - `skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh` + - `skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh` 5. Return diagnostics using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/references/output-contract.md`. +- Follow `skills/maps-runtime-diagnostics/references/output-contract.md`. - Include root cause, evidence commands, exact remediation, and post-fix verification. ## Diagnostic Rules @@ -67,5 +67,5 @@ Diagnose MAPS instance health from startup to protocol smoke tests. Produce acti ## Reference Loading Load only what is needed: -- Startup and bind triage: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md` -- Final response shape: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/references/output-contract.md` +- Startup and bind triage: `skills/maps-runtime-diagnostics/references/startup-gates-and-bind-checks.md` +- Final response shape: `skills/maps-runtime-diagnostics/references/output-contract.md` diff --git a/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh index 2900f8b15..7658dea3b 100755 --- a/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh +++ b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh index ab5252eec..ca632078e 100755 --- a/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh +++ b/skills/maps-runtime-diagnostics/scripts/run_maps_runtime_diagnostics_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" if [[ "${RUN_RUNTIME_SMOKE:-0}" == "1" ]]; then diff --git a/skills/maps-satellite-gateway-config/SKILL.md b/skills/maps-satellite-gateway-config/SKILL.md index 09b766ba1..4ab56fbda 100644 --- a/skills/maps-satellite-gateway-config/SKILL.md +++ b/skills/maps-satellite-gateway-config/SKILL.md @@ -15,14 +15,14 @@ Generate Iridium-like pub-sub service patterns using MAPS satellite capabilities - Capture encoding mode. If encoding is CBC, enable SIN/MIN hierarchy routing policy. 2. Build protocol option matrix. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md`. +- Read `skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md`. - Produce at least 2 viable pattern variants when user asks for "more choices". - For each variant, specify source and destination protocol path, mapping namespace, and operational tradeoffs. 3. Map selected variant to MAPS config surfaces. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/satellite-config-map.md`. -- Update `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` satellite endpoint and protocol blocks. -- Update `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` and `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` only when required by chosen pattern. +- Read `skills/maps-satellite-gateway-config/references/satellite-config-map.md`. +- Update `NetworkManager.yaml` satellite endpoint and protocol blocks. +- Update `DestinationManager.yaml` and `routing.yaml` only when required by chosen pattern. 4. Build deployable entities. - Prefer minimal diffs. @@ -32,16 +32,16 @@ Generate Iridium-like pub-sub service patterns using MAPS satellite capabilities 5. Validate before finalizing. - Confirm provider-profile assumptions, poll cadence bounds, and protocol listener compatibility. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh` + - `skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh` + - `skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh` - Include startup/provider checks: ```bash -rg -n "type: satellite|satellite://|Inmarsat|Orbcomm|Viasat" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "type: satellite|satellite://|Inmarsat|Orbcomm|Viasat" NetworkManager.yaml docker logs 2>&1 | rg -n "satellite|OGWS|Inmarsat|Viasat|Protocol not available|Startup aborted" ``` 6. Return with output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/output-contract.md`. +- Follow `skills/maps-satellite-gateway-config/references/output-contract.md`. - Include pattern matrix, selected profile, deployable YAML, diagnostics, and verification. ## Satellite-Specific Rules @@ -79,6 +79,6 @@ docker logs 2>&1 | rg -n "satellite|OGWS|Inmarsat|Viasat|Protocol no ## Reference Loading Load only what is needed: -- Service-pattern variants: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md` -- Config mapping and diagnostics: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/satellite-config-map.md` -- Output format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/references/output-contract.md` +- Service-pattern variants: `skills/maps-satellite-gateway-config/references/satellite-pubsub-patterns.md` +- Config mapping and diagnostics: `skills/maps-satellite-gateway-config/references/satellite-config-map.md` +- Output format: `skills/maps-satellite-gateway-config/references/output-contract.md` diff --git a/skills/maps-satellite-gateway-config/references/satellite-config-map.md b/skills/maps-satellite-gateway-config/references/satellite-config-map.md index 6138fc6ae..81434cac9 100644 --- a/skills/maps-satellite-gateway-config/references/satellite-config-map.md +++ b/skills/maps-satellite-gateway-config/references/satellite-config-map.md @@ -2,13 +2,13 @@ ## Primary Surface -- `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +- `NetworkManager.yaml` - satellite endpoint entries under `endPointServerConfigList[]` - protocol block `protocolConfigs[].type: satellite` Secondary surfaces for pub-sub pattern realization: -- `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` -- `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` +- `DestinationManager.yaml` +- `routing.yaml` ## Provider Profiles @@ -51,10 +51,10 @@ For non-CBC or unsupported payload encodings: ## Validation Commands ```bash -rg -n "type: satellite|satellite://|Orbcomm|Viasat|Inmarsat" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "type: mqtt|type: mqtt-sn|type: amqp|type: stomp|type: nats|type: coap|type: ws" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "namespace: |namespaceMapping:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml -rg -n "\\{sin\\}|\\{min\\}|common/in" /Users/krital/dev/starsense/mapsmessaging_server/src/main/java/io/mapsmessaging/network/protocol/impl/satellite +rg -n "type: satellite|satellite://|Orbcomm|Viasat|Inmarsat" NetworkManager.yaml +rg -n "type: mqtt|type: mqtt-sn|type: amqp|type: stomp|type: nats|type: coap|type: ws" NetworkManager.yaml +rg -n "namespace: |namespaceMapping:" DestinationManager.yaml +rg -n "\\{sin\\}|\\{min\\}|common/in" src/main/java/io/mapsmessaging/network/protocol/impl/satellite ``` ## Failure Classes diff --git a/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh index 3178e38cb..543347a39 100755 --- a/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh +++ b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh index a3059166b..844949936 100755 --- a/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh +++ b/skills/maps-satellite-gateway-config/scripts/run_maps_satellite_gateway_config_skill_smoke.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" diff --git a/skills/maps-scenario-composer/SKILL.md b/skills/maps-scenario-composer/SKILL.md index 56f76031c..04f30cb41 100644 --- a/skills/maps-scenario-composer/SKILL.md +++ b/skills/maps-scenario-composer/SKILL.md @@ -15,7 +15,7 @@ Compose multi-skill scenario outputs into one deployable, testable, and conflict - Identify conflicts (port reuse, topic collisions, incompatible auth/storage assumptions, duplicate routes). 2. Build composition plan. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/references/composition-patterns.md`. +- Read `skills/maps-scenario-composer/references/composition-patterns.md`. - Define per-skill scenario slices and merge strategy. - Decide composition mode: - additive (independent scenarios merged) @@ -39,11 +39,11 @@ Compose multi-skill scenario outputs into one deployable, testable, and conflict - One integrated startup/listener verification sequence. - One integrated runtime smoke and cross-scenario verification sequence. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh` + - `skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh` + - `skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh` 5. Return using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/references/output-contract.md`. +- Follow `skills/maps-scenario-composer/references/output-contract.md`. - Include composition matrix, merged deployable entity, and consolidated verification. ## Rules @@ -76,6 +76,6 @@ Compose multi-skill scenario outputs into one deployable, testable, and conflict ## Reference Loading Load only what is needed: -- Composition design patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/references/composition-patterns.md` -- Final response structure: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/references/output-contract.md` -- Optional generator script: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/scripts/compose_scenarios.py` +- Composition design patterns: `skills/maps-scenario-composer/references/composition-patterns.md` +- Final response structure: `skills/maps-scenario-composer/references/output-contract.md` +- Optional generator script: `skills/maps-scenario-composer/scripts/compose_scenarios.py` diff --git a/skills/maps-scenario-composer/references/composition-patterns.md b/skills/maps-scenario-composer/references/composition-patterns.md index 60f19b56a..03086911f 100644 --- a/skills/maps-scenario-composer/references/composition-patterns.md +++ b/skills/maps-scenario-composer/references/composition-patterns.md @@ -45,11 +45,11 @@ Resolve in this order: Generate a unified deliverable with concrete merged YAML: ```bash -python3 /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/scripts/compose_scenarios.py \ +python3 skills/maps-scenario-composer/scripts/compose_scenarios.py \ --skills maps-deployment-packager,maps-selector-rule-engineer,maps-geospatial-routing-builder \ --mode hybrid \ --conflict-policy override \ - --artifact maps-selector-rule-engineer=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md \ - --artifact maps-geospatial-routing-builder=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md \ + --artifact maps-selector-rule-engineer=skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md \ + --artifact maps-geospatial-routing-builder=skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md \ --out-dir /tmp/maps-composed ``` diff --git a/skills/maps-scenario-composer/references/examples/composed-deliverable-example.md b/skills/maps-scenario-composer/references/examples/composed-deliverable-example.md index 8010e31f3..f060e1014 100644 --- a/skills/maps-scenario-composer/references/examples/composed-deliverable-example.md +++ b/skills/maps-scenario-composer/references/examples/composed-deliverable-example.md @@ -33,9 +33,9 @@ mergedArtifacts: - per-slice failure map with merged rollback steps. ## Traceability Map -- merged section -> `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/SKILL.md` -- merged section -> `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/SKILL.md` -- merged section -> `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/SKILL.md` +- merged section -> `skills/maps-deployment-packager/SKILL.md` +- merged section -> `skills/maps-selector-rule-engineer/SKILL.md` +- merged section -> `skills/maps-geospatial-routing-builder/SKILL.md` ## Scenario Metrics and Dashboard - combined metrics and cross-scenario health pane. diff --git a/skills/maps-scenario-composer/scripts/compose_scenarios.py b/skills/maps-scenario-composer/scripts/compose_scenarios.py index 6e726c0ae..f4a1233c5 100755 --- a/skills/maps-scenario-composer/scripts/compose_scenarios.py +++ b/skills/maps-scenario-composer/scripts/compose_scenarios.py @@ -9,7 +9,7 @@ import yaml -ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server') +ROOT = Path(__file__).resolve().parents[3] SKILLS_ROOT = ROOT / 'skills' MANAGER_FILE_MAP = { diff --git a/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh b/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh index c2727b6c0..2bc310b6e 100755 --- a/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh +++ b/skills/maps-scenario-composer/scripts/run_maps_scenario_composer_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh b/skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh index 88c4cd0fd..e0cb6cd38 100755 --- a/skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh +++ b/skills/maps-scenario-composer/scripts/run_scenario_composer_skill_smoke.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" OUT="/tmp/maps-scenario-composer.out" MERGED_DIR="/tmp/maps-scenario-composer-merged" TMP_A="/tmp/maps-scenario-composer-a.yaml" @@ -14,9 +15,9 @@ python3 "${VALIDATOR}" "${ROOT}" python3 "${ROOT}/scripts/compose_scenarios.py" \ --skills maps-deployment-packager,maps-selector-rule-engineer,maps-geospatial-routing-builder \ --mode hybrid \ - --artifact maps-deployment-packager=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/references/output-contract.md \ - --artifact maps-selector-rule-engineer=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md \ - --artifact maps-geospatial-routing-builder=/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md \ + --artifact maps-deployment-packager=skills/maps-deployment-packager/references/output-contract.md \ + --artifact maps-selector-rule-engineer=skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md \ + --artifact maps-geospatial-routing-builder=skills/maps-geospatial-routing-builder/references/examples/simple-geospatial-output.md \ --conflict-policy override \ --out-dir "${MERGED_DIR}" >"${OUT}" rg -n "Composition Matrix|Unified Assumptions|Merged Deployable Entity|Unified Apply Sequence|Integrated Verification|Traceability Map|Conflict Resolution Log|Scenario Metrics and Dashboard|C4 Architecture Diagram" "${OUT}" >/dev/null diff --git a/skills/maps-schema-pipeline-builder/SKILL.md b/skills/maps-schema-pipeline-builder/SKILL.md index eabb97a70..bd2418361 100644 --- a/skills/maps-schema-pipeline-builder/SKILL.md +++ b/skills/maps-schema-pipeline-builder/SKILL.md @@ -14,11 +14,11 @@ Translate schema and format requirements into deployable MAPS configuration enti - Resolve missing details only when schema behavior would change. 2. Map contract to configuration surfaces. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md`. +- Read `skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md`. - Map schema-aware message behavior to: - - `/Users/krital/dev/starsense/mapsmessaging_server/SchemaManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` + - `SchemaManager.yaml` + - `DestinationManager.yaml` + - `NetworkManager.yaml` - If required, include relevant transformation manager config paths. 3. Build deployable entities. @@ -30,13 +30,13 @@ Translate schema and format requirements into deployable MAPS configuration enti - Check key fields and linkage consistency (`schemaId`, `contentType`, namespace mapping). - Run targeted checks: ```bash -rg -n "schemaId|contentType|messageOverride|qualityOfService" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml -rg -n "SchemaManager|schema|type:" /Users/krital/dev/starsense/mapsmessaging_server/SchemaManager.yaml -rg -n "protocolConfigs|messageDefaults|contentType" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +rg -n "schemaId|contentType|messageOverride|qualityOfService" DestinationManager.yaml +rg -n "SchemaManager|schema|type:" SchemaManager.yaml +rg -n "protocolConfigs|messageDefaults|contentType" NetworkManager.yaml ``` 5. Return output using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/references/output-contract.md`. +- Follow `skills/maps-schema-pipeline-builder/references/output-contract.md`. - Always include assumptions, deployable YAML, apply steps, and validation commands. ## Rules @@ -70,5 +70,5 @@ rg -n "protocolConfigs|messageDefaults|contentType" /Users/krital/dev/starsense/ ## Reference Loading Load only what is needed: -- Schema mapping details: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md` -- Response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/references/output-contract.md` +- Schema mapping details: `skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md` +- Response format: `skills/maps-schema-pipeline-builder/references/output-contract.md` diff --git a/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md b/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md index 61fa1bb4c..432098fb2 100644 --- a/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md +++ b/skills/maps-schema-pipeline-builder/references/schema-mapping-guide.md @@ -14,11 +14,11 @@ Supported payload families in MAPS context: ## Configuration Surfaces -- `/Users/krital/dev/starsense/mapsmessaging_server/SchemaManager.yaml` +- `SchemaManager.yaml` - schema catalog and registration behavior. -- `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` +- `DestinationManager.yaml` - namespace-level message overrides (`schemaId`, `contentType`, QoS, retain). -- `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +- `NetworkManager.yaml` - protocol-level message defaults and content-type baselines. ## Mapping Patterns @@ -42,9 +42,9 @@ Supported payload families in MAPS context: ## Validation Checklist ```bash -rg -n "schemaId:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml -rg -n "contentType:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "schema|Schema" /Users/krital/dev/starsense/mapsmessaging_server/SchemaManager.yaml +rg -n "schemaId:" DestinationManager.yaml +rg -n "contentType:" DestinationManager.yaml NetworkManager.yaml +rg -n "schema|Schema" SchemaManager.yaml ``` ## Common Failure Classes diff --git a/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh index b81c2fe48..5e6dac373 100755 --- a/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh +++ b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_skill_smoke.sh b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_skill_smoke.sh index a4fa1d24b..48d611b35 100755 --- a/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_skill_smoke.sh +++ b/skills/maps-schema-pipeline-builder/scripts/run_maps_schema_pipeline_builder_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null diff --git a/skills/maps-selector-rule-engineer/SKILL.md b/skills/maps-selector-rule-engineer/SKILL.md index 6a8a31ed8..2a082769c 100644 --- a/skills/maps-selector-rule-engineer/SKILL.md +++ b/skills/maps-selector-rule-engineer/SKILL.md @@ -14,7 +14,7 @@ Build clear, testable selector configurations for routing and subscriptions, fro - Identify whether selectors apply at routing layer, subscription layer, or both. 2. Build selector design. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/selector-patterns.md`. +- Read `skills/maps-selector-rule-engineer/references/selector-patterns.md`. - Create explicit selector evaluation order. - Define conflict policy (first-match, priority-based, or layered pass). @@ -27,12 +27,12 @@ Build clear, testable selector configurations for routing and subscriptions, fro - Verify no contradictory selector overlap unless intentionally prioritized. - Include runtime verification commands with correlation payload markers. - Prefer bundled scripts for repeatable validation: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh` + - `skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh` + - `skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh` + - `skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh` 5. Return using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/output-contract.md`. +- Follow `skills/maps-selector-rule-engineer/references/output-contract.md`. - Include selector matrix, deployable config, apply steps, and verification. ## Rules @@ -64,8 +64,8 @@ Build clear, testable selector configurations for routing and subscriptions, fro ## Reference Loading Load only what is needed: -- Selector design patterns: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/selector-patterns.md` -- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/output-contract.md` +- Selector design patterns: `skills/maps-selector-rule-engineer/references/selector-patterns.md` +- Final response format: `skills/maps-selector-rule-engineer/references/output-contract.md` - Example artifacts: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md` - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md` + - `skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md` + - `skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md` diff --git a/skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md b/skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md index ccc4c2030..3ba633b01 100644 --- a/skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md +++ b/skills/maps-selector-rule-engineer/references/examples/advanced-selector-output.md @@ -4,9 +4,9 @@ - Stage 1 route by `vehicleType` to intermediate topics. - Stage 2 subscriber selectors split high-priority alerts and normal events. - File targets: - - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + - `NetworkManager.yaml` + - `DestinationManager.yaml` + - `routing.yaml` ## Selector Evaluation Model - Routing selector order: @@ -39,7 +39,7 @@ routes: ## Apply Steps ```bash -cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml.bak +cp routing.yaml routing.yaml.bak # apply staged selector patch and restart runtime ``` @@ -51,7 +51,7 @@ cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/d - `{ "vehicleType":"other", "priority":9 }` should not appear in emergency-only subscriber stream. - `{ "vehicleType":"public", "priority":2 }` should not appear in high-priority stream. ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh --source-topic /selector/in --match-topic /selector/final/high --nonmatch-topic /selector/final/normal +bash skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh --source-topic /selector/in --match-topic /selector/final/high --nonmatch-topic /selector/final/normal ``` ## Performance and Risk Notes diff --git a/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md b/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md index 09e005638..67eb64c8f 100644 --- a/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md +++ b/skills/maps-selector-rule-engineer/references/examples/simple-selector-output.md @@ -3,9 +3,9 @@ ## Selector Requirement Mapping - Route `priority >= 5` messages to `/selector/match` and others to `/selector/nonmatch`. - File targets: - - `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` - - `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` + - `NetworkManager.yaml` + - `DestinationManager.yaml` + - `routing.yaml` ## Selector Evaluation Model - Routing selector order: @@ -34,7 +34,7 @@ routes: ## Apply Steps ```bash -cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml.bak +cp routing.yaml routing.yaml.bak # apply selector route patch ``` @@ -44,7 +44,7 @@ cp /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml /Users/krital/d - Negative vector: - payload: `{ "priority": 1 }` should route to `/selector/nonmatch`. ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh --source-topic /selector/in --match-topic /selector/match --nonmatch-topic /selector/nonmatch +bash skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh --source-topic /selector/in --match-topic /selector/match --nonmatch-topic /selector/nonmatch ``` ## Performance and Risk Notes diff --git a/skills/maps-selector-rule-engineer/references/selector-patterns.md b/skills/maps-selector-rule-engineer/references/selector-patterns.md index cfe1015a7..a89048194 100644 --- a/skills/maps-selector-rule-engineer/references/selector-patterns.md +++ b/skills/maps-selector-rule-engineer/references/selector-patterns.md @@ -34,11 +34,11 @@ Skill smoke gate: ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh +bash skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh ``` Runtime selector smoke (subscribe before publish): ```bash -bash /Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh --source-topic /selector/in --match-topic /selector/match --nonmatch-topic /selector/nonmatch +bash skills/maps-selector-rule-engineer/scripts/run_selector_mqtt_smoke.sh --source-topic /selector/in --match-topic /selector/match --nonmatch-topic /selector/nonmatch ``` diff --git a/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh b/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh index f63d79910..6bd675f94 100755 --- a/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh +++ b/skills/maps-selector-rule-engineer/scripts/run_maps_selector_rule_engineer_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh b/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh index 04e2214eb..49570fd11 100755 --- a/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh +++ b/skills/maps-selector-rule-engineer/scripts/run_selector_skill_smoke.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" python3 "${ROOT}/scripts/validate_selector_artifacts.py" diff --git a/skills/maps-selector-rule-engineer/scripts/validate_selector_artifacts.py b/skills/maps-selector-rule-engineer/scripts/validate_selector_artifacts.py index f0be21e59..ac2a4ebaa 100755 --- a/skills/maps-selector-rule-engineer/scripts/validate_selector_artifacts.py +++ b/skills/maps-selector-rule-engineer/scripts/validate_selector_artifacts.py @@ -5,7 +5,7 @@ import sys from pathlib import Path -ROOT = Path('/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer') +ROOT = Path(__file__).resolve().parents[1] CONTRACT = ROOT / 'references' / 'output-contract.md' EXAMPLES = [ ROOT / 'references' / 'examples' / 'simple-selector-output.md', @@ -55,8 +55,8 @@ def main() -> int: errors.append(f'{ex.name}: missing bash command block') if '```mermaid' not in txt: errors.append(f'{ex.name}: missing mermaid diagram block') - if '/Users/krital/dev/starsense/mapsmessaging_server' not in txt: - errors.append(f'{ex.name}: missing absolute path reference') + if 'skills/' not in txt: + errors.append(f'{ex.name}: missing repo-relative reference') if errors: print('selector artifact validation failed:') diff --git a/skills/maps-skill-suite-orchestrator/SKILL.md b/skills/maps-skill-suite-orchestrator/SKILL.md index 9f2d768c9..9dc11d404 100644 --- a/skills/maps-skill-suite-orchestrator/SKILL.md +++ b/skills/maps-skill-suite-orchestrator/SKILL.md @@ -17,68 +17,68 @@ Use this as the entrypoint index for all MAPS skills in this repository. 1. `mapsmessaging-config-builder` - Build deployable MAPS manager YAML from protocol, encoding, topology, schema, and routing intent. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/SKILL.md` +- Link: `skills/mapsmessaging-config-builder/SKILL.md` 2. `maps-runtime-diagnostics` - Diagnose startup/runtime failures, bind issues, provider/config blockers, and smoke-test failures. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-runtime-diagnostics/SKILL.md` +- Link: `skills/maps-runtime-diagnostics/SKILL.md` 3. `maps-protocol-bridge-tester` - Design and run layered ingress/egress/end-to-end bridge tests with strict pass/fail markers. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-protocol-bridge-tester/SKILL.md` +- Link: `skills/maps-protocol-bridge-tester/SKILL.md` 4. `maps-satellite-gateway-config` - Generate satellite pub/sub patterns using Orbcomm or Viasat with broad protocol fan-out and CBC SIN/MIN routing. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-satellite-gateway-config/SKILL.md` +- Link: `skills/maps-satellite-gateway-config/SKILL.md` 5. `maps-schema-pipeline-builder` - Build schema-aware pipelines across JSON/Protobuf/Avro/CSV/raw with schemaId/contentType mapping. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-schema-pipeline-builder/SKILL.md` +- Link: `skills/maps-schema-pipeline-builder/SKILL.md` 6. `maps-transform-chain-designer` - Design deterministic ordered transform chains (CloudEvent, mutate, convert, enrich). -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/SKILL.md` +- Link: `skills/maps-transform-chain-designer/SKILL.md` 7. `maps-aggregator-config-engineer` - Configure unique MAPS windowed aggregation behavior and validate window/timeout/fairness semantics. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-aggregator-config-engineer/SKILL.md` +- Link: `skills/maps-aggregator-config-engineer/SKILL.md` 8. `maps-canbus-ingestion-builder` - Build CAN/N2K ingestion profiles for `vcan` and native interfaces with deterministic topic mapping. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-canbus-ingestion-builder/SKILL.md` +- Link: `skills/maps-canbus-ingestion-builder/SKILL.md` 9. `maps-deployment-packager` - Package deployables for local, Docker, Kubernetes-style bundles, Fly.io, AWS, GCP, and Azure. - Includes auth, storage, file-vs-Consul mode, Fly KV options, optional Consul (HCP/self-managed), and object storage (S3/R2). -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-deployment-packager/SKILL.md` +- Link: `skills/maps-deployment-packager/SKILL.md` 10. `maps-release-readiness-checker` - Run evidence-based release gates with Docker image availability and smoke checks. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-release-readiness-checker/SKILL.md` +- Link: `skills/maps-release-readiness-checker/SKILL.md` 11. `maps-ml-stream-configurator` - Build simple-to-advanced ML selector stream pipelines with staged intermediate destinations and model chaining. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-stream-configurator/SKILL.md` +- Link: `skills/maps-ml-stream-configurator/SKILL.md` 12. `maps-artifact-execution-smoke-harness` - Execute generated artifacts end-to-end and return startup, listener, and traffic smoke evidence. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/SKILL.md` +- Link: `skills/maps-artifact-execution-smoke-harness/SKILL.md` 13. `maps-selector-rule-engineer` - Design selector logic for routing rules and subscriber selectors with deterministic precedence and verification. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-selector-rule-engineer/SKILL.md` +- Link: `skills/maps-selector-rule-engineer/SKILL.md` 14. `maps-geospatial-routing-builder` - Build geohash and GPS/distance-driven routing behavior with deployable config and geospatial validation. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-geospatial-routing-builder/SKILL.md` +- Link: `skills/maps-geospatial-routing-builder/SKILL.md` 15. `maps-ml-model-lifecycle-playbook` - Provide MAPS-native model lifecycle guidance from stream training to external model ingestion for inference. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-ml-model-lifecycle-playbook/SKILL.md` +- Link: `skills/maps-ml-model-lifecycle-playbook/SKILL.md` 16. `maps-scenario-composer` - Combine scenarios from multiple skills into one merged deployable with unified apply and integrated verification. -- Link: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-scenario-composer/SKILL.md` +- Link: `skills/maps-scenario-composer/SKILL.md` ## Selection Guide @@ -200,13 +200,13 @@ Every skill output should include: ## Validation Scripts -- `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh` -- `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh` +- `skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh` +- `skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh` ## Reference Loading Read only required skill files: -- `/Users/krital/dev/starsense/mapsmessaging_server/skills//SKILL.md` +- `skills//SKILL.md` Load reference docs only for the selected target skill and scenario mode. diff --git a/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh index 0317367e5..024c75bd6 100755 --- a/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh +++ b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh index b6574c61f..5937cf700 100755 --- a/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh +++ b/skills/maps-skill-suite-orchestrator/scripts/run_maps_skill_suite_orchestrator_skill_smoke.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-skill-suite-orchestrator" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" rg -n "maps-scenario-composer|Quick Start Template|Advanced Template|Multi-Skill Unified Deliverable" "${ROOT}/SKILL.md" >/dev/null diff --git a/skills/maps-transform-chain-designer/SKILL.md b/skills/maps-transform-chain-designer/SKILL.md index 88adb0f7b..1ff9049c4 100644 --- a/skills/maps-transform-chain-designer/SKILL.md +++ b/skills/maps-transform-chain-designer/SKILL.md @@ -14,7 +14,7 @@ Translate transformation requirements into ordered, deterministic MAPS configura - Resolve ambiguity only when ordering or output format would differ. 2. Design ordered chain. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/references/transform-chain-patterns.md`. +- Read `skills/maps-transform-chain-designer/references/transform-chain-patterns.md`. - Produce explicit stage order with input/output contentType at each step. - Enforce deterministic, non-throwing behavior. @@ -28,7 +28,7 @@ Translate transformation requirements into ordered, deterministic MAPS configura - Include static checks and runtime smoke checks. 5. Return using output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/references/output-contract.md`. +- Follow `skills/maps-transform-chain-designer/references/output-contract.md`. - Include ordered stages, deployable config, apply steps, and test commands. ## Rules @@ -62,5 +62,5 @@ Translate transformation requirements into ordered, deterministic MAPS configura ## Reference Loading Load only what is needed: -- Chain patterns and checks: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/references/transform-chain-patterns.md` -- Final response format: `/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer/references/output-contract.md` +- Chain patterns and checks: `skills/maps-transform-chain-designer/references/transform-chain-patterns.md` +- Final response format: `skills/maps-transform-chain-designer/references/output-contract.md` diff --git a/skills/maps-transform-chain-designer/references/transform-chain-patterns.md b/skills/maps-transform-chain-designer/references/transform-chain-patterns.md index 6904767a7..b9cb44dd2 100644 --- a/skills/maps-transform-chain-designer/references/transform-chain-patterns.md +++ b/skills/maps-transform-chain-designer/references/transform-chain-patterns.md @@ -38,8 +38,8 @@ If user mandates a different order, evaluate compatibility and flag impossible h ## Validation Commands ```bash -rg -n "contentType|schemaId|messageDefaults|messageOverride" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml -rg -n "transform|Transformation|CloudEvent|JSONToXML|XMLToJSON" /Users/krital/dev/starsense/mapsmessaging_server/src/main/java +rg -n "contentType|schemaId|messageDefaults|messageOverride" NetworkManager.yaml DestinationManager.yaml +rg -n "transform|Transformation|CloudEvent|JSONToXML|XMLToJSON" src/main/java ``` ## Failure Patterns diff --git a/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh index cf1c053e1..066d05bdc 100755 --- a/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh +++ b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_skill_smoke.sh b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_skill_smoke.sh index 4d9420010..e3017730c 100755 --- a/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_skill_smoke.sh +++ b/skills/maps-transform-chain-designer/scripts/run_maps_transform_chain_designer_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-transform-chain-designer" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null diff --git a/skills/mapsmessaging-config-builder/SKILL.md b/skills/mapsmessaging-config-builder/SKILL.md index 335dd5463..f7ef42872 100644 --- a/skills/mapsmessaging-config-builder/SKILL.md +++ b/skills/mapsmessaging-config-builder/SKILL.md @@ -15,10 +15,10 @@ Build production-grade MAPS configuration output from requirements. Convert narr - Default safely when unspecified: `authenticationRealm: anon`, no payload overrides, `proxyProtocol: false`. 2. Map contract to config surfaces. -- Read `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md`. -- Map listeners/adapters to `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml`. -- Map namespace storage and message overrides to `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml`. -- Map federation/topology to `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml`. +- Read `skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md`. +- Map listeners/adapters to `NetworkManager.yaml`. +- Map namespace storage and message overrides to `DestinationManager.yaml`. +- Map federation/topology to `routing.yaml`. - If request includes aggregator, ML, or schema behavior, target corresponding manager YAML files in this repo and keep changes minimal. 3. Build deployable entities. @@ -30,16 +30,16 @@ Build production-grade MAPS configuration output from requirements. Convert narr - Re-open touched YAML files and match existing key casing and style. - Run targeted checks: ```bash -rg -n "type: (mqtt|mqtt-sn|amqp|stomp|coap|ws|nats|satellite|canbus)" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "namespace: |namespaceMapping: |contentType:|schemaId:" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml -rg -n "predefinedServers|autoDiscovery|enabled" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +rg -n "type: (mqtt|mqtt-sn|amqp|stomp|coap|ws|nats|satellite|canbus)" NetworkManager.yaml +rg -n "namespace: |namespaceMapping: |contentType:|schemaId:" DestinationManager.yaml +rg -n "predefinedServers|autoDiscovery|enabled" routing.yaml ``` - For runtime checks, include startup diagnostics first, then protocol smoke checks. - For executable runtime smoke, use: - - `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh` + - `skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh` 5. Return output using the output contract. -- Follow `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/references/output-contract.md`. +- Follow `skills/mapsmessaging-config-builder/references/output-contract.md`. - Always include assumptions, file-by-file deployable content, apply steps, startup diagnostics, and protocol verification commands. ## Platform Rules @@ -75,5 +75,5 @@ rg -n "predefinedServers|autoDiscovery|enabled" /Users/krital/dev/starsense/maps ## Reference Loading Load only what is needed for the task: -- Protocol/link mapping: `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md` -- Final response shape: `/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder/references/output-contract.md` +- Protocol/link mapping: `skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md` +- Final response shape: `skills/mapsmessaging-config-builder/references/output-contract.md` diff --git a/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md b/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md index e2dd00de4..e43f1f077 100644 --- a/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md +++ b/skills/mapsmessaging-config-builder/references/protocol-and-routing-map.md @@ -2,9 +2,9 @@ ## Config Surfaces -- `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml`: listener URLs, transport (`tcp`/`udp`/`ssl`/`dtls`/`hmac`/`satellite`), protocol adapters, auth realms, protocol defaults. -- `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml`: namespace storage layout, message override defaults (`contentType`, QoS, retain, `schemaId`). -- `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml`: inter-server topology and predefined peers. +- `NetworkManager.yaml`: listener URLs, transport (`tcp`/`udp`/`ssl`/`dtls`/`hmac`/`satellite`), protocol adapters, auth realms, protocol defaults. +- `DestinationManager.yaml`: namespace storage layout, message override defaults (`contentType`, QoS, retain, `schemaId`). +- `routing.yaml`: inter-server topology and predefined peers. - Other manager files (`AggregatorManager.yaml`, `MLModelManager.yaml`, `SchemaManager.yaml`) when request explicitly includes those capabilities. ## Supported Protocol Targets @@ -79,8 +79,8 @@ docker exec sh -lc '(ss -lnt 2>/dev/null || netstat -lnt 2>/dev/null ## Practical Search Patterns ```bash -rg -n "endPointServerConfigList|protocolConfigs|messageDefaults|url:" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "namespace: |namespaceMapping: |messageOverride|schemaId" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml -rg -n "routing:|predefinedServers|autoDiscovery|enabled" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml -rg -n "window|timeout|maxEventsPerTopic|contribution" /Users/krital/dev/starsense/mapsmessaging_server/AggregatorManager.yaml +rg -n "endPointServerConfigList|protocolConfigs|messageDefaults|url:" NetworkManager.yaml +rg -n "namespace: |namespaceMapping: |messageOverride|schemaId" DestinationManager.yaml +rg -n "routing:|predefinedServers|autoDiscovery|enabled" routing.yaml +rg -n "window|timeout|maxEventsPerTopic|contribution" AggregatorManager.yaml ``` diff --git a/skills/mapsmessaging-config-builder/references/test-scenario-01-output.md b/skills/mapsmessaging-config-builder/references/test-scenario-01-output.md index 0fd550e4a..39e9dd2aa 100644 --- a/skills/mapsmessaging-config-builder/references/test-scenario-01-output.md +++ b/skills/mapsmessaging-config-builder/references/test-scenario-01-output.md @@ -1,8 +1,8 @@ Requirement Mapping -- "Expose MQTT over TCP on 1883" -> `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` fields: `endPointServerConfigList[].url`, `endPointConfig.type=tcp`, `protocolConfigs[].type=mqtt` -- "Default JSON payload" -> `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` field: `protocolConfigs[].messageDefaults.contentType=application/json` -- "Map /telemetry namespace" -> `/Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml` fields: `namespace`, `namespaceMapping` -- "Add route server edge-a" -> `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml` fields: `routing.predefinedServers[]`, `routing.enabled=true` +- "Expose MQTT over TCP on 1883" -> `NetworkManager.yaml` fields: `endPointServerConfigList[].url`, `endPointConfig.type=tcp`, `protocolConfigs[].type=mqtt` +- "Default JSON payload" -> `NetworkManager.yaml` field: `protocolConfigs[].messageDefaults.contentType=application/json` +- "Map /telemetry namespace" -> `DestinationManager.yaml` fields: `namespace`, `namespaceMapping` +- "Add route server edge-a" -> `routing.yaml` fields: `routing.predefinedServers[]`, `routing.enabled=true` Assumptions - `authenticationRealm` defaults to `anon`. @@ -11,7 +11,7 @@ Assumptions Deployable Config Entity ```diff -*** /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +*** NetworkManager.yaml + - + authenticationRealm: anon + name: mqtt-tcp-ingress-1883 @@ -24,13 +24,13 @@ Deployable Config Entity + contentType: application/json + url: tcp://0.0.0.0:1883/ -*** /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml +*** DestinationManager.yaml + - + type: Memory + namespace: /telemetry/ + namespaceMapping: /telemetry/ + -*** /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +*** routing.yaml + enabled: true + predefinedServers: + - @@ -42,9 +42,9 @@ Apply Steps ```bash # apply edits in working tree # then verify keys exist -rg -n "type: mqtt|contentType: application/json|tcp://0.0.0.0:1883/" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "namespace: /telemetry/|namespaceMapping: /telemetry/" /Users/krital/dev/starsense/mapsmessaging_server/DestinationManager.yaml -rg -n "enabled: true|name: edge-a|url: https://edge-a:8080/" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +rg -n "type: mqtt|contentType: application/json|tcp://0.0.0.0:1883/" NetworkManager.yaml +rg -n "namespace: /telemetry/|namespaceMapping: /telemetry/" DestinationManager.yaml +rg -n "enabled: true|name: edge-a|url: https://edge-a:8080/" routing.yaml ``` Verification diff --git a/skills/mapsmessaging-config-builder/references/test-scenario-02-output.md b/skills/mapsmessaging-config-builder/references/test-scenario-02-output.md index c8001f0f7..feedfc84c 100644 --- a/skills/mapsmessaging-config-builder/references/test-scenario-02-output.md +++ b/skills/mapsmessaging-config-builder/references/test-scenario-02-output.md @@ -1,7 +1,7 @@ Requirement Mapping -- "Expose AMQP over TCP on 5672" -> `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml`: `url`, `endPointConfig.type=tcp`, `protocolConfigs[].type=amqp` -- "Set XML default payload" -> `/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml`: `protocolConfigs[].messageDefaults.contentType=application/xml` -- "Enable server routing to core-hub" -> `/Users/krital/dev/starsense/mapsmessaging_server/routing.yaml`: `routing.enabled=true`, `predefinedServers[]` +- "Expose AMQP over TCP on 5672" -> `NetworkManager.yaml`: `url`, `endPointConfig.type=tcp`, `protocolConfigs[].type=amqp` +- "Set XML default payload" -> `NetworkManager.yaml`: `protocolConfigs[].messageDefaults.contentType=application/xml` +- "Enable server routing to core-hub" -> `routing.yaml`: `routing.enabled=true`, `predefinedServers[]` Assumptions - Realm uses `anon`. @@ -9,7 +9,7 @@ Assumptions Deployable Config Entity ```diff -*** /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml +*** NetworkManager.yaml + - + authenticationRealm: anon + name: amqp-tcp-ingress-5672 @@ -22,7 +22,7 @@ Deployable Config Entity + contentType: application/xml + url: tcp://0.0.0.0:5672/ -*** /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +*** routing.yaml + enabled: true + predefinedServers: + - @@ -32,13 +32,13 @@ Deployable Config Entity Apply Steps ```bash -rg -n "type: amqp|contentType: application/xml|tcp://0.0.0.0:5672/" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "enabled: true|name: core-hub|url: https://core-hub:8080/" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +rg -n "type: amqp|contentType: application/xml|tcp://0.0.0.0:5672/" NetworkManager.yaml +rg -n "enabled: true|name: core-hub|url: https://core-hub:8080/" routing.yaml ``` Verification ```bash # AMQP smoke checks are environment-specific; verify listener then route entry -rg -n "amqp-tcp-ingress-5672|type: amqp" /Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml -rg -n "core-hub" /Users/krital/dev/starsense/mapsmessaging_server/routing.yaml +rg -n "amqp-tcp-ingress-5672|type: amqp" NetworkManager.yaml +rg -n "core-hub" routing.yaml ``` diff --git a/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh index bd599f650..6617979c6 100755 --- a/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh +++ b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_runtime_smoke.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server" -HARNESS="/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +HARNESS="${ROOT}/skills/maps-artifact-execution-smoke-harness/scripts/run_artifact_smoke.sh" IMAGE="${IMAGE:-}" PLATFORM="${PLATFORM:-}" MQTT_PORT="${MQTT_PORT:-1883}" diff --git a/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_skill_smoke.sh b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_skill_smoke.sh index 3e5905067..509f178b8 100755 --- a/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_skill_smoke.sh +++ b/skills/mapsmessaging-config-builder/scripts/run_mapsmessaging_config_builder_skill_smoke.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="/Users/krital/dev/starsense/mapsmessaging_server/skills/mapsmessaging-config-builder" -VALIDATOR="/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CODEX_HOME_DEFAULT="${CODEX_HOME:-$HOME/.codex}" +VALIDATOR="${VALIDATOR:-${CODEX_HOME_DEFAULT}/skills/.system/skill-creator/scripts/quick_validate.py}" python3 "${VALIDATOR}" "${ROOT}" test -f "${ROOT}/references/output-contract.md" rg -n "Scenario Metrics and Dashboard|C4 Architecture Diagram" "${ROOT}/references/output-contract.md" >/dev/null diff --git a/skills/smoke/fixtures/maps-aggregator-config-engineer/artifact.md b/skills/smoke/fixtures/maps-aggregator-config-engineer/artifact.md index 199e51875..ab054edbf 100644 --- a/skills/smoke/fixtures/maps-aggregator-config-engineer/artifact.md +++ b/skills/smoke/fixtures/maps-aggregator-config-engineer/artifact.md @@ -42,7 +42,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-artifact-execution-smoke-harness/artifact.md b/skills/smoke/fixtures/maps-artifact-execution-smoke-harness/artifact.md index 51c7825e7..d09486760 100644 --- a/skills/smoke/fixtures/maps-artifact-execution-smoke-harness/artifact.md +++ b/skills/smoke/fixtures/maps-artifact-execution-smoke-harness/artifact.md @@ -40,7 +40,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-canbus-ingestion-builder/artifact.md b/skills/smoke/fixtures/maps-canbus-ingestion-builder/artifact.md index 014d92a33..26e8d114b 100644 --- a/skills/smoke/fixtures/maps-canbus-ingestion-builder/artifact.md +++ b/skills/smoke/fixtures/maps-canbus-ingestion-builder/artifact.md @@ -42,7 +42,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-deployment-packager/artifact.md b/skills/smoke/fixtures/maps-deployment-packager/artifact.md index efa41742b..b5db28a94 100644 --- a/skills/smoke/fixtures/maps-deployment-packager/artifact.md +++ b/skills/smoke/fixtures/maps-deployment-packager/artifact.md @@ -75,7 +75,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-geospatial-routing-builder/artifact.md b/skills/smoke/fixtures/maps-geospatial-routing-builder/artifact.md index cf3a69f5c..1e0b9e8bb 100644 --- a/skills/smoke/fixtures/maps-geospatial-routing-builder/artifact.md +++ b/skills/smoke/fixtures/maps-geospatial-routing-builder/artifact.md @@ -42,7 +42,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-ml-model-lifecycle-playbook/artifact.md b/skills/smoke/fixtures/maps-ml-model-lifecycle-playbook/artifact.md index 5b7de3e9b..b2fd268e0 100644 --- a/skills/smoke/fixtures/maps-ml-model-lifecycle-playbook/artifact.md +++ b/skills/smoke/fixtures/maps-ml-model-lifecycle-playbook/artifact.md @@ -42,7 +42,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-ml-stream-configurator/artifact.md b/skills/smoke/fixtures/maps-ml-stream-configurator/artifact.md index 8194e1226..67681b843 100644 --- a/skills/smoke/fixtures/maps-ml-stream-configurator/artifact.md +++ b/skills/smoke/fixtures/maps-ml-stream-configurator/artifact.md @@ -42,7 +42,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-protocol-bridge-tester/artifact.md b/skills/smoke/fixtures/maps-protocol-bridge-tester/artifact.md index e56bc4163..48b268e1c 100644 --- a/skills/smoke/fixtures/maps-protocol-bridge-tester/artifact.md +++ b/skills/smoke/fixtures/maps-protocol-bridge-tester/artifact.md @@ -35,7 +35,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-release-readiness-checker/artifact.md b/skills/smoke/fixtures/maps-release-readiness-checker/artifact.md index d52c12ded..875732c4e 100644 --- a/skills/smoke/fixtures/maps-release-readiness-checker/artifact.md +++ b/skills/smoke/fixtures/maps-release-readiness-checker/artifact.md @@ -34,7 +34,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-runtime-diagnostics/artifact.md b/skills/smoke/fixtures/maps-runtime-diagnostics/artifact.md index 54a877ac1..298a0b2c9 100644 --- a/skills/smoke/fixtures/maps-runtime-diagnostics/artifact.md +++ b/skills/smoke/fixtures/maps-runtime-diagnostics/artifact.md @@ -31,7 +31,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-satellite-gateway-config/artifact.md b/skills/smoke/fixtures/maps-satellite-gateway-config/artifact.md index b4d175644..9010afa11 100644 --- a/skills/smoke/fixtures/maps-satellite-gateway-config/artifact.md +++ b/skills/smoke/fixtures/maps-satellite-gateway-config/artifact.md @@ -49,7 +49,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-scenario-composer/artifact.md b/skills/smoke/fixtures/maps-scenario-composer/artifact.md index aa84594a8..fae3688cf 100644 --- a/skills/smoke/fixtures/maps-scenario-composer/artifact.md +++ b/skills/smoke/fixtures/maps-scenario-composer/artifact.md @@ -42,7 +42,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-schema-pipeline-builder/artifact.md b/skills/smoke/fixtures/maps-schema-pipeline-builder/artifact.md index 3c284785b..f9c368862 100644 --- a/skills/smoke/fixtures/maps-schema-pipeline-builder/artifact.md +++ b/skills/smoke/fixtures/maps-schema-pipeline-builder/artifact.md @@ -39,7 +39,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-selector-rule-engineer/artifact.md b/skills/smoke/fixtures/maps-selector-rule-engineer/artifact.md index ef153e5ed..7e9b3238d 100644 --- a/skills/smoke/fixtures/maps-selector-rule-engineer/artifact.md +++ b/skills/smoke/fixtures/maps-selector-rule-engineer/artifact.md @@ -42,7 +42,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/maps-skill-suite-orchestrator/artifact.md b/skills/smoke/fixtures/maps-skill-suite-orchestrator/artifact.md index bf44bc480..80bf00999 100644 --- a/skills/smoke/fixtures/maps-skill-suite-orchestrator/artifact.md +++ b/skills/smoke/fixtures/maps-skill-suite-orchestrator/artifact.md @@ -20,7 +20,7 @@ Use in Advanced Combination Matrix mode. - maps-ml-stream-configurator ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/skills/maps-skill-suite-orchestrator/SKILL.md` +`skills/maps-skill-suite-orchestrator/SKILL.md` ```bash echo smoke-check diff --git a/skills/smoke/fixtures/maps-transform-chain-designer/artifact.md b/skills/smoke/fixtures/maps-transform-chain-designer/artifact.md index 41ea69540..7c5f158fe 100644 --- a/skills/smoke/fixtures/maps-transform-chain-designer/artifact.md +++ b/skills/smoke/fixtures/maps-transform-chain-designer/artifact.md @@ -39,7 +39,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/fixtures/mapsmessaging-config-builder/artifact.md b/skills/smoke/fixtures/mapsmessaging-config-builder/artifact.md index d39570664..076cd6287 100644 --- a/skills/smoke/fixtures/mapsmessaging-config-builder/artifact.md +++ b/skills/smoke/fixtures/mapsmessaging-config-builder/artifact.md @@ -43,7 +43,7 @@ Smoke placeholder for `Scenario Metrics and Dashboard`. Smoke placeholder for `C4 Architecture Diagram`. ## Absolute Path Example -`/Users/krital/dev/starsense/mapsmessaging_server/NetworkManager.yaml` +`NetworkManager.yaml` ## Mermaid C4 Placeholder ```mermaid diff --git a/skills/smoke/validate_skills_smoke.py b/skills/smoke/validate_skills_smoke.py index d574d19bf..b71f3138d 100755 --- a/skills/smoke/validate_skills_smoke.py +++ b/skills/smoke/validate_skills_smoke.py @@ -15,7 +15,7 @@ SKILLS_DIR = REPO_ROOT / "skills" FIXTURES_DIR = SKILLS_DIR / "smoke" / "fixtures" DEFAULT_QUICK_VALIDATE = Path( - "/Users/krital/.codex/skills/.system/skill-creator/scripts/quick_validate.py" + "$CODEX_HOME/skills/.system/skill-creator/scripts/quick_validate.py" ) From d4e7e38b239899f2d1eab5d32f49b3b57bd3f763 Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 15:27:43 +0200 Subject: [PATCH 08/12] feat(skills): add per-skill zip packaging script --- docs/skills-install.md | 6 +++ skills/package-skills.py | 103 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 skills/package-skills.py diff --git a/docs/skills-install.md b/docs/skills-install.md index 6165bde2c..ed99eb4a8 100644 --- a/docs/skills-install.md +++ b/docs/skills-install.md @@ -11,6 +11,12 @@ Examples: - `skills/maps-runtime-diagnostics` - `skills/maps-aggregator-config-engineer` +To generate one zip per skill folder: + +```bash +python3 skills/package-skills.py +``` + ## Install into Codex Codex reads skills from `$CODEX_HOME/skills` (often `~/.codex/skills`). diff --git a/skills/package-skills.py b/skills/package-skills.py new file mode 100644 index 000000000..e6c205633 --- /dev/null +++ b/skills/package-skills.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import argparse +from pathlib import Path +from zipfile import ZIP_DEFLATED, ZipFile + +EXCLUDE_DIRS = { + "__pycache__", + ".pytest_cache", + ".mypy_cache", + ".ruff_cache", +} + +EXCLUDE_SUFFIXES = { + ".pyc", + ".pyo", +} + +EXCLUDE_FILES = { + ".DS_Store", +} + + +def should_include(path: Path) -> bool: + if any(part in EXCLUDE_DIRS for part in path.parts): + return False + if path.name in EXCLUDE_FILES: + return False + if path.suffix in EXCLUDE_SUFFIXES: + return False + if path.suffix == ".zip": + return False + return True + + +def find_skill_dirs(skills_dir: Path) -> list[Path]: + dirs: list[Path] = [] + for child in sorted(skills_dir.iterdir()): + if not child.is_dir(): + continue + if child.name.startswith("."): + continue + if (child / "SKILL.md").is_file(): + dirs.append(child) + return dirs + + +def package_skill(skill_dir: Path, out_dir: Path) -> Path: + zip_path = out_dir / f"{skill_dir.name}.zip" + if zip_path.exists(): + zip_path.unlink() + + with ZipFile(zip_path, mode="w", compression=ZIP_DEFLATED) as zf: + for p in sorted(skill_dir.rglob("*")): + if p.is_dir(): + continue + rel = p.relative_to(skill_dir.parent) + if not should_include(rel): + continue + zf.write(p, arcname=str(rel)) + return zip_path + + +def main() -> int: + parser = argparse.ArgumentParser( + description="Create one installable zip artifact per skill directory." + ) + parser.add_argument( + "--skills-dir", + default=str(Path(__file__).resolve().parent), + help="Directory containing skill folders (default: script directory)", + ) + parser.add_argument( + "--output-dir", + default=None, + help="Directory for zip artifacts (default: --skills-dir)", + ) + args = parser.parse_args() + + skills_dir = Path(args.skills_dir).resolve() + out_dir = Path(args.output_dir).resolve() if args.output_dir else skills_dir + + if not skills_dir.is_dir(): + raise SystemExit(f"skills dir does not exist: {skills_dir}") + + out_dir.mkdir(parents=True, exist_ok=True) + skill_dirs = find_skill_dirs(skills_dir) + if not skill_dirs: + raise SystemExit(f"no skill folders found under: {skills_dir}") + + created: list[Path] = [] + for skill_dir in skill_dirs: + created.append(package_skill(skill_dir, out_dir)) + + print(f"Packaged {len(created)} skills into: {out_dir}") + for item in created: + print(f"- {item.name}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 42f8cf9a6256af32f79bc19644562b88dd09f427 Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 16:42:39 +0200 Subject: [PATCH 09/12] skills: harden Fly packaging rules for path/context and arch --- skills/maps-deployment-packager/SKILL.md | 8 ++++++++ .../references/deployment-targets.md | 10 ++++++++++ .../references/output-contract.md | 7 +++++++ 3 files changed, 25 insertions(+) diff --git a/skills/maps-deployment-packager/SKILL.md b/skills/maps-deployment-packager/SKILL.md index f15c96bd9..2e6979a7a 100644 --- a/skills/maps-deployment-packager/SKILL.md +++ b/skills/maps-deployment-packager/SKILL.md @@ -35,6 +35,10 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs - Kubernetes-style: ConfigMap-ready YAML payload blocks and container args/env. - Cloud-target packaging: - Fly.io deployment bundle and service config, including optional Fly KV mapping profile when selected + - for Fly.io Docker builds: + - Dockerfile path must be relative to the selected working directory for `fly deploy` + - Dockerfile `COPY` sources must be relative to Docker build context (avoid repo-root-prefixed paths when deploying from a subdirectory) + - include explicit image architecture selection when required by available artifacts (for example force `amd64` when only x86 MAPS base images are available) - AWS deployment bundle (container/task/service profile) - Google Cloud deployment bundle (container/service profile) - Microsoft Azure deployment bundle (container/app service profile) @@ -61,6 +65,8 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs - when Fly.io is selected with KV mode, no Consul cluster dependency is required - when Consul mode is selected, deployment specifies dedicated Consul topology (HCP or self-managed) - when object storage is selected, provider, endpoint, bucket, and credentials mapping are explicit + - when Fly.io is selected, validate Dockerfile resolution and build-context-relative `COPY` statements + - when Fly.io is selected and image architecture availability is constrained, validate explicit architecture selection in build args or deploy command 5. Return using output contract. - Follow `skills/maps-deployment-packager/references/output-contract.md`. @@ -77,6 +83,8 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs - Always include at least one simple local deployment profile and one advanced cloud profile in matrix mode. - Always include auth mode, storage mode, and config source mode in generated deployment profiles. - Always include backend option details when relevant: Fly KV usage, Consul topology choice, and object storage provider choice. +- For Fly.io profiles, always state the effective build context directory and ensure Dockerfile path is valid from that directory. +- For Fly.io profiles, always state architecture behavior (`amd64`/`arm64`) and the reason when forcing one architecture. ## Scenario Modes diff --git a/skills/maps-deployment-packager/references/deployment-targets.md b/skills/maps-deployment-packager/references/deployment-targets.md index 213ecb6d3..715b62419 100644 --- a/skills/maps-deployment-packager/references/deployment-targets.md +++ b/skills/maps-deployment-packager/references/deployment-targets.md @@ -48,6 +48,13 @@ Output expectations: - Generate app and service deployment bundle with mapped ports, env, volumes, and config source mode. - Offer Fly.io KV profile as a first-class default for lightweight state/config needs without running a Consul cluster. - If Consul-based mode is selected, treat it as an explicit override and include dedicated Consul topology choice. +- Make Fly build context explicit: + - if deploying from the Fly bundle directory, use `dockerfile = "Dockerfile"` in `fly.toml` + - if deploying from repo root, use a repo-root-relative Dockerfile path + - Dockerfile `COPY` lines must be relative to the chosen build context +- Make architecture selection explicit: + - include `TARGETARCH` behavior in Fly build args + - when only x86 MAPS images are available, force `TARGETARCH=amd64` even when the operator runs on Apple Silicon/arm64 ### AWS - Generate container deployment profile (task/service style) including volume/storage class and auth/config parameters. @@ -139,5 +146,8 @@ rg -n "directory:|storageConfig:|type: File|type: Memory|autoPauseTimeout" Desti - Authentication profile declared but not wired in deployment env/config. - File vs Consul mode mismatch between deployment commands and runtime flags/env. - Fly KV mode selected but deployment still depends on unavailable Consul endpoint. +- Fly Dockerfile path resolved relative to wrong working directory (for example duplicated subpath segments). +- Fly Docker build context mismatch causes `COPY` source file not found at build time. +- Fly build auto-selects unsupported architecture image tag when only x86 artifacts are available. - Consul mode selected without explicit topology (HCP vs self-managed) and connection details. - Object storage selected without provider endpoint and credential mapping details. diff --git a/skills/maps-deployment-packager/references/output-contract.md b/skills/maps-deployment-packager/references/output-contract.md index e55414874..c128bc694 100644 --- a/skills/maps-deployment-packager/references/output-contract.md +++ b/skills/maps-deployment-packager/references/output-contract.md @@ -45,10 +45,15 @@ Always return in this order. 9. `Deployable Entity` - Full files, patch blocks, command scripts, or ConfigMap YAML blocks. +- For Fly.io targets, include: + - the intended `fly deploy` working directory + - Dockerfile path as resolved from that working directory + - explicit architecture selection behavior (`TARGETARCH` and/or deploy flags) 10. `Apply Steps` - Exact commands to apply/deploy artifacts. - For air-gapped bundles, include offline image/artifact load steps. +- For Fly.io targets, commands must be coherent with the declared working directory and Dockerfile path. 11. `Startup Diagnostics` - Commands to confirm process/container startup and config load. @@ -83,6 +88,8 @@ Always return in this order. - Never omit storage and volume mapping. - Never omit file-vs-Consul config source declaration. - Never omit backend choice declaration (Fly KV vs dedicated Consul vs none). +- Never omit Fly working directory plus Dockerfile path resolution details when Fly.io is selected. +- Never omit explicit Fly architecture selection behavior when image availability is architecture-constrained. - Never omit Consul topology details when Consul mode is selected. - Never omit object storage provider/endpoint/credential mapping when object storage is selected. - Never omit scenario-specific metrics and at least one testable dashboard output. From dcbf0868d2609661abecaca8beddf2952895f861 Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 20:11:24 +0200 Subject: [PATCH 10/12] skills: capture Fly deployment fixes from local validation --- skills/maps-deployment-packager/SKILL.md | 4 ++++ .../references/deployment-targets.md | 8 ++++++++ .../references/output-contract.md | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/skills/maps-deployment-packager/SKILL.md b/skills/maps-deployment-packager/SKILL.md index 2e6979a7a..a005c3ca5 100644 --- a/skills/maps-deployment-packager/SKILL.md +++ b/skills/maps-deployment-packager/SKILL.md @@ -39,6 +39,8 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs - Dockerfile path must be relative to the selected working directory for `fly deploy` - Dockerfile `COPY` sources must be relative to Docker build context (avoid repo-root-prefixed paths when deploying from a subdirectory) - include explicit image architecture selection when required by available artifacts (for example force `amd64` when only x86 MAPS base images are available) + - when MAPS container runs as non-root and Fly volume mounts as root-owned, include startup ownership fix before process drop (for example `chown` of `MAPS_DATA` path) + - include runtime sizing defaults for constrained Fly machines (`[vm]` memory and JVM heap/metaspace flags) - AWS deployment bundle (container/task/service profile) - Google Cloud deployment bundle (container/service profile) - Microsoft Azure deployment bundle (container/app service profile) @@ -67,6 +69,8 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs - when object storage is selected, provider, endpoint, bucket, and credentials mapping are explicit - when Fly.io is selected, validate Dockerfile resolution and build-context-relative `COPY` statements - when Fly.io is selected and image architecture availability is constrained, validate explicit architecture selection in build args or deploy command + - when Fly.io persistent volume is selected, validate runtime write access to `MAPS_DATA` for effective service user + - when Fly.io machine size is small, validate JVM options are bounded to avoid OOM/restart loops 5. Return using output contract. - Follow `skills/maps-deployment-packager/references/output-contract.md`. diff --git a/skills/maps-deployment-packager/references/deployment-targets.md b/skills/maps-deployment-packager/references/deployment-targets.md index 715b62419..60baca04f 100644 --- a/skills/maps-deployment-packager/references/deployment-targets.md +++ b/skills/maps-deployment-packager/references/deployment-targets.md @@ -55,6 +55,12 @@ Output expectations: - Make architecture selection explicit: - include `TARGETARCH` behavior in Fly build args - when only x86 MAPS images are available, force `TARGETARCH=amd64` even when the operator runs on Apple Silicon/arm64 +- Handle Fly mounted volume ownership explicitly: + - Fly volumes commonly mount root-owned paths; if MAPS starts as non-root user, include startup ownership remediation for `MAPS_DATA` (for example pre-start `chown`) + - include an access check in diagnostics to confirm MAPS can write under `MAPS_DATA` +- Include machine/JVM sizing defaults for Fly profiles: + - specify `[vm]` memory in `fly.toml` + - bound JVM memory through `JAVA_OPTS` or equivalent env to match selected machine size ### AWS - Generate container deployment profile (task/service style) including volume/storage class and auth/config parameters. @@ -149,5 +155,7 @@ rg -n "directory:|storageConfig:|type: File|type: Memory|autoPauseTimeout" Desti - Fly Dockerfile path resolved relative to wrong working directory (for example duplicated subpath segments). - Fly Docker build context mismatch causes `COPY` source file not found at build time. - Fly build auto-selects unsupported architecture image tag when only x86 artifacts are available. +- Fly volume write failures because `MAPS_DATA` remains root-owned while daemon runs as non-root. +- Fly machine memory and JVM heap defaults are mismatched, causing startup OOM/restart loops. - Consul mode selected without explicit topology (HCP vs self-managed) and connection details. - Object storage selected without provider endpoint and credential mapping details. diff --git a/skills/maps-deployment-packager/references/output-contract.md b/skills/maps-deployment-packager/references/output-contract.md index c128bc694..de15a77c0 100644 --- a/skills/maps-deployment-packager/references/output-contract.md +++ b/skills/maps-deployment-packager/references/output-contract.md @@ -14,6 +14,7 @@ Always return in this order. 3. `Storage and Volume Profile` - Selected storage mode (ephemeral/persistent) and destination/storage type expectations. - Include exact volume/mount mappings per target. +- For Fly.io with persistent volumes and non-root runtime, include ownership/access strategy for `MAPS_DATA`. 4. `Configuration Source Mode` - File-based or Consul-based configuration mode. @@ -57,6 +58,7 @@ Always return in this order. 11. `Startup Diagnostics` - Commands to confirm process/container startup and config load. +- For Fly.io, include one command that verifies write access in `MAPS_DATA` with the effective runtime user. 12. `Listener Verification` - Commands proving expected protocol listeners are bound. @@ -90,6 +92,8 @@ Always return in this order. - Never omit backend choice declaration (Fly KV vs dedicated Consul vs none). - Never omit Fly working directory plus Dockerfile path resolution details when Fly.io is selected. - Never omit explicit Fly architecture selection behavior when image availability is architecture-constrained. +- Never omit Fly volume ownership/write-access strategy when persistent storage and non-root runtime are both used. +- Never omit Fly memory/JVM sizing assumptions when Fly profile includes constrained machine sizes. - Never omit Consul topology details when Consul mode is selected. - Never omit object storage provider/endpoint/credential mapping when object storage is selected. - Never omit scenario-specific metrics and at least one testable dashboard output. From 7a253524a5a335461433876f5635cbc106e65ce9 Mon Sep 17 00:00:00 2001 From: krital Date: Wed, 25 Feb 2026 20:39:07 +0200 Subject: [PATCH 11/12] skills: enforce Fly logging and runtime parity rules --- skills/maps-deployment-packager/SKILL.md | 1 + .../maps-deployment-packager/references/deployment-targets.md | 4 ++++ skills/maps-deployment-packager/references/output-contract.md | 2 ++ 3 files changed, 7 insertions(+) diff --git a/skills/maps-deployment-packager/SKILL.md b/skills/maps-deployment-packager/SKILL.md index a005c3ca5..37c0b267c 100644 --- a/skills/maps-deployment-packager/SKILL.md +++ b/skills/maps-deployment-packager/SKILL.md @@ -41,6 +41,7 @@ Convert MAPS manager YAML and runtime settings into deployable packaging outputs - include explicit image architecture selection when required by available artifacts (for example force `amd64` when only x86 MAPS base images are available) - when MAPS container runs as non-root and Fly volume mounts as root-owned, include startup ownership fix before process drop (for example `chown` of `MAPS_DATA` path) - include runtime sizing defaults for constrained Fly machines (`[vm]` memory and JVM heap/metaspace flags) + - include Fly-compatible logging profile mapping (for example logback override to stdout/stderr) and state the selected logging file path - AWS deployment bundle (container/task/service profile) - Google Cloud deployment bundle (container/service profile) - Microsoft Azure deployment bundle (container/app service profile) diff --git a/skills/maps-deployment-packager/references/deployment-targets.md b/skills/maps-deployment-packager/references/deployment-targets.md index 60baca04f..5fb7bdb5b 100644 --- a/skills/maps-deployment-packager/references/deployment-targets.md +++ b/skills/maps-deployment-packager/references/deployment-targets.md @@ -61,6 +61,9 @@ Output expectations: - Include machine/JVM sizing defaults for Fly profiles: - specify `[vm]` memory in `fly.toml` - bound JVM memory through `JAVA_OPTS` or equivalent env to match selected machine size +- Include logging profile compatibility for Fly: + - if runtime logs are expected via Fly logs, ensure selected logback/logging config writes to stdout/stderr + - declare any logging config override file copied into the image ### AWS - Generate container deployment profile (task/service style) including volume/storage class and auth/config parameters. @@ -157,5 +160,6 @@ rg -n "directory:|storageConfig:|type: File|type: Memory|autoPauseTimeout" Desti - Fly build auto-selects unsupported architecture image tag when only x86 artifacts are available. - Fly volume write failures because `MAPS_DATA` remains root-owned while daemon runs as non-root. - Fly machine memory and JVM heap defaults are mismatched, causing startup OOM/restart loops. +- Fly logging configuration remains file-only/non-console, reducing observability through `fly logs`. - Consul mode selected without explicit topology (HCP vs self-managed) and connection details. - Object storage selected without provider endpoint and credential mapping details. diff --git a/skills/maps-deployment-packager/references/output-contract.md b/skills/maps-deployment-packager/references/output-contract.md index de15a77c0..6dbad70f8 100644 --- a/skills/maps-deployment-packager/references/output-contract.md +++ b/skills/maps-deployment-packager/references/output-contract.md @@ -59,6 +59,7 @@ Always return in this order. 11. `Startup Diagnostics` - Commands to confirm process/container startup and config load. - For Fly.io, include one command that verifies write access in `MAPS_DATA` with the effective runtime user. +- For Fly.io, include one command that confirms runtime logs are visible through `fly logs` (or equivalent) with selected logging config. 12. `Listener Verification` - Commands proving expected protocol listeners are bound. @@ -94,6 +95,7 @@ Always return in this order. - Never omit explicit Fly architecture selection behavior when image availability is architecture-constrained. - Never omit Fly volume ownership/write-access strategy when persistent storage and non-root runtime are both used. - Never omit Fly memory/JVM sizing assumptions when Fly profile includes constrained machine sizes. +- Never omit Fly logging profile mapping when Fly deployment relies on platform log collection. - Never omit Consul topology details when Consul mode is selected. - Never omit object storage provider/endpoint/credential mapping when object storage is selected. - Never omit scenario-specific metrics and at least one testable dashboard output. From 088ddac0becfe052e448d5375f427756398f7dba Mon Sep 17 00:00:00 2001 From: krital Date: Thu, 26 Feb 2026 18:35:11 +0200 Subject: [PATCH 12/12] skills: sanitize mermaid labels for cross-skill rendering --- .../scripts/render_skill_mermaid_diagrams.py | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100755 skills/scripts/render_skill_mermaid_diagrams.py diff --git a/skills/scripts/render_skill_mermaid_diagrams.py b/skills/scripts/render_skill_mermaid_diagrams.py new file mode 100755 index 000000000..f09ddb1fb --- /dev/null +++ b/skills/scripts/render_skill_mermaid_diagrams.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 +""" +Render Mermaid diagrams for all skills. + +Inputs: +- .mmd files under skills/ +- ```mermaid fenced blocks inside .md files under skills/ + +Output: +- SVG files under skills/rendered-mermaid/ mirroring source layout. +""" + +from __future__ import annotations + +import argparse +import json +import re +import shutil +import subprocess +import sys +import tempfile +from pathlib import Path + + +MERMAID_FENCE_RE = re.compile(r"```mermaid\s*\n(.*?)\n```", re.DOTALL) +NODE_LABEL_RE = re.compile(r"(\b[A-Za-z0-9_]+)\[([^\[\]\n\"]+)\]") + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Render Mermaid diagrams for skills.") + parser.add_argument( + "--skills-root", + default="skills", + help="Path to skills directory (default: skills)", + ) + parser.add_argument( + "--out-dir", + default="skills/rendered-mermaid", + help="Output directory for rendered SVGs (default: skills/rendered-mermaid)", + ) + parser.add_argument( + "--include-md-fences", + action="store_true", + help="Include mermaid fences inside markdown files.", + ) + parser.add_argument( + "--puppeteer-config", + default="", + help="Optional Puppeteer config JSON path passed to mmdc (-p).", + ) + return parser.parse_args() + + +def ensure_mmdc() -> str: + mmdc = shutil.which("mmdc") + if mmdc: + return mmdc + print( + "mmdc not found on PATH. Install Mermaid CLI, e.g. `npm i -g @mermaid-js/mermaid-cli`.", + file=sys.stderr, + ) + raise SystemExit(2) + + +def iter_mmd_files(skills_root: Path) -> list[Path]: + return sorted( + path + for path in skills_root.rglob("*.mmd") + if "rendered-mermaid" not in path.parts + ) + + +def iter_md_mermaid_fences(skills_root: Path) -> list[tuple[Path, int, str]]: + results: list[tuple[Path, int, str]] = [] + for md in sorted(skills_root.rglob("*.md")): + if "rendered-mermaid" in md.parts: + continue + text = md.read_text(encoding="utf-8") + matches = list(MERMAID_FENCE_RE.finditer(text)) + for idx, match in enumerate(matches, start=1): + results.append((md, idx, match.group(1).strip() + "\n")) + return results + + +def sanitize_mermaid(diagram: str) -> str: + """ + Normalize node labels for Mermaid CLI compatibility. + + Converts node labels from `A[label]` to `A["label"]` and escapes angle + brackets in label text to avoid parser errors on path-like labels such as + `/geo/intermediate/`. + """ + + def repl(match: re.Match[str]) -> str: + node_id = match.group(1) + label = match.group(2) + safe = label.replace("\\", "\\\\").replace('"', '\\"') + safe = safe.replace("<", "<").replace(">", ">") + return f'{node_id}["{safe}"]' + + return NODE_LABEL_RE.sub(repl, diagram) + + +def render(mmdc: str, src: Path, dst_svg: Path, puppeteer_cfg: Path | None) -> None: + dst_svg.parent.mkdir(parents=True, exist_ok=True) + cmd = [mmdc, "-i", str(src), "-o", str(dst_svg), "-b", "transparent"] + if puppeteer_cfg: + cmd.extend(["-p", str(puppeteer_cfg)]) + subprocess.run(cmd, check=True) + + +def main() -> int: + args = parse_args() + skills_root = Path(args.skills_root).resolve() + out_dir = Path(args.out_dir).resolve() + + if not skills_root.exists(): + print(f"Skills root not found: {skills_root}", file=sys.stderr) + return 2 + + mmdc = ensure_mmdc() + rendered = 0 + failed = 0 + auto_puppeteer_cfg: tempfile.NamedTemporaryFile[str] | None = None + puppeteer_cfg: Path | None = None + + if args.puppeteer_config: + puppeteer_cfg = Path(args.puppeteer_config).resolve() + else: + auto_puppeteer_cfg = tempfile.NamedTemporaryFile( + mode="w", suffix=".json", delete=False + ) + json.dump( + {"args": ["--no-sandbox", "--disable-setuid-sandbox"]}, + auto_puppeteer_cfg, + ) + auto_puppeteer_cfg.flush() + puppeteer_cfg = Path(auto_puppeteer_cfg.name) + + for src in iter_mmd_files(skills_root): + rel = src.relative_to(skills_root) + dst_svg = out_dir / rel.with_suffix(".svg") + try: + render(mmdc, src, dst_svg, puppeteer_cfg) + rendered += 1 + except subprocess.CalledProcessError as exc: + failed += 1 + print(f"Failed rendering {src}: {exc}", file=sys.stderr) + + if args.include_md_fences: + for md_file, idx, diagram in iter_md_mermaid_fences(skills_root): + rel = md_file.relative_to(skills_root) + tmp_mmd = out_dir / rel.parent / f"{md_file.stem}.mermaid-{idx}.mmd" + tmp_mmd.parent.mkdir(parents=True, exist_ok=True) + tmp_mmd.write_text(sanitize_mermaid(diagram), encoding="utf-8") + dst_svg = tmp_mmd.with_suffix(".svg") + try: + render(mmdc, tmp_mmd, dst_svg, puppeteer_cfg) + rendered += 1 + except subprocess.CalledProcessError as exc: + failed += 1 + print(f"Failed rendering {md_file}#{idx}: {exc}", file=sys.stderr) + + if auto_puppeteer_cfg is not None: + try: + Path(auto_puppeteer_cfg.name).unlink(missing_ok=True) + except OSError: + pass + + print(f"Rendered {rendered} Mermaid diagram(s) into {out_dir}; failures={failed}") + return 1 if failed else 0 + + +if __name__ == "__main__": + raise SystemExit(main())