Skip to content

Repository files navigation

AgentIT

Tests Security Python License Built for GitOps

AgentIT

Score a repo’s enterprise readiness, open quality-filtered GitOps PRs, and let humans merge so Argo CD deploys.

Built for OpenShift + Argo GitOps platform engineers who want Assess → Scan → Deliver PR → merge → Argo → reassess — without silent cluster mutations or catalog dump PRs.

AgentIT Fleet scoreboard

Fleet — portfolio scores, GitOps sync state, open PRs, Scan.

Table of contents

Demo

CLI happy path (no cluster, no LLM) — score the checked-in sample app:

uv sync --extra dev
uv run agentit assess ./examples/sample-app --no-llm --format terminal

Animated agentit assess terminal output

Static frame (SVG): docs/assets/readme/cli-assess.svg · Sample write-up: examples/sample-assessment.md

Portal dogfood (internal OpenShift Route; OpenShift SSO — not a public sandbox):

https://agentit-agentit.apps.aws-jb-acsacm-1.dev05.red-chesterfield.com

Screenshots below were taken against that environment at tip 9604e9dc (Health → Deployed commit). To refresh media later: oc port-forward -n agentit pod/<portal-pod> 18080:8080 and capture /fleet, /ledger, /schedules, /decisions, /health (app port bypasses oauth-proxy).

Who it’s for

You… AgentIT helps you…
Run OpenShift + Argo CD for many apps See fleet scores, sync state, and open remediation PRs in one place
Own platform standards (security, probes, GitOps, SLOs) Assess repos with seven dimensions + detect skills
Want automation without surprise applies Get finding-tied PRs; you merge; Argo syncs

How it works

  1. Assess — clone a repo, run analyzers + mode: detect skills → scores and findings
  2. Scan — SkillEngine matches findings → remediations (SSA dry-run + clear-evidence gate)
  3. Deliver PR — open GitOps / source PRs that are finding-tied (Phase A finding_gate)
  4. Human merge — never auto-merge (ADR 0001)
  5. Argo operate — ApplicationSet / Application syncs after merge
  6. Reassess — cadence + watchers (drift, vulns, SLOs) feed the next loop
flowchart LR
    A["Repo"] --> B["Assess"]
    B --> C["Scan / generate"]
    C --> D["Gate"]
    D --> E["Open PRs"]
    E --> F["Human merge"]
    F --> G["Argo sync"]
    G --> H["Reassess / learn"]
