read_control_plane_logs

Generated automatically from the published contract sources.

Build metadata: Registered in this build. Registration describes the default dispatcher in this build. It does not guarantee that a caller has the required credential or grant, that a tool is listed for that connection, or that the required service is configured.

A script calls this action over HTTPS at POST https://turnzero.ai/api/v1/actions/read_control_plane_logs, with a bearer credential and the action's payload as the JSON body. It also accepts GET.

Contract description

Read the platform's stored log entries, using `since`, `until`, `limit`, `level`, `contains`, `field`, `value`, `source`, and `address` or `subject`. Either of those two reads one person's lines: the plane hashes the value under its record identity key, matches the lines' `address_hash` or `subject_hash`, and answers the hash as `identity_hash`. Super-admin (platform operator) only. Here `source` filters the record's writer (`app`, `platform`, `router`, or `egress`); it does not select the container-console reads offered by `read_logs`.

Access and action metadata

{
  "name": "read_control_plane_logs",
  "resource": "environment",
  "tier": "observe",
  "grant": "super_admin",
  "summary": "Super-admin: the control plane's own diagnostics — the control_plane scope's entries within a window or the most recent N, filtered as read_logs filters and by one person's address or subject, hashed in the plane under the record identity key (the logging service).",
  "annotations": {
    "readOnlyHint": true,
    "destructiveHint": false,
    "openWorldHint": false,
    "idempotentHint": true
  }
}

MCP catalog entry

{
  "name": "read_control_plane_logs",
  "tier": "observe",
  "scenario": "API-L0-12",
  "summary": "Read the platform's stored log entries, using `since`, `until`, `limit`, `level`, `contains`, `field`, `value`, `source`, and `address` or `subject`. Either of those two reads one person's lines: the plane hashes the value under its record identity key, matches the lines' `address_hash` or `subject_hash`, and answers the hash as `identity_hash`. Super-admin (platform operator) only. Here `source` filters the record's writer (`app`, `platform`, `router`, or `egress`); it does not select the container-console reads offered by `read_logs`.",
  "owners": [
    "LGS-L0-16",
    "LGS-L0-17",
    "PLD-L0-79"
  ]
}

request

JSON pointer Description and constraints
"" (root) Type: object
Required fields: []
/properties/since Inclusive start of the time window. Use YYYY-MM-DD followed by T (or t), HH:mm, optional :ss, an optional decimal fraction of 1–9 digits after seconds, then Z (or z) or a signed HH:mm offset. The calendar date must exist; hours are 00–23, minutes and seconds 00–59, and offset hours/minutes 00–23/00–59. Leap seconds and 24:00 are not accepted. Values normalize to UTC at millisecond precision. Omission leaves this bound open; the HTTP action returns 400 invalid_request naming the member for null, empty strings, wrong types, or malformed values. MCP rejects wrong argument types before action dispatch.

Type: string
/properties/limit How many entries at most, 1 to 1000; 100 where none is given.

Type: integer
Minimum: 1
Maximum: 1000
/properties/until Inclusive end of the time window. Use YYYY-MM-DD followed by T (or t), HH:mm, optional :ss, an optional decimal fraction of 1–9 digits after seconds, then Z (or z) or a signed HH:mm offset. The calendar date must exist; hours are 00–23, minutes and seconds 00–59, and offset hours/minutes 00–23/00–59. Leap seconds and 24:00 are not accepted. Values normalize to UTC at millisecond precision. Omission leaves this bound open; the HTTP action returns 400 invalid_request naming the member for null, empty strings, wrong types, or malformed values. MCP rejects wrong argument types before action dispatch.

Type: string
/properties/level The lowest level to include — `debug`, `info`, `warn`, or `error`; entries at that level and above are answered, and any other value is ignored.

Type: string
/properties/contains Only entries whose message contains this text.

Type: string
/properties/field The name of one structured field to match; give the value it must hold in `value`.

Type: string
/properties/value The scalar value the named field must equal, with its JSON type preserved. Omit value to match entries containing the field; explicit null matches a null field value.

Type: ["string","number","boolean","null"]
/properties/source Which of the platform's own records to read: `platform` (the control plane process), `router` (the serving router), or `egress` (the outbound proxy); omitted, all three. `app` never appears here.

Type: string
Allowed values: ["app","platform","router","egress"]
/properties/address One person's lines by the address they report. The plane trims and lowercases it, hashes it under its record identity key into the twelve-character member the record carries, and answers only the entries holding that member as `address_hash` or `subject_hash`. The address itself is written to no line. Give `address` or `subject`, not both; the other filters still apply. A plane that holds no key refuses it with 400 invalid_request, every member it wrote being empty.

Type: string
Minimum length: 1
/properties/subject One person's lines by a provider's subject — for GitHub the account's number, for Google the `sub` claim, for the emailed-code route the lowercased address — hashed as given, and otherwise as `address`.

Type: string
Minimum length: 1

response

JSON pointer Description and constraints
"" (root) Type: object
Required fields: ["contract_version","scope","lines"]
/properties/contract_version Required value: 1
/properties/reference The short reference the platform recorded this call under, ten lowercase hexadecimal characters, the value the call’s record row carries; quote it when reporting the call.

