JSON reports: ascribe permalinks and ascribe addresses
The JSON Schemas of what ascribe permalinks and ascribe addresses write with --format json.
For AI agents: the documentation index is at llms.txt, and this page is available as Markdown.
Part of the JSON report contract, whose rules every document here follows.
ascribe permalinks sync
schemas/permalinks-sync.schema.json:
{
"$defs": {
"MovedEntry": {
"description": "A permalink whose place changed.",
"properties": {
"from": {
"description": "Where the list had it.",
"type": "string"
},
"name": {
"description": "Its name.",
"type": "string"
},
"to": {
"description": "Where it's declared now.",
"type": "string"
}
},
"required": [
"name",
"from",
"to"
],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "What `ascribe permalinks sync` does to the list.",
"properties": {
"added": {
"description": "The names added, by name.",
"items": {
"type": "string"
},
"type": "array"
},
"aliased": {
"description": "The names moved to another permalink recorded, new or leading\nsomewhere new, by name.",
"items": {
"type": "string"
},
"type": "array"
},
"ascribe_version": {
"description": "The version of Ascribe that wrote it.",
"type": "string"
},
"changed": {
"description": "Whether the list's file changes: it's new, or its text differs.",
"type": "boolean"
},
"created": {
"description": "Whether the project had no list, so this makes one.",
"type": "boolean"
},
"forwarded": {
"description": "The names moved to a page recorded, new or leading somewhere new, by\nname.",
"items": {
"type": "string"
},
"type": "array"
},
"moved": {
"description": "The names whose place changed, by name.",
"items": {
"$ref": "#/$defs/MovedEntry"
},
"type": "array"
},
"removed": {
"description": "The names the list keeps that the project no longer has, by name.\n`ascribe check` warns about each.",
"items": {
"type": "string"
},
"type": "array"
},
"retired": {
"description": "The retired permalinks recorded, new or with a new reason, by name.",
"items": {
"type": "string"
},
"type": "array"
},
"schema_version": {
"description": "The version of this schema. It changes only when a field is removed\nor changes meaning.",
"minimum": 0,
"type": "integer"
},
"written": {
"description": "Whether the list's file was written: it changes, and nothing said to\nwrite nothing (`--check`, `--dry-run`).",
"type": "boolean"
}
},
"required": [
"schema_version",
"ascribe_version",
"changed",
"written",
"created",
"added",
"moved",
"aliased",
"forwarded",
"retired",
"removed"
],
"title": "PermalinksSyncReport",
"type": "object"
}
ascribe permalinks list
schemas/permalinks-list.schema.json:
{
"$defs": {
"AliasEntry": {
"description": "A name `ascribe.addresses` moves to another permalink: an alias.",
"properties": {
"name": {
"description": "Its name.",
"type": "string"
},
"state": {
"$ref": "#/$defs/ListState",
"description": "Whether the list has it, leading there: `listed`, or `not_listed`."
},
"target": {
"description": "The name it was moved to.",
"type": "string"
}
},
"required": [
"name",
"target",
"state"
],
"type": "object"
},
"DeclaredEntry": {
"description": "A permalink the content declares.",
"properties": {
"file": {
"description": "The file it's declared in, from the project root, as `ascribe check`\nreports it.",
"type": "string"
},
"line": {
"description": "The line of its `@id` or its frontmatter `permalink`, from 1.",
"minimum": 0,
"type": "integer"
},
"listed_at": {
"description": "The place the list has for it, when that's somewhere else.",
"type": [
"string",
"null"
]
},
"name": {
"description": "Its name.",
"type": "string"
},
"place": {
"description": "Where it's declared, as the list writes it: the file's path from the\ncontent root, and `#` and the id for a heading.",
"type": "string"
},
"state": {
"$ref": "#/$defs/ListState",
"description": "Whether the list has it: `listed` at one of the places its name is\ndeclared, `moved` when the list has it somewhere else, or\n`not_listed`."
}
},
"required": [
"name",
"place",
"file",
"line",
"state",
"listed_at"
],
"type": "object"
},
"ListState": {
"description": "Whether the list has a permalink where it's declared.",
"oneOf": [
{
"const": "listed",
"description": "At one of the places its name is declared.",
"type": "string"
},
{
"const": "moved",
"description": "At a place that doesn't declare it any more.",
"type": "string"
},
{
"const": "not_listed",
"description": "Not at all.",
"type": "string"
}
]
},
"ListedAs": {
"description": "Which of the list's tables has a name.",
"oneOf": [
{
"const": "permalink",
"description": "`[permalinks]`: a permalink the content declared.",
"type": "string"
},
{
"const": "alias",
"description": "`[aliases]`: a name moved to another permalink.",
"type": "string"
},
{
"const": "moved",
"description": "`[moved]`: a name moved to a page.",
"type": "string"
},
{
"const": "retired",
"description": "`[retired]`: a retired permalink.",
"type": "string"
}
]
},
"MovedName": {
"description": "A name `ascribe.addresses` moves to a page.",
"properties": {
"name": {
"description": "Its name.",
"type": "string"
},
"state": {
"$ref": "#/$defs/ListState",
"description": "Whether the list has it, leading there: `listed`, or `not_listed`."
},
"to": {
"description": "Where its address leads now, as written: a page, and `#` and a\nheading's id.",
"type": "string"
}
},
"required": [
"name",
"to",
"state"
],
"type": "object"
},
"RemovedEntry": {
"description": "A name the list has that the project doesn't.",
"properties": {
"name": {
"description": "Its name.",
"type": "string"
},
"place": {
"description": "Where the list says a permalink was declared; for an alias, the name\nit led to; for a moved one, where; for a retired one, its reason.",
"type": "string"
},
"was": {
"$ref": "#/$defs/ListedAs",
"description": "What the list has it as."
}
},
"required": [
"name",
"was",
"place"
],
"type": "object"
},
"RetiredEntry": {
"description": "A name `ascribe.addresses` retires.",
"properties": {
"name": {
"description": "Its name.",
"type": "string"
},
"reason": {
"description": "Why it was retired.",
"type": "string"
},
"state": {
"$ref": "#/$defs/ListState",
"description": "Whether the list has it as retired, with this reason: `listed`, or\n`not_listed`."
}
},
"required": [
"name",
"reason",
"state"
],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "What `ascribe permalinks list` answers.",
"properties": {
"aliases": {
"description": "The names `ascribe.addresses` moves to another permalink, by name.",
"items": {
"$ref": "#/$defs/AliasEntry"
},
"type": "array"
},
"ascribe_version": {
"description": "The version of Ascribe that wrote it.",
"type": "string"
},
"has_list": {
"description": "Whether the project has `ascribe.permalinks`. Without it, every\npermalink is `not_listed`, and nothing is `removed`.",
"type": "boolean"
},
"moved": {
"description": "The names `ascribe.addresses` moves to a page, by name.",
"items": {
"$ref": "#/$defs/MovedName"
},
"type": "array"
},
"permalinks": {
"description": "Every permalink the content declares, in path order and then in\ndocument order, a page's own first. A name declared in several\nplaces is here once for each.",
"items": {
"$ref": "#/$defs/DeclaredEntry"
},
"type": "array"
},
"removed": {
"description": "The names the list has that the project no longer has, by name.",
"items": {
"$ref": "#/$defs/RemovedEntry"
},
"type": "array"
},
"retired": {
"description": "The names `ascribe.addresses` retires, or moves to one that's\nretired, by name.",
"items": {
"$ref": "#/$defs/RetiredEntry"
},
"type": "array"
},
"schema_version": {
"description": "The version of this schema. It changes only when a field is removed\nor changes meaning.",
"minimum": 0,
"type": "integer"
}
},
"required": [
"schema_version",
"ascribe_version",
"has_list",
"permalinks",
"aliases",
"moved",
"retired",
"removed"
],
"title": "PermalinksListReport",
"type": "object"
}
ascribe permalinks verify
schemas/permalinks-verify.schema.json:
{
"$defs": {
"RetiredName": {
"description": "A name the list has as retired.",
"properties": {
"name": {
"description": "The name.",
"type": "string"
},
"reason": {
"description": "Why it was retired, as the docs' authors wrote it.",
"type": "string"
}
},
"required": [
"name",
"reason"
],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "What `ascribe permalinks verify` answers.",
"properties": {
"ascribe_version": {
"description": "The version of Ascribe that wrote it.",
"type": "string"
},
"found": {
"description": "The names the list has, as permalinks, or moved to another permalink\nor a page, in the order given, each once.",
"items": {
"type": "string"
},
"type": "array"
},
"list": {
"description": "The list checked against, as given.",
"type": "string"
},
"missing": {
"description": "The names it doesn't have at all, in the order given, each once.",
"items": {
"type": "string"
},
"type": "array"
},
"retired": {
"description": "The names the list has as retired, in the order given, each once.",
"items": {
"$ref": "#/$defs/RetiredName"
},
"type": "array"
},
"schema_version": {
"description": "The version of this schema. It changes only when a field is removed\nor changes meaning.",
"minimum": 0,
"type": "integer"
}
},
"required": [
"schema_version",
"ascribe_version",
"list",
"found",
"retired",
"missing"
],
"title": "PermalinksVerifyReport",
"type": "object"
}
ascribe permalinks retire
schemas/permalinks-retire.schema.json:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "What `ascribe permalinks retire` did.",
"properties": {
"ascribe_version": {
"description": "The version of Ascribe that wrote it.",
"type": "string"
},
"created": {
"description": "Whether `ascribe.addresses` was made, since the project had none.",
"type": "boolean"
},
"list_changed": {
"description": "Whether `ascribe.permalinks` was changed to record them. Only a name\nthe content no longer declares is recorded as retired.",
"type": "boolean"
},
"reason": {
"description": "The reason each was given; none when each leads to `to`.",
"type": [
"string",
"null"
]
},
"retired": {
"description": "The names retired, each written in `ascribe.addresses` as\n`go:<name>`: in `[retired]`, or, with `to`, in `[moved]`, in order.",
"items": {
"type": "string"
},
"type": "array"
},
"schema_version": {
"description": "The version of this schema. It changes only when a field is removed\nor changes meaning.",
"minimum": 0,
"type": "integer"
},
"to": {
"description": "Where each address leads now, as written in `ascribe.addresses`;\nnone when it shows the reason.",
"type": [
"string",
"null"
]
},
"written": {
"description": "Whether the files were written: false with `--dry-run`, which says\nwhat would change.",
"type": "boolean"
}
},
"required": [
"schema_version",
"ascribe_version",
"retired",
"reason",
"to",
"created",
"list_changed",
"written"
],
"title": "PermalinksRetireReport",
"type": "object"
}
ascribe addresses init
schemas/addresses-init.schema.json:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "What `ascribe addresses init --format json` writes.",
"properties": {
"ascribe_version": {
"description": "The version of Ascribe that wrote it.",
"type": "string"
},
"created": {
"description": "Whether the project had no file, so this made one. A file already\nthere is left as it is, but for what's moved into it.",
"type": "boolean"
},
"file": {
"description": "The file, from the project's folder: `ascribe.addresses`.",
"type": "string"
},
"moved": {
"description": "The keys moved into the file from `ascribe.toml`'s `[permalinks]`,\neach `go:<name>`, in the order written there; empty when it has\nnone.",
"items": {
"type": "string"
},
"type": "array"
},
"schema_version": {
"description": "The version of this schema. It changes only when a field is removed\nor changes meaning.",
"minimum": 0,
"type": "integer"
},
"written": {
"description": "Whether a file was written: one made, or moved into, without\n`--dry-run`.",
"type": "boolean"
}
},
"required": [
"schema_version",
"ascribe_version",
"file",
"created",
"moved",
"written"
],
"title": "AddressesInitReport",
"type": "object"
}
ascribe addresses move and retire
schemas/addresses-record.schema.json:
{
"$defs": {
"Edit": {
"description": "One edit of a fix.",
"properties": {
"new_text": {
"description": "The text that replaces it.",
"type": "string"
},
"range": {
"$ref": "#/$defs/Range",
"description": "The text it replaces."
}
},
"required": [
"range",
"new_text"
],
"type": "object"
},
"Pos": {
"description": "A position in a file.",
"properties": {
"column": {
"description": "The column, from 1, in Unicode characters (not bytes or UTF-16\nunits).",
"minimum": 0,
"type": "integer"
},
"line": {
"description": "The line, from 1.",
"minimum": 0,
"type": "integer"
},
"offset": {
"description": "The byte offset from the start of the file.",
"minimum": 0,
"type": "integer"
}
},
"required": [
"line",
"column",
"offset"
],
"type": "object"
},
"Range": {
"description": "A span of a file. `end` is just past its last character; an empty range\n(an insertion) has equal positions.",
"properties": {
"end": {
"$ref": "#/$defs/Pos",
"description": "Just past its last character."
},
"start": {
"$ref": "#/$defs/Pos",
"description": "Its first character."
}
},
"required": [
"start",
"end"
],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "What `ascribe addresses move` and `retire` write with `--format json`.",
"properties": {
"ascribe_version": {
"description": "The version of Ascribe that wrote it.",
"type": "string"
},
"changed": {
"description": "Whether the file changed: an entry already the same changes nothing.",
"type": "boolean"
},
"edits": {
"description": "The edits that make the change, each replacing the text of its\nrange in the file as it was; none when nothing changed.",
"items": {
"$ref": "#/$defs/Edit"
},
"type": "array"
},
"file": {
"description": "The file, from the project's folder: `ascribe.addresses`.",
"type": "string"
},
"key": {
"description": "The entry's key: a page's path from the content root, a file's path\nwith `#` and an id, an address starting with `/`, or a permalink,\n`go:<name>`.",
"type": "string"
},
"schema_version": {
"description": "The version of this schema. It changes only when a field is removed\nor changes meaning.",
"minimum": 0,
"type": "integer"
},
"table": {
"description": "The table the entry is in: `moved` or `retired`.",
"type": "string"
},
"value": {
"description": "The entry's value: where it moved, or why it was retired.",
"type": "string"
},
"written": {
"description": "Whether the change was written: the MCP server's tools write\nnothing, and give the edits to apply.",
"type": "boolean"
}
},
"required": [
"schema_version",
"ascribe_version",
"file",
"table",
"key",
"value",
"changed",
"written",
"edits"
],
"title": "AddressesRecordReport",
"type": "object"
}
ascribe addresses move --from-git
schemas/addresses-from-git.schema.json:
{
"$defs": {
"Edit": {
"description": "One edit of a fix.",
"properties": {
"new_text": {
"description": "The text that replaces it.",
"type": "string"
},
"range": {
"$ref": "#/$defs/Range",
"description": "The text it replaces."
}
},
"required": [
"range",
"new_text"
],
"type": "object"
},
"MoveJson": {
"description": "A move `--from-git` records.",
"properties": {
"key": {
"description": "The entry's key: where the page was.",
"type": "string"
},
"value": {
"description": "The entry's value: where it is now.",
"type": "string"
}
},
"required": [
"key",
"value"
],
"type": "object"
},
"Pos": {
"description": "A position in a file.",
"properties": {
"column": {
"description": "The column, from 1, in Unicode characters (not bytes or UTF-16\nunits).",
"minimum": 0,
"type": "integer"
},
"line": {
"description": "The line, from 1.",
"minimum": 0,
"type": "integer"
},
"offset": {
"description": "The byte offset from the start of the file.",
"minimum": 0,
"type": "integer"
}
},
"required": [
"line",
"column",
"offset"
],
"type": "object"
},
"Range": {
"description": "A span of a file. `end` is just past its last character; an empty range\n(an insertion) has equal positions.",
"properties": {
"end": {
"$ref": "#/$defs/Pos",
"description": "Just past its last character."
},
"start": {
"$ref": "#/$defs/Pos",
"description": "Its first character."
}
},
"required": [
"start",
"end"
],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "What `ascribe addresses move --from-git --format json` writes.",
"properties": {
"ascribe_version": {
"description": "The version of Ascribe that wrote it.",
"type": "string"
},
"base": {
"description": "The base git's renames are seen from: the revision asked for, or the\ndefault branch, and its commit when that's something else.",
"type": "string"
},
"changed": {
"description": "Whether the file changed.",
"type": "boolean"
},
"edits": {
"description": "The edits that make the change, each replacing the text of its\nrange in the file as it was; none when nothing changed.",
"items": {
"$ref": "#/$defs/Edit"
},
"type": "array"
},
"file": {
"description": "The file, from the project's folder: `ascribe.addresses`.",
"type": "string"
},
"moves": {
"description": "Each move recorded, in path order: the page's old path, from the\ncontent root, and its new one.",
"items": {
"$ref": "#/$defs/MoveJson"
},
"type": "array"
},
"schema_version": {
"description": "The version of this schema. It changes only when a field is removed\nor changes meaning.",
"minimum": 0,
"type": "integer"
},
"written": {
"description": "Whether the change was written: the MCP server's tools write\nnothing, and give the edits to apply.",
"type": "boolean"
}
},
"required": [
"schema_version",
"ascribe_version",
"file",
"base",
"moves",
"changed",
"written",
"edits"
],
"title": "AddressesFromGitReport",
"type": "object"
}
ascribe addresses list
schemas/addresses-list.schema.json:
{
"$defs": {
"Gone": {
"description": "An address retired on purpose.",
"properties": {
"entry": {
"description": "The `ascribe.addresses` key it comes from.",
"type": "string"
},
"page": {
"description": "Where the page saying so is, from the host's root: the base path,\n`GONE_FOLDER`, and the key's address from the base path, its page's\nfor a Markdown version.",
"type": "string"
},
"path": {
"description": "The address, from the host's root.",
"type": "string"
},
"reason": {
"description": "Why it was retired.",
"type": "string"
}
},
"required": [
"path",
"reason",
"entry",
"page"
],
"type": "object"
},
"Redirect": {
"description": "An address that leads somewhere else now.",
"properties": {
"entry": {
"description": "The `ascribe.addresses` key the pair comes from; or, for a pair a\n`[former]` setting makes, `former.` and the setting:\n`former.base-path`, `former.permalink-path`, or `former.agents`.",
"type": "string"
},
"from": {
"description": "The old address, from the host's root, in the published case and\nslash form.",
"type": "string"
},
"status": {
"description": "The HTTP status: 301.",
"maximum": 65535,
"minimum": 0,
"type": "integer"
},
"to": {
"description": "Where it leads now, from the host's root.",
"type": "string"
}
},
"required": [
"from",
"to",
"status",
"entry"
],
"type": "object"
},
"Redirects": {
"description": "Where the addresses a build used to publish lead now, and which were\nretired: `_ascribe/redirects.json`.",
"properties": {
"build": {
"description": "The build's name.",
"type": "string"
},
"gone": {
"description": "Each retired address, sorted by `path`.",
"items": {
"$ref": "#/$defs/Gone"
},
"type": "array"
},
"redirects": {
"description": "Each pair, sorted by `from`.",
"items": {
"$ref": "#/$defs/Redirect"
},
"type": "array"
},
"version": {
"description": "The format's version.",
"minimum": 0,
"type": "integer"
}
},
"required": [
"version",
"build",
"redirects",
"gone"
],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "What `ascribe addresses list --format json` writes.",
"properties": {
"ascribe_version": {
"description": "The version of Ascribe that wrote it.",
"type": "string"
},
"builds": {
"description": "Each build's redirects and retired addresses, as its\n`_ascribe/redirects.json` has them, in the content model's order.",
"items": {
"$ref": "#/$defs/Redirects"
},
"type": "array"
},
"has_file": {
"description": "Whether the project has `ascribe.addresses`. Without it, every\nbuild's lists are empty.",
"type": "boolean"
},
"schema_version": {
"description": "The version of this schema. It changes only when a field is removed\nor changes meaning.",
"minimum": 0,
"type": "integer"
}
},
"required": [
"schema_version",
"ascribe_version",
"has_file",
"builds"
],
"title": "AddressesListReport",
"type": "object"
}