platformforge 0.1.0__py3-none-any.whl
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.
- platformforge/__init__.py +7 -0
- platformforge/__main__.py +5 -0
- platformforge/_forge_portal.py +913 -0
- platformforge/_graphstudio.py +376 -0
- platformforge/_graphview.py +181 -0
- platformforge/_installkit.py +1706 -0
- platformforge/agents/__init__.py +156 -0
- platformforge/agents/bench.py +61 -0
- platformforge/agents/contextpack.py +137 -0
- platformforge/agents/contracts.py +394 -0
- platformforge/agents/coordinators.py +98 -0
- platformforge/agents/critic.py +113 -0
- platformforge/agents/debate.py +161 -0
- platformforge/agents/executors.py +160 -0
- platformforge/agents/guardian.py +48 -0
- platformforge/agents/mirrors.py +240 -0
- platformforge/agents/orchestrator.py +295 -0
- platformforge/agents/planner.py +116 -0
- platformforge/agents/playbook.py +51 -0
- platformforge/agents/referee.py +132 -0
- platformforge/agents/reviewers.py +113 -0
- platformforge/agents/roster.py +893 -0
- platformforge/agents/runledger.py +85 -0
- platformforge/agents/runstore.py +74 -0
- platformforge/agents/specialists.py +73 -0
- platformforge/agents/taskspec.py +94 -0
- platformforge/agents/uniqueness.py +115 -0
- platformforge/agents/verifier.py +106 -0
- platformforge/aiplat/__init__.py +4 -0
- platformforge/aiplat/models.py +175 -0
- platformforge/analytics/__init__.py +6 -0
- platformforge/analytics/capacity.py +109 -0
- platformforge/analytics/debt.py +92 -0
- platformforge/analytics/dx.py +69 -0
- platformforge/analytics/finops_v4.py +171 -0
- platformforge/analytics/goldenpath.py +131 -0
- platformforge/analytics/history.py +233 -0
- platformforge/analytics/measurement.py +149 -0
- platformforge/analytics/models.py +127 -0
- platformforge/analytics/opsanalytics.py +119 -0
- platformforge/analytics/policyintel.py +139 -0
- platformforge/analytics/reliability.py +106 -0
- platformforge/analytics/soak.py +135 -0
- platformforge/analytics/store.py +254 -0
- platformforge/bench.py +174 -0
- platformforge/cases/__init__.py +13 -0
- platformforge/cases/casefile.py +106 -0
- platformforge/cases/context_audit.py +134 -0
- platformforge/cases/ledgers.py +174 -0
- platformforge/cases/replay.py +142 -0
- platformforge/cases/routing_audit.py +162 -0
- platformforge/caveman/__init__.py +11 -0
- platformforge/caveman/compress.py +156 -0
- platformforge/cicd/__init__.py +16 -0
- platformforge/cicd/backstage.py +51 -0
- platformforge/cicd/dockerfile.py +64 -0
- platformforge/cicd/github_actions.py +122 -0
- platformforge/cicd/gitlab_ci.py +56 -0
- platformforge/cicd/gitops.py +130 -0
- platformforge/cli/__init__.py +0 -0
- platformforge/cli/fleetcmd.py +457 -0
- platformforge/cli/main.py +3832 -0
- platformforge/cloud/__init__.py +8 -0
- platformforge/cloud/aws.py +254 -0
- platformforge/cloud/common.py +69 -0
- platformforge/cloud/multicloud.py +143 -0
- platformforge/collect/__init__.py +11 -0
- platformforge/collect/detect.py +254 -0
- platformforge/context/__init__.py +10 -0
- platformforge/context/capsule.py +60 -0
- platformforge/context/gateway.py +227 -0
- platformforge/context/refs.py +49 -0
- platformforge/context/sufficiency.py +50 -0
- platformforge/core/__init__.py +1 -0
- platformforge/core/hashing.py +39 -0
- platformforge/core/ownership.py +220 -0
- platformforge/core/receipts.py +74 -0
- platformforge/core/redaction.py +97 -0
- platformforge/core/store.py +119 -0
- platformforge/core/workspace.py +89 -0
- platformforge/data/contracts/agent-handoff.schema.json +26 -0
- platformforge/data/contracts/agent-run.schema.json +27 -0
- platformforge/data/contracts/agent-spec.schema.json +43 -0
- platformforge/data/contracts/capability.schema.json +23 -0
- platformforge/data/contracts/change-event.schema.json +22 -0
- platformforge/data/contracts/change-intent.schema.json +62 -0
- platformforge/data/contracts/change-plan.schema.json +43 -0
- platformforge/data/contracts/collector-receipt.schema.json +36 -0
- platformforge/data/contracts/context-pack.schema.json +29 -0
- platformforge/data/contracts/debate.schema.json +31 -0
- platformforge/data/contracts/distribution-manifest-v1.schema.json +81 -0
- platformforge/data/contracts/drift-event.schema.json +21 -0
- platformforge/data/contracts/fact.schema.json +35 -0
- platformforge/data/contracts/finding.schema.json +20 -0
- platformforge/data/contracts/graph-v2.schema.json +67 -0
- platformforge/data/contracts/graph.schema.json +40 -0
- platformforge/data/contracts/install-receipt-v1.schema.json +49 -0
- platformforge/data/contracts/observation.schema.json +93 -0
- platformforge/data/contracts/receipt.schema.json +21 -0
- platformforge/data/contracts/recommendation.schema.json +32 -0
- platformforge/data/contracts/refusal.schema.json +16 -0
- platformforge/data/contracts/slo-contract.schema.json +25 -0
- platformforge/data/contracts/task-spec.schema.json +37 -0
- platformforge/data/contracts/workspace-manifest-v1.schema.json +62 -0
- platformforge/data/evals/cases/agent-budget-exhaustion/case.yaml +6 -0
- platformforge/data/evals/cases/agent-conflicting-specialists/case.yaml +11 -0
- platformforge/data/evals/cases/agent-fleet-optimization/case.yaml +13 -0
- platformforge/data/evals/cases/agent-host-no-subagents/case.yaml +6 -0
- platformforge/data/evals/cases/agent-incident-multi/case.yaml +13 -0
- platformforge/data/evals/cases/agent-missing-evidence/case.yaml +6 -0
- platformforge/data/evals/cases/agent-multi-domain-audit/case.yaml +14 -0
- platformforge/data/evals/cases/agent-production-change/case.yaml +15 -0
- platformforge/data/evals/cases/agent-security-mandatory/case.yaml +12 -0
- platformforge/data/evals/cases/agent-simple-iac/case.yaml +14 -0
- platformforge/data/evals/cases/approval-integrity-seal/case.yaml +6 -0
- platformforge/data/evals/cases/capacity-hot/case.yaml +7 -0
- platformforge/data/evals/cases/capacity-hot/fixture/capacity.json +5 -0
- platformforge/data/evals/cases/catalog-noowner/case.yaml +7 -0
- platformforge/data/evals/cases/catalog-noowner/fixture/catalog-info.yaml +6 -0
- platformforge/data/evals/cases/contract-fact/case.yaml +5 -0
- platformforge/data/evals/cases/contract-fact/fixture/doc.json +2 -0
- platformforge/data/evals/cases/cosign-unverified/case.yaml +8 -0
- platformforge/data/evals/cases/cosign-unverified/fixture/sig.json +33 -0
- platformforge/data/evals/cases/expected-delta-refusal/case.yaml +6 -0
- platformforge/data/evals/cases/finops-noattr/case.yaml +9 -0
- platformforge/data/evals/cases/finops-noattr/fixture/costs.json +7 -0
- platformforge/data/evals/cases/fleet-inv-absent-allocation-unknown/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-centrality-not-criticality/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-correlation-not-causality/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-dx-no-person-metrics/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-federation-restricted-denied/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-federation-secret-denied/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-history-window-deterministic/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-low-util-not-deletable/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-member-key-deterministic/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-missing-denominator/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-partial-coverage-visible/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-plan-changeintent-only/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-report-all-cited/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-small-sample-confidence/case.yaml +7 -0
- platformforge/data/evals/cases/fleet-inv-uncertain-optimization-suppressed/case.yaml +7 -0
- platformforge/data/evals/cases/gha-dangerous/case.yaml +12 -0
- platformforge/data/evals/cases/gha-dangerous/fixture/.github/workflows/ci.yaml +11 -0
- platformforge/data/evals/cases/gitops-v2/case.yaml +11 -0
- platformforge/data/evals/cases/gitops-v2/fixture/argo.yaml +41 -0
- platformforge/data/evals/cases/graph-k8s-blast/case.yaml +7 -0
- platformforge/data/evals/cases/graph-k8s-blast/fixture/deploy.yaml +15 -0
- platformforge/data/evals/cases/iac-module-nopin/case.yaml +8 -0
- platformforge/data/evals/cases/iac-module-nopin/fixture/main.tf +3 -0
- platformforge/data/evals/cases/iac-plan-replace/case.yaml +8 -0
- platformforge/data/evals/cases/iac-plan-replace/fixture/plan.json +12 -0
- platformforge/data/evals/cases/iac-sg-open/case.yaml +8 -0
- platformforge/data/evals/cases/iac-sg-open/fixture/main.tf +9 -0
- platformforge/data/evals/cases/iam-oidc/case.yaml +8 -0
- platformforge/data/evals/cases/iam-oidc/fixture/policy.json +11 -0
- platformforge/data/evals/cases/iam-wildcard-positive/case.yaml +8 -0
- platformforge/data/evals/cases/iam-wildcard-positive/fixture/policy.json +3 -0
- platformforge/data/evals/cases/k8s-bad-actor/case.yaml +19 -0
- platformforge/data/evals/cases/k8s-bad-actor/fixture/app.yaml +97 -0
- platformforge/data/evals/cases/k8s-beta-api/case.yaml +8 -0
- platformforge/data/evals/cases/k8s-beta-api/fixture/cr.yaml +7 -0
- platformforge/data/evals/cases/k8s-dep-api-boundary/case.yaml +15 -0
- platformforge/data/evals/cases/k8s-dep-api-boundary/fixture/app.yaml +25 -0
- platformforge/data/evals/cases/k8s-dep-api-clean/case.yaml +12 -0
- platformforge/data/evals/cases/k8s-dep-api-clean/fixture/app.yaml +29 -0
- platformforge/data/evals/cases/k8s-dep-api-unknown/case.yaml +11 -0
- platformforge/data/evals/cases/k8s-dep-api-unknown/fixture/app.yaml +25 -0
- platformforge/data/evals/cases/k8s-dep-api-v120/case.yaml +12 -0
- platformforge/data/evals/cases/k8s-dep-api-v120/fixture/app.yaml +25 -0
- platformforge/data/evals/cases/k8s-dep-api-v129/case.yaml +9 -0
- platformforge/data/evals/cases/k8s-dep-api-v129/fixture/app.yaml +25 -0
- platformforge/data/evals/cases/k8s-hpa-noreq/case.yaml +8 -0
- platformforge/data/evals/cases/k8s-hpa-noreq/fixture/app.yaml +28 -0
- platformforge/data/evals/cases/k8s-limits-boundary/case.yaml +10 -0
- platformforge/data/evals/cases/k8s-limits-boundary/fixture/app.yaml +15 -0
- platformforge/data/evals/cases/k8s-limits-negative/case.yaml +8 -0
- platformforge/data/evals/cases/k8s-limits-negative/fixture/deploy.yaml +15 -0
- platformforge/data/evals/cases/k8s-limits-positive/case.yaml +8 -0
- platformforge/data/evals/cases/k8s-limits-positive/fixture/deploy.yaml +14 -0
- platformforge/data/evals/cases/k8s-nopdb/case.yaml +7 -0
- platformforge/data/evals/cases/k8s-nopdb/fixture/app.yaml +34 -0
- platformforge/data/evals/cases/knowledge-registry/case.yaml +10 -0
- platformforge/data/evals/cases/kyverno-dep/case.yaml +10 -0
- platformforge/data/evals/cases/kyverno-dep/fixture/pol.yaml +18 -0
- platformforge/data/evals/cases/kyverno-legacy/case.yaml +8 -0
- platformforge/data/evals/cases/kyverno-legacy/fixture/pol.yaml +7 -0
- platformforge/data/evals/cases/live-aws-collect/case.yaml +11 -0
- platformforge/data/evals/cases/live-aws-collect/fixture/aws/ec2_describe-vpcs.json +15 -0
- platformforge/data/evals/cases/live-aws-collect/fixture/aws/iam_list-users.denied.txt +1 -0
- platformforge/data/evals/cases/live-aws-collect/fixture/aws/sts_get-caller-identity.json +5 -0
- platformforge/data/evals/cases/live-drift/case.yaml +8 -0
- platformforge/data/evals/cases/live-drift/fixture/after.json +22 -0
- platformforge/data/evals/cases/live-drift/fixture/before.json +22 -0
- platformforge/data/evals/cases/live-incident/case.yaml +7 -0
- platformforge/data/evals/cases/live-incident/fixture/changes.json +8 -0
- platformforge/data/evals/cases/live-incident/fixture/incident.json +7 -0
- platformforge/data/evals/cases/live-k8s-collect/case.yaml +10 -0
- platformforge/data/evals/cases/live-k8s-collect/fixture/kubectl/get_configmaps.denied.txt +1 -0
- platformforge/data/evals/cases/live-k8s-collect/fixture/kubectl/get_deployments.apps.json +25 -0
- platformforge/data/evals/cases/live-k8s-collect/fixture/kubectl/get_pods.json +17 -0
- platformforge/data/evals/cases/live-k8s-collect/fixture/kubectl/get_secrets.json +13 -0
- platformforge/data/evals/cases/live-multicluster/case.yaml +7 -0
- platformforge/data/evals/cases/live-multicluster/fixture/clusters.json +6 -0
- platformforge/data/evals/cases/live-plan/case.yaml +7 -0
- platformforge/data/evals/cases/live-plan/fixture/drift.json +8 -0
- platformforge/data/evals/cases/live-reconcile/case.yaml +7 -0
- platformforge/data/evals/cases/live-reconcile/fixture/desired.json +7 -0
- platformforge/data/evals/cases/live-reconcile/fixture/observed.json +18 -0
- platformforge/data/evals/cases/live-secrets-boundary/case.yaml +8 -0
- platformforge/data/evals/cases/live-secrets-boundary/fixture/envelope.json +16 -0
- platformforge/data/evals/cases/live-temporal-graph/case.yaml +10 -0
- platformforge/data/evals/cases/live-temporal-graph/fixture/graph.json +22 -0
- platformforge/data/evals/cases/ops-approval/case.yaml +6 -0
- platformforge/data/evals/cases/ops-convergence/case.yaml +6 -0
- platformforge/data/evals/cases/ops-execution-safety/case.yaml +6 -0
- platformforge/data/evals/cases/ops-intent/case.yaml +6 -0
- platformforge/data/evals/cases/ops-planning/case.yaml +6 -0
- platformforge/data/evals/cases/ops-policy/case.yaml +6 -0
- platformforge/data/evals/cases/ops-rollback/case.yaml +6 -0
- platformforge/data/evals/cases/ops-verification/case.yaml +6 -0
- platformforge/data/evals/cases/rollback-argocd-revision/case.yaml +6 -0
- platformforge/data/evals/cases/rollback-blind-inverse/case.yaml +6 -0
- platformforge/data/evals/cases/rollback-git-commit/case.yaml +6 -0
- platformforge/data/evals/cases/rollback-impossible/case.yaml +6 -0
- platformforge/data/evals/cases/rollback-k8s-annotation-restore/case.yaml +6 -0
- platformforge/data/evals/cases/rollback-k8s-scale/case.yaml +6 -0
- platformforge/data/evals/cases/rollback-material-tamper/case.yaml +6 -0
- platformforge/data/evals/cases/rollback-terraform-replan/case.yaml +6 -0
- platformforge/data/evals/cases/rollback-unknown/case.yaml +6 -0
- platformforge/data/evals/cases/routing-specialist/case.yaml +9 -0
- platformforge/data/evals/cases/rtk-roundtrip/case.yaml +5 -0
- platformforge/data/evals/cases/rtk-roundtrip/fixture/verbose.txt +300 -0
- platformforge/data/evals/cases/sbom-vuln/case.yaml +9 -0
- platformforge/data/evals/cases/sbom-vuln/fixture/sbom.json +9 -0
- platformforge/data/evals/cases/secret-prose-mixed/fixture/app.env +1 -0
- platformforge/data/evals/cases/secret-prose-mixed/fixture/policy-notes.md +7 -0
- platformforge/data/evals/cases/secrets-noleak/case.yaml +5 -0
- platformforge/data/evals/cases/secrets-noleak/fixture/app.env +2 -0
- platformforge/data/evals/cases/slo-fastburn/case.yaml +8 -0
- platformforge/data/evals/cases/slo-fastburn/fixture/events.yaml +2 -0
- platformforge/data/evals/cases/slo-fastburn/fixture/slo.yaml +4 -0
- platformforge/data/evals/cases/slo-noinput/case.yaml +8 -0
- platformforge/data/evals/cases/slo-noinput/fixture/events.yaml +1 -0
- platformforge/data/evals/cases/slo-noinput/fixture/slo.yaml +4 -0
- platformforge/data/evals/cases/sot-conflict/case.yaml +6 -0
- platformforge/data/evals/cases/token-budget/case.yaml +6 -0
- platformforge/data/evals/cases/token-budget/fixture/big.py +50 -0
- platformforge/data/evals/cases/xr-delete/case.yaml +8 -0
- platformforge/data/evals/cases/xr-delete/fixture/xr.yaml +10 -0
- platformforge/data/evals/cases/xr-graph-chain/case.yaml +8 -0
- platformforge/data/evals/cases/xr-graph-chain/fixture/xrd.yaml +90 -0
- platformforge/data/evals/cases/xr-negative-crd/case.yaml +8 -0
- platformforge/data/evals/cases/xr-negative-crd/fixture/widget.yaml +19 -0
- platformforge/data/evals/cases/xr-upbound-mr/case.yaml +8 -0
- platformforge/data/evals/cases/xr-upbound-mr/fixture/bucket.yaml +12 -0
- platformforge/data/evals/qpt-bench/change-review/case.yaml +5 -0
- platformforge/data/evals/qpt-bench/change-review/fixture/plan.json +9 -0
- platformforge/data/evals/qpt-bench/gha-security/case.yaml +5 -0
- platformforge/data/evals/qpt-bench/gha-security/fixture/ci.yml +10 -0
- platformforge/data/evals/qpt-bench/iam-investigate/case.yaml +5 -0
- platformforge/data/evals/qpt-bench/iam-investigate/fixture/policy.json +6 -0
- platformforge/data/evals/qpt-bench/incident-analysis/case.yaml +5 -0
- platformforge/data/evals/qpt-bench/incident-analysis/fixture/query.json +5 -0
- platformforge/data/evals/qpt-bench/incident-analysis/fixture/rules.yaml +6 -0
- platformforge/data/evals/qpt-bench/k8s-review/case.yaml +6 -0
- platformforge/data/evals/qpt-bench/k8s-review/fixture/deploy.yaml +15 -0
- platformforge/data/evals/qpt-bench/tf-security/case.yaml +5 -0
- platformforge/data/evals/qpt-bench/tf-security/fixture/main.tf +17 -0
- platformforge/data/knowledge/aws/eks.yaml +20 -0
- platformforge/data/knowledge/aws/iam.yaml +28 -0
- platformforge/data/knowledge/aws/network-exposure.yaml +19 -0
- platformforge/data/knowledge/aws/organizations.yaml +19 -0
- platformforge/data/knowledge/crossplane/composition-providers.yaml +20 -0
- platformforge/data/knowledge/crossplane/managed-resources.yaml +26 -0
- platformforge/data/knowledge/crossplane/v1-v2.yaml +25 -0
- platformforge/data/knowledge/kubernetes/api-deprecations.yaml +33 -0
- platformforge/data/knowledge/kubernetes/autoscaling-rbac.yaml +27 -0
- platformforge/data/knowledge/kubernetes/gateway-api.yaml +20 -0
- platformforge/data/knowledge/kubernetes/pod-security.yaml +26 -0
- platformforge/data/knowledge/sources.yaml +516 -0
- platformforge/data/knowledge/terraform/lifecycle.yaml +18 -0
- platformforge/data/knowledge/terraform/plan-semantics.yaml +26 -0
- platformforge/data/lab/chaos-pod-kill/chaos.yaml +3 -0
- platformforge/data/lab/chaos-pod-kill/facts.json +13 -0
- platformforge/data/lab/fleets/acme/capacity.yaml +35 -0
- platformforge/data/lab/fleets/acme/costs.yaml +25 -0
- platformforge/data/lab/fleets/acme/events.yaml +41 -0
- platformforge/data/lab/fleets/acme/fleet.yaml +51 -0
- platformforge/data/lab/fleets/acme/graph.yaml +45 -0
- platformforge/data/lab/fleets/acme/policies.yaml +28 -0
- platformforge/data/lab/fleets/acme/requests.yaml +24 -0
- platformforge/data/lab/scenarios/argo-bad-rollout/expected.yaml +6 -0
- platformforge/data/lab/scenarios/argo-bad-rollout/fixture/app.yaml +9 -0
- platformforge/data/lab/scenarios/aws-dump/expected.yaml +19 -0
- platformforge/data/lab/scenarios/aws-dump/fixture/compute.json +4 -0
- platformforge/data/lab/scenarios/aws-dump/fixture/iam.json +7 -0
- platformforge/data/lab/scenarios/aws-dump/fixture/network.json +6 -0
- platformforge/data/lab/scenarios/aws-dump/fixture/org.json +4 -0
- platformforge/data/lab/scenarios/aws-dump/fixture/storage.json +4 -0
- platformforge/data/lab/scenarios/container-unsigned/expected.yaml +5 -0
- platformforge/data/lab/scenarios/container-unsigned/fixture/supply.json +11 -0
- platformforge/data/lab/scenarios/cost-idle-workload/expected.yaml +5 -0
- platformforge/data/lab/scenarios/cost-idle-workload/fixture/costs.json +12 -0
- platformforge/data/lab/scenarios/crossplane-platform/expected.yaml +16 -0
- platformforge/data/lab/scenarios/crossplane-platform/fixture/negative.yaml +18 -0
- platformforge/data/lab/scenarios/crossplane-platform/fixture/xrd.yaml +90 -0
- platformforge/data/lab/scenarios/demo-platform/expected.yaml +16 -0
- platformforge/data/lab/scenarios/demo-platform/fixture/.github/workflows/ci.yml +10 -0
- platformforge/data/lab/scenarios/demo-platform/fixture/deploy.yaml +16 -0
- platformforge/data/lab/scenarios/demo-platform/fixture/infra.tf +5 -0
- platformforge/data/lab/scenarios/fleet-ai/expected.yaml +12 -0
- platformforge/data/lab/scenarios/fleet-capacity/expected.yaml +12 -0
- platformforge/data/lab/scenarios/fleet-cost/expected.yaml +18 -0
- platformforge/data/lab/scenarios/fleet-federation/expected.yaml +11 -0
- platformforge/data/lab/scenarios/fleet-golden-path/expected.yaml +18 -0
- platformforge/data/lab/scenarios/fleet-op-hotspot/expected.yaml +11 -0
- platformforge/data/lab/scenarios/fleet-ownership/expected.yaml +17 -0
- platformforge/data/lab/scenarios/fleet-partial/expected.yaml +10 -0
- platformforge/data/lab/scenarios/fleet-policy-friction/expected.yaml +10 -0
- platformforge/data/lab/scenarios/fleet-recurring-incident/expected.yaml +12 -0
- platformforge/data/lab/scenarios/fleet-report/expected.yaml +13 -0
- platformforge/data/lab/scenarios/fleet-risk/expected.yaml +18 -0
- platformforge/data/lab/scenarios/gitops-drift/expected.yaml +6 -0
- platformforge/data/lab/scenarios/gitops-drift/fixture/app.yaml +12 -0
- platformforge/data/lab/scenarios/k8s-bad-readiness/expected.yaml +6 -0
- platformforge/data/lab/scenarios/k8s-bad-readiness/fixture/deploy.yaml +23 -0
- platformforge/data/lab/scenarios/k8s-bad-readiness/fixture/netpol.yaml +9 -0
- platformforge/data/lab/scenarios/k8s-missing-limits/expected.yaml +6 -0
- platformforge/data/lab/scenarios/k8s-missing-limits/fixture/deploy.yaml +26 -0
- platformforge/data/lab/scenarios/k8s-missing-limits/fixture/netpol.yaml +9 -0
- platformforge/data/lab/scenarios/k8s-single-replica/expected.yaml +5 -0
- platformforge/data/lab/scenarios/k8s-single-replica/fixture/deploy.yaml +26 -0
- platformforge/data/lab/scenarios/k8s-single-replica/fixture/netpol.yaml +4 -0
- platformforge/data/lab/scenarios/live-aws-collect/expected.yaml +4 -0
- platformforge/data/lab/scenarios/live-aws-collect/fixture/aws/ec2_describe-vpcs.json +15 -0
- platformforge/data/lab/scenarios/live-aws-collect/fixture/aws/iam_list-users.denied.txt +1 -0
- platformforge/data/lab/scenarios/live-aws-collect/fixture/aws/sts_get-caller-identity.json +5 -0
- platformforge/data/lab/scenarios/live-k8s-collect/expected.yaml +4 -0
- platformforge/data/lab/scenarios/live-k8s-collect/fixture/kubectl/get_configmaps.denied.txt +1 -0
- platformforge/data/lab/scenarios/live-k8s-collect/fixture/kubectl/get_deployments.apps.json +25 -0
- platformforge/data/lab/scenarios/live-k8s-collect/fixture/kubectl/get_pods.json +17 -0
- platformforge/data/lab/scenarios/live-k8s-collect/fixture/kubectl/get_secrets.json +13 -0
- platformforge/data/lab/scenarios/live-kind/expected.yaml +14 -0
- platformforge/data/lab/scenarios/live-kind/fixture/kubectl/get_configmaps.denied.txt +1 -0
- platformforge/data/lab/scenarios/live-kind/fixture/kubectl/get_deployments.apps.json +25 -0
- platformforge/data/lab/scenarios/live-kind/fixture/kubectl/get_pods.json +17 -0
- platformforge/data/lab/scenarios/live-kind/fixture/kubectl/get_secrets.json +13 -0
- platformforge/data/lab/scenarios/network-policy-missing/expected.yaml +6 -0
- platformforge/data/lab/scenarios/network-policy-missing/fixture/deploy.yaml +26 -0
- platformforge/data/lab/scenarios/ops-bad-rollout/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-bad-rollout/fixture/ops.yaml +33 -0
- platformforge/data/lab/scenarios/ops-break-glass/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-break-glass/fixture/ops.yaml +21 -0
- platformforge/data/lab/scenarios/ops-broken-selector/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-broken-selector/fixture/ops.yaml +21 -0
- platformforge/data/lab/scenarios/ops-changed-plan-hash/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-changed-plan-hash/fixture/ops.yaml +20 -0
- platformforge/data/lab/scenarios/ops-conflicting-operation/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-conflicting-operation/fixture/ops.yaml +21 -0
- platformforge/data/lab/scenarios/ops-expired-approval/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-expired-approval/fixture/ops.yaml +20 -0
- platformforge/data/lab/scenarios/ops-partial-failure/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-partial-failure/fixture/ops.yaml +24 -0
- platformforge/data/lab/scenarios/ops-policy-denial/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-policy-denial/fixture/ops.yaml +17 -0
- platformforge/data/lab/scenarios/ops-replica-drift/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-replica-drift/fixture/ops.yaml +28 -0
- platformforge/data/lab/scenarios/ops-rollback-annotate/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-rollback-annotate/fixture/ops.yaml +41 -0
- platformforge/data/lab/scenarios/ops-rollback-gitops/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-rollback-gitops/fixture/ops.yaml +38 -0
- platformforge/data/lab/scenarios/ops-rollback-impossible/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-rollback-impossible/fixture/ops.yaml +34 -0
- platformforge/data/lab/scenarios/ops-rollback-scale/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-rollback-scale/fixture/ops.yaml +40 -0
- platformforge/data/lab/scenarios/ops-rollback-terraform/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-rollback-terraform/fixture/ops.yaml +38 -0
- platformforge/data/lab/scenarios/ops-rollback-terraform/fixture/tf/tfplan.bin +1 -0
- platformforge/data/lab/scenarios/ops-stale-observation/expected.yaml +3 -0
- platformforge/data/lab/scenarios/ops-stale-observation/fixture/ops.yaml +20 -0
- platformforge/data/lab/scenarios/secret-exposure/expected.yaml +5 -0
- platformforge/data/lab/scenarios/secret-exposure/fixture/app.env +2 -0
- platformforge/data/lab/scenarios/slo-burn/expected.yaml +5 -0
- platformforge/data/lab/scenarios/slo-burn/fixture/events.yaml +2 -0
- platformforge/data/lab/scenarios/slo-burn/fixture/slo.yaml +4 -0
- platformforge/data/lab/scenarios/terraform-iam-wildcard/expected.yaml +5 -0
- platformforge/data/lab/scenarios/terraform-iam-wildcard/fixture/policy.json +14 -0
- platformforge/data/lab/scenarios/terraform-public-bucket/expected.yaml +6 -0
- platformforge/data/lab/scenarios/terraform-public-bucket/fixture/main.tf +5 -0
- platformforge/data/portable_skills/platformforge-agents/SKILL.md +47 -0
- platformforge/data/portable_skills/platformforge-change/SKILL.md +41 -0
- platformforge/data/portable_skills/platformforge-core/SKILL.md +62 -0
- platformforge/data/portable_skills/platformforge-economy/SKILL.md +42 -0
- platformforge/data/portable_skills/platformforge-finops/SKILL.md +34 -0
- platformforge/data/portable_skills/platformforge-fleet/SKILL.md +39 -0
- platformforge/data/portable_skills/platformforge-governance/SKILL.md +76 -0
- platformforge/data/portable_skills/platformforge-graph/SKILL.md +46 -0
- platformforge/data/portable_skills/platformforge-lab/SKILL.md +39 -0
- platformforge/data/portable_skills/platformforge-sdd/SKILL.md +39 -0
- platformforge/data/portable_skills/platformforge-security/SKILL.md +38 -0
- platformforge/data/portable_skills/platformforge-sre/SKILL.md +41 -0
- platformforge/data/rules/catalog/finops.yaml +26 -0
- platformforge/data/rules/catalog/gitops.yaml +161 -0
- platformforge/data/rules/catalog/iac.yaml +84 -0
- platformforge/data/rules/catalog/k8s.yaml +322 -0
- platformforge/data/rules/catalog/orchestration.yaml +99 -0
- platformforge/data/rules/catalog/product.yaml +42 -0
- platformforge/data/rules/catalog/routing.yaml +122 -0
- platformforge/data/rules/catalog/security.yaml +159 -0
- platformforge/data/rules/catalog/sre.yaml +67 -0
- platformforge/diagnose/__init__.py +75 -0
- platformforge/distribution/__init__.py +18 -0
- platformforge/distribution/bundle.py +127 -0
- platformforge/distribution/hostflow.py +247 -0
- platformforge/distribution/models.py +80 -0
- platformforge/distribution/service.py +225 -0
- platformforge/economy/__init__.py +27 -0
- platformforge/economy/bench.py +66 -0
- platformforge/economy/budget.py +198 -0
- platformforge/economy/cache.py +287 -0
- platformforge/economy/checkpoint.py +112 -0
- platformforge/economy/collection.py +142 -0
- platformforge/economy/doctor.py +207 -0
- platformforge/economy/engine.py +158 -0
- platformforge/economy/envelope.py +61 -0
- platformforge/economy/fleetpack.py +86 -0
- platformforge/economy/ledger.py +232 -0
- platformforge/economy/plan.py +131 -0
- platformforge/economy/pricing.py +101 -0
- platformforge/economy/qpt.py +286 -0
- platformforge/economy/reconcile.py +86 -0
- platformforge/economy/verifyplan.py +107 -0
- platformforge/economy/waste.py +123 -0
- platformforge/evals/__init__.py +16 -0
- platformforge/evals/coverage.py +140 -0
- platformforge/evals/fleet_invariants.py +260 -0
- platformforge/evals/ops_invariants.py +158 -0
- platformforge/evals/runner.py +541 -0
- platformforge/federation/__init__.py +4 -0
- platformforge/federation/node.py +135 -0
- platformforge/finops/__init__.py +14 -0
- platformforge/finops/alloc.py +31 -0
- platformforge/finops/costs.py +79 -0
- platformforge/finops/focus.py +100 -0
- platformforge/finops/graph_cost.py +51 -0
- platformforge/finops/ingest.py +144 -0
- platformforge/finops/insights.py +193 -0
- platformforge/finops/unit.py +36 -0
- platformforge/fleet/__init__.py +5 -0
- platformforge/fleet/loader.py +73 -0
- platformforge/fleet/models.py +155 -0
- platformforge/fleet/orggraph.py +172 -0
- platformforge/fleet/query.py +154 -0
- platformforge/forge/__init__.py +9 -0
- platformforge/forge/collect.py +88 -0
- platformforge/forge/delegate.py +77 -0
- platformforge/forge/manifest.py +106 -0
- platformforge/freeze/__init__.py +22 -0
- platformforge/freeze/exceptions.py +56 -0
- platformforge/freeze/manifest.py +167 -0
- platformforge/freeze/snapshots.py +108 -0
- platformforge/graph/__init__.py +39 -0
- platformforge/graph/backend.py +174 -0
- platformforge/graph/bench.py +245 -0
- platformforge/graph/build.py +130 -0
- platformforge/graph/delivery.py +183 -0
- platformforge/graph/diff.py +292 -0
- platformforge/graph/events.py +116 -0
- platformforge/graph/migrate.py +44 -0
- platformforge/graph/model.py +264 -0
- platformforge/graph/persist.py +97 -0
- platformforge/graph/query.py +290 -0
- platformforge/graph/temporal.py +78 -0
- platformforge/graph/vocab.py +63 -0
- platformforge/graphview.py +94 -0
- platformforge/iac/__init__.py +7 -0
- platformforge/iac/drift.py +53 -0
- platformforge/iac/plan.py +84 -0
- platformforge/iac/terraform.py +123 -0
- platformforge/install/__init__.py +1 -0
- platformforge/install/service.py +421 -0
- platformforge/k8s/__init__.py +8 -0
- platformforge/k8s/helm.py +152 -0
- platformforge/k8s/hubble.py +87 -0
- platformforge/k8s/manifests.py +513 -0
- platformforge/knowledge/__init__.py +1 -0
- platformforge/knowledge/packs.py +157 -0
- platformforge/knowledge/registry.py +249 -0
- platformforge/knowledge/select.py +127 -0
- platformforge/lab/__init__.py +5 -0
- platformforge/lab/chaos.py +71 -0
- platformforge/lab/fleetlab.py +351 -0
- platformforge/lab/opslab.py +271 -0
- platformforge/lab/runner.py +219 -0
- platformforge/live/__init__.py +36 -0
- platformforge/live/budget.py +92 -0
- platformforge/live/capability.py +80 -0
- platformforge/live/collectors/__init__.py +6 -0
- platformforge/live/collectors/aws.py +370 -0
- platformforge/live/collectors/aws_transport.py +98 -0
- platformforge/live/collectors/k8s.py +389 -0
- platformforge/live/collectors/k8s_transport.py +85 -0
- platformforge/live/cursors.py +48 -0
- platformforge/live/drift.py +130 -0
- platformforge/live/envelope.py +85 -0
- platformforge/live/federation.py +113 -0
- platformforge/live/fixtures.py +168 -0
- platformforge/live/identity.py +258 -0
- platformforge/live/incident.py +200 -0
- platformforge/live/models.py +435 -0
- platformforge/live/reconcile.py +382 -0
- platformforge/live/remediate.py +169 -0
- platformforge/live/store.py +256 -0
- platformforge/live/topology.py +249 -0
- platformforge/mcp/__init__.py +7 -0
- platformforge/mcp/parity.py +69 -0
- platformforge/mcp/registry.py +427 -0
- platformforge/mcp/server.py +84 -0
- platformforge/mcp/tools.py +732 -0
- platformforge/models/__init__.py +21 -0
- platformforge/models/base.py +214 -0
- platformforge/observe/__init__.py +26 -0
- platformforge/observe/capacity.py +39 -0
- platformforge/observe/dr.py +67 -0
- platformforge/observe/grafana.py +76 -0
- platformforge/observe/incident.py +58 -0
- platformforge/observe/otel.py +135 -0
- platformforge/observe/postmortem.py +72 -0
- platformforge/observe/prometheus.py +88 -0
- platformforge/observe/slo.py +125 -0
- platformforge/ops/__init__.py +8 -0
- platformforge/ops/actions.py +215 -0
- platformforge/ops/analytics.py +83 -0
- platformforge/ops/approval.py +275 -0
- platformforge/ops/autorem.py +101 -0
- platformforge/ops/config.py +175 -0
- platformforge/ops/engine.py +758 -0
- platformforge/ops/envelope.py +135 -0
- platformforge/ops/executors/__init__.py +1 -0
- platformforge/ops/executors/base.py +211 -0
- platformforge/ops/executors/git.py +77 -0
- platformforge/ops/executors/gitops.py +134 -0
- platformforge/ops/executors/terraform.py +84 -0
- platformforge/ops/gates.py +135 -0
- platformforge/ops/goldenpath.py +180 -0
- platformforge/ops/material.py +181 -0
- platformforge/ops/models.py +421 -0
- platformforge/ops/operation.py +335 -0
- platformforge/ops/opgraph.py +233 -0
- platformforge/ops/policy.py +275 -0
- platformforge/ops/preconditions.py +109 -0
- platformforge/ops/registry.py +101 -0
- platformforge/ops/risk.py +216 -0
- platformforge/ops/rollback.py +287 -0
- platformforge/ops/rollback_builders.py +163 -0
- platformforge/ops/runbook.py +269 -0
- platformforge/ops/simulate.py +125 -0
- platformforge/ops/source_of_truth.py +198 -0
- platformforge/ops/store.py +157 -0
- platformforge/ops/verify.py +190 -0
- platformforge/optimize/__init__.py +4 -0
- platformforge/optimize/engine.py +109 -0
- platformforge/optimize/models.py +68 -0
- platformforge/optimize/scan.py +196 -0
- platformforge/plan/__init__.py +107 -0
- platformforge/portable_cli.py +199 -0
- platformforge/portal_adapter.py +740 -0
- platformforge/portal_assets/chunk-7_l-b4Tr.js +1 -0
- platformforge/portal_assets/chunk-B0Iad6pD.js +1 -0
- platformforge/portal_assets/chunk-B605XnCF.js +1 -0
- platformforge/portal_assets/chunk-B7N3TXcn.js +1 -0
- platformforge/portal_assets/chunk-BAj6yGem.js +1 -0
- platformforge/portal_assets/chunk-BGUitn2r.js +1 -0
- platformforge/portal_assets/chunk-BVKnCv85.js +1 -0
- platformforge/portal_assets/chunk-BYyM9V_w.js +1 -0
- platformforge/portal_assets/chunk-BaQMhq-G.js +1 -0
- platformforge/portal_assets/chunk-BavOrxVm.js +1 -0
- platformforge/portal_assets/chunk-Bb0C24YV.js +1 -0
- platformforge/portal_assets/chunk-BfCFGPzs.js +1 -0
- platformforge/portal_assets/chunk-C2t4OUVu.js +1 -0
- platformforge/portal_assets/chunk-C3pI4QjU.js +1 -0
- platformforge/portal_assets/chunk-C4gpbtbP.js +1 -0
- platformforge/portal_assets/chunk-CGWeHhKY.js +1 -0
- platformforge/portal_assets/chunk-CJCT86Dr.js +1 -0
- platformforge/portal_assets/chunk-CXcsLDPJ.js +1 -0
- platformforge/portal_assets/chunk-CcjxoLxw.js +1 -0
- platformforge/portal_assets/chunk-D-gBPXHa.js +1 -0
- platformforge/portal_assets/chunk-D3eZogIe.js +1 -0
- platformforge/portal_assets/chunk-DQU0VyoQ.js +1 -0
- platformforge/portal_assets/chunk-DqWNkF1O.js +1 -0
- platformforge/portal_assets/chunk-DuPPkSIE.js +3 -0
- platformforge/portal_assets/chunk-DyIHOW_a.js +1 -0
- platformforge/portal_assets/chunk-Fx4zSGL5.js +1 -0
- platformforge/portal_assets/chunk-UBKt05Rg.js +1 -0
- platformforge/portal_assets/chunk-htnJDQEY.js +1 -0
- platformforge/portal_assets/chunk-kXRFMGqe.js +1 -0
- platformforge/portal_assets/chunk-qe3u763a.js +1 -0
- platformforge/portal_assets/favicon.ico +0 -0
- platformforge/portal_assets/index.html +13 -0
- platformforge/portal_assets/main-QDFVZK3T.js +5 -0
- platformforge/portal_assets/styles-MQEBDFDX.css +1 -0
- platformforge/product/__init__.py +10 -0
- platformforge/product/backstage.py +49 -0
- platformforge/product/catalog.py +74 -0
- platformforge/product/crossplane.py +341 -0
- platformforge/product/golden_paths/__init__.py +5 -0
- platformforge/product/golden_paths/engine.py +97 -0
- platformforge/product/golden_paths/library.yaml +198 -0
- platformforge/product/golden_paths/model.py +84 -0
- platformforge/product/maturity.py +107 -0
- platformforge/product/scorecards.py +84 -0
- platformforge/resources.py +36 -0
- platformforge/risk/__init__.py +5 -0
- platformforge/risk/engine.py +95 -0
- platformforge/risk/signals.py +49 -0
- platformforge/routing/__init__.py +13 -0
- platformforge/routing/decision.py +191 -0
- platformforge/routing/router.py +328 -0
- platformforge/rtk/__init__.py +9 -0
- platformforge/rtk/compact.py +127 -0
- platformforge/rtk/parsers.py +199 -0
- platformforge/rules/__init__.py +5 -0
- platformforge/rules/engine.py +345 -0
- platformforge/sandbox/__init__.py +7 -0
- platformforge/sandbox/env.py +151 -0
- platformforge/sandbox/review.py +92 -0
- platformforge/sdd/__init__.py +8 -0
- platformforge/sdd/lifecycle.py +239 -0
- platformforge/security/__init__.py +19 -0
- platformforge/security/cosign.py +67 -0
- platformforge/security/iam.py +112 -0
- platformforge/security/identity.py +84 -0
- platformforge/security/kyverno.py +106 -0
- platformforge/security/sbom.py +59 -0
- platformforge/security/scan.py +63 -0
- platformforge/security/slsa.py +86 -0
- platformforge/security/supply.py +62 -0
- platformforge/tokensave/__init__.py +20 -0
- platformforge/tokensave/budget.py +62 -0
- platformforge/tokensave/estimate.py +21 -0
- platformforge/tokensave/index.py +172 -0
- platformforge/tokensave/ledger.py +121 -0
- platformforge/tokensave/packs.py +285 -0
- platformforge/ui/__init__.py +28 -0
- platformforge/ui/app.py +465 -0
- platformforge/ui/home.py +113 -0
- platformforge/ui/i18n.py +143 -0
- platformforge/ui/kit.py +689 -0
- platformforge/ui/screen.py +628 -0
- platformforge/ui/tui.py +94 -0
- platformforge/ui/wizard.py +309 -0
- platformforge/workspace/__init__.py +13 -0
- platformforge/workspace/models.py +35 -0
- platformforge/workspace/service.py +69 -0
- platformforge-0.1.0.dist-info/METADATA +212 -0
- platformforge-0.1.0.dist-info/RECORD +659 -0
- platformforge-0.1.0.dist-info/WHEEL +4 -0
- platformforge-0.1.0.dist-info/entry_points.txt +3 -0
- platformforge-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: platformforge-governance
|
|
3
|
+
description: "Governança do próprio Platform Forge e da plataforma analisada — freeze de arquitetura (manifest, snapshots, check de drift de contrato, FeatureException/RFC de unfreeze), corpus de evidência (cases golden/holdout, replay determinístico, ledgers de falso positivo/negativo, route-audit, context-audit), evals (coverage/precision), policy-as-code (`policy check`) e platform product (maturity, scorecard, golden paths, Backstage). Use quando `freeze check` falhar, antes de mudar roster/schema/CLI/capabilities, para decidir se uma mudança cabe no freeze ou exige exceção, para adicionar caso/eval de regressão, auditar precisão de regras, checar políticas ou medir maturidade/golden path. Não use para revisar mudança de infra do usuário (→ platformforge-change) nem para fluxo de fases de feature (→ platformforge-sdd)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Governança — freeze, evidência, policy, produto
|
|
7
|
+
|
|
8
|
+
Estado atual: **ARCHITECTURE FROZEN** (`docs/freeze/LIFECYCLE.md`). O
|
|
9
|
+
freeze é o default; quem quer mudar arquitetura carrega o ônus da prova.
|
|
10
|
+
|
|
11
|
+
## Freeze
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
platformforge freeze check # drift de contrato + gate de exceções
|
|
15
|
+
platformforge freeze manifest # superfície congelada atual
|
|
16
|
+
platformforge freeze snapshot # recalcula hashes (só com exceção aprovada)
|
|
17
|
+
platformforge freeze exception --spec docs/freeze/exceptions/FE-XXX.json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Snapshots em `docs/freeze/snapshots/` hasheiam **todo campo** de
|
|
21
|
+
agents (`roster.py`), capabilities, CLI, MCP e schemas. Consequência
|
|
22
|
+
prática:
|
|
23
|
+
|
|
24
|
+
- Mudar texto no `roster.py` (até descrição) = `breaking` no
|
|
25
|
+
`freeze check`. Ajuste de apresentação vai no renderer
|
|
26
|
+
(`agents/mirrors.py`), que não é snapshotado.
|
|
27
|
+
- Cabe no freeze sem review: bug-fix, performance-fix (com receipt),
|
|
28
|
+
security-fix, knowledge-update, new-eval, fixture real sanitizada,
|
|
29
|
+
compatibilidade, documentação.
|
|
30
|
+
- Exige FeatureException (`FE-000-template.json`): subsistema novo,
|
|
31
|
+
família de schema pública, nível de autonomia, control plane, pilar de
|
|
32
|
+
domínio, expansão grande de roster. Precisa de `real_world_blocker`
|
|
33
|
+
nomeado + evidência — "seria legal" é não-razão explícita (§210).
|
|
34
|
+
- `freeze snapshot` sem exceção aprovada esconde drift — não rode para
|
|
35
|
+
"deixar verde".
|
|
36
|
+
|
|
37
|
+
## Corpus de evidência
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
platformforge cases list|validate # .platformforge/cases/<golden|holdout>/<id>/case.yaml
|
|
41
|
+
platformforge cases template [--out f] # esqueleto de case (grava case.yaml no cwd)
|
|
42
|
+
platformforge cases replay [--tier golden] # replay determinístico, hash canônico
|
|
43
|
+
platformforge cases ledger | ledger-check # FP/FN: todo registro aponta regressão
|
|
44
|
+
platformforge cases route-audit | route-bench # Router V2 sobre o corpus
|
|
45
|
+
platformforge cases context-audit --stamp # context_cost medido
|
|
46
|
+
platformforge evals list|run|coverage|precision [--type T]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- Defeito real encontrado → registro no ledger **e** case de regressão;
|
|
50
|
+
`ledger-check` falha se o ponteiro não resolve.
|
|
51
|
+
- `holdout` não é usado para calibrar — só para medir. Ajustar regra
|
|
52
|
+
olhando holdout invalida a medição.
|
|
53
|
+
- Replay é determinístico: hash diferente sem mudança de código é bug,
|
|
54
|
+
não flakiness.
|
|
55
|
+
|
|
56
|
+
## Policy e produto
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
platformforge policy list | policy check <path>
|
|
60
|
+
platformforge product maturity|scorecard|capabilities [--facts f --findings f]
|
|
61
|
+
platformforge product paths | product path --id <id> | product path-analyze
|
|
62
|
+
platformforge product backstage [--facts f]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- Maturity/scorecard derivam de facts+findings — passe `--facts`/`--findings`
|
|
66
|
+
do repo analisado; sem eles o score reflete só sinais declarados.
|
|
67
|
+
- Métricas de DX são por time, nunca individuais.
|
|
68
|
+
|
|
69
|
+
## Fronteira
|
|
70
|
+
|
|
71
|
+
- `ops`/`live` são boundary do host (níveis S0–S5, `--execute`, aprovação
|
|
72
|
+
humana). Esta skill audita, não executa — mutação governada pertence a
|
|
73
|
+
`platformforge-change` + gate humano.
|
|
74
|
+
- Receipts (`docs/freeze/*-RECEIPT.json`) são ligados a um SHA medido;
|
|
75
|
+
nunca edite à mão para refletir commit novo — regenere pela via que os
|
|
76
|
+
produziu.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: platformforge-graph
|
|
3
|
+
description: "Constrói e consulta o grafo de plataforma (Graphfy) a partir de fatos — deps, dependents, blast radius por classe de impacto, paths, gaps, cycles, diff entre snapshots, grafo de identidade (identity-become/access/workloads/blast) e queries temporais (at/timeline). Use para 'o que essa mudança afeta', 'quem depende deste serviço', mapear ownership/deploy/routing, detectar gaps de observabilidade/segurança e cruzar repos de um workspace.yaml. Não use para extrair fatos (→ analyze) nem para julgar regras (→ judge)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Graphfy — grafo de plataforma
|
|
7
|
+
|
|
8
|
+
Grafo é derivado de fatos (`attrs.graph`), nunca de texto livre. Contrato:
|
|
9
|
+
`platformforge/graph/v1`; vocabulário em `platformforge/graph/vocab.py` e
|
|
10
|
+
`GRAPHFY.md`. Backends pluggáveis: memory + SQLite (`graph/backend.py`).
|
|
11
|
+
|
|
12
|
+
## Verbos
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
platformforge graph build facts.json # grava .platformforge/graph/
|
|
16
|
+
platformforge graph build facts.json --source-type observed # tipo do snapshot
|
|
17
|
+
platformforge graph stats
|
|
18
|
+
platformforge graph deps --node <id> # transitivo, só arestas de dependência
|
|
19
|
+
platformforge graph dependents --node <id>
|
|
20
|
+
platformforge graph blast --node <id> # by_class: reliability/security/…
|
|
21
|
+
platformforge graph paths --src A --dst B
|
|
22
|
+
platformforge graph gaps # nós sem owner/monitoramento/policy
|
|
23
|
+
platformforge graph cycles
|
|
24
|
+
platformforge graph snapshots # ids dos snapshots
|
|
25
|
+
platformforge graph diff --before <id> --after <id>
|
|
26
|
+
platformforge graph at --at <ISO-ts> # grafo num instante
|
|
27
|
+
platformforge graph timeline --edge-id <id> # vida de uma aresta
|
|
28
|
+
platformforge graph identity-become|identity-access|identity-workloads|identity-blast
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Regras de leitura
|
|
32
|
+
|
|
33
|
+
- `deps`/`dependents` filtram `DEPENDENCY_KINDS` — `owns` não é dependência.
|
|
34
|
+
- `blast` retorna classes separadas + `note`: proximidade ≠ causalidade.
|
|
35
|
+
Classe `organizational` é reportada à parte (ownership ≠ blast radius).
|
|
36
|
+
- Edge `inferred` (fatos t6–t7) nunca é apresentada como `observed`.
|
|
37
|
+
- Sem grafo construído → recusa `PF-GRAPH-NOGRAPH` com unlock
|
|
38
|
+
(`graph build <facts.json>`); não reinterprete silenciosamente.
|
|
39
|
+
- Diff usa cones de ancestrais memoizados (SCC) — escala a 10k nós /
|
|
40
|
+
500k arestas medidos; além disso, `unsupported-on-host`.
|
|
41
|
+
|
|
42
|
+
## Multi-repo
|
|
43
|
+
|
|
44
|
+
Fatos vindos de `analyze` sobre raiz de workspace carregam
|
|
45
|
+
`attrs.workspace_member`; `graph build` cruza os membros por node id
|
|
46
|
+
content-derived (mesma label → mesmo nó → aresta cross-repo).
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: platformforge-lab
|
|
3
|
+
description: "Executa e avalia cenários determinísticos do Forge Lab — fixtures offline com contrato expected.yaml, comparação expected-vs-observed por prefixo de regra e categoria, chaos controlado por profiles. Use para validar analyzer novo, regredir regras, criar cenário novo para um finding, simular falha no grafo, ou avaliar o próprio platform-forge. Não substitui pytest (cobre comportamento unitário; Lab cobre o pipeline analyze→judge)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Forge Lab — avaliação determinística
|
|
7
|
+
|
|
8
|
+
Cenário = `lab/scenarios/<nome>/` com `fixture/` (artefatos) +
|
|
9
|
+
`expected.yaml` (`analyzers`, `rules_fired`, `categories`). 44 cenários,
|
|
10
|
+
incl. 12 `fleet-*` sobre a fixture compartilhada `lab/fleets/acme`.
|
|
11
|
+
|
|
12
|
+
## Verbos
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
platformforge lab list # cenários
|
|
16
|
+
platformforge lab run <nome> # um
|
|
17
|
+
platformforge lab run-all # suite
|
|
18
|
+
platformforge lab chaos <dir> --profile static|container|kubernetes|cloud
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Profiles não-`static` são recusados sem `--allow-profile`; alvo real de
|
|
22
|
+
produção recusado sem `--allow-prod` — boundary por design, não erro.
|
|
23
|
+
|
|
24
|
+
## Criar cenário
|
|
25
|
+
|
|
26
|
+
1. `lab/scenarios/<nome>/fixture/` com os artefatos mínimos.
|
|
27
|
+
2. `expected.yaml`: `analyzers: [iac|k8s|gha|gitops|secrets|iam|slo|finops|supply|catalog|crossplane|fleet_report|…]`, `rules_fired` por prefixo (`PF-K8S-`), `categories`.
|
|
28
|
+
3. `lab run <nome>` — runner roda analyze+judge e compara.
|
|
29
|
+
|
|
30
|
+
Domínios por arquivo único leem um nome fixo dentro de `fixture/`:
|
|
31
|
+
`iam`→`policy.json`, `supply`→`supply.json`, `finops`→`costs.json`,
|
|
32
|
+
`slo`→`slo.yaml` + `events.yaml`. Os demais (iac, k8s, gha, gitops,
|
|
33
|
+
secrets, sbom, catalog, crossplane) varrem `fixture/` inteira.
|
|
34
|
+
|
|
35
|
+
## Disciplina
|
|
36
|
+
|
|
37
|
+
- `rules_fired` é prefixo — liste regra inteira se o caso depende dela.
|
|
38
|
+
- Cenário que passa com finding errado ainda falhou — confira `observed`.
|
|
39
|
+
- Fixture não contém segredo real — usar placeholder + pattern.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: platformforge-sdd
|
|
3
|
+
description: "Conduz mudanças no próprio Platform Forge pelo SDD nativo — feature dir com intent/design/contract/plan, cascata de hashes (mudança upstream invalida downstream), gates por evidência, override com recibo, learn no fechamento. Use ao iniciar feature/fase, quando `sdd check` recusar, para re-selar com `sdd stamp`, ou para fechar fase com gate. Não use para analisar plataformas de usuário (→ platformforge-core)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDD nativo — fases e gates
|
|
7
|
+
|
|
8
|
+
Cada feature vive em `sdd/<FEATURE>/`. Fases na ordem:
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
init → discover → define → design → contract → plan → build → review →
|
|
12
|
+
verify → ship → learn
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Cascata de hashes: mudar uma fase upstream invalida as downstream
|
|
16
|
+
(stale → `sdd check` falha até `sdd stamp` re-selar).
|
|
17
|
+
|
|
18
|
+
## Verbos
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
platformforge sdd init --feature F --body "objetivo"
|
|
22
|
+
platformforge sdd discover --feature F --body "..."
|
|
23
|
+
platformforge sdd design --feature F --body "..."
|
|
24
|
+
platformforge sdd contract --feature F --body "..."
|
|
25
|
+
platformforge sdd status --feature F # fases: current/stale/blocked
|
|
26
|
+
platformforge sdd check --feature F --phase plan --verify "pytest -q"
|
|
27
|
+
platformforge sdd stamp --feature F --phase plan # re-sela após editar
|
|
28
|
+
platformforge sdd ship --feature F --override --override-reason "porquê"
|
|
29
|
+
platformforge sdd learn --feature F --body "o que aprendeu"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Disciplina
|
|
33
|
+
|
|
34
|
+
- Gate falha porque upstream está stale ou evidência ausente — corrija o
|
|
35
|
+
artefato e `sdd stamp`; não use `--override` pra esconder dívida
|
|
36
|
+
(o recibo fica registrado).
|
|
37
|
+
- `sdd check --verify "cmd"` roda o comando e anexa o resultado como
|
|
38
|
+
evidência da fase.
|
|
39
|
+
- `learn` é fase de fechamento — capture o que mudou a arquitetura real.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: platformforge-security
|
|
3
|
+
description: "Análise defensiva de plataforma — grafo IAM (principais, ações, recursos, wildcard, trust/SCP/boundary/OIDC/role chaining), secrets com redação automática, SBOM/SLSA e supply chain, Kyverno version-aware, Cosign (claimed ≠ verified), regras PF-SEC-*/PF-IAM-* e grafo de identidade (identity-become/access/workloads/blast). Use para auditar postura, 'isto vaza segredo?', revisar políticas IAM, verificar assinatura/SLSA de artefatos, supply chain de imagens. Não cria exploits nem coleta credenciais."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DevSecOps — leitura, nunca mutação
|
|
7
|
+
|
|
8
|
+
## Verbos
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
platformforge analyze iam <dir|policy.json> # grafo principal→ação→recurso
|
|
12
|
+
platformforge analyze secrets <dir> # valores redatados por padrão
|
|
13
|
+
platformforge analyze sbom <sbom.json> # licenças, pinagem, SLSA
|
|
14
|
+
platformforge analyze supply <provenance.json>
|
|
15
|
+
platformforge analyze kyverno <dir> --kyverno-version <v> # deprecations
|
|
16
|
+
platformforge analyze cosign <artifact> # assinatura: claimed ≠ verified
|
|
17
|
+
platformforge analyze slsa <provenance.json>
|
|
18
|
+
platformforge security <root> # bundle secrets+iam+sbom+supply → judge
|
|
19
|
+
platformforge graph identity-become --node <id> # quem pode virar o principal
|
|
20
|
+
platformforge graph identity-access --node <id> # acesso por caminho de identidade
|
|
21
|
+
platformforge graph identity-workloads --node <id>
|
|
22
|
+
platformforge graph identity-blast --node <id>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Wildcard normalizado: `"*"` vira `wildcard` / `wildcard-principal` antes de
|
|
26
|
+
contar — `{"Principal":{"AWS":"*"}}` conta como público.
|
|
27
|
+
Admin: `"*"` ou `iam:*` em actions, ou `iam:PassRole` + `"*"` em resources.
|
|
28
|
+
|
|
29
|
+
## Disciplina
|
|
30
|
+
|
|
31
|
+
- Secrets em fact.attrs carregam só `redacted`/`sha256_prefix` — nunca
|
|
32
|
+
valor. Não remover a redação pra "mostrar o contexto".
|
|
33
|
+
- Finding inclui `location` do artefato — remediação aponta o arquivo, não
|
|
34
|
+
o valor.
|
|
35
|
+
- Supply chain sem assinatura verificada = finding; scanner local offline
|
|
36
|
+
falhando degrada a evidência, não cancela o relatório.
|
|
37
|
+
- "Sem caminho de identidade encontrado" é um resultado nomeado — nunca
|
|
38
|
+
apresente como "sem risco".
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: platformforge-sre
|
|
3
|
+
description: "Avalia confiabilidade de plataforma a partir de contratos SLO, eventos e sinais de observabilidade — error budget, burn rate multi-window, incident readiness, capacity headroom, postmortem, DR, correlação OTel trace→log→métrica e projeções prometheus/grafana. Use para 'este SLO aguenta', burn rate, error budget, readiness operacional, revisar alertas, planejar runbook, capacity, ou correlacionar telemetria sem credencial. Não use para custos (→ platformforge-finops) nem para blast radius estrutural (→ platformforge-graph)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SRE / observabilidade
|
|
7
|
+
|
|
8
|
+
OTel é o contrato canônico; projeções de vendor (prometheus/grafana) são
|
|
9
|
+
leitura, nunca fonte de verdade. Tudo offline — sem credencial.
|
|
10
|
+
|
|
11
|
+
## Verbos
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
platformforge observe slo contract.yaml --sli '{"total_events":1e6,"bad_events":400}'
|
|
15
|
+
platformforge observe slo-burn contract.yaml --windows '{"1h":{"good":1,"bad":0,"total":100}}'
|
|
16
|
+
platformforge observe otel <otel.yaml> # correlação declarada vs ausente
|
|
17
|
+
platformforge observe semconv <attrs.json> # conformidade de convenção semântica
|
|
18
|
+
platformforge observe incident <signal.yaml> --alerts a.yaml --changes c.yaml
|
|
19
|
+
platformforge observe timeline <events.json>
|
|
20
|
+
platformforge observe postmortem --incident inc.json
|
|
21
|
+
platformforge observe capacity <cap.yaml> --window 86400
|
|
22
|
+
platformforge observe dr <dr.yaml> --facts facts.json
|
|
23
|
+
platformforge observe prometheus <rules.yaml> # projeção: alertas/recording
|
|
24
|
+
platformforge observe grafana <dashboard.json> # projeção: painéis/datasources
|
|
25
|
+
platformforge reliability <facts.json> # sre+k8s rules only
|
|
26
|
+
platformforge correlate <otel.yaml> # = observe otel
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Contrato SLO: `contracts/slo-contract.schema.json`. Regras PF-OBS-* em
|
|
30
|
+
`rules/catalog/sre.yaml`.
|
|
31
|
+
|
|
32
|
+
## Disciplina
|
|
33
|
+
|
|
34
|
+
- Error budget calculado do contrato + SLI observado; sem SLI →
|
|
35
|
+
`PF-OBS-NODATA`, não chute.
|
|
36
|
+
- Correlação OTel é declarada-vs-ausente: atributo de log referenciando
|
|
37
|
+
trace sem binding é finding, não prova.
|
|
38
|
+
- `observe incident` sem `--alerts`/`--changes` degrada a evidência — o
|
|
39
|
+
sinal ausente volta em `unresolved`, não vira pressuposto.
|
|
40
|
+
- Burn rate usa janelas múltiplas — `slo-burn` exige `--windows` por
|
|
41
|
+
janela declarada.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# FinOps rules — operate on finops.cost facts (tier-1 measured spend).
|
|
2
|
+
rules:
|
|
3
|
+
- rule_id: PF-FIN-001
|
|
4
|
+
domain: finops
|
|
5
|
+
title: "Spend-bearing resource without cost allocation tag"
|
|
6
|
+
severity: medium
|
|
7
|
+
applies_to: {fact_kind: finops.cost}
|
|
8
|
+
conditions:
|
|
9
|
+
all:
|
|
10
|
+
- {path: attrs.tags.cost_center, op: absent}
|
|
11
|
+
- {path: attrs.amount, op: gt, value: 0}
|
|
12
|
+
message: "unallocated spend breaks unit economics and accountability"
|
|
13
|
+
sources: ['finops-framework']
|
|
14
|
+
source_refs:
|
|
15
|
+
finops-framework: "framework/capabilities/allocation"
|
|
16
|
+
|
|
17
|
+
- rule_id: PF-FIN-002
|
|
18
|
+
domain: finops
|
|
19
|
+
title: "Cost recorded without service attribution"
|
|
20
|
+
severity: low
|
|
21
|
+
applies_to: {fact_kind: finops.cost}
|
|
22
|
+
conditions:
|
|
23
|
+
all:
|
|
24
|
+
- {path: attrs.service, op: absent}
|
|
25
|
+
message: "service-less cost rows can't be attributed downstream"
|
|
26
|
+
sources: ['focus-spec']
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# GitOps & CI/CD rules — PF-GITOPS-* / PF-CICD-*.
|
|
2
|
+
rules:
|
|
3
|
+
- rule_id: PF-GITOPS-001
|
|
4
|
+
domain: gitops
|
|
5
|
+
title: "ArgoCD app without automated sync"
|
|
6
|
+
severity: low
|
|
7
|
+
applies_to: {fact_kind: gitops.argocd_app}
|
|
8
|
+
conditions:
|
|
9
|
+
all:
|
|
10
|
+
- {path: attrs.automated_sync, op: equals, value: false}
|
|
11
|
+
message: "manual sync lets cluster drift from git silently"
|
|
12
|
+
sources: ['argocd-docs']
|
|
13
|
+
source_refs:
|
|
14
|
+
argocd-docs: "en/stable/user-guide/auto_sync"
|
|
15
|
+
|
|
16
|
+
- rule_id: PF-GITOPS-002
|
|
17
|
+
domain: gitops
|
|
18
|
+
title: "ArgoCD sync without self-heal"
|
|
19
|
+
severity: medium
|
|
20
|
+
applies_to: {fact_kind: gitops.argocd_app}
|
|
21
|
+
conditions:
|
|
22
|
+
all:
|
|
23
|
+
- {path: attrs.automated_sync, op: equals, value: true}
|
|
24
|
+
- {path: attrs.self_heal, op: equals, value: false}
|
|
25
|
+
message: "out-of-band changes persist until the next sync"
|
|
26
|
+
sources: ['argocd-docs']
|
|
27
|
+
source_refs:
|
|
28
|
+
argocd-docs: "en/stable/user-guide/auto_sync#automatic-self-healing"
|
|
29
|
+
|
|
30
|
+
- rule_id: PF-GITOPS-003
|
|
31
|
+
domain: gitops
|
|
32
|
+
title: "ArgoCD sync without prune"
|
|
33
|
+
severity: medium
|
|
34
|
+
applies_to: {fact_kind: gitops.argocd_app}
|
|
35
|
+
conditions:
|
|
36
|
+
all:
|
|
37
|
+
- {path: attrs.automated_sync, op: equals, value: true}
|
|
38
|
+
- {path: attrs.prune, op: equals, value: false}
|
|
39
|
+
message: "deleted manifests linger in the cluster"
|
|
40
|
+
sources: ['argocd-docs']
|
|
41
|
+
source_refs:
|
|
42
|
+
argocd-docs: "en/stable/user-guide/auto_sync#automatic-pruning"
|
|
43
|
+
|
|
44
|
+
- rule_id: PF-GITOPS-010
|
|
45
|
+
domain: gitops
|
|
46
|
+
title: "Flux resource suspended"
|
|
47
|
+
severity: info
|
|
48
|
+
applies_to: {fact_kind: gitops.flux_resource}
|
|
49
|
+
conditions:
|
|
50
|
+
all:
|
|
51
|
+
- {path: attrs.suspend, op: equals, value: true}
|
|
52
|
+
message: "suspended resources stop reconciling — confirm intent"
|
|
53
|
+
sources: ['flux-docs']
|
|
54
|
+
source_refs:
|
|
55
|
+
flux-docs: "flux/components/kustomize/kustomizations#suspension"
|
|
56
|
+
|
|
57
|
+
- rule_id: PF-CICD-001
|
|
58
|
+
domain: cicd
|
|
59
|
+
title: "Third-party action not pinned to SHA"
|
|
60
|
+
severity: high
|
|
61
|
+
applies_to: {fact_kind: cicd.github_workflow}
|
|
62
|
+
conditions:
|
|
63
|
+
all:
|
|
64
|
+
- {path: attrs.unpinned_third_party, op: not_empty}
|
|
65
|
+
message: "tag/branch refs are mutable — supply-chain hijack surface"
|
|
66
|
+
sources: ['github-actions-docs']
|
|
67
|
+
source_refs:
|
|
68
|
+
github-actions-docs: "en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions"
|
|
69
|
+
|
|
70
|
+
- rule_id: PF-CICD-002
|
|
71
|
+
domain: cicd
|
|
72
|
+
title: "Dangerous trigger on privileged context"
|
|
73
|
+
severity: critical
|
|
74
|
+
applies_to: {fact_kind: cicd.github_workflow}
|
|
75
|
+
conditions:
|
|
76
|
+
all:
|
|
77
|
+
- {path: attrs.dangerous_triggers, op: not_empty}
|
|
78
|
+
message: "pull_request_target/workflow_run expose secrets to forks"
|
|
79
|
+
sources: ['github-securitylab']
|
|
80
|
+
source_refs:
|
|
81
|
+
github-securitylab: "resources/github-actions-preventing-pwn-requests"
|
|
82
|
+
|
|
83
|
+
- rule_id: PF-CICD-003
|
|
84
|
+
domain: cicd
|
|
85
|
+
title: "Script injection via untrusted context"
|
|
86
|
+
severity: critical
|
|
87
|
+
applies_to: {fact_kind: cicd.github_workflow}
|
|
88
|
+
conditions:
|
|
89
|
+
all:
|
|
90
|
+
- {path: attrs.script_injection_risk, op: not_empty}
|
|
91
|
+
message: "${{ }} inside run: interpolates attacker-controlled text"
|
|
92
|
+
sources: ['github-actions-docs']
|
|
93
|
+
source_refs:
|
|
94
|
+
github-actions-docs: "en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#understanding-the-risk-of-script-injections"
|
|
95
|
+
|
|
96
|
+
- rule_id: PF-CICD-004
|
|
97
|
+
domain: cicd
|
|
98
|
+
title: "Broad write permissions at workflow level"
|
|
99
|
+
severity: medium
|
|
100
|
+
applies_to: {fact_kind: cicd.github_workflow}
|
|
101
|
+
conditions:
|
|
102
|
+
any:
|
|
103
|
+
- {path: attrs.write_perms, op: contains, value: "*"}
|
|
104
|
+
- {path: attrs.write_perms, op: contains, value: "id-token"}
|
|
105
|
+
message: "default broad GITHUB_TOKEN permissions widen compromise impact"
|
|
106
|
+
sources: ['github-actions-docs']
|
|
107
|
+
source_refs:
|
|
108
|
+
github-actions-docs: "en/actions/writing-workflows/workflow-syntax-for-github-actions#permissions"
|
|
109
|
+
|
|
110
|
+
- rule_id: PF-CICD-005
|
|
111
|
+
domain: cicd
|
|
112
|
+
title: "Self-hosted runner on untrusted path"
|
|
113
|
+
severity: medium
|
|
114
|
+
applies_to: {fact_kind: cicd.github_workflow}
|
|
115
|
+
conditions:
|
|
116
|
+
all:
|
|
117
|
+
- {path: attrs.self_hosted_jobs, op: not_empty}
|
|
118
|
+
- {path: attrs.dangerous_triggers, op: not_empty}
|
|
119
|
+
message: "self-hosted + fork-reachable triggers = host compromise"
|
|
120
|
+
sources: ['github-actions-docs']
|
|
121
|
+
source_refs:
|
|
122
|
+
github-actions-docs: "en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#hardening-for-self-hosted-runners"
|
|
123
|
+
|
|
124
|
+
- rule_id: PF-GITOPS-020
|
|
125
|
+
domain: gitops
|
|
126
|
+
title: "ArgoCD app not scoped to an AppProject"
|
|
127
|
+
severity: medium
|
|
128
|
+
applies_to: {fact_kind: gitops.argocd_app}
|
|
129
|
+
conditions:
|
|
130
|
+
all:
|
|
131
|
+
- {path: attrs.app_project_scope, op: equals, value: false}
|
|
132
|
+
message: "unscoped apps can deploy any source to any destination"
|
|
133
|
+
sources: ['argocd-docs']
|
|
134
|
+
source_refs:
|
|
135
|
+
argocd-docs: "en/stable/user-guide/projects/"
|
|
136
|
+
|
|
137
|
+
- rule_id: PF-GITOPS-021
|
|
138
|
+
domain: gitops
|
|
139
|
+
title: "AppProject without source restrictions"
|
|
140
|
+
severity: high
|
|
141
|
+
applies_to: {fact_kind: gitops.argocd_app}
|
|
142
|
+
conditions:
|
|
143
|
+
all:
|
|
144
|
+
- {path: attrs.source_restrictions, op: equals, value: 0}
|
|
145
|
+
message: "project admits any repository — supply-chain surface"
|
|
146
|
+
sources: ['argocd-docs']
|
|
147
|
+
source_refs:
|
|
148
|
+
argocd-docs: "en/stable/user-guide/projects/"
|
|
149
|
+
|
|
150
|
+
- rule_id: PF-GITOPS-022
|
|
151
|
+
domain: gitops
|
|
152
|
+
title: "ApplicationSet without generators"
|
|
153
|
+
severity: info
|
|
154
|
+
applies_to: {fact_kind: gitops.argocd_app}
|
|
155
|
+
conditions:
|
|
156
|
+
all:
|
|
157
|
+
- {path: attrs.generators, op: empty}
|
|
158
|
+
message: "ApplicationSet produces no applications"
|
|
159
|
+
sources: ['argocd-docs']
|
|
160
|
+
source_refs:
|
|
161
|
+
argocd-docs: "en/stable/operator-manual/applicationset/Generators/"
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# IaC rules — executable, not decorative. Convention: PF-IAC-NNN.
|
|
2
|
+
rules:
|
|
3
|
+
- rule_id: PF-IAC-001
|
|
4
|
+
domain: iac
|
|
5
|
+
title: "S3 bucket exposes public ACL"
|
|
6
|
+
severity: critical
|
|
7
|
+
applies_to: {fact_kind: iac.resource}
|
|
8
|
+
conditions:
|
|
9
|
+
all:
|
|
10
|
+
- {path: attrs.type, op: equals, value: aws_s3_bucket}
|
|
11
|
+
- {path: attrs.body.acl, op: in,
|
|
12
|
+
value: [public-read, public-read-write, authenticated-write]}
|
|
13
|
+
message: "public ACL on object storage is a near-certain exposure"
|
|
14
|
+
sources: ['aws-s3-docs']
|
|
15
|
+
source_refs:
|
|
16
|
+
aws-s3-docs: "AmazonS3/latest/userguide/about-object-ownership.html"
|
|
17
|
+
|
|
18
|
+
- rule_id: PF-IAC-002
|
|
19
|
+
domain: iac
|
|
20
|
+
title: "Security group ingress open to the world"
|
|
21
|
+
severity: critical
|
|
22
|
+
applies_to: {fact_kind: iac.resource}
|
|
23
|
+
conditions:
|
|
24
|
+
all:
|
|
25
|
+
- {path: attrs.type, op: equals, value: aws_security_group}
|
|
26
|
+
- {path: "attrs.body.ingress[*].cidr_blocks[*]", op: equals,
|
|
27
|
+
value: "0.0.0.0/0"}
|
|
28
|
+
message: "ingress from 0.0.0.0/0 must be justified per-resource"
|
|
29
|
+
sources: ['aws-vpc-docs']
|
|
30
|
+
source_refs:
|
|
31
|
+
aws-vpc-docs: "vpc/latest/userguide/security-group-rules.html"
|
|
32
|
+
|
|
33
|
+
- rule_id: PF-IAC-003
|
|
34
|
+
domain: iac
|
|
35
|
+
title: "Resource without tags/labels"
|
|
36
|
+
severity: info
|
|
37
|
+
applies_to: {fact_kind: iac.resource}
|
|
38
|
+
conditions:
|
|
39
|
+
all:
|
|
40
|
+
- {path: attrs.tags, op: absent}
|
|
41
|
+
- {path: attrs.type, op: matches, value: "^(aws|azurerm|google)_"}
|
|
42
|
+
message: "untracked resources break cost allocation and ownership"
|
|
43
|
+
sources: ['aws-docs']
|
|
44
|
+
source_refs:
|
|
45
|
+
aws-docs: "general/latest/gr/aws_tagging.html"
|
|
46
|
+
|
|
47
|
+
- rule_id: PF-IAC-010
|
|
48
|
+
domain: iac
|
|
49
|
+
title: "Plan destroys a resource"
|
|
50
|
+
severity: high
|
|
51
|
+
applies_to: {fact_kind: iac.plan_change}
|
|
52
|
+
conditions:
|
|
53
|
+
all:
|
|
54
|
+
- {path: attrs.delete, op: equals, value: true}
|
|
55
|
+
message: "deletion in a plan needs explicit human acceptance"
|
|
56
|
+
sources: ['terraform-docs']
|
|
57
|
+
source_refs:
|
|
58
|
+
terraform-docs: "terraform/language/state#staging-a-deletion"
|
|
59
|
+
|
|
60
|
+
- rule_id: PF-IAC-011
|
|
61
|
+
domain: iac
|
|
62
|
+
title: "Plan replaces a resource"
|
|
63
|
+
severity: medium
|
|
64
|
+
applies_to: {fact_kind: iac.plan_change}
|
|
65
|
+
conditions:
|
|
66
|
+
all:
|
|
67
|
+
- {path: attrs.replace, op: equals, value: true}
|
|
68
|
+
message: "replacement implies downtime unless proven otherwise"
|
|
69
|
+
sources: ['terraform-docs']
|
|
70
|
+
source_refs:
|
|
71
|
+
terraform-docs: "terraform/cli/commands/plan#resource-replacement"
|
|
72
|
+
|
|
73
|
+
- rule_id: PF-IAC-020
|
|
74
|
+
domain: iac
|
|
75
|
+
title: "Module sourced without version pin"
|
|
76
|
+
severity: medium
|
|
77
|
+
applies_to: {fact_kind: iac.module}
|
|
78
|
+
conditions:
|
|
79
|
+
all:
|
|
80
|
+
- {path: attrs.version, op: absent}
|
|
81
|
+
message: "unpinned module sources make builds non-reproducible"
|
|
82
|
+
sources: ['terraform-docs']
|
|
83
|
+
source_refs:
|
|
84
|
+
terraform-docs: "terraform/language/modules/sources#version-constraints"
|