Type: string
Pattern: ^[0-9a-f]{10}$
/properties/scope Required value: control_plane
/properties/lines Type: array
/properties/lines/items Type: string
/properties/entries Type: array
/properties/entries/items Type: object
Required fields: ["at","level","source","message"]
/properties/entries/items/properties/at Type: string
/properties/entries/items/properties/level Type: string
/properties/entries/items/properties/source Type: string
/properties/entries/items/properties/message Type: string
/properties/entries/items/properties/fields Type: object
/properties/identity_hash Present where `address` or `subject` was given: the member the plane computed, the value the record's `address_hash` or `subject_hash` carries for that person, for a search of the standard output the store does not hold (PLD-L0-79).

Type: string

Complete payload contract

{
  "request": {
    "type": "object",
    "required": [],
    "properties": {
      "since": {
        "type": "string",
        "description": "Inclusive start of the time window. Use YYYY-MM-DD followed by T (or t), HH:mm, optional :ss, an optional decimal fraction of 1–9 digits after seconds, then Z (or z) or a signed HH:mm offset. The calendar date must exist; hours are 00–23, minutes and seconds 00–59, and offset hours/minutes 00–23/00–59. Leap seconds and 24:00 are not accepted. Values normalize to UTC at millisecond precision. Omission leaves this bound open; the HTTP action returns 400 invalid_request naming the member for null, empty strings, wrong types, or malformed values. MCP rejects wrong argument types before action dispatch."
      },
      "limit": {
        "type": "integer",
        "minimum": 1,
        "maximum": 1000,
        "description": "How many entries at most, 1 to 1000; 100 where none is given."
      },
      "until": {
        "type": "string",
        "description": "Inclusive end of the time window. Use YYYY-MM-DD followed by T (or t), HH:mm, optional :ss, an optional decimal fraction of 1–9 digits after seconds, then Z (or z) or a signed HH:mm offset. The calendar date must exist; hours are 00–23, minutes and seconds 00–59, and offset hours/minutes 00–23/00–59. Leap seconds and 24:00 are not accepted. Values normalize to UTC at millisecond precision. Omission leaves this bound open; the HTTP action returns 400 invalid_request naming the member for null, empty strings, wrong types, or malformed values. MCP rejects wrong argument types before action dispatch."
      },
      "level": {
        "type": "string",
        "description": "The lowest level to include — `debug`, `info`, `warn`, or `error`; entries at that level and above are answered, and any other value is ignored."
      },
      "contains": {
        "type": "string",
        "description": "Only entries whose message contains this text."
      },
      "field": {
        "type": "string",
        "description": "The name of one structured field to match; give the value it must hold in `value`."
      },
      "value": {
        "type": [
          "string",
          "number",
          "boolean",
          "null"
        ],
        "description": "The scalar value the named field must equal, with its JSON type preserved. Omit value to match entries containing the field; explicit null matches a null field value."
      },
      "source": {
        "type": "string",
        "description": "Which of the platform's own records to read: `platform` (the control plane process), `router` (the serving router), or `egress` (the outbound proxy); omitted, all three. `app` never appears here.",
        "enum": [
          "app",
          "platform",
          "router",
          "egress"
        ]
      },
      "address": {
        "type": "string",
        "minLength": 1,
        "description": "One person's lines by the address they report. The plane trims and lowercases it, hashes it under its record identity key into the twelve-character member the record carries, and answers only the entries holding that member as `address_hash` or `subject_hash`. The address itself is written to no line. Give `address` or `subject`, not both; the other filters still apply. A plane that holds no key refuses it with 400 invalid_request, every member it wrote being empty."
      },
      "subject": {
        "type": "string",
        "minLength": 1,
        "description": "One person's lines by a provider's subject — for GitHub the account's number, for Google the `sub` claim, for the emailed-code route the lowercased address — hashed as given, and otherwise as `address`."
      }
    }
  },
  "response": {
    "type": "object",
    "required": [
      "contract_version",
      "scope",
      "lines"
    ],
    "properties": {
      "contract_version": {
        "const": 1
      },
      "reference": {
        "type": "string",
        "pattern": "^[0-9a-f]{10}$",
        "description": "The short reference the platform recorded this call under, ten lowercase hexadecimal characters, the value the call’s record row carries; quote it when reporting the call."
      },
      "scope": {
        "const": "control_plane"
      },
      "lines": {
        "type": "array",
        "items": {
          "type": "string"
        }
      },
      "entries": {
        "type": "array",
        "items": {
          "type": "object",
          "required": [
            "at",
            "level",
            "source",
            "message"
          ],
          "properties": {
            "at": {
              "type": "string"
            },
            "level": {
              "type": "string"
            },
            "source": {
              "type": "string"
            },
            "message": {
              "type": "string"
            },
            "fields": {
              "type": "object"
            }
          }
        }
      },
      "identity_hash": {
        "type": "string",
        "description": "Present where `address` or `subject` was given: the member the plane computed, the value the record's `address_hash` or `subject_hash` carries for that person, for a search of the standard output the store does not hold (PLD-L0-79)."
      }
    }
  }
}

Shared contracts