Анатомия пакета¶
Из чего состоит пакет: раскладка каталога, обёртка объекта, манифест
(engines, requires, variables, knowledge), ссылки между объектами по
ключам, версии и их неизменяемость, переименования и файл установки. Страница
для автора пакета и администратора установки; первый пакет по шагам — в
Пакете за 10 минут.
Раскладка¶
<пакет>/
├── package.yaml # kind: Package — манифест
├── task-types/ # kind: TaskType
├── artifact-types/ # kind: ArtifactType
├── project-templates/ # kind: ProjectTemplate
├── workspace-types/ # kind: WorkspaceType
├── roles/ # kind: Role
├── capabilities/ # kind: Capability
├── skills/ # kind: Skill
├── agents/ # kind: Agent
├── rules/ # kind: WorkRule
├── processes/ # kind: Process
├── calendars/ # kind: Calendar
├── knowledge-packs/ # kind: KnowledgePack
├── notification-rules/ # kind: NotificationRule
├── schemas/ # JSON Schema данных процессов (data: {$ref: …})
├── tests/ # *.test.yaml — сценарии
├── .layout/ # раскладка визуального редактора; логики не несёт
├── integration/ # код наблюдателя и скиллов — у интеграции
└── README.md
- Каталог пакета называется его ключом.
checkиtestпо пути каталога берут ключ пакета из имени каталога и сверяют его сkeyманифеста: расхождение — ошибка «key … не совпадает с ключом пакета в установке». Копию пакета для пробы кладите в каталог с тем же именем. Пакет из чужого репозитория, подключённый в файле установки поpathилиgit, может лежать где угодно: его ключ — ключ записи установки. - Вид объекта определяет поле
kind, а не папка. Папки — соглашение для людей;package-sdk addраскладывает файлы по ним. - Загрузчик читает все файлы
*.yamlпакета во всех подкаталогах, кромеpackage.yaml,tests/,schemas/и.layout/. Каждый такой файл обязан быть объектом каталога: файл с неизвестнымkind— ошибка. Поэтому вспомогательные YAML-файлы кладите вschemas/или давайте им другое расширение. - В
tests/читаются только файлы*.test.yaml. - Язык файлов — YAML 1.2: булевы значения только
trueиfalse. Ключonу старта процесса берите в кавычки ("on":), если файл читает ещё и инструмент на YAML 1.1. - Числа и даты
package-sdkчитает так же, как ядро при публикации:012— двенадцать,1_000и2026-09-30— строки,.infи.nan— ошибка. Поэтомуcheck,testиplanвидят ровно те значения, которые получит стенд.
Обёртка объекта¶
# yaml-language-server: $schema=<путь к schema/v1/object.schema.json>
apiVersion: taimen.ai/v1
kind: Role
key: access-approver
spec:
name: Access approver
description: Decides on access requests
| Поле | Правило |
|---|---|
apiVersion |
константа формата taimen.ai/v1 — имя схемы, а не адрес сервиса |
kind |
вид объекта: Package, Installation и виды каталога из карты видов |
key |
идентичность объекта в tenant'е; форма ключа зависит от вида (ниже) |
spec |
ровно тело запроса API сервиса, который хранит объект, в camelCase и без поля идентичности |
| Вид | Ключ |
|---|---|
Package, TaskType, ArtifactType, ProjectTemplate, WorkspaceType, Process, Calendar |
^[a-z0-9][a-z0-9_-]*$, до 63 символов |
Role, Agent |
slug ^[a-z0-9][a-z0-9-]*$, 2–63 символа |
WorkRule, NotificationRule |
^[a-z0-9][a-z0-9._-]*$, до 128 символов |
Skill |
имя скилла, например access.grant; версия — в spec.version |
Capability |
имя способности |
KnowledgePack |
имя онтологии ^[a-z0-9][a-z0-9._-]{0,63}$; совпадает со spec.name |
У ключа пакета, который создаёт package-sdk init, правило строже: строчные
буквы, цифры и -, начинается с буквы.
Первая строка-комментарий подключает схему к редактору с YAML Language Server:
подсказки полей и ошибки прямо при наборе. package-sdk init и add пишут
её сами, со ссылкой на схему установленного SDK.
Окончательный валидатор — ядро
Схема проверяет форму. Грамматику выражений, условий правил, исходов
решений и процессов проверяет код ядра: check импортирует его
валидаторы (дополнение sandbox), а с --server отправляет пакет ещё и
ядру стенда.
Манифест¶
apiVersion: taimen.ai/v1
kind: Package
key: access-requests
spec:
version: 0.2.0
displayName: Access requests
description: Access requests to internal resources and their review
license: Apache-2.0
authors: ["Example Integrations <dev@example.com>"]
homepage: https://git.example.com/example/access-requests
engines:
control-plane: ">=0.10,<0.11"
requires:
- {package: access-base, version: ">=0.1"}
knowledge: ["access@1"]
variables:
ACCESS_WORKSPACE_ID:
kind: workspace
description: Workspace where access requests are reviewed
ACCESS_ESCALATION_HOURS:
kind: integer
description: Hours before an unanswered request is escalated
default: "24"
| Поле | Обязательно | Что задаёт |
|---|---|---|
version |
да | версия пакета, SemVer X.Y.Z |
displayName |
да | название для людей |
description |
нет | описание |
engines |
нет | диапазоны версий компонентов, с которыми пакет совместим |
requires |
нет | пакеты, на объекты которых этот пакет ссылается |
variables |
нет | объявление каждой переменной установки ${NAME} |
knowledge |
нет | онтологии (имя@мажор), на которые опираются процессы пакета |
license |
нет | лицензия, идентификатор SPDX |
authors, homepage |
нет | авторы; адрес пакета (https://) |
renames |
нет | явные переименования объектов (см. ниже) |
engines — совместимость¶
engines — диапазоны версий компонентов платформы, против которых пакет
проверен: {control-plane: ">=0.10,<0.11"}. Диапазон — условия через запятую,
выполняться должны все; операторы >=, >, <=, <, =, ^, ~; версия
без оператора — точная версия или префикс (1.2 — любая 1.2.x); * —
любая.
initзаписывает диапазон по коду ядра, который стоит рядом с инструментом: тот же minor.checkотвергает неразбираемый диапазон (engines_invalid) и предупреждает, если код ядра рядом с инструментом вне диапазона (engines_mismatch): тогда проверка и тесты идут не той версией, на которую рассчитан пакет.planчитает версию ядра стенда из егоopenapi.jsonи отказывает до записи, если она вне диапазона.
requires — зависимости¶
Пакет ссылается только на свои объекты и объекты пакетов из requires.
Элемент — ключ пакета (любая версия) или {package, version} с диапазоном в
той же грамматике, что у engines.
requiresподтягиваются в установку сами: в файле установки достаточно назвать пакет, который вы ставите.- Зависимость ищется по порядку:
spec.packagesDirустановки,packages/рядом с файлом установки, каталог файла установки. Пакет, который проверяют по пути (check --package <каталог>), ищет своиrequiresрядом с собой — в соседних каталогах. - Версия зависимости в установке вне диапазона — ошибка
requires_version_mismatch; цикл зависимостей — ошибкацикл requires. - Песочница тестов строит каталог из объектов пакета и всех его
requires: роль или скилл из пакета-зависимости в тесте видны.
variables — переменные установки¶
Всё, что зависит от конкретного стенда — UUID пространства работы, адрес
внешней системы, порог суммы, — не пишется в пакет, а выносится в переменную:
в любой строке spec пишется ${NAME}, а в манифесте переменная объявляется.
| Поле переменной | Что задаёт |
|---|---|
description |
обязательно: что это и откуда взять значение |
kind |
обязательно: url (абсолютный http(s):// URL), workspace, project, principal, role (UUID объекта стенда), integer, string |
required |
по умолчанию true |
default |
значение, если установка не задала своё (строкой) |
example |
пример значения для describe --env-example |
Правила check:
- использованная, но не объявленная переменная — ошибка
variable_undeclared; - объявленная, но нигде не использованная — ошибка
variable_unused; defaultилиexample, не подходящие виду, — ошибкаvariable_invalid_value;required: trueвместе сdefault— предупреждениеvariable_required_with_default:defaultи так делает переменную необязательной.
Значения переменных задаёт установка: файл --env (по умолчанию .env в
текущем каталоге) и окружение процесса, причём окружение сильнее файла.
plan проверяет, что каждая обязательная переменная задана, значение
подходит виду, а UUID пространства работы, проекта, principal'а и роли
существует на стенде. Самих значений в файл плана plan не пишет — только их
хэш. Заготовку файла переменных печатает
package-sdk describe <пакет> --env-example.
Секретов в пакете нет
У переменной нет поля secret, и значения секретов в пакет и в файл
переменных не пишутся. Секрет исполнителя — имя в placement.secrets
описания агента: сам секрет лежит на узле, который исполняет агента.
workspaceId правила вывода работы задаётся только переменной: это топология
установки, а не содержимое пакета.
Подстановка ${NAME} — текстовая и идёт до того, как ядро разбирает
значение: внутри выражения процесса переменная становится частью его текста.
Числовую переменную при сравнении с number оборачивайте в double(…),
строковую берите в кавычки CEL — примеры в Выражениях.
Значение-подстановка всегда строка, даже если переменная вида integer.
knowledge — онтологии¶
knowledge перечисляет онтологии памяти (имя@мажор), на виды и связи
которых опираются процессы пакета в memory, recall, remember и
контексте шагов.
- Онтология из списка должна быть объявлена
KnowledgePackв пакете или егоrequires(иначеknowledge_unknown); встроенная онтология памятиdefaultобъявления не требует. - Вид или связь, которых нет в объявленных онтологиях, — ошибка
knowledge_term_unknown(предупреждение, если содержимое части онтологий не видно, например встроеннойdefault: тогда решает память при регистрации). - Процессы обращаются к памяти, а
knowledgeне объявлен — предупреждениеknowledge_undeclared.
Включение онтологий для пространства работы — топология, поэтому оно задаётся в установке, а не в пакете.
Ссылки по ключам¶
Объекты ссылаются друг на друга ключами, а не идентификаторами стенда:
| Откуда | Куда | Пример |
|---|---|---|
действие правила, шаг human процесса, ensureWork исхода |
тип задачи | taskType: access-review |
identity процесса и правила, assignee правила |
агент | identity: {agent: access-requests-process}, assignee: agent:<ключ> |
owner, assign шагов процесса |
роль | assign: [{role: access-approver}] |
интерпретация правила, шаг call, invokeSkill |
скилл | access.grant@1 — имя и версия |
artifactSchema типа задачи |
тип артефакта | type: access-grant |
knowledge, extends онтологии |
онтология | access@1 |
check проверяет, что каждая ссылка замкнута внутри пакета и его requires.
Системный тип задачи task есть в каждом tenant'е и объявления не требует.
Идентификаторы конкретного стенда (UUID workspace, principal'а) в пакет не
пишутся — только через переменные.
Версии¶
Версия пакета¶
spec.version — SemVer пакета. По ней установка проверяет диапазоны
requires, она попадает в packages.lock, а ядро запоминает у каждого
поставленного объекта, каким пакетом и какой версии он поставлен (связь
объекта с пакетом, см. Пакеты каталога).
Поднимайте версию пакета при каждом выпуске: patch — исправление без изменения поведения, minor — новые объекты и совместимые изменения, major — изменение, которое ломает установки или зависимые пакеты.
Неизменяемые версии объектов¶
Часть видов в ядре версионируется и неизменяема: опубликованная версия не меняется, правка — новая версия.
| Вид | Как публикуется правка |
|---|---|
TaskType, ProjectTemplate |
файл отличается от новейшей активной версии — публикуется новая версия, прежние активные переводятся в deprecated; задачи и проекты остаются на своей версии |
ArtifactType |
новая версия, если файл отличается от новейшей |
Process |
spec.version — целое; правка — version: N+1. То же число с другим содержимым — 409 process_version_conflict. Открытые дела дорабатывают по своей версии, если нет карты миграции |
Skill |
spec.version задаёт пакет. Изменение контракта, протокола, побочных эффектов или уровня риска при той же версии — ошибка «поднимите spec.version» |
KnowledgePack |
spec.version — целое. Другое содержимое при той же версии — ошибка knowledge_pack_conflict |
Agent |
новая неизменяемая ревизия появляется, только если изменилось описание |
Изменяемые виды правятся на месте: WorkRule, Role, WorkspaceType —
частичным обновлением, Capability только создаётся. Удаления нет ни у
одного вида. Типы задач, шаблоны проектов, правила вывода работы, агенты,
правила уведомлений, процессы и календари выводятся из оборота списком
retire установки.
Переименования¶
Переименовать объект — не удалить старый и создать новый. Для этого в
манифесте есть renames, как moved в Terraform:
to— объект этого пакета,from— ключ, которого в пакете больше нет (check: вид должен быть видом каталога, а объектto— существовать).- План переносит процесс или календарь вместе с историей версий, старый ключ
выводится: новых дел не заводит (
409 process_retired), открытые дорабатывают. - Переименование других видов план не переносит — это предупреждение
rename_not_planned: старый объект остаётся, новый создаётся. package-sdk edit rename --package <каталог> --kind Process --from <ключ> --to <ключ>переименует файл, ключ и допишетrenamesсама.
Установка¶
Файл установки говорит, какие пакеты и откуда ставятся на конкретный стенд. Он живёт в git установки, отдельно от пакетов. Здесь — форма файла; процедура целиком (источники git, lock и кэш, план, правки консоли, применение, вывод из оборота, выпуск тегом) — в Установке и выпуске.
apiVersion: taimen.ai/v1
kind: Installation
key: prod
spec:
packages:
- notifications # каталог установки: packages/notifications
- {key: access-requests, path: ../access-requests} # путь относительно файла установки
- {key: helpdesk, git: https://git.example.com/example/helpdesk.git, ref: v0.2.0}
knowledge:
- {workspace: "${ACCESS_WORKSPACE_ID}", packs: ["access@1"]}
retire:
TaskType: [legacy-access-review]
| Источник | Форма | Ключ пакета |
|---|---|---|
| каталог установки | ключ | равен имени каталога в packages/ рядом с файлом установки (или spec.packagesDir) |
| путь | {key, path} |
из манифеста, сверяется с key |
| git | {key, git, ref, path?} |
из манифеста, сверяется с key |
git—https://хост/путьбез учётных данных в адресе илиgit@хост:путь; доступ даёт credential helper git.ref— только тег: ветки и коммиты не принимаются.path— подкаталог пакета в репозитории.knowledge— какие онтологии включить для пространства работы; набор заменяет прежний целиком, план показывает итог и разницу.retire— ключи, которые установка выводит из оборота:TaskType,ProjectTemplate,WorkRule,Agent,NotificationRule,Process,Calendar.- Пустой
packages: []— законная установка: только системный типtask.
packages.lock — воспроизводимость¶
lock пишет рядом с файлом установки packages.lock
(package-sdk.lock/v1): для каждого пакета — источник, версию, коммит тега
(у git) и contentHash — хэш канонического набора файлов пакета. plan
строится только по зафиксированному содержимому:
| Отказ | Когда |
|---|---|
lock_required |
пакет из git, а записи в lock нет |
source_ref_moved |
тег в источнике переставили после фиксации |
content_mismatch |
содержимое разошлось с contentHash |
lock_stale |
lock не соответствует установке: нет пакета, другой источник |
Для пакетов из каталога установки и по пути lock необязателен — они и так в
git установки; но если lock есть, он покрывает все пакеты и сверяется. Кэш
источников git — $PACKAGE_SDK_CACHE, иначе $XDG_CACHE_HOME/package-sdk или
~/.cache/package-sdk.
План и применение¶
package-sdk plan --install installation.yaml --server https://platform.example.com --out plan.json
package-sdk apply --plan plan.json --server https://platform.example.com
План package-sdk.plan/v1 — один документ на все виды, построенный без
единой записи. Его секции применяются по порядку:
catalog— виды, которые установщик ставит ресурсами ядра;core— план ядра для пакетов с процессами или календарями: у такого пакета ядро само планирует и ставит типы задач, агентов, календари, процессы и правила вывода работы;knowledge— регистрация онтологий и включение их для пространств работы;notification-rules— правила уведомлений, прошедшие проверку сервиса;retire— вывод из оборота.
В плане записаны версия ядра стенда, хэш фиксации источников (lockHash), хэш
значений переменных (variablesHash) и planHash всего документа. apply
применяет только неизменённый план, к тому же стенду, после подтверждения
человека в терминале. Перед каждой секцией он строит её заново и сверяет с
планом: расхождение — plan_stale до первой записи этой секции.
Секции не атомарны между собой
Каждая запись идемпотентна. Если применение оборвалось между секциями,
повторный plan покажет остаток, а повторный apply его доставит.
См. также¶
- Пакеты — карта видов и путь автора
- Пакет за 10 минут
- Работа: типы задач и роли
- Процессы в пакете — версии и миграции дел
- Установка и выпуск — lock, план, применение, выпуск тегом
- Пакеты каталога — как каждый вид отображается на API
- Сценарии и план ядра — план ядра для процессов