Loading
Step What happens
Assess 7 dimensions → findings + scores
Scan / generate Skills match findings; Scan/onboard produces remediations
Gate Finding-tied PRs only on auto delivery and manual /deliver. Manual also mirrors auto’s file filter, wrong-layer strip, per-cluster file cap, and clear-evidence (blocks Hello-World #31/#32-class catalog dumps; refuses octocat/Hello-World probes; refuses theater audit stubs even when middleware is wired — pinky #12). SSA dry-run + clear-evidence also refuse destructive Containerfile rewrites / root-only audit.py. dockerfile_pin is path-bound (pinning one Dockerfile cannot clear :latest on others — pulse-agent#2); USER/HEALTHCHECK/UBI clear via additive harden on that path. SBOM clears via CI generation (sbom-ci), not static files. Validate/fix/retry runs per finding-cluster, after partitioning — one cluster's unfixable failure (e.g. no live scale target for autoscaling) can never discard an unrelated, individually-valid cluster's files (pulse-agent #gitops); every per-cluster refusal is a real, visible event, not just a log line.
Operate Human merges on GitHub; Argo CD deploys. Awaiting verification only when a PR was actually opened
Learn Watchers surface drift/CVEs/SLOs; Decisions audit LLM approve/reject; repeated theater cools down. Security-analyzer fixtures use short EXAMPLE… placeholders + # notsecret; historical hex allowlisted via root .gitleaks.toml top-level [allowlist].regexes (InfoSec / PwnedAlert Generic Secret FP; never real credentials).

Fleet apps land under apps/{app}/ in the gitops repo (ApplicationSet). AgentIT itself deploys from this repo’s Helm chart/ via Application agentit.

Portal highlights

Real dogfood UI (not mockups):

Surface What you see
Fleet Portfolio scoreboard — scores, deploy/GitOps badges, open PRs, Scan
Assessment Dimension scores, Assessed → Onboarded → Merged → Monitored
Ledger PRs waiting for your approval — Merge / Close (HITL)
Fleet SLOs Availability / error-rate / latency across apps
Schedules Re-assess cadence + platform CronJobs + onboarding manifests
Decisions LLM decide-point audit (approve / reject / gate)
Health Tekton pipeline, Argo Synced/Healthy, deployed tip SHA

Assessment detail with score and lifecycle

Assessment Detail — score, dimension bars, lifecycle stepper.

Ledger waiting for human PR approval

Ledger — quality-gated PR with Merge PR (human-in-the-loop).

More screenshots — Fleet SLOs, Schedules, Decisions, Health

Fleet SLOs

Fleet SLOs — breached vs met across the portfolio.

Scheduled Operations

Schedules — reassess cadence + live platform CronJobs.

LLM Decisions audit log

Decisions — LLM approve/reject/gate audit trail.

System Health with Tekton and Argo

Health — CI PipelineRun, Argo Synced/Healthy, tip 9604e9dc.

Primary spine: Fleet → Assessment Detail → Ledger. Operate surfaces (menu): Health, Insights, Events, Decisions, DLQ, Schedules. See docs/portal-experience-design-language.md and ADR 0007.

Quick start

Requires Python ≥ 3.12 and uv.

git clone https://github.com/alimobrem/AgentIT.git
cd AgentIT
uv sync --extra dev

# 1) Score a repo (no cluster)
uv run agentit assess https://github.com/some-org/some-app --format terminal

# 2) Assess + generate hardening manifests locally
uv run agentit onboard https://github.com/some-org/some-app --output-dir ./out

# 3) Local portal (needs Postgres: AGENTIT_DB_DSN)
uv run agentit portal --port 8080
# open http://localhost:8080

Useful commands: self-assess, watch, learn, test-skill, activate-skill, clear-skill-cooldown. Full list: uv run agentit --help.

Scoring details: docs/score-methodology.md. Shareable badge: GET /badge/{app}.svg.

Environment variables
Variable Purpose
AGENTIT_DB_DSN Postgres DSN (required for portal / fleet / watchers)
AGENTIT_TEST_PG_DSN Throwaway Postgres for pytest / capability-scout tests-pass (never the fleet DB — fixtures truncate). Chart sidecar default; CI sets its own.
ANTHROPIC_API_KEY or Vertex (ANTHROPIC_VERTEX_PROJECT_ID + CLOUD_ML_REGION) Optional LLM
GITHUB_TOKEN PR create / infra-repo / webhooks
AGENTIT_KAFKA_BOOTSTRAP Kafka (optional; no-op if unset)
AGENTIT_EXTERNAL_URL Public base URL for outbound registrations
AGENTIT_AGENT_MODE local (default) or kubernetes Jobs
AGENTIT_OFFLINE 1 — hard-stop kube client (tests/review)

Honest scope (Phase A)

AgentIT is a GitOps assistant, not an auto-apply bot.

  • No catalog dumps — auto delivery and manual /deliver only open finding-tied PRs (finding_gate)
  • Honest refuse UX — when Phase A refuses (“No open findings / score delta”), Onboard Results does not promise “will open N PRs” or offer Retry Scan delivery; green Assessment Detail Scan CTAs / empty Open PRs copy do not promise PRs either
  • Capability-gated cluster packs — Scan probes cluster GVKs (Tekton Task/Pipeline, Kyverno Policy, PDB, HPA, ResourceQuota, …). Missing CRD / Not Found and Forbidden (RBAC) skip those files — they do not count as auto-validation converge failure. Source-layer remediations (Containerfile pin, CI SBOM workflow, app audit, …) are never blocked because cluster dry-run failed. Onboard Results shows skip/refuse reasons instead of “will open N PRs” when nothing opened (pulse-agent class / #192 extended)
  • No half-onboarded Fleet apps — every app is GitOps-registered (or self-managed) or removed. Not-registered rows show Register GitOps / Delete only — never a Scan-for-PR CTA. Demo forks you cannot deliver to (e.g. octocat/Spoon-Knife) belong off Fleet, not in “Not GitOps-registered” limbo (dogfood: octocat/Spoon-Knife removed — undeliverable; Fleet is pinky + AgentIT only)
  • Bring your own GitOps repo — Assess / Register-for-GitOps accept an optional GitOps Infra Repo URL. Supplied and already accessible → used as-is. Supplied but missing → created empty (org-aware: /orgs/{owner}/repos for an org, /user/repos only when the owner is the authenticated token's own account — never silently redirected elsewhere) in the exact org/owner the URL specifies, then GitOps-registered the same way. Supplied but AgentIT lacks push access → hard refusal, never a silently substituted repo. Blank → unchanged existing default (shared {token-account}/agentit-gitops). Either way, the fleet-wide agentit-managed-apps ApplicationSet gets an additional Git generator entry for the new repo — it never replaces another app's already-registered repo (github_pr.ensure_applicationset())
  • Fleet deploy badges for ApplicationSet apps — enrichment looks up managed-{app} first (then literal name), same as gitops_registered, so Synced/Healthy apps like pinky / managed-pinky show synced — not a false “not deployed”
  • Human merge required — AgentIT opens PRs; it does not merge them
  • No silent cluster applies for app remediations — path is PR → merge → Argo
  • Clear-evidence gate — refuses theater stubs, root-only audit.py without package wire-up, destructive Containerfile rewrites, SLSA/hermetic prose without a real cosign sign Task (image_signingcosign-sign-task), static sbom.cdx.json / bare Tekton sbom-task for compliance sbom (clears only via CI generation: sbomsbom-ci / anchore/sbom-action or Pipeline sbom-generate), Kyverno-only health policies without probes in repo YAML (healthworkload-health-probes), PDB as a fake clear for single-replica (replicasworkload-replicas), otel-collector as a fake clear for app tracing (detect-only), shallow migrations (SELECT 1 / empty upgrade() / comment-only op.execute), empty or :latest image-scan Tasks, Grafana ConfigMaps without grafana_dashboard + panels, PDB/ServiceMonitor selectors that match no live Services/workloads, and empty Argo CD Applications / bogus deploy/ paths when the tree is missing. Intent matrix: docs/checks-remediations-intent-audit.md
  • Awaiting verification only when a delivery actually produced a pr_url
  • Async GitHub push webhooks/api/webhook/github-push returns 202 immediately and assesses in the background (GitHub’s ~10s timeout). Webhook claims stay incomplete until success; hard failure / busy exhaustion / TTL (~15m) releases the claim so retries work. Portal assess concurrency + 1Gi memory from #189 unchanged
  • Webhook → gated auto delivery — remediable findings from push re-assessment (and /api/webhook/finding) enter the same auto_validate_and_deliver path as Scan/onboard (finding_gate + clear-evidence + caps). Human gate remains PR merge — never auto-apply / catalog dumps
  • Coverage: "Also included" companions — generated content that doesn't map to the open finding's exact clearing skill no longer gets silently thrown away when it's otherwise safe to ship (same delivery layer, not narrative/secret-blocked, not on that finding's refuse_companions denylist). Rides along in the same PR under a distinct "Also included" section — never claimed to clear anything itself; a companion with no room in any same-layer PR is dropped, never spun into its own always-refused PR attempt
  • Real image digest pinningcontainer findings pin to the base image's actual current digest (target registry's own v2 Manifest API), not just a slightly-less-floating :1 major-stream tag, when the registry is reachable; falls back to :1 per-image otherwise, never blocks delivery
  • Deterministic fields, generalized — Tekton Pipeline/PipelineRun repo-url/image-ref params are force-set to the real values after generation, same as Argo Application repoURL — an LLM is never trusted with a value this codebase already knows for certain
  • CodeChangeAgent no longer touches dockerfile/container/secrets — the legacy onboarding agent's deterministic and LLM paths did a blind action: "create" full-file overwrite with no knowledge of the existing file, bypassing every guardrail the skill-engine containerfile path has. Confirmed live on PulseSRE/pulse-agent#2 (deleted RUN pip install + CMD) and PulseSRE/pulse-ui#39 (swapped nginx→nodejs base image family, left :latest unpinned, deleted ENTRYPOINT, fabricated a generic .env.example over a real one). dockerfile/container findings are now exclusively owned by the skill engine's pin/harden path; secrets is contractually detect-only (SOLUTION_CONTRACTS) and no longer auto-PR'd at all. is_destructive_dockerfile_rewrite() also gained CMD/ENTRYPOINT/EXPOSE token tracking and a base-image-family-swap guard as defense in depth
  • CodeChangeAgent removed entirely (no Python onboarding agent remains) — after the fix above, its remaining categories (health, gitignore, logging/structured, otel/tracing/instrumentation) were audited and found to either duplicate an already-guarded skill (healthworkload-health-probes clears the finding via K8s probes without an unwired app-code stub) or violate their own detect-only contract (logging/tracing/instrumentationSOLUTION_CONTRACTS auto_pr=False, "human wires/instruments"; gitignore was unreachable dead code, no analyzer emits that category). Deleted agents/codechange.py + its agents/codechange.md registration; AGENT_CLASSES is now always empty. Skills own every remediation domain
  • Migration scaffolding requires a real databasedb-migration-tooling (and the migration finding itself) used to fire for any repo lacking formal migration tooling, regardless of whether the app has a database at all. Confirmed live: PulseSRE/pulse-ui#40 invented a schema_migrations_baseline table for a database-less React UI repo. analyzers/data_governance.py::has_database_dependency() (reusing stack_detector.DB_PATTERNS) now gates the finding; the generator independently refuses when report.stack.databases is empty
  • Treat outputs as drafts until you validate against your sources of record (cluster, GitHub, Argo)

Quality rules: docs/plan-quality-helpful-prs.md. Product contract: docs/release-notes.md.

Works on plain Kubernetes?

Capability OpenShift (supported) Plain Kubernetes
agentit assess / local CLI Yes Yes — no cluster needed
Portal + Postgres store Yes (bundled chart) Possible with your own Postgres; chart targets OpenShift
Browser auth (auth.enabled) OpenShift oauth-proxy + Route Not the same path — bring your own ingress/IdP
GitOps deploy Argo CD Application / ApplicationSet Argo CD works; chart assumes OpenShift-friendly defaults
Self-deploy (Rollouts, Tekton agentit-ci, ImageStreams) Hard-requires OpenShift Pipelines / Rollouts as charted Degrades — use your own CI promote path
Watchers (drift, vuln, SLO, self-health) Designed for this stack Partial — kube client works; OpenShift-only APIs/CRDs skip or warn

Bottom line: scoring and local generation are cluster-agnostic. Full operate loop (portal, Scan → PR → Argo, watchers) is built and tested for OpenShift.

Deploy to OpenShift

Helm chart in chart/ + Argo CD Application in argocd/application.yaml. Argo is the deployer: merge to main alone does not move the portal — Tekton agentit-ci builds, smokes, then pins image.tag. Confirm rollout via Health → deploy-status (or AGENTIT_IMAGE_TAG on the portal pod) matching the tip SHA — green GitHub Actions alone is not a deploy.

Ops: docs/deployment.md. Merge gate + post-merge tip: docs/ci-deploy.md (scripts/ci-merge-gate.sh — never merge on queued checks). Topology: docs/architecture.md.

Portal memory defaults to 1Gi with in-process assess concurrency 1 (chart/values.yaml resources + assessConcurrency) so concurrent GitHub push webhooks cannot stack clone+assess working sets and OOMKill the pod (busy callers get HTTP 503 and can retry).

Tip promote under node pressure: Tekton run-tests / build-image / self-assess CPU requests stay modest (100m) so pods schedule instead of Pending ExceededNodeResources; burst via limits. Drift-detector memory defaults to 512Mi–1Gi (agents.driftDetector.resources).

Architecture

flowchart TB
    subgraph Operator["Platform engineer"]
        Portal["Portal / CLI"]
    end
    subgraph AgentIT["AgentIT"]
        Assess["Assess"]
        Scan["Scan + gate"]
        PRs["Open PRs"]
    end
    subgraph Git["GitHub"]
        Code["App / source repo"]
        Gitops["GitOps repo apps/{app}/"]
    end
    subgraph Cluster["OpenShift"]
        Argo["Argo CD"]
        Apps["Fleet apps"]
    end
    Portal --> Assess --> Scan --> PRs
    PRs --> Code
    PRs --> Gitops
    Code -->|"human merge"| Argo
    Gitops -->|"human merge"| Argo
    Argo --> Apps
    Apps -.->|"reassess / watchers"| Portal
Loading

Full diagrams: docs/architecture.md · Self-managed vs fleet: docs/architecture-agentit-vs-fleet-gitops.md.

Docs

Doc Role
docs/score-methodology.md Score dimensions, weights, PR impact
docs/architecture.md System diagrams, Scan pipeline
docs/ci-deploy.md Merge gate + post-merge Tekton/rollout tip
docs/plan-quality-helpful-prs.md Quality PR rules (finding-tied, no theater)
docs/checks-remediations-intent-audit.md Intent vs detect vs skill audit (verify before/after)
docs/adr/ Architecture Decision Records (HITL, Postgres, …)
docs/release-notes.md Product contract (Scan HITL, portal IA)
docs/portal-experience-design-language.md Portal EDL
docs/deployment.md OpenShift / Argo / Tekton ops
CHANGELOG.md Version history
docs/README.md Docs index
docs/history/ Session notes (not product truth)

Issues and PRs welcome on GitHub. Prefer small, focused changes; run uv run pytest before opening a PR. Maintainers use docs/ci-deploy.md before merging to main.

License

MIT

About

Agent-powered platform to make MVPs enterprise-ready on Red Hat infrastructure

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages