served.observe
Fetches the build identity the site serves (`build.json` under the configured base URL, one bounded probe, no shell), judges it against the expected commit (HEAD unless named) by containment and appends the observation to the checkout-local record. Exit 0 when the deployment serves a build containing the commit, 10 when it measurably does not (behind, or built dirty), 12 when the question could not be answered (unreachable, unreadable, or a served commit this clone lacks).
Fetches the build identity the site serves (`build.json` under the configured base URL, one bounded probe, no shell), judges it against the expected commit (HEAD unless named) by containment and appends the observation to the checkout-local record. Exit 0 when the deployment serves a build containing the commit, 10 when it measurably does not (behind, or built dirty), 12 when the question could not be answered (unreachable, unreadable, or a served commit this clone lacks).
- command
- behaviorally_verified
- module served
- #deployment
- #evidence
- #verification
Exposure
Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.
| surface | as |
|---|---|
| MCP | — |
| HTTP | — |
| command line | majordomus served observe |
Schemas
The canonical input and output, from the Rust types; the MCP tool schema and the OpenAPI parameters and responses are derived from these.
input · ObserveInput
served.observe: which deployment, where it is, which commit is expected
and how long the probe may take. Everything is optional — the defaults are this
repository's own site, its build.json and HEAD.
use majordomus_cli::capability::builtin::served::ObserveInput;
let input: ObserveInput = serde_json::from_str(r#"{"commit":"HEAD"}"#).unwrap();
assert_eq!(input.commit.as_deref(), Some("HEAD"));
assert!(serde_json::from_str::<ObserveInput>(r#"{"shell":"rm"}"#).is_err());| property | type | required | description |
|---|---|---|---|
| commit | string | null | no | The commit expected to be served, any revision git resolves; HEAD when absent. |
| deployment | string | null | no | The name the observation is recorded under; pages when absent. |
| dry_run | boolean | no | Judge without recording. Recording is the default, because an observation nobody kept is a measurement nobody can read. default false |
| identity | string | null | no | The identity file under the base; build.json when absent. |
| timeout_seconds | integer | null | no | The bound on the probe in seconds; ten when absent. |
| url | string | null | no | The site's base URL; base_url of site/config.toml when absent. |
JSON Schema
{
"additionalProperties": false,
"description": "The input of `served.observe`: which deployment, where it is, which commit is expected\nand how long the probe may take. Everything is optional — the defaults are this\nrepository's own site, its `build.json` and `HEAD`.\n\n```\nuse majordomus_cli::capability::builtin::served::ObserveInput;\nlet input: ObserveInput = serde_json::from_str(r#\"{\"commit\":\"HEAD\"}\"#).unwrap();\nassert_eq!(input.commit.as_deref(), Some(\"HEAD\"));\nassert!(serde_json::from_str::<ObserveInput>(r#\"{\"shell\":\"rm\"}\"#).is_err());\n```",
"properties": {
"commit": {
"description": "The commit expected to be served, any revision git resolves; `HEAD` when absent.",
"type": [
"string",
"null"
]
},
"deployment": {
"description": "The name the observation is recorded under; `pages` when absent.",
"type": [
"string",
"null"
]
},
"dry_run": {
"default": false,
"description": "Judge without recording. Recording is the default, because an observation nobody\nkept is a measurement nobody can read.",
"type": "boolean"
},
"identity": {
"description": "The identity file under the base; `build.json` when absent.",
"type": [
"string",
"null"
]
},
"timeout_seconds": {
"description": "The bound on the probe in seconds; ten when absent.",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"url": {
"description": "The site's base URL; `base_url` of `site/config.toml` when absent.",
"type": [
"string",
"null"
]
}
},
"title": "ObserveInput",
"type": "object"
}output · Observed
served.observe did: the observation, where it was recorded, and the exit status
the command line reports the verdict with.
use majordomus_cli::capability::builtin::served::Observed;
// the shape a caller reads: a dry run judges and records nothing
let json = r#"{"observation":{"schema":"majordomus.served-observation/v1",
"deployment":"pages","url":"https://majordomus.dev/build.json",
"expected":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","verdict":"unreachable",
"reason":"nothing was received","at":"1970-01-01T00:00:00Z"},"exit_code":12}"#;
let got: Observed = serde_json::from_str(json).unwrap();
assert_eq!(got.exit_code, 12);
assert!(got.recorded.is_none());| property | type | required | description |
|---|---|---|---|
| exit_code | integer | yes | The exit status the command line reports: 0 served, 10 a measured no, 12 unanswered. |
| observation | reference | yes | The observation, with its judgement. |
| recorded | string | null | no | Where it was recorded, repository-relative; absent on a dry run. |
JSON Schema
{
"$defs": {
"BuildIdentity": {
"description": "The build identity a deployment serves, as far as this module relies on it. Other\nfields of the served document are ignored rather than refused: the document is written\nby another program, and a field it adds is not a malformation.\n\n```\nuse majordomus_cli::served::BuildIdentity;\nlet id = BuildIdentity {\n commit: \"a\".repeat(40),\n dirty: false,\n source_version: Some(\"0.7.0\".into()),\n source_hash: None,\n};\n// what is judged is the commit and whether the tree it was built from was committed\nassert_eq!(id.commit.len(), 40);\nassert!(!id.dirty);\n```",
"properties": {
"commit": {
"description": "The full commit the served build was made from.",
"type": "string"
},
"dirty": {
"description": "Whether the tree it was built from had uncommitted changes. A dirty build names a\ncommit it does not equal, so it proves no commit.",
"type": "boolean"
},
"source_hash": {
"description": "The fingerprint of the site's canonical inputs, when the build states one.",
"type": [
"string",
"null"
]
},
"source_version": {
"description": "The version the build states, when it states one.",
"type": [
"string",
"null"
]
}
},
"required": [
"commit",
"dirty"
],
"type": "object"
},
"Observation": {
"description": "One observation of one deployment, as recorded: what was asked, what was served, what\nwas judged and when. Everything needed to judge it again later is in the record, which\nis what lets `Observation::rejudge` answer without probing.\n\n```\nuse majordomus_cli::served::{observe, Fetch, Fetched, GitAncestry, Observation, OBSERVATION_SCHEMA};\nuse std::{path::Path, time::SystemTime};\nstruct None_;\nimpl Fetch for None_ {\n fn fetch(&self, _: &str) -> Fetched { Fetched::Unreachable(\"no route\".into()) }\n}\nlet git = GitAncestry { root: Path::new(env!(\"CARGO_MANIFEST_DIR\")) };\nlet o: Observation = observe(\"pages\", \"https://s\", \"build.json\", &\"a\".repeat(40), &None_,\n &git, SystemTime::UNIX_EPOCH);\nassert_eq!(o.schema, OBSERVATION_SCHEMA);\nassert_eq!(o.url, \"https://s/build.json\");\nassert_eq!(o.at, \"1970-01-01T00:00:00Z\");\n```",
"properties": {
"at": {
"description": "When, RFC 3339 UTC.",
"type": "string"
},
"deployment": {
"description": "Which deployment: the name the caller observed it under (`pages`, or a deployment\nobject's id).",
"type": "string"
},
"expected": {
"description": "The commit that was expected, full.",
"type": "string"
},
"reason": {
"description": "Why, in one line a reader can act on.",
"type": "string"
},
"schema": {
"description": "Always `OBSERVATION_SCHEMA`.",
"type": "string"
},
"served": {
"anyOf": [
{
"$ref": "#/$defs/BuildIdentity"
},
{
"type": "null"
}
],
"description": "What was served, when a build identity was received."
},
"url": {
"description": "The identity URL probed.",
"type": "string"
},
"verdict": {
"$ref": "#/$defs/ServedVerdict",
"description": "The verdict."
}
},
"required": [
"schema",
"deployment",
"url",
"expected",
"verdict",
"reason",
"at"
],
"type": "object"
},
"ServedVerdict": {
"description": "What an observation says about the expected commit. Only `ServedVerdict::Served` is a\nproof; the other five are each a different reason the question was not answered yes.\n\n```\nuse majordomus_cli::served::ServedVerdict;\n// a measured no and an unanswered question are never spelled the same\nassert!(ServedVerdict::Served.passes());\nassert_eq!(ServedVerdict::Stale.exit_code(), 10);\nassert_eq!(ServedVerdict::Unreachable.exit_code(), 12);\n```",
"oneOf": [
{
"const": "served",
"description": "The served build is the expected commit or contains it. The only passing verdict.",
"type": "string"
},
{
"const": "stale",
"description": "The served build does not contain the expected commit: the deployment is behind.",
"type": "string"
},
{
"const": "unreachable",
"description": "Nothing was received. The deployment was not measured.",
"type": "string"
},
{
"const": "malformed",
"description": "Something was received and it is not a build identity.",
"type": "string"
},
{
"const": "dirty",
"description": "The served build was made from an uncommitted tree, so it proves no commit.",
"type": "string"
},
{
"const": "undecided",
"description": "The served commit is not in this clone, or git could not be asked; containment is\nundecided. Fetching the remote usually turns this into an answer.",
"type": "string"
}
]
}
},
"description": "What `served.observe` did: the observation, where it was recorded, and the exit status\nthe command line reports the verdict with.\n\n```\nuse majordomus_cli::capability::builtin::served::Observed;\n// the shape a caller reads: a dry run judges and records nothing\nlet json = r#\"{\"observation\":{\"schema\":\"majordomus.served-observation/v1\",\n \"deployment\":\"pages\",\"url\":\"https://majordomus.dev/build.json\",\n \"expected\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"verdict\":\"unreachable\",\n \"reason\":\"nothing was received\",\"at\":\"1970-01-01T00:00:00Z\"},\"exit_code\":12}\"#;\nlet got: Observed = serde_json::from_str(json).unwrap();\nassert_eq!(got.exit_code, 12);\nassert!(got.recorded.is_none());\n```",
"properties": {
"exit_code": {
"description": "The exit status the command line reports: 0 served, 10 a measured no, 12 unanswered.",
"format": "int32",
"type": "integer"
},
"observation": {
"$ref": "#/$defs/Observation",
"description": "The observation, with its judgement."
},
"recorded": {
"description": "Where it was recorded, repository-relative; absent on a dry run.",
"type": [
"string",
"null"
]
}
},
"required": [
"observation",
"exit_code"
],
"title": "Observed",
"type": "object"
}Policies
- benchmark
- waived — waived: external_dependency
- cache
- disabled — every call runs the handler
Benchmark targets
Derived from the registry for this repository: one requirement per transport, and the cases the input type provides. The whole matrix is on the benchmarks page.
| transport | state | cases | targets |
|---|---|---|---|
| direct | waived (external_dependency) | 0 |