Přeskočit na obsah

Tato stránka byla automaticky přeložena z angličtiny, jediného jazyka, ve kterém se tento web píše. Číst originál.

economics.tasks

One record per task, folded from the ledger of every checkout `git worktree list` reports and the archives a ledger rotation left: its issue and intent, checkout and branch, first start, last finish or refusal, wall seconds, refusal count, and the episodes that carried it with their spans. Interventions, CI reruns, spend and acceptance are present on every record as not_observed, each with the reason and the issue that will supply it. Lists every ledger read with its line and skipped-line counts and every checkout not read; an optional since/until window filters by each task's start.

One record per task, folded from the ledger of every checkout `git worktree list` reports and the archives a ledger rotation left: its issue and intent, checkout and branch, first start, last finish or refusal, wall seconds, refusal count, and the episodes that carried it with their spans. Interventions, CI reruns, spend and acceptance are present on every record as not_observed, each with the reason and the issue that will supply it. Lists every ledger read with its line and skipped-line counts and every checkout not read; an optional since/until window filters by each task's start.

Zpřístupnění

Kde je tato jedna definice dosažitelná. Absence je explicitní: povrch, který není uveden, ji nenese.

povrchjako
MCPtool majordomus_economics_tasks
HTTPGET /api/v1/economics/tasks operationId economics.tasks
příkazová řádkamajordomus economics tasks

Schémata

Kanonický vstup a výstup z typů Rustu; schéma nástroje MCP a parametry a odpovědi OpenAPI se odvozují z nich.

input · TaskEconomicsQuery

Which tasks to answer. A window filters by each task's task.started time, so a task with no start line in the ledgers read is answered only when no window is given.

