Это полная версия для чтения оригинала, зафиксированного на ревизии 61e75e9aa9a8719dfb480bf1f5226553b3a21d70. Перевод предназначен для чтения человеком и не изменяет нормативный оригинал или устанавливаемый пакет навыка. Для установки используйте руководство.

Примеры OKF 0.2

Содержание

Ниже приведены короткие примеры из устанавливаемого навыка. Дополнительные проверяемые примеры есть в необязательном наборе fixtures/v02 (fixtures/v02/corpus.yaml) в репозитории. Для работы навыка клонировать репозиторий не требуется.

Набор примеров в репозитории охватывает:

Все искусственные материалы, созданные для репозитория, используют зарезервированные домены вроде https://example.invalid/ и явно обозначены как искусственные. Содержание приложения A из исходной спецификации сохранено без переобозначения.

Минимальная заметка

Начните новую заметку формата 0.2 с:

---
type: <описательный тип>
---

<известное содержание>

Добавляйте необязательные поля только при наличии основания:

Авторство человека не означает, что содержание проверено

Автор-человек использует префикс human: в generated.by. Это указывает, кто написал текущее содержание. Само авторство не добавляет verified и не даёт уровень human-reviewed: для него человек должен подтвердить содержание.

Несколько источников

Каждый источник, на который можно сослаться, получает стабильный sources[].id. Утверждения в тексте используют именованные сноски с той же меткой. Перестановка элементов sources не должна менять соответствие ссылок.

Проверка: объект или список

Одиночный объект и список из одного элемента читаются с одинаковым смыслом. При чтении сохраняйте исходную форму YAML; нормализуйте только типизированное представление.

Примеры вычислений не запускаются

Примеры с кодом внутри заметки и в отдельном файле показывают формы контракта. Они не обещают обнаружение и привязку среды выполнения, упаковку исполнителя или проверяющего, форматы квитанций и заключений, изоляцию, кеширование или запуск средствами библиотеки.

Примеры совместимости

Старые timestamp и # Citations встречаются только в примерах совместимости и миграции. При смешанных метаданных происхождения чтение использует 0.2: старые значения подставляются только при отсутствии замещающих полей. Исходные старые данные сохраняются без потерь. Миграция блокирует одновременное наличие sources и старого раздела Citations, возвращая reconcile_sources_and_citations, вместо их объединения. Будущие версии читаются по мере возможности без изменения объявления версии.

Выбор цитат при миграции

CLI и MCP принимают одну и ту же точную структуру; неуказанные поля запрещены:

[
  {
    "path": "index.md",
    "entries": [
      {"legacy_number": 1, "source_id": "numbered"}
    ]
  },
  {
    "path": "log.md",
    "entries": [
      {
        "legacy_entry": "https://example.invalid/raw",
        "source_id": "raw-url"
      }
    ]
  },
  {
    "path": "nested/report.md",
    "entries": [
      {
        "legacy_number": 2,
        "legacy_entry": "[Отчёт](https://example.invalid/report)",
        "source_id": "report",
        "title": "Отчёт"
      },
      {
        "legacy_number": 3,
        "legacy_entry": "[Отчёт](https://example.invalid/report)",
        "source_id": "report-copy",
        "title": "Отчёт"
      }
    ]
  }
]

Первая запись выбирает нумерованную цитату [1], вторая — ненумерованный URL по точному исходному тексту. Две вложенные записи показывают допустимые непересекающиеся пары номера и текста: одинаковый текст разрешён, поскольку разные ненулевые номера делают условия выбора независимыми. При двух условиях должны совпасть оба. Повторение ненулевого номера всегда запрещено. Выбор только по тексту пересекается с любым повторным использованием того же текста, включая другой выбор только по тексту, и отклоняется как неоднозначный. Точное сравнение не удаляет пробелы и не нормализует переводы строк. legacy_entry должен быть корректным UTF-8 длиной 1–4096 байт, содержать непробельный текст после TrimSpace и не содержать NUL. TAB, LF и CR разрешены; остальные управляющие символы C0 и DEL запрещены. Авторизация и контрольная сумма привязаны к точным байтам, поэтому LF и CRLF — разные входные значения. Канонический порядок: путь, legacy_number, точный legacy_entry.

Неоднозначность повторяющегося номера или исходного текста возвращает disambiguate_citation_entry. Её нельзя обозначать как disambiguate_citation_destination: этот код предназначен для неоднозначного определения назначения ссылки парсером.

Явный путь для цитаты, времени создания или вычисления должен указывать на существующий документ набора. Отсутствие документа блокирует операцию с migration_document_missing, не возвращает ручных действий и не позволяет создать документ через сопоставления. Дополнительный код действия не вводится.

Входные данные миграции проверяются до определения исходной версии. Каждое переданное поле автора, времени, цитаты, времени создания, вычисления или ресурса, нарушающее структуру либо правила предметной области, отклоняется даже для target-noop или набора без корневого документа. Гарантия отсутствия записи сохраняется.

Исходная версия определяется ровно один раз перед Preview. Preview и Apply используют один и тот же полный зафиксированный expected_source: запрошенный способ выбора, declaration_present, declaration_valid, declaration_raw, declared_version, поля разрешённой версии, происхождения и перехода, а также упорядоченные кандидаты и блокирующие причины. Переход с доказательством допускает только format_version: 2 с обязательным непустым resolution_digest. Операция target-noop для текущего состояния обходится без доказательства, но всё равно проверяет целевой документ.

