Documentation
¶
Overview ¶
Package probe runs live checks against the ecosystem and produces `verified-behavior` facts that merge into the same fact store `studio index` builds. Unlike index, probe performs live network I/O: it reads its targets from the facts already in the store and turns declared expectations into behavioral truth by actually requesting the resource.
Feature: cli/studio/probe (REQ: probe-verb, REQ: domain-liveness, REQ: network-failure-is-data)
This phase's Task 2 lands the domain-liveness kind (adapter id `probe-domain`): it requests https-first with an http fallback on transport failure, records the URL that answered as the evidence pointer, and maps a both-schemes transport failure to the reserved non-numeric object `down`. Probers reach the network only through the package-level HTTPGetFn seam, so tests never hit the network.
Index ¶
Constants ¶
const ( // DomainAdapterID is the adapter id stamped on every domain-kind fact. It is // part of the store merge key, so it must differ from the ci kind's id and // from every index adapter's id (REQ: probe-verb, REQ: probe-merge). DomainAdapterID = "probe-domain" // ServesStatusPredicate is the predicate the registries adapter declares and // the domain probe verifies — the join point between the declared and the // verified-behavior fact for one domain (REQ: domain-liveness). ServesStatusPredicate = "serves-status" // DownObject is the reserved non-numeric object marking a domain that // answered over neither scheme — distinct from any numeric HTTP status // (including 5xx, which is a response) (REQ: network-failure-is-data). DownObject = "down" // KindDomain names the domain-liveness probe kind in the run summary. KindDomain = "domain" )
const ( // CIAdapterID is the adapter id stamped on every ci-kind fact. It is part of // the store merge key and must differ from the domain kind's id and from // every index adapter's id, so one kind's merge never clobbers another's // (REQ: probe-verb, REQ: probe-merge). CIAdapterID = "probe-ci" // CIStatusPredicate is the predicate the ci kind emits: a repo's latest // default-branch CI run conclusion, joinable against the repo's other facts // by its store slug subject (REQ: ci-state). CIStatusPredicate = "ci-status" // KindCI names the ci-state probe kind in the run summary. KindCI = "ci" )
Variables ¶
var ( // ExecCommandFn is the ci kind's exec seam: it runs name with args in dir // and returns stdout. Every `git`/`gh` invocation goes through this var so // tests drive git/gh outcomes without touching the filesystem or the // network (house exec-seam pattern, mirroring internal/rehearse/runner). ExecCommandFn = execCommandOutput // LookPathFn is the seam for the upfront `gh` presence check: an absent // binary skips the ci kind entirely with one summary warning, exactly as // rehearse skips a scenario needing a missing binary. LookPathFn = exec.LookPath )
Test seams — package-level vars wrapping external functions. Production code calls these vars; tests replace them via t.Cleanup.
var HTTPGetFn = func(url string) (*http.Response, error) { client := &http.Client{Timeout: httpTimeout} return client.Get(url) }
HTTPGetFn is the test seam for the domain kind's HTTP requests: production code issues every domain GET through this var so tests replace it via t.Cleanup and never touch the network. It mirrors http.Get's signature: a non-nil error is a transport-level failure (no HTTP response), which is what the https→http fallback and the `down` mapping key on (REQ: domain-liveness, REQ: network-failure-is-data).
Functions ¶
This section is empty.
Types ¶
type CIRepo ¶
type CIRepo struct {
// Dir is the absolute repo directory `git remote get-url origin` runs in.
Dir string
// Slug is the store's repo slug — the emitted fact's subject.
Slug string
// Ecosystem is carried onto the emitted fact so it joins the same ecosystem
// as the repo's index facts.
Ecosystem string
}
CIRepo is one CI target: the local repo directory to run git/gh in, and the stable store ID the emitted fact's subject must carry so consumers can join CI state against the repo's other facts (REQ: ci-state).
type Result ¶
type Result struct {
// Kinds are the probe kinds that ran, in run order (e.g. ["domain"]).
Kinds []string
// Facts are the verified-behavior facts produced this run, ready to merge.
Facts []fact.Fact
// Warnings are per-target or per-kind notices for the run summary.
Warnings []string
}
Result is the outcome of a probe run: the facts produced (to be merged into the store) plus the human-facing warnings collected along the way. The verb merges Facts and renders Kinds/Warnings into its run summary.
func RunCI ¶
RunCI runs the ci-state kind over the given repos. When `gh` is not on PATH the whole kind is skipped upfront with one warning and no facts (mirroring rehearse's missing-binary skip). For each repo it resolves the GitHub org/name from `git remote get-url origin`; a repo with no origin remote or a non-GitHub remote is skipped with a per-repo notice. For each GitHub-remoted repo it queries the latest default-branch Actions run conclusion via `gh api` and emits one verified-behavior fact under adapter id probe-ci (version = cliVersion), with the evidence pointer set to the queried gh api path and observed_at/verified_at both stamped at now. A repo with no runs or a failing `gh api` call records a per-repo warning and emits no fact — an unreachable CI is "not probed", not "down" (REQ: ci-state).
func RunDomain ¶
RunDomain runs the domain-liveness kind over the domain targets carried by existing: every distinct subject of a `serves-status` fact is a domain to check (the domains the registries adapter declared). For each it issues an https-first / http-fallback GET through HTTPGetFn and emits one `(<domain>, serves-status, <status|down>)` verified-behavior fact under adapter id probe-domain (version = cliVersion), with the evidence pointer set to the URL that answered (or the https URL attempted when neither scheme answered) and observed_at/verified_at both stamped at now (REQ: domain-liveness, REQ: network-failure-is-data). The domain's ecosystem is carried over from its declared fact so the verified fact joins the same ecosystem.