use majordomus_cli::economics::tasks::TaskEconomicsQuery;
let q: TaskEconomicsQuery = serde_json::from_str(r#"{"since":"2026-10-21T00:00:00Z"}"#).unwrap();
assert_eq!(q.since.as_deref(), Some("2026-10-21T00:00:00Z"));
assert!(q.until.is_none());
assert_eq!(serde_json::from_str::<TaskEconomicsQuery>("{}").unwrap(), TaskEconomicsQuery::default());
// a misspelt bound is refused, never read as no bound
assert!(serde_json::from_str::<TaskEconomicsQuery>(r#"{"after":"x"}"#).is_err());
vlastnosttyppovinnépopis
od string | null ne Answer only tasks started at or after this time (YYYY-MM-DDTHH:MM:SSZ).
do string | null ne Answer only tasks started before this time (YYYY-MM-DDTHH:MM:SSZ).
JSON Schema
{
  "additionalProperties": false,
  "description": "Which tasks to answer. A window filters by each task's `task.started` time, so a task\nwith no start line in the ledgers read is answered only when no window is given.\n\n```\nuse majordomus_cli::economics::tasks::TaskEconomicsQuery;\nlet q: TaskEconomicsQuery = serde_json::from_str(r#\"{\"since\":\"2026-10-21T00:00:00Z\"}\"#).unwrap();\nassert_eq!(q.since.as_deref(), Some(\"2026-10-21T00:00:00Z\"));\nassert!(q.until.is_none());\nassert_eq!(serde_json::from_str::<TaskEconomicsQuery>(\"{}\").unwrap(), TaskEconomicsQuery::default());\n// a misspelt bound is refused, never read as no bound\nassert!(serde_json::from_str::<TaskEconomicsQuery>(r#\"{\"after\":\"x\"}\"#).is_err());\n```",
  "properties": {
    "since": {
      "description": "Answer only tasks started at or after this time (`YYYY-MM-DDTHH:MM:SSZ`).",
      "type": [
        "string",
        "null"
      ]
    },
    "until": {
      "description": "Answer only tasks started before this time (`YYYY-MM-DDTHH:MM:SSZ`).",
      "type": [
        "string",
        "null"
      ]
    }
  },
  "title": "TaskEconomicsQuery",
  "type": "object"
}

output · TaskEconomicsList

Every task the ledgers read carry, and what was read to answer it.

use majordomus_cli::economics::tasks::{fold, TaskEconomicsList, TaskEconomicsQuery, TaskEconomicsSource};
let text = r#"{"ts":"2026-10-21T10:00:00Z","event":"task.started","head":"h","branch":"b","by":"me","session":"s-1","task_id":"t-1"}"#;
let source = TaskEconomicsSource::parse("repo", "ledger.jsonl", text);
let list: TaskEconomicsList = fold(vec![source], &TaskEconomicsQuery::default());
assert_eq!((list.count, list.tasks.len()), (1, 1));
assert_eq!(list.ledgers[0].path, "ledger.jsonl");
assert!(list.unread.is_empty(), "fold reads no checkout, so it names none unread");
vlastnosttyppovinnépopis
počet integer ano How many tasks are answered: the number of distinct task ids within the window.
ledgers array ano Every ledger file read, with its line and skipped-line counts.
úlohy array ano One record per task, in the order the tasks started.
nepřečteno array ano Every checkout whose ledger could not be read, and why.
okno reference ano The window the tasks were filtered by, as given.
JSON Schema
{
  "$defs": {
    "TaskEconomicsEpisode": {
      "description": "One episode that carried a task, with the span of the lines it wrote about it.\n\n```\nuse majordomus_cli::economics::tasks::{fold, TaskEconomicsEpisode, TaskEconomicsSource};\nlet line = |ts: &str, event: &str, session: &str| {\n    format!(r#\"{{\"ts\":\"{ts}\",\"event\":\"{event}\",\"head\":\"h\",\"branch\":\"b\",\"by\":\"me\",\"session\":\"{session}\",\"task_id\":\"t-1\"}}\"#)\n};\nlet text = [\n    line(\"2026-10-21T10:00:00Z\", \"task.started\", \"s-1\"),\n    line(\"2026-10-21T11:00:00Z\", \"task.finished\", \"s-2\"),\n]\n.join(\"\\n\");\nlet list = fold(vec![TaskEconomicsSource::parse(\"repo\", \"ledger.jsonl\", &text)], &Default::default());\nlet episodes: &[TaskEconomicsEpisode] = &list.tasks[0].episodes;\nassert_eq!(episodes.len(), 2, \"two session stamps are two episodes\");\nassert_eq!((episodes[1].session.as_str(), episodes[1].lines), (\"s-2\", 1));\nassert_eq!(episodes[1].first_at, \"2026-10-21T11:00:00Z\");\n```",
      "properties": {
        "first_at": {
          "description": "The time of the episode's first line about the task.",
          "type": "string"
        },
        "last_at": {
          "description": "The time of the episode's last line about the task.",
          "type": "string"
        },
        "lines": {
          "description": "How many of the episode's lines are about the task.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "provider": {
          "description": "The provider that ran the episode, when the ledger names it. Left out of the answer\nwhen it does not, so it reads back as empty: without `default` the text form, which\nreads the capability's JSON, refused every episode whose provider is unknown.",
          "type": "string"
        },
        "session": {
          "description": "The episode's session id.",
          "type": "string"
        }
      },
      "required": [
        "session",
        "first_at",
        "last_at",
        "lines"
      ],
      "type": "object"
    },
    "TaskEconomicsField": {
      "description": "A field of the record that nothing observes yet, carrying the reason and the issue that\nwill supply it in place of a value.\n\n```\nuse majordomus_cli::economics::tasks::{fold, TaskEconomicsField, TaskEconomicsSource};\nlet text = r#\"{\"ts\":\"2026-10-21T10:00:00Z\",\"event\":\"task.started\",\"head\":\"h\",\"branch\":\"b\",\"by\":\"me\",\"task_id\":\"t-1\"}\"#;\nlet list = fold(vec![TaskEconomicsSource::parse(\"repo\", \"ledger.jsonl\", text)], &Default::default());\nlet field: &TaskEconomicsField = &list.tasks[0].ci_reruns;\nlet v = serde_json::to_value(field).unwrap();\nassert_eq!(v[\"status\"], \"not_observed\");\nassert!(field.reason.contains(\"I3378\"), \"{}\", field.reason);\n```",
      "properties": {
        "reason": {
          "description": "Why there is no value, naming what will supply it.",
          "type": "string"
        },
        "status": {
          "$ref": "#/$defs/TaskEconomicsFieldStatus",
          "description": "Always `not_observed` until the field's supplier lands."
        }
      },
      "required": [
        "status",
        "reason"
      ],
      "type": "object"
    },
    "TaskEconomicsFieldStatus": {
      "description": "Whether a field holds an observation. Its one variant says there is none, which is not a\nzero.\n\n```\nuse majordomus_cli::economics::tasks::TaskEconomicsFieldStatus;\nlet v = serde_json::to_value(TaskEconomicsFieldStatus::NotObserved).unwrap();\nassert_eq!(v, \"not_observed\");\n```",
      "oneOf": [
        {
          "const": "not_observed",
          "description": "Nothing observes the field yet: there is no value, which is not a zero.",
          "type": "string"
        }
      ]
    },
    "TaskEconomicsLedger": {
      "description": "One ledger file that was read, with how many of its lines were entries and how many\ncould not be read as one.\n\n```\nuse majordomus_cli::economics::tasks::{TaskEconomicsLedger, TaskEconomicsSource};\nlet s = TaskEconomicsSource::parse(\"repo\", \".ai/local/state/ledger.jsonl\", \"{}\\nnot json\\n\");\nlet ledger: &TaskEconomicsLedger = &s.ledgers[0];\nassert_eq!(ledger.checkout, \"repo\");\nassert_eq!(ledger.path, \".ai/local/state/ledger.jsonl\");\nassert_eq!((ledger.lines, ledger.skipped), (0, 2), \"neither line is a ledger entry\");\n```",
      "properties": {
        "checkout": {
          "description": "The checkout the ledger belongs to.",
          "type": "string"
        },
        "lines": {
          "description": "How many lines were read as ledger entries.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "path": {
          "description": "The file, relative to the checkout.",
          "type": "string"
        },
        "skipped": {
          "description": "How many non-empty lines could not be read as ledger entries.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "checkout",
        "path",
        "lines",
        "skipped"
      ],
      "type": "object"
    },
    "TaskEconomicsQuery": {
      "additionalProperties": false,
      "description": "Which tasks to answer. A window filters by each task's `task.started` time, so a task\nwith no start line in the ledgers read is answered only when no window is given.\n\n```\nuse majordomus_cli::economics::tasks::TaskEconomicsQuery;\nlet q: TaskEconomicsQuery = serde_json::from_str(r#\"{\"since\":\"2026-10-21T00:00:00Z\"}\"#).unwrap();\nassert_eq!(q.since.as_deref(), Some(\"2026-10-21T00:00:00Z\"));\nassert!(q.until.is_none());\nassert_eq!(serde_json::from_str::<TaskEconomicsQuery>(\"{}\").unwrap(), TaskEconomicsQuery::default());\n// a misspelt bound is refused, never read as no bound\nassert!(serde_json::from_str::<TaskEconomicsQuery>(r#\"{\"after\":\"x\"}\"#).is_err());\n```",
      "properties": {
        "since": {
          "description": "Answer only tasks started at or after this time (`YYYY-MM-DDTHH:MM:SSZ`).",
          "type": [
            "string",
            "null"
          ]
        },
        "until": {
          "description": "Answer only tasks started before this time (`YYYY-MM-DDTHH:MM:SSZ`).",
          "type": [
            "string",
            "null"
          ]
        }
      },
      "type": "object"
    },
    "TaskEconomicsRecord": {
      "description": "One task's delivery economics: who carried it, when, how often `finish` refused it, and\nthe fields nothing observes yet, each saying why it has no value.\n\n```\nuse majordomus_cli::economics::tasks::{\n    fold, TaskEconomicsRecord, TaskEconomicsSource, TaskEconomicsState,\n};\nlet text = r#\"{\"ts\":\"2026-10-21T10:00:00Z\",\"event\":\"task.started\",\"head\":\"h\",\"branch\":\"b\",\n    \"by\":\"me\",\"session\":\"s-1\",\"task_id\":\"t-1\",\"issue\":\"I3376\"}\"#;\nlet source = TaskEconomicsSource::parse(\"repo\", \"ledger.jsonl\", &text.replace('\\n', \"\"));\nlet list = fold(vec![source], &Default::default());\nlet r: &TaskEconomicsRecord = &list.tasks[0];\nassert_eq!((r.task_id.as_str(), r.branch.as_str()), (\"t-1\", \"b\"));\nassert_eq!(r.state, TaskEconomicsState::Open);\nassert_eq!(r.outcome, \"active\");\nassert_eq!(r.wall_seconds, None, \"an open task with no refusal has no end\");\nassert_eq!(r.issue.as_deref(), Some(\"I3376\"));\nassert!(r.spend.reason.contains(\"I3379\"));\n```",
      "properties": {
        "accepted": {
          "$ref": "#/$defs/TaskEconomicsField",
          "description": "Whether the task's result was accepted."
        },
        "branch": {
          "description": "The branch the task started on.",
          "type": "string"
        },
        "checkout": {
          "description": "The checkout whose ledger carries the task.",
          "type": "string"
        },
        "ci_reruns": {
          "$ref": "#/$defs/TaskEconomicsField",
          "description": "CI runs of the task's work that were rerun."
        },
        "ended_at": {
          "description": "The time of the task's last `task.finished` line, or of its last `task.refused` line\nwhile it has none.",
          "type": [
            "string",
            "null"
          ]
        },
        "episodes": {
          "description": "The episodes that carried the task, each with the span of its lines about it.",
          "items": {
            "$ref": "#/$defs/TaskEconomicsEpisode"
          },
          "type": "array"
        },
        "intent": {
          "description": "The intent the task was started under, when it named one.",
          "type": [
            "string",
            "null"
          ]
        },
        "interventions": {
          "$ref": "#/$defs/TaskEconomicsField",
          "description": "Human interventions during the task."
        },
        "issue": {
          "description": "The issue the task was started under, when it named one.",
          "type": [
            "string",
            "null"
          ]
        },
        "outcome": {
          "description": "The outcome as recorded: the finish's outcome, or `active` / `handed_over` while open.",
          "type": "string"
        },
        "refusals": {
          "description": "How many times `finish` refused the task.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "spend": {
          "$ref": "#/$defs/TaskEconomicsField",
          "description": "What the task cost."
        },
        "started_at": {
          "description": "The time of the task's first `task.started` line.",
          "type": [
            "string",
            "null"
          ]
        },
        "state": {
          "$ref": "#/$defs/TaskEconomicsState",
          "description": "`finished` once a `task.finished` line is read, `open` otherwise."
        },
        "task_id": {
          "description": "The task's id, as `start` wrote it.",
          "type": "string"
        },
        "wall_seconds": {
          "description": "Seconds from `started_at` to `ended_at`; absent while either is.",
          "format": "int64",
          "type": [
            "integer",
            "null"
          ]
        }
      },
      "required": [
        "task_id",
        "checkout",
        "branch",
        "state",
        "outcome",
        "refusals",
        "episodes",
        "interventions",
        "ci_reruns",
        "spend",
        "accepted"
      ],
      "type": "object"
    },
    "TaskEconomicsState": {
      "description": "Whether a task has finished, as the command line, MCP and HTTP spell it.\n\n```\nuse majordomus_cli::economics::tasks::TaskEconomicsState;\nassert_eq!(serde_json::to_value(TaskEconomicsState::Open).unwrap(), \"open\");\nassert_eq!(serde_json::to_value(TaskEconomicsState::Finished).unwrap(), \"finished\");\n```",
      "oneOf": [
        {
          "const": "open",
          "description": "No `task.finished` line was read for the task.",
          "type": "string"
        },
        {
          "const": "finished",
          "description": "A `task.finished` line was read for the task.",
          "type": "string"
        }
      ]
    },
    "TaskEconomicsUnread": {
      "description": "A checkout whose ledger was not read, and the reason, so a missing ledger is never read\nas a checkout with no tasks.\n\n```\nuse majordomus_cli::economics::tasks::{tasks, TaskEconomicsQuery, TaskEconomicsUnread};\nlet dir = tempfile::tempdir().unwrap();\nlet list = tasks(dir.path(), &TaskEconomicsQuery::default());\nlet unread: &TaskEconomicsUnread = &list.unread[0];\nassert_eq!(unread.checkout, dir.path().display().to_string());\nassert_eq!(unread.reason, \"no ledger under .ai/local/state\");\n```",
      "properties": {
        "checkout": {
          "description": "The checkout.",
          "type": "string"
        },
        "reason": {
          "description": "Why its ledger was not read.",
          "type": "string"
        }
      },
      "required": [
        "checkout",
        "reason"
      ],
      "type": "object"
    }
  },
  "description": "Every task the ledgers read carry, and what was read to answer it.\n\n```\nuse majordomus_cli::economics::tasks::{fold, TaskEconomicsList, TaskEconomicsQuery, TaskEconomicsSource};\nlet text = r#\"{\"ts\":\"2026-10-21T10:00:00Z\",\"event\":\"task.started\",\"head\":\"h\",\"branch\":\"b\",\"by\":\"me\",\"session\":\"s-1\",\"task_id\":\"t-1\"}\"#;\nlet source = TaskEconomicsSource::parse(\"repo\", \"ledger.jsonl\", text);\nlet list: TaskEconomicsList = fold(vec![source], &TaskEconomicsQuery::default());\nassert_eq!((list.count, list.tasks.len()), (1, 1));\nassert_eq!(list.ledgers[0].path, \"ledger.jsonl\");\nassert!(list.unread.is_empty(), \"fold reads no checkout, so it names none unread\");\n```",
  "properties": {
    "count": {
      "description": "How many tasks are answered: the number of distinct task ids within the window.",
      "format": "uint",
      "minimum": 0,
      "type": "integer"
    },
    "ledgers": {
      "description": "Every ledger file read, with its line and skipped-line counts.",
      "items": {
        "$ref": "#/$defs/TaskEconomicsLedger"
      },
      "type": "array"
    },
    "tasks": {
      "description": "One record per task, in the order the tasks started.",
      "items": {
        "$ref": "#/$defs/TaskEconomicsRecord"
      },
      "type": "array"
    },
    "unread": {
      "description": "Every checkout whose ledger could not be read, and why.",
      "items": {
        "$ref": "#/$defs/TaskEconomicsUnread"
      },
      "type": "array"
    },
    "window": {
      "$ref": "#/$defs/TaskEconomicsQuery",
      "description": "The window the tasks were filtered by, as given."
    }
  },
  "required": [
    "count",
    "window",
    "tasks",
    "ledgers",
    "unread"
  ],
  "title": "TaskEconomicsList",
  "type": "object"
}

Politiky

benchmark
povinné — cíl na každém transportu, který expozice deklaruje; případy jsou ty ze vstupního typu
cache
vypnuto — každé volání spustí handler

Cíle benchmarku

Odvozeno z registru pro tento repozitář: jeden požadavek na transport a případy, které poskytuje typ vstupu. Celá matice je na stránce měření výkonu.

transportstatepřípadytargets
directpokryto2vše
okno
mcppokryto2vše
okno
httppokryto2vše
okno

Prohledává názvy a popisy všech stránek, které tento web publikuje.