@trac3er/oh-my-god 2.1.0 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/omg/AGENTS.fragment.md +2 -2
- package/.agents/skills/omg/algorithms/SKILL.md +1 -1
- package/.agents/skills/omg/algorithms/openai.yaml +1 -1
- package/.agents/skills/omg/api-twin/SKILL.md +1 -1
- package/.agents/skills/omg/api-twin/openai.yaml +1 -1
- package/.agents/skills/omg/claim-judge/SKILL.md +1 -1
- package/.agents/skills/omg/claim-judge/openai.yaml +1 -1
- package/.agents/skills/omg/codex-rules.md +1 -1
- package/.agents/skills/omg/control-plane/SKILL.md +1 -1
- package/.agents/skills/omg/control-plane/openai.yaml +1 -1
- package/.agents/skills/omg/data-lineage/SKILL.md +1 -1
- package/.agents/skills/omg/data-lineage/openai.yaml +1 -1
- package/.agents/skills/omg/delta-classifier/SKILL.md +1 -1
- package/.agents/skills/omg/delta-classifier/openai.yaml +1 -1
- package/.agents/skills/omg/eval-gate/SKILL.md +1 -1
- package/.agents/skills/omg/eval-gate/openai.yaml +1 -1
- package/.agents/skills/omg/health/SKILL.md +1 -1
- package/.agents/skills/omg/health/openai.yaml +1 -1
- package/.agents/skills/omg/hook-governor/SKILL.md +1 -1
- package/.agents/skills/omg/hook-governor/openai.yaml +1 -1
- package/.agents/skills/omg/incident-replay/SKILL.md +1 -1
- package/.agents/skills/omg/incident-replay/openai.yaml +1 -1
- package/.agents/skills/omg/lsp-pack/SKILL.md +1 -1
- package/.agents/skills/omg/lsp-pack/openai.yaml +1 -1
- package/.agents/skills/omg/mcp-fabric/SKILL.md +1 -1
- package/.agents/skills/omg/mcp-fabric/openai.yaml +1 -1
- package/.agents/skills/omg/plan-council/SKILL.md +1 -1
- package/.agents/skills/omg/plan-council/openai.yaml +1 -1
- package/.agents/skills/omg/preflight/SKILL.md +1 -1
- package/.agents/skills/omg/preflight/openai.yaml +1 -1
- package/.agents/skills/omg/proof-gate/SKILL.md +1 -1
- package/.agents/skills/omg/proof-gate/openai.yaml +1 -1
- package/.agents/skills/omg/remote-supervisor/SKILL.md +1 -1
- package/.agents/skills/omg/remote-supervisor/openai.yaml +1 -1
- package/.agents/skills/omg/robotics/SKILL.md +1 -1
- package/.agents/skills/omg/robotics/openai.yaml +1 -1
- package/.agents/skills/omg/secure-worktree-pipeline/SKILL.md +1 -1
- package/.agents/skills/omg/secure-worktree-pipeline/openai.yaml +1 -1
- package/.agents/skills/omg/security-check/SKILL.md +1 -1
- package/.agents/skills/omg/security-check/openai.yaml +1 -1
- package/.agents/skills/omg/test-intent-lock/SKILL.md +1 -1
- package/.agents/skills/omg/test-intent-lock/openai.yaml +1 -1
- package/.agents/skills/omg/tracebank/SKILL.md +1 -1
- package/.agents/skills/omg/tracebank/openai.yaml +1 -1
- package/.agents/skills/omg/vision/SKILL.md +1 -1
- package/.agents/skills/omg/vision/openai.yaml +1 -1
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +16 -0
- package/CLI-ADAPTER-MAP.md +3 -3
- package/OMG-setup.sh +114 -1
- package/OMG_COMPAT_CONTRACT.md +1 -1
- package/README.md +2 -1
- package/artifacts/release/.claude-plugin/marketplace.json +3 -3
- package/artifacts/release/.claude-plugin/plugin.json +1 -1
- package/artifacts/release/OMG_COMPAT_CONTRACT.md +1 -1
- package/artifacts/release/dist/enterprise/bundle/.claude-plugin/marketplace.json +3 -3
- package/artifacts/release/dist/enterprise/bundle/.claude-plugin/plugin.json +1 -1
- package/artifacts/release/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +1 -1
- package/artifacts/release/dist/enterprise/bundle/plugins/advanced/plugin.json +26 -9
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/algorithms.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/api-twin.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/control-plane.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/health.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/plan-council.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/preflight.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/robotics.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/security-check.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/tracebank.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/bundles/vision.yaml +1 -1
- package/artifacts/release/dist/enterprise/bundle/registry/omg-capability.schema.json +1 -1
- package/artifacts/release/dist/enterprise/bundle/settings.json +3 -3
- package/artifacts/release/dist/enterprise/manifest.json +30 -40
- package/artifacts/release/dist/public/bundle/.claude-plugin/marketplace.json +3 -3
- package/artifacts/release/dist/public/bundle/.claude-plugin/plugin.json +1 -1
- package/artifacts/release/dist/public/bundle/OMG_COMPAT_CONTRACT.md +1 -1
- package/artifacts/release/dist/public/bundle/plugins/advanced/plugin.json +26 -9
- package/artifacts/release/dist/public/bundle/registry/bundles/algorithms.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/api-twin.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/claim-judge.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/control-plane.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/data-lineage.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/delta-classifier.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/eval-gate.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/health.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/hook-governor.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/incident-replay.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/lsp-pack.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/mcp-fabric.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/plan-council.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/preflight.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/proof-gate.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/remote-supervisor.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/robotics.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/security-check.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/test-intent-lock.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/tracebank.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/bundles/vision.yaml +1 -1
- package/artifacts/release/dist/public/bundle/registry/omg-capability.schema.json +1 -1
- package/artifacts/release/dist/public/bundle/settings.json +3 -3
- package/artifacts/release/dist/public/manifest.json +30 -40
- package/artifacts/release/plugins/advanced/plugin.json +26 -9
- package/artifacts/release/registry/bundles/algorithms.yaml +1 -1
- package/artifacts/release/registry/bundles/api-twin.yaml +1 -1
- package/artifacts/release/registry/bundles/claim-judge.yaml +1 -1
- package/artifacts/release/registry/bundles/control-plane.yaml +1 -1
- package/artifacts/release/registry/bundles/data-lineage.yaml +1 -1
- package/artifacts/release/registry/bundles/delta-classifier.yaml +1 -1
- package/artifacts/release/registry/bundles/eval-gate.yaml +1 -1
- package/artifacts/release/registry/bundles/health.yaml +1 -1
- package/artifacts/release/registry/bundles/hook-governor.yaml +1 -1
- package/artifacts/release/registry/bundles/incident-replay.yaml +1 -1
- package/artifacts/release/registry/bundles/lsp-pack.yaml +1 -1
- package/artifacts/release/registry/bundles/mcp-fabric.yaml +1 -1
- package/artifacts/release/registry/bundles/plan-council.yaml +1 -1
- package/artifacts/release/registry/bundles/preflight.yaml +1 -1
- package/artifacts/release/registry/bundles/proof-gate.yaml +1 -1
- package/artifacts/release/registry/bundles/remote-supervisor.yaml +1 -1
- package/artifacts/release/registry/bundles/robotics.yaml +1 -1
- package/artifacts/release/registry/bundles/secure-worktree-pipeline.yaml +1 -1
- package/artifacts/release/registry/bundles/security-check.yaml +1 -1
- package/artifacts/release/registry/bundles/test-intent-lock.yaml +1 -1
- package/artifacts/release/registry/bundles/tracebank.yaml +1 -1
- package/artifacts/release/registry/bundles/vision.yaml +1 -1
- package/artifacts/release/registry/omg-capability.schema.json +1 -1
- package/artifacts/release/settings.json +3 -3
- package/build/lib/commands/OMG:profile-review.md +43 -0
- package/build/lib/commands/OMG:validate.md +59 -0
- package/build/lib/control_plane/service.py +40 -1
- package/build/lib/hooks/_agent_registry.py +2 -0
- package/build/lib/hooks/firewall.py +263 -4
- package/build/lib/hooks/intentgate-keyword-detector.py +15 -3
- package/build/lib/hooks/policy_engine.py +77 -0
- package/build/lib/hooks/prompt-enhancer.py +146 -0
- package/build/lib/hooks/session-end-capture.py +374 -6
- package/build/lib/hooks/session-start.py +13 -35
- package/build/lib/hooks/setup_wizard.py +333 -1
- package/build/lib/hooks/shadow_manager.py +111 -2
- package/build/lib/hooks/stop_dispatcher.py +108 -4
- package/build/lib/plugins/advanced/plugin.json +26 -9
- package/build/lib/plugins/core/plugin.json +44 -11
- package/build/lib/registry/bundles/algorithms.yaml +1 -1
- package/build/lib/registry/bundles/api-twin.yaml +1 -1
- package/build/lib/registry/bundles/claim-judge.yaml +1 -1
- package/build/lib/registry/bundles/control-plane.yaml +1 -1
- package/build/lib/registry/bundles/data-lineage.yaml +1 -1
- package/build/lib/registry/bundles/delta-classifier.yaml +1 -1
- package/build/lib/registry/bundles/eval-gate.yaml +1 -1
- package/build/lib/registry/bundles/health.yaml +1 -1
- package/build/lib/registry/bundles/hook-governor.yaml +1 -1
- package/build/lib/registry/bundles/incident-replay.yaml +1 -1
- package/build/lib/registry/bundles/lsp-pack.yaml +1 -1
- package/build/lib/registry/bundles/mcp-fabric.yaml +1 -1
- package/build/lib/registry/bundles/plan-council.yaml +1 -1
- package/build/lib/registry/bundles/preflight.yaml +1 -1
- package/build/lib/registry/bundles/proof-gate.yaml +1 -1
- package/build/lib/registry/bundles/remote-supervisor.yaml +1 -1
- package/build/lib/registry/bundles/robotics.yaml +1 -1
- package/build/lib/registry/bundles/secure-worktree-pipeline.yaml +1 -1
- package/build/lib/registry/bundles/security-check.yaml +1 -1
- package/build/lib/registry/bundles/test-intent-lock.yaml +1 -1
- package/build/lib/registry/bundles/tracebank.yaml +1 -1
- package/build/lib/registry/bundles/vision.yaml +1 -1
- package/build/lib/registry/omg-capability.schema.json +1 -1
- package/build/lib/runtime/adoption.py +1 -1
- package/build/lib/runtime/background_verification.py +62 -0
- package/build/lib/runtime/claim_judge.py +165 -5
- package/build/lib/runtime/compat.py +15 -1
- package/build/lib/runtime/context_engine.py +261 -4
- package/build/lib/runtime/contract_compiler.py +370 -93
- package/build/lib/runtime/defense_state.py +79 -8
- package/build/lib/runtime/delta_classifier.py +80 -2
- package/build/lib/runtime/evidence_query.py +56 -4
- package/build/lib/runtime/evidence_registry.py +16 -0
- package/build/lib/runtime/evidence_requirements.py +47 -0
- package/build/lib/runtime/forge_agents.py +179 -9
- package/build/lib/runtime/forge_contracts.py +208 -2
- package/build/lib/runtime/interaction_journal.py +318 -42
- package/build/lib/runtime/memory_store.py +134 -1
- package/build/lib/runtime/mutation_gate.py +57 -11
- package/build/lib/runtime/omg_compat_contract_snapshot.json +2 -2
- package/build/lib/runtime/omg_mcp_server.py +14 -4
- package/build/lib/runtime/preflight.py +14 -0
- package/build/lib/runtime/profile_io.py +294 -0
- package/build/lib/runtime/proof_gate.py +122 -7
- package/build/lib/runtime/release_run_coordinator.py +339 -0
- package/build/lib/runtime/release_surfaces.py +243 -0
- package/build/lib/runtime/rollback_manifest.py +136 -0
- package/build/lib/runtime/router_critics.py +50 -0
- package/build/lib/runtime/runtime_contracts.py +137 -0
- package/build/lib/runtime/security_check.py +16 -0
- package/build/lib/runtime/session_health.py +60 -16
- package/build/lib/runtime/team_router.py +156 -13
- package/build/lib/runtime/test_intent_lock.py +102 -0
- package/build/lib/runtime/tool_plan_gate.py +249 -24
- package/build/lib/runtime/validate.py +194 -0
- package/build/lib/runtime/verification_controller.py +52 -2
- package/commands/OMG:diagnose-plugins.md +33 -0
- package/commands/OMG:profile-review.md +43 -0
- package/commands/OMG:setup.md +4 -1
- package/commands/OMG:validate.md +59 -0
- package/control_plane/service.py +40 -1
- package/dist/enterprise/bundle/.claude-plugin/marketplace.json +3 -3
- package/dist/enterprise/bundle/.claude-plugin/plugin.json +1 -1
- package/dist/enterprise/bundle/OMG_COMPAT_CONTRACT.md +1 -1
- package/dist/enterprise/bundle/plugins/advanced/plugin.json +26 -9
- package/dist/enterprise/bundle/registry/bundles/algorithms.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/api-twin.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/claim-judge.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/control-plane.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/data-lineage.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/delta-classifier.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/eval-gate.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/health.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/hook-governor.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/incident-replay.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/lsp-pack.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/mcp-fabric.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/plan-council.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/preflight.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/proof-gate.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/remote-supervisor.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/robotics.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/security-check.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/test-intent-lock.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/tracebank.yaml +1 -1
- package/dist/enterprise/bundle/registry/bundles/vision.yaml +1 -1
- package/dist/enterprise/bundle/registry/omg-capability.schema.json +1 -1
- package/dist/enterprise/bundle/settings.json +3 -3
- package/dist/enterprise/manifest.json +30 -40
- package/dist/oh_my_god-2.1.4-py3-none-any.whl +0 -0
- package/dist/oh_my_god-2.1.4.tar.gz +0 -0
- package/dist/public/bundle/.claude-plugin/marketplace.json +3 -3
- package/dist/public/bundle/.claude-plugin/plugin.json +1 -1
- package/dist/public/bundle/OMG_COMPAT_CONTRACT.md +1 -1
- package/dist/public/bundle/plugins/advanced/plugin.json +26 -9
- package/dist/public/bundle/registry/bundles/algorithms.yaml +1 -1
- package/dist/public/bundle/registry/bundles/api-twin.yaml +1 -1
- package/dist/public/bundle/registry/bundles/claim-judge.yaml +1 -1
- package/dist/public/bundle/registry/bundles/control-plane.yaml +1 -1
- package/dist/public/bundle/registry/bundles/data-lineage.yaml +1 -1
- package/dist/public/bundle/registry/bundles/delta-classifier.yaml +1 -1
- package/dist/public/bundle/registry/bundles/eval-gate.yaml +1 -1
- package/dist/public/bundle/registry/bundles/health.yaml +1 -1
- package/dist/public/bundle/registry/bundles/hook-governor.yaml +1 -1
- package/dist/public/bundle/registry/bundles/incident-replay.yaml +1 -1
- package/dist/public/bundle/registry/bundles/lsp-pack.yaml +1 -1
- package/dist/public/bundle/registry/bundles/mcp-fabric.yaml +1 -1
- package/dist/public/bundle/registry/bundles/plan-council.yaml +1 -1
- package/dist/public/bundle/registry/bundles/preflight.yaml +1 -1
- package/dist/public/bundle/registry/bundles/proof-gate.yaml +1 -1
- package/dist/public/bundle/registry/bundles/remote-supervisor.yaml +1 -1
- package/dist/public/bundle/registry/bundles/robotics.yaml +1 -1
- package/dist/public/bundle/registry/bundles/secure-worktree-pipeline.yaml +1 -1
- package/dist/public/bundle/registry/bundles/security-check.yaml +1 -1
- package/dist/public/bundle/registry/bundles/test-intent-lock.yaml +1 -1
- package/dist/public/bundle/registry/bundles/tracebank.yaml +1 -1
- package/dist/public/bundle/registry/bundles/vision.yaml +1 -1
- package/dist/public/bundle/registry/omg-capability.schema.json +1 -1
- package/dist/public/bundle/settings.json +3 -3
- package/dist/public/manifest.json +30 -40
- package/docs/install/opencode.md +30 -0
- package/docs/proof.md +11 -0
- package/docs/release-checklist.md +14 -1
- package/hooks/_agent_registry.py +2 -0
- package/hooks/firewall.py +263 -4
- package/hooks/intentgate-keyword-detector.py +15 -3
- package/hooks/policy_engine.py +77 -0
- package/hooks/prompt-enhancer.py +146 -0
- package/hooks/session-end-capture.py +374 -6
- package/hooks/session-start.py +13 -35
- package/hooks/setup_wizard.py +342 -2
- package/hooks/shadow_manager.py +111 -2
- package/hooks/stop_dispatcher.py +108 -4
- package/hud/omg-hud.mjs +30 -6
- package/lab/pipeline.py +197 -26
- package/package.json +1 -1
- package/plugins/advanced/plugin.json +26 -9
- package/plugins/core/plugin.json +51 -12
- package/pyproject.toml +10 -2
- package/registry/bundles/algorithms.yaml +1 -1
- package/registry/bundles/api-twin.yaml +1 -1
- package/registry/bundles/claim-judge.yaml +1 -1
- package/registry/bundles/control-plane.yaml +1 -1
- package/registry/bundles/data-lineage.yaml +1 -1
- package/registry/bundles/delta-classifier.yaml +1 -1
- package/registry/bundles/eval-gate.yaml +1 -1
- package/registry/bundles/health.yaml +1 -1
- package/registry/bundles/hook-governor.yaml +1 -1
- package/registry/bundles/incident-replay.yaml +1 -1
- package/registry/bundles/lsp-pack.yaml +1 -1
- package/registry/bundles/mcp-fabric.yaml +1 -1
- package/registry/bundles/plan-council.yaml +1 -1
- package/registry/bundles/preflight.yaml +1 -1
- package/registry/bundles/proof-gate.yaml +1 -1
- package/registry/bundles/remote-supervisor.yaml +1 -1
- package/registry/bundles/robotics.yaml +1 -1
- package/registry/bundles/secure-worktree-pipeline.yaml +1 -1
- package/registry/bundles/security-check.yaml +1 -1
- package/registry/bundles/test-intent-lock.yaml +1 -1
- package/registry/bundles/tracebank.yaml +1 -1
- package/registry/bundles/vision.yaml +1 -1
- package/registry/omg-capability.schema.json +1 -1
- package/runtime/adoption.py +7 -5
- package/runtime/background_verification.py +62 -0
- package/runtime/claim_judge.py +165 -5
- package/runtime/compat.py +48 -1
- package/runtime/context_engine.py +261 -4
- package/runtime/contract_compiler.py +370 -93
- package/runtime/defense_state.py +79 -8
- package/runtime/delta_classifier.py +80 -2
- package/runtime/evidence_query.py +56 -4
- package/runtime/evidence_registry.py +16 -0
- package/runtime/evidence_requirements.py +47 -0
- package/runtime/forge_agents.py +179 -9
- package/runtime/forge_contracts.py +208 -2
- package/runtime/hook_governor.py +19 -1
- package/runtime/interaction_journal.py +318 -42
- package/runtime/memory_store.py +134 -1
- package/runtime/mutation_gate.py +57 -11
- package/runtime/omg_compat_contract_snapshot.json +2 -2
- package/runtime/omg_mcp_server.py +14 -4
- package/runtime/plugin_diagnostics.py +248 -0
- package/runtime/plugin_interop.py +1007 -0
- package/runtime/preflight.py +14 -0
- package/runtime/profile_io.py +294 -0
- package/runtime/proof_gate.py +122 -7
- package/runtime/providers/opencode_provider.py +94 -0
- package/runtime/release_run_coordinator.py +339 -0
- package/runtime/release_surfaces.py +243 -0
- package/runtime/rollback_manifest.py +136 -0
- package/runtime/router_critics.py +50 -0
- package/runtime/runtime_contracts.py +137 -0
- package/runtime/security_check.py +16 -0
- package/runtime/session_health.py +60 -16
- package/runtime/team_router.py +156 -13
- package/runtime/test_intent_lock.py +102 -0
- package/runtime/tool_plan_gate.py +218 -19
- package/runtime/validate.py +289 -0
- package/runtime/verification_controller.py +52 -2
- package/scripts/omg.py +306 -3
- package/scripts/prepare-release-proof-fixtures.py +191 -7
- package/scripts/print-canonical-version.py +80 -0
- package/scripts/sync-release-identity.py +476 -0
- package/scripts/validate-release-identity.py +246 -0
- package/scripts/verify-standalone.sh +3 -0
- package/settings.json +3 -3
- package/templates/plugins-allowlist.yaml +19 -0
- package/artifacts/release/dist/enterprise/bundle/.gemini/settings.json +0 -11
- package/artifacts/release/dist/enterprise/bundle/.kimi/mcp.json +0 -11
- package/artifacts/release/dist/public/bundle/.gemini/settings.json +0 -11
- package/artifacts/release/dist/public/bundle/.kimi/mcp.json +0 -11
- package/build/lib/yaml.py +0 -321
- package/dist/enterprise/bundle/.gemini/settings.json +0 -11
- package/dist/enterprise/bundle/.kimi/mcp.json +0 -11
- package/dist/public/bundle/.gemini/settings.json +0 -11
- package/dist/public/bundle/.kimi/mcp.json +0 -11
package/runtime/mutation_gate.py
CHANGED
|
@@ -2,13 +2,25 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
+
import re
|
|
6
|
+
import warnings
|
|
5
7
|
from datetime import datetime, timezone
|
|
6
8
|
from hashlib import sha256
|
|
7
9
|
from pathlib import Path
|
|
8
10
|
|
|
11
|
+
from runtime.release_run_coordinator import resolve_current_run_id
|
|
12
|
+
from runtime.test_intent_lock import verify_lock
|
|
13
|
+
|
|
9
14
|
|
|
10
15
|
_MUTATING_TOOLS = frozenset({"Write", "Edit", "MultiEdit"})
|
|
11
16
|
_EXEMPTIONS = frozenset({"docs", "config", "generated", "test"})
|
|
17
|
+
_MUTATION_BASH_PATTERNS = (
|
|
18
|
+
r"\b(git\s+(add|commit|push|rebase|cherry-pick|merge|tag))\b",
|
|
19
|
+
r"\b(rm|mv|cp|tee|touch|mkdir|rmdir|ln)\b",
|
|
20
|
+
r"\b(sed\s+-i|perl\s+-pi)\b",
|
|
21
|
+
r"\b(chmod|chown)\b",
|
|
22
|
+
r">\s*[^\s]",
|
|
23
|
+
)
|
|
12
24
|
|
|
13
25
|
|
|
14
26
|
def check_mutation_allowed(
|
|
@@ -18,11 +30,25 @@ def check_mutation_allowed(
|
|
|
18
30
|
lock_id: str | None,
|
|
19
31
|
*,
|
|
20
32
|
exemption: str | None = None,
|
|
33
|
+
command: str | None = None,
|
|
34
|
+
run_id: str | None = None,
|
|
35
|
+
metadata: dict[str, object] | None = None,
|
|
21
36
|
) -> dict[str, str | None]:
|
|
22
37
|
normalized_tool = str(tool or "").strip()
|
|
23
38
|
normalized_file_path = str(file_path or "").strip()
|
|
24
39
|
normalized_lock_id = str(lock_id or "").strip() or None
|
|
25
40
|
normalized_exemption = str(exemption or "").strip().lower() or None
|
|
41
|
+
normalized_command = str(command or "").strip()
|
|
42
|
+
metadata_obj = metadata if isinstance(metadata, dict) else {}
|
|
43
|
+
explicit_exempt = bool(metadata_obj.get("exempt") is True)
|
|
44
|
+
strict_mode = os.environ.get("OMG_TDD_GATE_STRICT", "0").strip() == "1"
|
|
45
|
+
|
|
46
|
+
if explicit_exempt:
|
|
47
|
+
return {
|
|
48
|
+
"status": "exempt",
|
|
49
|
+
"reason": "metadata exemption allows mutation without lock",
|
|
50
|
+
"lock_id": normalized_lock_id,
|
|
51
|
+
}
|
|
26
52
|
|
|
27
53
|
if normalized_exemption in _EXEMPTIONS:
|
|
28
54
|
return {
|
|
@@ -31,36 +57,56 @@ def check_mutation_allowed(
|
|
|
31
57
|
"lock_id": normalized_lock_id,
|
|
32
58
|
}
|
|
33
59
|
|
|
34
|
-
|
|
60
|
+
requires_lock = normalized_tool in _MUTATING_TOOLS
|
|
61
|
+
if normalized_tool == "Bash":
|
|
62
|
+
requires_lock = _is_mutation_capable_bash(normalized_command)
|
|
63
|
+
|
|
64
|
+
if not requires_lock:
|
|
35
65
|
return {
|
|
36
66
|
"status": "allowed",
|
|
37
67
|
"reason": "tool is read-only for mutation gate",
|
|
38
68
|
"lock_id": normalized_lock_id,
|
|
39
69
|
}
|
|
40
70
|
|
|
41
|
-
|
|
71
|
+
resolved_run_id = str(run_id or "").strip() or resolve_current_run_id(project_dir=project_dir)
|
|
72
|
+
verification = verify_lock(project_dir, run_id=resolved_run_id, lock_id=normalized_lock_id)
|
|
73
|
+
if verification.get("status") == "ok":
|
|
42
74
|
return {
|
|
43
75
|
"status": "allowed",
|
|
44
76
|
"reason": "active test intent lock found",
|
|
77
|
+
"lock_id": str(verification.get("lock_id") or normalized_lock_id or "") or None,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
reason = str(verification.get("reason", "no_active_test_intent_lock"))
|
|
81
|
+
if strict_mode:
|
|
82
|
+
_write_block_artifact(project_dir, normalized_tool, normalized_file_path, reason)
|
|
83
|
+
return {
|
|
84
|
+
"status": "blocked",
|
|
85
|
+
"reason": reason,
|
|
45
86
|
"lock_id": normalized_lock_id,
|
|
46
87
|
}
|
|
47
88
|
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
89
|
+
warnings.warn(
|
|
90
|
+
f"mutation_gate_permissive_allow:{normalized_tool}:{reason}",
|
|
91
|
+
RuntimeWarning,
|
|
92
|
+
stacklevel=2,
|
|
52
93
|
)
|
|
53
|
-
_write_block_artifact(project_dir, normalized_tool, normalized_file_path, reason)
|
|
54
94
|
return {
|
|
55
|
-
"status": "
|
|
95
|
+
"status": "allowed",
|
|
56
96
|
"reason": reason,
|
|
57
97
|
"lock_id": normalized_lock_id,
|
|
58
98
|
}
|
|
59
99
|
|
|
60
100
|
|
|
61
|
-
def
|
|
62
|
-
|
|
63
|
-
|
|
101
|
+
def _is_mutation_capable_bash(command: str) -> bool:
|
|
102
|
+
normalized_command = str(command or "").strip()
|
|
103
|
+
if not normalized_command:
|
|
104
|
+
return False
|
|
105
|
+
lowered = normalized_command.lower()
|
|
106
|
+
for pattern in _MUTATION_BASH_PATTERNS:
|
|
107
|
+
if re.search(pattern, lowered):
|
|
108
|
+
return True
|
|
109
|
+
return False
|
|
64
110
|
|
|
65
111
|
|
|
66
112
|
def _write_block_artifact(project_dir: str, tool: str, file_path: str, reason: str) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "OmgCompatContractSnapshot",
|
|
3
|
-
"contract_version": "2.1.
|
|
3
|
+
"contract_version": "2.1.4",
|
|
4
4
|
"count": 47,
|
|
5
5
|
"contracts": [
|
|
6
6
|
{
|
|
@@ -912,5 +912,5 @@
|
|
|
912
912
|
"notes": "Writes long-form memory artifact for writing workflows."
|
|
913
913
|
}
|
|
914
914
|
],
|
|
915
|
-
"generated_at": "2026-03-
|
|
915
|
+
"generated_at": "2026-03-09T21:20:44.496932+00:00"
|
|
916
916
|
}
|
|
@@ -125,7 +125,7 @@ def _read_repo_text(rel_path: str) -> str:
|
|
|
125
125
|
|
|
126
126
|
@mcp.tool()
|
|
127
127
|
def omg_policy_evaluate(tool: str, input: dict[str, Any]) -> dict[str, Any]:
|
|
128
|
-
if tool in {"Write", "Edit", "MultiEdit"}:
|
|
128
|
+
if tool in {"Write", "Edit", "MultiEdit", "Bash"}:
|
|
129
129
|
run_id_candidate = input.get("run_id") if isinstance(input, dict) else None
|
|
130
130
|
run_id: str | None = None
|
|
131
131
|
if isinstance(run_id_candidate, str) and run_id_candidate.strip():
|
|
@@ -138,9 +138,10 @@ def omg_policy_evaluate(tool: str, input: dict[str, Any]) -> dict[str, Any]:
|
|
|
138
138
|
if not run_id:
|
|
139
139
|
run_id = resolve_current_run_id()
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
if tool in {"Write", "Edit", "MultiEdit"}:
|
|
142
|
+
tool_plan_result = tool_plan_gate_check(_service().project_dir, run_id, tool)
|
|
143
|
+
if tool_plan_result.get("status") == "blocked":
|
|
144
|
+
return tool_plan_result
|
|
144
145
|
|
|
145
146
|
lock_id: str | None = None
|
|
146
147
|
if isinstance(metadata, dict):
|
|
@@ -158,6 +159,9 @@ def omg_policy_evaluate(tool: str, input: dict[str, Any]) -> dict[str, Any]:
|
|
|
158
159
|
"file_path": str(input.get("file_path", "")) if isinstance(input, dict) else "",
|
|
159
160
|
"lock_id": lock_id,
|
|
160
161
|
"exemption": exemption,
|
|
162
|
+
"command": str(input.get("command", "")) if isinstance(input, dict) else "",
|
|
163
|
+
"run_id": run_id,
|
|
164
|
+
"metadata": metadata if isinstance(metadata, dict) else None,
|
|
161
165
|
}
|
|
162
166
|
)
|
|
163
167
|
if gate_status == 200 and gate_payload.get("status") == "blocked":
|
|
@@ -238,6 +242,12 @@ def omg_guide_assert(candidate: str, rules: dict[str, Any]) -> dict[str, Any]:
|
|
|
238
242
|
return payload
|
|
239
243
|
|
|
240
244
|
|
|
245
|
+
@mcp.tool()
|
|
246
|
+
def omg_get_session_health(run_id: str | None = None) -> dict[str, Any]:
|
|
247
|
+
_status, payload = _service().session_health({"run_id": run_id})
|
|
248
|
+
return payload
|
|
249
|
+
|
|
250
|
+
|
|
241
251
|
@mcp.prompt(name="omg_contract_summary", description="Summarize the OMG production contract and generated host outputs")
|
|
242
252
|
def omg_contract_summary(channel: str = "public") -> str:
|
|
243
253
|
return (
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import time
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Callable, cast
|
|
7
|
+
|
|
8
|
+
from runtime import plugin_interop
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _load_allowlist(root: str | None) -> list[plugin_interop.PluginAllowlistEntry]:
|
|
12
|
+
load_fn = cast(
|
|
13
|
+
Callable[[str | None], list[plugin_interop.PluginAllowlistEntry]] | None,
|
|
14
|
+
getattr(plugin_interop, "load_plugin_allowlist", None),
|
|
15
|
+
)
|
|
16
|
+
if callable(load_fn):
|
|
17
|
+
return load_fn(root)
|
|
18
|
+
return []
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
_LIVE_BUDGET_MS: float = 3000.0
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _resolve_mcp_command(server_name: str, root: str | None) -> list[str] | None:
|
|
25
|
+
root_path = Path(root or ".").resolve()
|
|
26
|
+
for mcp_path in (
|
|
27
|
+
root_path / ".claude-plugin" / "mcp.json",
|
|
28
|
+
root_path / ".mcp.json",
|
|
29
|
+
):
|
|
30
|
+
try:
|
|
31
|
+
raw = mcp_path.read_text(encoding="utf-8")
|
|
32
|
+
except OSError:
|
|
33
|
+
continue
|
|
34
|
+
try:
|
|
35
|
+
payload = json.loads(raw)
|
|
36
|
+
except (json.JSONDecodeError, ValueError):
|
|
37
|
+
continue
|
|
38
|
+
if not isinstance(payload, dict):
|
|
39
|
+
continue
|
|
40
|
+
servers = payload.get("mcpServers", {})
|
|
41
|
+
if not isinstance(servers, dict):
|
|
42
|
+
continue
|
|
43
|
+
entry = servers.get(server_name)
|
|
44
|
+
if not isinstance(entry, dict):
|
|
45
|
+
continue
|
|
46
|
+
cmd = entry.get("command")
|
|
47
|
+
args = entry.get("args", [])
|
|
48
|
+
if isinstance(cmd, str):
|
|
49
|
+
cmd_list = [cmd]
|
|
50
|
+
if isinstance(args, list):
|
|
51
|
+
cmd_list.extend(str(a) for a in args)
|
|
52
|
+
return cmd_list
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _probe_mcp_servers_live(
|
|
57
|
+
records: list[plugin_interop.PluginInteropRecord],
|
|
58
|
+
root: str | None,
|
|
59
|
+
) -> list[dict[str, object]]:
|
|
60
|
+
budget_start = time.monotonic()
|
|
61
|
+
results: list[dict[str, object]] = []
|
|
62
|
+
seen: set[str] = set()
|
|
63
|
+
|
|
64
|
+
for record in records:
|
|
65
|
+
for server_name in record.mcp_servers:
|
|
66
|
+
if server_name in seen:
|
|
67
|
+
continue
|
|
68
|
+
seen.add(server_name)
|
|
69
|
+
|
|
70
|
+
elapsed_total_ms = (time.monotonic() - budget_start) * 1000.0
|
|
71
|
+
if elapsed_total_ms >= _LIVE_BUDGET_MS:
|
|
72
|
+
results.append({
|
|
73
|
+
"server": server_name,
|
|
74
|
+
"status": "skipped",
|
|
75
|
+
"elapsed_ms": 0.0,
|
|
76
|
+
})
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
command = _resolve_mcp_command(server_name, root)
|
|
80
|
+
if command is None:
|
|
81
|
+
results.append({
|
|
82
|
+
"server": server_name,
|
|
83
|
+
"status": "skipped",
|
|
84
|
+
"elapsed_ms": 0.0,
|
|
85
|
+
})
|
|
86
|
+
continue
|
|
87
|
+
|
|
88
|
+
remaining_ms = _LIVE_BUDGET_MS - elapsed_total_ms
|
|
89
|
+
probe_timeout = min(1500, int(remaining_ms))
|
|
90
|
+
results.append(
|
|
91
|
+
plugin_interop.probe_mcp_server_live(
|
|
92
|
+
server_name, command, timeout_ms=probe_timeout,
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
return results
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _record_sort_key(record: plugin_interop.PluginInteropRecord) -> tuple[str, str, str, str]:
|
|
100
|
+
return (record.host, record.plugin_id, record.layer, record.source)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def run_plugin_diagnostics(root: str | None = None, live: bool = False) -> dict[str, object]:
|
|
104
|
+
started = time.monotonic()
|
|
105
|
+
|
|
106
|
+
omg_payload = plugin_interop.discover_omg_plugin_state(root)
|
|
107
|
+
host_payload = plugin_interop.discover_host_plugin_state(root)
|
|
108
|
+
|
|
109
|
+
all_records = [*omg_payload.records, *host_payload.records]
|
|
110
|
+
ordered_records = sorted(all_records, key=_record_sort_key)
|
|
111
|
+
conflicts = plugin_interop.classify_conflicts(ordered_records)
|
|
112
|
+
approvals = _load_allowlist(root)
|
|
113
|
+
approval_states = plugin_interop.get_approval_status_for_all(ordered_records, approvals)
|
|
114
|
+
|
|
115
|
+
blocker_count = sum(1 for conflict in conflicts if conflict.severity == "blocker")
|
|
116
|
+
warning_count = sum(1 for conflict in conflicts if conflict.severity == "warning")
|
|
117
|
+
info_count = sum(1 for conflict in conflicts if conflict.severity == "info")
|
|
118
|
+
|
|
119
|
+
if blocker_count > 0:
|
|
120
|
+
status = "error"
|
|
121
|
+
elif warning_count > 0:
|
|
122
|
+
status = "warn"
|
|
123
|
+
else:
|
|
124
|
+
status = "ok"
|
|
125
|
+
|
|
126
|
+
next_actions: list[str] = []
|
|
127
|
+
for conflict in conflicts:
|
|
128
|
+
action = conflict.next_action
|
|
129
|
+
if action and action not in next_actions:
|
|
130
|
+
next_actions.append(action)
|
|
131
|
+
if len(next_actions) >= 3:
|
|
132
|
+
break
|
|
133
|
+
|
|
134
|
+
result: dict[str, object] = {
|
|
135
|
+
"schema": "PluginDiagnosticsResult",
|
|
136
|
+
"status": status,
|
|
137
|
+
"records": [record.to_dict() for record in ordered_records],
|
|
138
|
+
"conflicts": [
|
|
139
|
+
{
|
|
140
|
+
"code": conflict.code,
|
|
141
|
+
"severity": conflict.severity,
|
|
142
|
+
"affected_plugin_ids": list(conflict.affected_plugin_ids),
|
|
143
|
+
"affected_hosts": list(conflict.affected_hosts),
|
|
144
|
+
"detail": conflict.detail,
|
|
145
|
+
"next_action": conflict.next_action,
|
|
146
|
+
}
|
|
147
|
+
for conflict in conflicts
|
|
148
|
+
],
|
|
149
|
+
"approval_states": dict(sorted(approval_states.items())),
|
|
150
|
+
"summary": {
|
|
151
|
+
"total_records": len(ordered_records),
|
|
152
|
+
"total_conflicts": len(conflicts),
|
|
153
|
+
"blockers": blocker_count,
|
|
154
|
+
"warnings": warning_count,
|
|
155
|
+
"infos": info_count,
|
|
156
|
+
},
|
|
157
|
+
"next_actions": next_actions,
|
|
158
|
+
"elapsed_ms": (time.monotonic() - started) * 1000.0,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if live:
|
|
162
|
+
result["live_probe_results"] = _probe_mcp_servers_live(ordered_records, root)
|
|
163
|
+
|
|
164
|
+
return result
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _infer_resource_type(source: str) -> str:
|
|
168
|
+
if source.startswith("mcp:"):
|
|
169
|
+
return "mcp_server"
|
|
170
|
+
if source.startswith("skill:"):
|
|
171
|
+
return "skill"
|
|
172
|
+
if source.startswith("plugin:"):
|
|
173
|
+
return "plugin"
|
|
174
|
+
raise ValueError("source must start with one of: mcp:, skill:, plugin:")
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _record_sources(record: dict[str, object]) -> set[str]:
|
|
178
|
+
discovered: set[str] = set()
|
|
179
|
+
for server in cast(list[object], record.get("mcp_servers", [])):
|
|
180
|
+
if isinstance(server, str):
|
|
181
|
+
discovered.add(f"mcp:{server}")
|
|
182
|
+
|
|
183
|
+
plugin_id = record.get("plugin_id")
|
|
184
|
+
source = record.get("source")
|
|
185
|
+
if isinstance(plugin_id, str):
|
|
186
|
+
if source == plugin_interop.Source.SKILL_REGISTRY.value:
|
|
187
|
+
discovered.add(f"skill:{plugin_id}")
|
|
188
|
+
else:
|
|
189
|
+
discovered.add(f"plugin:{plugin_id}")
|
|
190
|
+
return discovered
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def approve_plugin(source: str, host: str, reason: str, root: str | None = None) -> dict[str, object]:
|
|
194
|
+
diagnostics = run_plugin_diagnostics(root)
|
|
195
|
+
records = diagnostics.get("records", [])
|
|
196
|
+
approval_states = diagnostics.get("approval_states", {})
|
|
197
|
+
|
|
198
|
+
matching_discovered = False
|
|
199
|
+
if isinstance(records, list):
|
|
200
|
+
for record in cast(list[object], records):
|
|
201
|
+
if not isinstance(record, dict):
|
|
202
|
+
continue
|
|
203
|
+
record_host = cast(str | None, record.get("host"))
|
|
204
|
+
if record_host != host:
|
|
205
|
+
continue
|
|
206
|
+
if source in _record_sources(cast(dict[str, object], record)):
|
|
207
|
+
matching_discovered = True
|
|
208
|
+
break
|
|
209
|
+
|
|
210
|
+
if not matching_discovered and isinstance(approval_states, dict):
|
|
211
|
+
for plugin_id, _status in cast(dict[object, object], approval_states).items():
|
|
212
|
+
if not isinstance(plugin_id, str):
|
|
213
|
+
continue
|
|
214
|
+
if source in {f"plugin:{plugin_id}", f"skill:{plugin_id}"}:
|
|
215
|
+
matching_discovered = True
|
|
216
|
+
break
|
|
217
|
+
|
|
218
|
+
if not matching_discovered:
|
|
219
|
+
return {
|
|
220
|
+
"schema": "ApprovalResult",
|
|
221
|
+
"status": "error",
|
|
222
|
+
"message": (
|
|
223
|
+
f"No discovered resource matching source={source!r} and host={host!r}. "
|
|
224
|
+
"Run diagnose-plugins first."
|
|
225
|
+
),
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
entry = plugin_interop.PluginAllowlistEntry(
|
|
229
|
+
source=source,
|
|
230
|
+
host=host,
|
|
231
|
+
resource_type=_infer_resource_type(source),
|
|
232
|
+
reason=reason,
|
|
233
|
+
)
|
|
234
|
+
plugin_interop.validate_plugin_allowlist_entry(entry.to_dict())
|
|
235
|
+
entries = plugin_interop.load_plugin_allowlist(root)
|
|
236
|
+
|
|
237
|
+
exists = any(existing.source == source and existing.host == host for existing in entries)
|
|
238
|
+
if not exists:
|
|
239
|
+
entries.append(entry)
|
|
240
|
+
|
|
241
|
+
_ = plugin_interop.save_plugin_allowlist(entries, root)
|
|
242
|
+
return {
|
|
243
|
+
"schema": "ApprovalResult",
|
|
244
|
+
"status": "ok",
|
|
245
|
+
"source": source,
|
|
246
|
+
"host": host,
|
|
247
|
+
"message": "Approved and saved to .omg/state/plugins-allowlist.yaml",
|
|
248
|
+
}
|