Подстановка старых полей по §13 зависит только от наличия замещающего поля, а не от способа определения версии. Для версии по умолчанию, объявленной или явно указанной 0.1/0.2 и будущей версии применяется одно условие. GeneratedPresent и SourcesPresent подавляют подстановку даже при некорректном значении. TimestampAllowed и CitationsAllowed означают отсутствие замены; TimestampActive и CitationsActive дополнительно требуют наличия самой старой формы. CitationsActive требует точного заголовка # Citations, распознанного парсером. Одного числового маркера недостаточно. Текст [1] в наборе без объявления версии — собственный случай target-noop формата 0.2, а не признак старой версии. Общая предварительная проверка с учётом документов сначала проверяет явные входные данные. MCP не использует доказательство или хранилище и ничего не записывает. CLI при предварительном просмотре строит доказательство без доступа к хранилищу; CLI с --write выполняет пустую операцию CAS и сохраняет долговечную квитанцию в .okf, не изменяя файлы, учитываемые в ревизии. Сопоставление только по номеру для такого целевого состояния проверяет повторное применение, а не переписывает текст: именованная сноска и метаданные источника заметки уже должны совпадать. Иначе migration_replay_mismatch блокирует операцию без выдуманного ручного действия. Коллизия нормализованной метки возвращает normalized_footnote_label_collision и disambiguate_citation_entry.

Для каждого сопоставления с ненулевым legacy_number выбранный маркер [n], принадлежащий парсеру, должен отсутствовать, а ссылка на нормализованную именованную сноску [^SourceID] — присутствовать. Сопоставление только по тексту не требует ссылки из утверждения. Оставшаяся выбранная, отсутствующая или неверная ссылка возвращает migration_replay_mismatch на точном участке, распознанном парсером, без записи или авторизации через доказательство и план. Похожие на маркеры байты внутри строчного кода, блоков кода и исходного HTML считаются непрозрачным содержимым и игнорируются.

Отдельное поле миграции, которое нельзя представить в документе, возвращает invalid_request. Коллизия нормализованных SourceID внутри документа вместо этого блокируется с normalized_footnote_label_collision и disambiguate_citation_entry, включая target-noop. Коллизия в существующем документе сообщает тот же точный участок. Обе ветви ничего не публикуют и не записывают.

Apply перехода v0.1-to-v0.2, связанного с доказательством, может вернуть отсутствие изменений перехода только после проверки подлинности и повторного построения точного доказательства и контрольной суммы плана. Результат возвращается до открытия хранилища, .okf не создаётся. Для текущего target-noop MCP не использует доказательство и не открывает хранилище; CLI при предварительном просмотре строит доказательство без открытия хранилища; CLI с --write выполняет пустой CAS с долговечной квитанцией в .okf. На всех интерфейсах пути и байты файлов, учитываемых в ревизии, остаются идентичными.

Представление RelationRef в skosovsky/okf

Эти строки описывают расширение YAML-связей данного репозитория, а не исходный стандарт OKF 0.2:

Передаваемая строка Обозначаемая сущность
source корневая заметка source
source#part заметка source, фрагмент part
source\#part корневая заметка с ID source#part
source\#part#leaf\value заметка source#part, фрагмент leaf\value

Только символы # в ID заметки записываются как \#. Первый неэкранированный # служит разделителем; обратные косые черты во фрагменте сохраняются. Постороннее или неканоническое экранирование ID недопустимо. Обычные строки при чтении и записи сохраняются побайтно. JSON передаёт логическое значение source\#part как "source\\#part", не меняя формы схем графа и MCP или []string в квитанции хранилища версии 1.

Представление usage_count в MCP

В предметной области значение остаётся uint64, но все структурированные JSON-интерфейсы MCP используют каноническую десятичную строку либо null, если выходное поле допускает отсутствие значения:

{"usage_count":"18446744073709551615"}

Канонический шаблон — ^(0|[1-9][0-9]*)$; переполнение отклоняется на входе. Строковое представление предотвращает потерю точности float64 для MaxUint64. Старые текстовые представления сохраняют прежний вид.

Выбор источника в MCP set_usage_window

Допустимые варианты выбора заданы исчерпывающе. Для общего окна не передавайте ни одно из двух полей выбора:

{
  "kind": "set_usage_window",
  "concept_id": "report",
  "usage_window": {"from": "2026-07-01", "to": "2026-07-31"}
}

Для источника с идентификатором передайте одно непустое поле source_id:

{
  "kind": "set_usage_window",
  "concept_id": "report",
  "source_id": "policy",
  "usage_window": {"from": "2026-07-01", "to": "2026-07-31"}
}

Для источника без идентификатора передайте один точный объект source без поля id:

{
  "kind": "set_usage_window",
  "concept_id": "report",
  "source": {"resource": "policy.md", "title": "Правила"},
  "usage_window": {"from": "2026-07-01", "to": "2026-07-31"}
}

Пустой source_id, оба поля выбора одновременно, неизвестные поля выбора или источника, id внутри точного анонимного source и неоднозначное точное совпадение анонимных источников отклоняются. Чтобы удалить выбранное окно, используйте usage_window: null с теми же вариантами выбора.

Выбор источника в MCP remove_source

Удалите источник с идентификатором, передав один непустой source_id:

{
  "kind": "remove_source",
  "concept_id": "report",
  "source_id": "policy"
}

Удалите источник без идентификатора, передав один точный объект source без id:

{
  "kind": "remove_source",
  "concept_id": "report",
  "source": {"resource": "policy.md", "title": "Правила"}
}

У remove_source нет варианта выбора общего окна. Пустой source_id, оба поля выбора одновременно, неизвестные поля выбора или источника, id внутри точного анонимного source и неоднозначное точное совпадение анонимных источников отклоняются.