feat: harden community production foundation through story 1.5
This commit is contained in:
@@ -23,7 +23,18 @@ Crank превращает REST API endpoint-ы в MCP-инструменты,
|
||||
|
||||
## Справочник
|
||||
|
||||
- [Capability Inventory](./capability-inventory.json) — machine-readable реестр
|
||||
текущих и целевых flows; canonical path — `docs/capability-inventory.json`.
|
||||
- [Schema Capability Inventory](./schemas/capability-inventory.schema.json)
|
||||
- [Capability Baseline](./capability-baseline/manifest.json) — versioned SHA-256
|
||||
snapshot фактических UI, Admin API и MCP flows, taxonomy, checklist и
|
||||
sanitized evidence results.
|
||||
- [Schema Capability Baseline](./schemas/capability-baseline.schema.json) —
|
||||
fail-closed manifest contract.
|
||||
- [Настройки окружения](./runtime-config.md)
|
||||
- [Machine schema runtime-конфигурации](./schemas/runtime-config.schema.json)
|
||||
- [Миграции PostgreSQL](./migrations.md)
|
||||
- [Machine sequence миграций](./schemas/migration-sequence.json)
|
||||
- [Admin API](./admin-api.md)
|
||||
- [Развертывание](./deployment.md)
|
||||
- [Production checklist](./production-checklist.md)
|
||||
@@ -31,3 +42,12 @@ Crank превращает REST API endpoint-ы в MCP-инструменты,
|
||||
- [Архитектура](./architecture.md)
|
||||
- [Модель данных](./data-model.md)
|
||||
- [Тестирование](./testing-strategy.md)
|
||||
|
||||
В Inventory только статус `implemented` означает готовность. Статусы `planned`,
|
||||
`gap` и `blocked` остаются непроходными и не являются заявлением о наличии
|
||||
функции в текущей Community-версии.
|
||||
|
||||
Baseline разделяет implementation status, execution verdict и evidence mode.
|
||||
Полный pass — только `implemented + automated + pass`; `flaky`, `skipped`,
|
||||
`not_run` и `manual_only` остаются non-pass. После изменения snapshot должны
|
||||
обновиться `baseline_version` и manifest checksums.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"artifacts": [
|
||||
{
|
||||
"kind": "inventory",
|
||||
"path": "docs/capability-inventory.json",
|
||||
"sha256": "fa6728e211dc55bf49225884a6cf0182ecb2e3bc1dc59e4580499e551ae4dcf1"
|
||||
},
|
||||
{
|
||||
"kind": "required_surfaces",
|
||||
"path": "docs/capability-baseline/required-surfaces.json",
|
||||
"sha256": "61714a2a141cf0a657816f35a6bfe31a7f2de77296303343bfaf6aeab9802681"
|
||||
},
|
||||
{
|
||||
"kind": "taxonomy",
|
||||
"path": "docs/capability-baseline/outcome-taxonomy.json",
|
||||
"sha256": "2a57ef358ea08ad436bd96244cd7000a660e90b4ecd04a27d5fd071ea394e549"
|
||||
},
|
||||
{
|
||||
"kind": "checklist",
|
||||
"path": "docs/capability-baseline/manual-checklist.md",
|
||||
"sha256": "688cafba282bac5a781f6b90f1a305d2ec30d1bf11b5a1f1af1f20fed3c26798"
|
||||
},
|
||||
{
|
||||
"kind": "results",
|
||||
"path": "docs/capability-baseline/results.json",
|
||||
"sha256": "aa127c8e5aabed6bdc4fdcb4734da7ea1c4b2c82e42ff47c603737e2ffa38e58"
|
||||
}
|
||||
],
|
||||
"baseline_version": "2026.08.10.1",
|
||||
"schema_version": 1
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
# Community UI capability baseline checklist
|
||||
|
||||
baseline_version: 2026.08.10.1
|
||||
|
||||
This is a bounded brownfield baseline, not the release-candidate regression from Epic 8. For every charter record happy, loading, empty, error, recovery, stale-response, RU/EN, and safe-output observations. Use `not_run` for an applicable unexecuted state, `gap` for a missing required contract, and `n/a` only with a by-design reason.
|
||||
|
||||
## UI-01 Authentication and workspace
|
||||
|
||||
- flow_id: ui-auth-workspace
|
||||
- states: happy, loading, error, recovery, stale, ru-en, safe-output
|
||||
- verdict: pass
|
||||
- reason: Wrong-password error and successful recovery were observed; settings and RU/EN navigation remained usable.
|
||||
|
||||
## UI-02 Operations catalog and lifecycle
|
||||
|
||||
- flow_id: ui-operation-lifecycle
|
||||
- states: happy, loading, empty, error, recovery, stale, ru-en, safe-output
|
||||
- verdict: fail
|
||||
- reason: Happy, loading, empty, error and recovery rendered, but an older response overwrote newer state and a credential-shaped error canary reached the DOM; see DEF-UI-001 and DEF-UI-003.
|
||||
|
||||
## UI-03 Operation test execution
|
||||
|
||||
- flow_id: ui-operation-test
|
||||
- states: happy, loading, error, recovery, stale, ru-en, safe-output
|
||||
- verdict: pass
|
||||
- reason: Wizard happy path, validation feedback and recovery controls were observed; loading and empty are not applicable to this local step flow.
|
||||
|
||||
## UI-04 YAML and OpenAPI import/export
|
||||
|
||||
- flow_id: ui-operation-import-export
|
||||
- states: happy, loading, empty, error, recovery, stale, ru-en, safe-output
|
||||
- verdict: fail
|
||||
- reason: Import entry and recovery are present, but EN mode still exposes Russian-only OpenAPI text; see DEF-UI-002.
|
||||
|
||||
## UI-05 Agent lifecycle and bindings
|
||||
|
||||
- flow_id: ui-agent-management
|
||||
- states: happy, loading, empty, error, recovery, stale, ru-en, safe-output
|
||||
- verdict: fail
|
||||
- reason: Happy, error and recovery rendered, but stale-response protection is absent and a credential-shaped error canary reached the DOM; see DEF-UI-001 and DEF-UI-003.
|
||||
|
||||
## UI-06 MCP and approval keys
|
||||
|
||||
- flow_id: ui-mcp-approval-keys
|
||||
- states: happy, loading, empty, error, recovery, stale, ru-en, safe-output
|
||||
- verdict: pass
|
||||
- reason: Agent selection, key creation entry and single raw-key disclosure guidance were observed; the seeded stack made the initial empty state inapplicable.
|
||||
|
||||
## UI-07 Auth Profiles, Upstreams, and Secrets
|
||||
|
||||
- flow_id: ui-auth-profiles-upstreams-secrets
|
||||
- states: happy, loading, empty, error, recovery, stale, ru-en, safe-output
|
||||
- verdict: fail
|
||||
- reason: Happy, real empty, error and recovery rendered, but a credential-shaped error canary reached the DOM; see DEF-UI-003.
|
||||
|
||||
## UI-08 Logs and approvals
|
||||
|
||||
- flow_id: ui-logs-approvals
|
||||
- states: happy, loading, empty, error, recovery, stale, ru-en, safe-output
|
||||
- verdict: fail
|
||||
- reason: Happy, error and recovery rendered, but a credential-shaped error canary reached the DOM; see DEF-UI-003.
|
||||
|
||||
## UI-09 Usage
|
||||
|
||||
- flow_id: ui-usage
|
||||
- states: happy, loading, empty, error, recovery, stale, ru-en, safe-output
|
||||
- verdict: fail
|
||||
- reason: Happy, error and recovery rendered, but a credential-shaped error canary reached the DOM; see DEF-UI-003.
|
||||
|
||||
## UI-10 Cross-screen stale response
|
||||
|
||||
- flow_id: ui-auth-workspace
|
||||
- states: stale, recovery
|
||||
- verdict: fail
|
||||
- reason: A delayed older Operations response overwrote a newer empty response; see DEF-UI-001.
|
||||
|
||||
## UI-11 Localization consistency
|
||||
|
||||
- flow_id: ui-operation-lifecycle
|
||||
- states: ru-en
|
||||
- verdict: fail
|
||||
- reason: Switching to EN left RU fragments on the Operations screen and OpenAPI import has hardcoded RU text; see DEF-UI-002.
|
||||
|
||||
## UI-12 Unsafe output canaries
|
||||
|
||||
- flow_id: ui-logs-approvals
|
||||
- states: safe-output, error
|
||||
- verdict: fail
|
||||
- reason: Credential-shaped API error canaries were visible in multiple browser error states; see DEF-UI-003.
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"baseline_version": "2026.08.10.1",
|
||||
"evidence_modes": [
|
||||
"automated",
|
||||
"manual_only"
|
||||
],
|
||||
"execution_verdicts": [
|
||||
"pass",
|
||||
"fail",
|
||||
"blocked",
|
||||
"skipped",
|
||||
"flaky",
|
||||
"not_run"
|
||||
],
|
||||
"full_pass": {
|
||||
"evidence_mode": "automated",
|
||||
"execution_verdict": "pass",
|
||||
"implementation_status": "implemented"
|
||||
},
|
||||
"implementation_statuses": [
|
||||
"implemented",
|
||||
"planned",
|
||||
"gap",
|
||||
"blocked"
|
||||
],
|
||||
"manual_only_rule": "Requires a retained manual result and next_evidence; it is not a full baseline pass.",
|
||||
"non_pass_rule": "Failed, blocked, skipped, flaky, not_run, missing, or malformed evidence never becomes pass."
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
{
|
||||
"baseline_version": "2026.08.10.1",
|
||||
"required_flow_ids": [
|
||||
"api-agent-catalog",
|
||||
"api-approvals",
|
||||
"api-auth-profiles-upstreams-secrets",
|
||||
"api-auth-workspace",
|
||||
"api-canonical-request-trace-identity",
|
||||
"api-logs-usage",
|
||||
"api-mcp-approval-keys",
|
||||
"api-operation-import-export",
|
||||
"api-operation-lifecycle",
|
||||
"api-operation-test-run",
|
||||
"mcp-approval-lifecycle",
|
||||
"mcp-published-tool-call",
|
||||
"mcp-published-tool-list",
|
||||
"mcp-scoped-tool-search",
|
||||
"mcp-transport-session",
|
||||
"ui-agent-management",
|
||||
"ui-auth-profiles-upstreams-secrets",
|
||||
"ui-auth-workspace",
|
||||
"ui-logs-approvals",
|
||||
"ui-mcp-approval-keys",
|
||||
"ui-operation-import-export",
|
||||
"ui-operation-lifecycle",
|
||||
"ui-operation-test",
|
||||
"ui-usage"
|
||||
],
|
||||
"surface_groups": [
|
||||
{
|
||||
"flow_ids": [
|
||||
"api-canonical-request-trace-identity"
|
||||
],
|
||||
"id": "correlation"
|
||||
},
|
||||
{
|
||||
"flow_ids": [
|
||||
"ui-operation-lifecycle",
|
||||
"ui-operation-test",
|
||||
"ui-operation-import-export",
|
||||
"api-operation-lifecycle",
|
||||
"api-operation-test-run",
|
||||
"api-operation-import-export"
|
||||
],
|
||||
"id": "operations"
|
||||
},
|
||||
{
|
||||
"flow_ids": [
|
||||
"ui-agent-management",
|
||||
"api-agent-catalog"
|
||||
],
|
||||
"id": "agents"
|
||||
},
|
||||
{
|
||||
"flow_ids": [
|
||||
"ui-auth-profiles-upstreams-secrets",
|
||||
"api-auth-profiles-upstreams-secrets"
|
||||
],
|
||||
"id": "credentials"
|
||||
},
|
||||
{
|
||||
"flow_ids": [
|
||||
"ui-mcp-approval-keys",
|
||||
"api-mcp-approval-keys",
|
||||
"mcp-approval-lifecycle"
|
||||
],
|
||||
"id": "keys-and-approvals"
|
||||
},
|
||||
{
|
||||
"flow_ids": [
|
||||
"ui-logs-approvals",
|
||||
"ui-usage",
|
||||
"api-approvals",
|
||||
"api-logs-usage"
|
||||
],
|
||||
"id": "history-and-usage"
|
||||
},
|
||||
{
|
||||
"flow_ids": [
|
||||
"ui-auth-workspace",
|
||||
"api-auth-workspace"
|
||||
],
|
||||
"id": "auth-and-workspace"
|
||||
},
|
||||
{
|
||||
"flow_ids": [
|
||||
"mcp-transport-session",
|
||||
"mcp-published-tool-list",
|
||||
"mcp-published-tool-call",
|
||||
"mcp-scoped-tool-search"
|
||||
],
|
||||
"id": "mcp-tools"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
{
|
||||
"baseline_version": "2026.08.10.1",
|
||||
"defects": [
|
||||
{
|
||||
"contract": "Local Playwright stack starts only after the configured database exists and is stable.",
|
||||
"flow_ids": ["ui-auth-workspace"],
|
||||
"id": "DEF-BL-001",
|
||||
"next_action": "Make readiness wait for the configured database after PostgreSQL bootstrap completes.",
|
||||
"owner": "quality-community",
|
||||
"severity": "Medium",
|
||||
"steps": [
|
||||
"Start the default Playwright stack with a new local PostgreSQL container.",
|
||||
"Observe pg_isready succeed against the temporary bootstrap server.",
|
||||
"Observe Admin API lose its connection when PostgreSQL restarts after database creation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"contract": "Stopping the local Playwright stack terminates its loop and all child services.",
|
||||
"flow_ids": ["ui-auth-workspace"],
|
||||
"id": "DEF-BL-002",
|
||||
"next_action": "Exit after the signal cleanup trap and terminate the actual cargo child processes.",
|
||||
"owner": "quality-community",
|
||||
"severity": "Medium",
|
||||
"steps": [
|
||||
"Start the Playwright stack and wait for readiness.",
|
||||
"Send an interrupt to the stack process.",
|
||||
"Observe the loop or re-parented Admin API and MCP processes remain alive."
|
||||
]
|
||||
},
|
||||
{
|
||||
"contract": "Workspace-dependent asynchronous UI loads reject stale responses.",
|
||||
"flow_ids": [
|
||||
"ui-agent-management",
|
||||
"ui-auth-profiles-upstreams-secrets",
|
||||
"ui-logs-approvals",
|
||||
"ui-mcp-approval-keys",
|
||||
"ui-operation-lifecycle",
|
||||
"ui-usage"
|
||||
],
|
||||
"id": "DEF-UI-001",
|
||||
"next_action": "Add request-generation identity guards in the owning UI hardening story and automate reordered responses.",
|
||||
"owner": "admin-ui-community",
|
||||
"severity": "Medium",
|
||||
"steps": [
|
||||
"Inspect workspace-change loaders for Operations, Agents, keys, secrets, logs, and usage.",
|
||||
"Confirm requests are restarted on workspace change.",
|
||||
"Confirm no shared request-generation or abort guard prevents an older response from overwriting newer state."
|
||||
]
|
||||
},
|
||||
{
|
||||
"contract": "OpenAPI import user-visible text follows the selected RU or EN locale.",
|
||||
"flow_ids": ["ui-operation-import-export"],
|
||||
"id": "DEF-UI-002",
|
||||
"next_action": "Move OpenAPI import strings into the existing RU and EN i18n contract.",
|
||||
"owner": "import-ui-community",
|
||||
"severity": "Medium",
|
||||
"steps": [
|
||||
"Select the EN locale.",
|
||||
"Open the OpenAPI import flow.",
|
||||
"Observe Russian-only labels and status messages in the import component."
|
||||
]
|
||||
},
|
||||
{
|
||||
"contract": "Browser-visible error states never render credential-shaped fields received from an untrusted API response.",
|
||||
"flow_ids": [
|
||||
"ui-agent-management",
|
||||
"ui-auth-profiles-upstreams-secrets",
|
||||
"ui-logs-approvals",
|
||||
"ui-operation-lifecycle",
|
||||
"ui-usage"
|
||||
],
|
||||
"id": "DEF-UI-003",
|
||||
"next_action": "Normalize browser API errors through a safe allowlisted message before rendering and add canary regressions for every async screen.",
|
||||
"owner": "admin-ui-community",
|
||||
"severity": "High",
|
||||
"steps": [
|
||||
"Authenticate to the local Community UI with seeded test data.",
|
||||
"Return a bounded credential-shaped canary in a 500 response for each affected list endpoint.",
|
||||
"Observe the untrusted response message rendered in the corresponding browser error state."
|
||||
]
|
||||
}
|
||||
],
|
||||
"environment_class": "community-test",
|
||||
"manual_results": [
|
||||
{
|
||||
"check_id": "UI-01",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": ["ui-auth-workspace"],
|
||||
"next_evidence": "Automate the observed login error, recovery and locale transitions."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-02",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "fail",
|
||||
"flow_ids": ["ui-operation-lifecycle"],
|
||||
"next_evidence": "Retest reordered responses and safe error rendering after DEF-UI-001 and DEF-UI-003 are fixed."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-03",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": ["ui-operation-test"],
|
||||
"next_evidence": "Automate the observed wizard validation and recovery states."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-04",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "fail",
|
||||
"flow_ids": ["ui-operation-import-export"],
|
||||
"next_evidence": "Retest RU/EN after DEF-UI-002 and exercise malformed import recovery."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-05",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "fail",
|
||||
"flow_ids": ["ui-agent-management"],
|
||||
"next_evidence": "Retest reordered responses and safe error rendering after DEF-UI-001 and DEF-UI-003 are fixed."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-06",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": ["ui-mcp-approval-keys"],
|
||||
"next_evidence": "Automate the observed empty/key-guidance state and a bounded create-and-cleanup reveal pass."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-07",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "fail",
|
||||
"flow_ids": ["ui-auth-profiles-upstreams-secrets"],
|
||||
"next_evidence": "Retest safe error rendering after DEF-UI-003 is fixed."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-08",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "fail",
|
||||
"flow_ids": ["ui-logs-approvals"],
|
||||
"next_evidence": "Retest safe error rendering after DEF-UI-003 is fixed."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-09",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "fail",
|
||||
"flow_ids": ["ui-usage"],
|
||||
"next_evidence": "Retest safe errors and reordered responses after DEF-UI-001 and DEF-UI-003 are fixed."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-10",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "fail",
|
||||
"flow_ids": ["ui-auth-workspace"],
|
||||
"next_evidence": "Add deterministic reordered-response tests after DEF-UI-001 is addressed."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-11",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "fail",
|
||||
"flow_ids": ["ui-operation-lifecycle"],
|
||||
"next_evidence": "Repeat the EN locale pass after DEF-UI-002 is addressed."
|
||||
},
|
||||
{
|
||||
"check_id": "UI-12",
|
||||
"evidence_mode": "manual_only",
|
||||
"execution_verdict": "fail",
|
||||
"flow_ids": ["ui-logs-approvals"],
|
||||
"next_evidence": "Repeat the bounded canary pass after DEF-UI-003 is fixed."
|
||||
}
|
||||
],
|
||||
"runs": [
|
||||
{
|
||||
"accepted": true,
|
||||
"collector": "capability-baseline-collector-v1",
|
||||
"command_id": "rust-admin-integration",
|
||||
"evidence_mode": "automated",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": [
|
||||
"api-agent-catalog",
|
||||
"api-approvals",
|
||||
"api-auth-profiles-upstreams-secrets",
|
||||
"api-auth-workspace",
|
||||
"api-logs-usage",
|
||||
"api-mcp-approval-keys",
|
||||
"api-operation-import-export",
|
||||
"api-operation-lifecycle",
|
||||
"api-operation-test-run"
|
||||
],
|
||||
"id": "run-rust-admin-integration-fa07285c8e58",
|
||||
"environment_class": "community-test",
|
||||
"source_revision": "c30461cc92491ebe3d527e125a1657b73fa67006",
|
||||
"source_report_sha256": "fa07285c8e58dfad3834ffd420d80c91cdf0f0b5d0c54ef3e0eeaf35df3ab3f8"
|
||||
},
|
||||
{
|
||||
"accepted": true,
|
||||
"collector": "capability-baseline-collector-v1",
|
||||
"command_id": "rust-mcp-integration",
|
||||
"evidence_mode": "automated",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": [
|
||||
"mcp-approval-lifecycle",
|
||||
"mcp-published-tool-call",
|
||||
"mcp-published-tool-list",
|
||||
"mcp-scoped-tool-search",
|
||||
"mcp-transport-session"
|
||||
],
|
||||
"id": "run-rust-mcp-integration-ccff7c0029c1",
|
||||
"environment_class": "community-test",
|
||||
"source_revision": "c30461cc92491ebe3d527e125a1657b73fa67006",
|
||||
"source_report_sha256": "ccff7c0029c1347459a76b8ecd63a308a7162ddb5bc272441e79ffbf2ccdfb83"
|
||||
},
|
||||
{
|
||||
"accepted": true,
|
||||
"collector": "capability-baseline-collector-v1",
|
||||
"command_id": "ui-build",
|
||||
"evidence_mode": "automated",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": [
|
||||
"ui-auth-workspace",
|
||||
"ui-mcp-approval-keys",
|
||||
"ui-operation-import-export",
|
||||
"ui-operation-test"
|
||||
],
|
||||
"id": "run-ui-build-755e91f2200b",
|
||||
"environment_class": "community-test",
|
||||
"source_revision": "c30461cc92491ebe3d527e125a1657b73fa67006",
|
||||
"source_report_sha256": "755e91f2200b4ac43783820afde4f5d6b336ff7a6ebd5e71b055c43d5c2e4986"
|
||||
},
|
||||
{
|
||||
"accepted": true,
|
||||
"collector": "capability-baseline-collector-v1",
|
||||
"command_id": "ui-playwright",
|
||||
"evidence_mode": "automated",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": [
|
||||
"ui-auth-workspace",
|
||||
"ui-mcp-approval-keys",
|
||||
"ui-operation-import-export",
|
||||
"ui-operation-test"
|
||||
],
|
||||
"id": "run-ui-playwright-a1236d5f45ab",
|
||||
"environment_class": "community-test",
|
||||
"source_revision": "c30461cc92491ebe3d527e125a1657b73fa67006",
|
||||
"summary": {"passed": 21, "failed": 0, "flaky": 0, "skipped": 0},
|
||||
"source_report_sha256": "a1236d5f45ab6273625bdb61634b1ea6c6d3ac876757b85a0a5ed8b5855fea6b"
|
||||
},
|
||||
{
|
||||
"accepted": true,
|
||||
"collector": "capability-baseline-collector-v1",
|
||||
"command_id": "authenticated-product-smoke",
|
||||
"evidence_mode": "automated",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": [
|
||||
"api-agent-catalog",
|
||||
"api-mcp-approval-keys",
|
||||
"api-operation-lifecycle",
|
||||
"api-operation-test-run",
|
||||
"mcp-published-tool-call",
|
||||
"mcp-published-tool-list",
|
||||
"mcp-transport-session"
|
||||
],
|
||||
"id": "run-authenticated-product-smoke-471a29ea400f",
|
||||
"environment_class": "community-test",
|
||||
"source_revision": "c30461cc92491ebe3d527e125a1657b73fa67006",
|
||||
"safe_outcome": {
|
||||
"agent_id": "agent_019fe3a5468d75039020e367f1096136",
|
||||
"agent_revision": 1,
|
||||
"operation_id": "op_019fe3a546177533a2df26a36c79d358",
|
||||
"operation_version": 1,
|
||||
"stages": ["admin_test", "operation_publish", "agent_publish", "mcp_list", "mcp_call"]
|
||||
},
|
||||
"source_report_sha256": "471a29ea400fe1cb3eceb68d073c15ecba4e95ee5dff487fec0bb969f09c65e0"
|
||||
},
|
||||
{
|
||||
"accepted": true,
|
||||
"collector": "capability-baseline-collector-v1",
|
||||
"command_id": "just-verify",
|
||||
"environment_class": "community-test",
|
||||
"evidence_mode": "automated",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": [
|
||||
"api-agent-catalog",
|
||||
"api-approvals",
|
||||
"api-auth-profiles-upstreams-secrets",
|
||||
"api-auth-workspace",
|
||||
"api-logs-usage",
|
||||
"api-mcp-approval-keys",
|
||||
"api-operation-import-export",
|
||||
"api-operation-lifecycle",
|
||||
"api-operation-test-run",
|
||||
"mcp-approval-lifecycle",
|
||||
"mcp-published-tool-call",
|
||||
"mcp-published-tool-list",
|
||||
"mcp-scoped-tool-search",
|
||||
"mcp-transport-session"
|
||||
],
|
||||
"id": "run-just-verify-c6c16ce3c4b2",
|
||||
"source_report_sha256": "c6c16ce3c4b2fa8355ae73c6ad6e87f3c829e86d720cd153133c161d073330b2",
|
||||
"source_revision": "c30461cc92491ebe3d527e125a1657b73fa67006",
|
||||
"summary": {"exit_code": 0, "skipped": 0, "timed_out": false}
|
||||
},
|
||||
{
|
||||
"accepted": true,
|
||||
"collector": "capability-baseline-collector-v1",
|
||||
"command_id": "just-verify",
|
||||
"environment_class": "community-test",
|
||||
"evidence_mode": "automated",
|
||||
"execution_verdict": "pass",
|
||||
"flow_ids": [
|
||||
"api-canonical-request-trace-identity"
|
||||
],
|
||||
"id": "run-just-verify-a3e1538374ee",
|
||||
"source_report_sha256": "a3e1538374eea02b3140ea20a7966c01225a78ac510296d0bb08eaf87a3c476c",
|
||||
"source_revision": "c30461cc92491ebe3d527e125a1657b73fa67006",
|
||||
"summary": {"exit_code": 0, "skipped": 0, "timed_out": false}
|
||||
}
|
||||
],
|
||||
"source_revision": "c30461cc92491ebe3d527e125a1657b73fa67006"
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
{
|
||||
"flows": [
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/ui/tests/e2e/login.spec.js", "apps/ui/tests/e2e/workspace-settings.spec.js"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "ui-auth-workspace",
|
||||
"owner": "admin-ui-community",
|
||||
"requirements": ["FR-3", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "ui",
|
||||
"user_outcome": "An administrator can authenticate and work in the selected Community workspace."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/ui/tests/e2e/operations.spec.js", "apps/ui/tests/e2e/wizard.spec.js"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "ui-operation-lifecycle",
|
||||
"owner": "operations-ui-community",
|
||||
"requirements": ["FR-1", "FR-46"],
|
||||
"status": "blocked",
|
||||
"type": "ui",
|
||||
"user_outcome": "An administrator can create, edit, publish, archive, and inspect REST Operations."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/ui/tests/e2e/wizard.spec.js"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "ui-operation-test",
|
||||
"owner": "runtime-ui-community",
|
||||
"requirements": ["FR-2", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "ui",
|
||||
"user_outcome": "An administrator can execute a bounded Operation test and inspect its safe outcome."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/ui/tests/e2e/operations.spec.js", "apps/ui/tests/e2e/wizard.spec.js"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "ui-operation-import-export",
|
||||
"owner": "import-ui-community",
|
||||
"requirements": ["FR-1", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "ui",
|
||||
"user_outcome": "An administrator can import OpenAPI or YAML drafts and export an Operation configuration."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/ui/tests/e2e/agents.spec.js"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "ui-agent-management",
|
||||
"owner": "agents-ui-community",
|
||||
"requirements": ["FR-4", "FR-46"],
|
||||
"status": "blocked",
|
||||
"type": "ui",
|
||||
"user_outcome": "An administrator can manage an Agent and its published Operation bindings."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/ui/tests/e2e/api-keys.spec.js"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "ui-mcp-approval-keys",
|
||||
"owner": "keys-ui-community",
|
||||
"requirements": ["FR-3", "FR-5", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "ui",
|
||||
"user_outcome": "An administrator can create, reveal once, inspect, revoke, and delete MCP or approval keys."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/ui/tests/e2e/secrets.spec.js", "apps/ui/tests/e2e/wizard.spec.js"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "ui-auth-profiles-upstreams-secrets",
|
||||
"owner": "credentials-ui-community",
|
||||
"requirements": ["FR-3", "FR-46"],
|
||||
"status": "blocked",
|
||||
"type": "ui",
|
||||
"user_outcome": "An administrator can configure reusable upstream, Auth Profile, and secret references without re-reading plaintext."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/ui/tests/e2e/logs-usage.spec.js"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "ui-logs-approvals",
|
||||
"owner": "history-ui-community",
|
||||
"requirements": ["FR-5", "FR-6", "FR-46"],
|
||||
"status": "blocked",
|
||||
"type": "ui",
|
||||
"user_outcome": "An administrator can inspect invocation logs, safe details, and pending approvals."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/ui/tests/e2e/logs-usage.spec.js"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "ui-usage",
|
||||
"owner": "usage-ui-community",
|
||||
"requirements": ["FR-6", "FR-46"],
|
||||
"status": "blocked",
|
||||
"type": "ui",
|
||||
"user_outcome": "An administrator can inspect workspace, Operation, and Agent usage summaries."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/auth_rate_limit.rs", "apps/admin-api/tests/integration/community_access_usage.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "api-auth-workspace",
|
||||
"owner": "admin-api-community",
|
||||
"requirements": ["FR-3", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Authenticated Admin API requests are scoped to the authorized Community workspace."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/operations_agents.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "api-operation-lifecycle",
|
||||
"owner": "operations-api-community",
|
||||
"requirements": ["FR-1", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Admin API clients can manage immutable published Operation versions and drafts."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/operations_agents.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "api-operation-test-run",
|
||||
"owner": "runtime-api-community",
|
||||
"requirements": ["FR-2", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Admin API clients can execute a REST Operation test through the current runtime boundary."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/openapi_import.rs", "apps/admin-api/tests/integration/secrets_import_auth.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "api-operation-import-export",
|
||||
"owner": "import-api-community",
|
||||
"requirements": ["FR-1", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Admin API clients can preview and create OpenAPI imports and round-trip YAML configuration."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/operations_agents.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "api-agent-catalog",
|
||||
"owner": "agents-api-community",
|
||||
"requirements": ["FR-4", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Admin API clients can manage Agent revisions, exact bindings, publication, and catalog search policy."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/community_access_usage.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "api-mcp-approval-keys",
|
||||
"owner": "keys-api-community",
|
||||
"requirements": ["FR-3", "FR-5", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Admin API clients can manage separately scoped MCP and approval keys with a single raw disclosure."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/secrets_import_auth.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "api-auth-profiles-upstreams-secrets",
|
||||
"owner": "credentials-api-community",
|
||||
"requirements": ["FR-3", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Admin API clients can manage upstreams, Auth Profiles, and encrypted secret references."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/community_access_usage.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "api-approvals",
|
||||
"owner": "approvals-api-community",
|
||||
"requirements": ["FR-5", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Admin API clients can list and inspect approval requests without leaking unsafe payloads."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/community_access_usage.rs", "apps/admin-api/tests/dc08.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "api-logs-usage",
|
||||
"owner": "history-api-community",
|
||||
"requirements": ["FR-6", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Admin API clients can query safe invocation history and usage summaries."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/mcp-server/tests/integration/transport_protocol.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "mcp-transport-session",
|
||||
"owner": "mcp-transport-community",
|
||||
"requirements": ["FR-3", "FR-4", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "mcp",
|
||||
"user_outcome": "An authorized MCP client can initialize and terminate a bounded Streamable HTTP session."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/mcp-server/tests/integration/transport_protocol.rs", "apps/mcp-server/tests/integration/catalog_access.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "mcp-published-tool-list",
|
||||
"owner": "mcp-catalog-community",
|
||||
"requirements": ["FR-4", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "mcp",
|
||||
"user_outcome": "An MCP client sees only bound, authorized, published Tool versions for its Agent."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/mcp-server/tests/integration/transport_protocol.rs", "apps/mcp-server/tests/integration/execution_stages.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "mcp-published-tool-call",
|
||||
"owner": "mcp-runtime-community",
|
||||
"requirements": ["FR-2", "FR-4", "FR-6", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "mcp",
|
||||
"user_outcome": "An MCP client can invoke an authorized published REST Tool and receive a safe structured outcome."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/mcp-server/tests/integration/tool_search.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "mcp-scoped-tool-search",
|
||||
"owner": "mcp-catalog-community",
|
||||
"requirements": ["FR-4", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "mcp",
|
||||
"user_outcome": "An MCP client can use Agent-scoped search meta-tools without escaping its published catalog."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/mcp-server/tests/integration/catalog_access/approval_access.rs"], "manual": ["docs/capability-baseline/manual-checklist.md"]},
|
||||
"id": "mcp-approval-lifecycle",
|
||||
"owner": "mcp-approvals-community",
|
||||
"requirements": ["FR-5", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "mcp",
|
||||
"user_outcome": "A separately authorized approval client can list and decide pending requests with bounded side effects."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["apps/admin-api/tests/integration/request_context.rs", "apps/mcp-server/tests/integration/request_context.rs", "apps/mcp-server/tests/integration/execution_stages.rs", "crates/crank-registry/tests/integration/migrations.rs"], "manual": ["docs/observability.md"]},
|
||||
"id": "api-canonical-request-trace-identity",
|
||||
"owner": "observability-community",
|
||||
"requirements": ["FR-27", "FR-46"],
|
||||
"status": "implemented",
|
||||
"type": "api",
|
||||
"user_outcome": "Admin and MCP requests expose separate safe Request and Trace identities that survive runtime execution and history persistence without requiring telemetry export."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["tests/unit/test_validate_capability_inventory.py"], "manual": ["docs/intro.md"]},
|
||||
"id": "planned-production-foundation",
|
||||
"owner": "platform-community",
|
||||
"requirements": ["FR-7", "FR-8", "FR-9", "FR-10", "FR-11", "FR-12", "FR-13", "FR-14", "FR-28", "FR-29", "FR-30", "FR-31", "FR-32", "FR-33", "FR-34", "FR-35"],
|
||||
"status": "planned",
|
||||
"type": "api",
|
||||
"user_outcome": "Community runtime, safety, correlation, and observability foundations reach their planned production contracts."
|
||||
},
|
||||
{
|
||||
"capabilities": ["resources"],
|
||||
"evidence": {"automated": ["tests/unit/test_validate_capability_inventory.py"], "manual": ["docs/intro.md"]},
|
||||
"id": "planned-resource-read",
|
||||
"owner": "mcp-community",
|
||||
"requirements": ["FR-15", "FR-16", "FR-46"],
|
||||
"status": "planned",
|
||||
"type": "mcp",
|
||||
"user_outcome": "MCP clients can discover and read published Resources."
|
||||
},
|
||||
{
|
||||
"capabilities": ["prompts"],
|
||||
"evidence": {"automated": ["tests/unit/test_validate_capability_inventory.py"], "manual": ["docs/intro.md"]},
|
||||
"id": "planned-prompt-get",
|
||||
"owner": "mcp-community",
|
||||
"requirements": ["FR-17", "FR-18", "FR-19", "FR-46"],
|
||||
"status": "planned",
|
||||
"type": "mcp",
|
||||
"user_outcome": "MCP clients can list and render published parameterized Prompts."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tasks"],
|
||||
"evidence": {"automated": ["tests/unit/test_validate_capability_inventory.py"], "manual": ["docs/intro.md"]},
|
||||
"id": "planned-background-task",
|
||||
"owner": "execution-community",
|
||||
"requirements": ["FR-20", "FR-21", "FR-22", "FR-23", "FR-24", "FR-25", "FR-26", "FR-46"],
|
||||
"status": "planned",
|
||||
"type": "mcp",
|
||||
"user_outcome": "Users can observe and control durable background executions."
|
||||
},
|
||||
{
|
||||
"capabilities": ["load_runs"],
|
||||
"evidence": {"automated": ["tests/unit/test_validate_capability_inventory.py"], "manual": ["docs/intro.md"]},
|
||||
"id": "planned-load-run",
|
||||
"owner": "quality-community",
|
||||
"requirements": ["FR-36", "FR-37", "FR-38", "FR-39", "FR-40", "FR-41", "FR-46"],
|
||||
"status": "planned",
|
||||
"type": "ui",
|
||||
"user_outcome": "Administrators can run a bounded load scenario and inspect its quality statistics."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["tests/unit/test_validate_capability_inventory.py"], "manual": ["docs/intro.md"]},
|
||||
"id": "planned-community-deployment",
|
||||
"owner": "release-community",
|
||||
"requirements": ["FR-42", "FR-43", "FR-44", "FR-45", "FR-46"],
|
||||
"status": "planned",
|
||||
"type": "api",
|
||||
"user_outcome": "Operators can deploy, upgrade, restore, and operate a production Community installation."
|
||||
},
|
||||
{
|
||||
"capabilities": ["tools"],
|
||||
"evidence": {"automated": ["tests/unit/test_validate_capability_inventory.py"], "manual": ["docs/intro.md"]},
|
||||
"id": "planned-release-qualification",
|
||||
"owner": "quality-community",
|
||||
"requirements": ["FR-47", "FR-48", "FR-49", "FR-50", "FR-51", "FR-52", "FR-53", "FR-54"],
|
||||
"status": "planned",
|
||||
"type": "api",
|
||||
"user_outcome": "A release candidate is qualified by immutable, reproducible technical and manual evidence."
|
||||
}
|
||||
],
|
||||
"product": "crank-community",
|
||||
"schema_version": 1
|
||||
}
|
||||
+10
-7
@@ -2,11 +2,12 @@
|
||||
|
||||
Документ описывает поддерживаемый путь запуска Crank на сервере.
|
||||
|
||||
Crank запускается как три контейнера за reverse proxy:
|
||||
Crank запускает три long-running контейнера за reverse proxy и один обязательный one-shot migration job:
|
||||
|
||||
- `ui`
|
||||
- `admin-api`
|
||||
- `mcp-server`
|
||||
- `migrate` (завершается до readiness Admin/MCP)
|
||||
|
||||
Можно использовать внешний PostgreSQL или локальный PostgreSQL из compose-профиля `local-db`.
|
||||
|
||||
@@ -18,8 +19,10 @@ reverse proxy
|
||||
/api/admin/ -> admin-api:3001
|
||||
/mcp/ -> mcp-server:3002
|
||||
|
||||
admin-api -> PostgreSQL
|
||||
mcp-server -> PostgreSQL
|
||||
migrate -> PostgreSQL -> exit 0
|
||||
|
|
||||
+-> admin-api readiness
|
||||
+-> mcp-server readiness
|
||||
admin-api -> Valkey/Redis, опционально
|
||||
mcp-server -> Valkey/Redis, опционально
|
||||
admin-api -> внешний OTLP endpoint, опционально
|
||||
@@ -105,7 +108,7 @@ docker compose \
|
||||
config -q
|
||||
```
|
||||
|
||||
Запуск с внешним PostgreSQL:
|
||||
Перед обновлением существующей установки выполните preflight и проверенный backup по [migration runbook](migrations.md). Source Compose по умолчанию поднимает локальный PostgreSQL 16. После безопасной последовательности запустите:
|
||||
|
||||
```bash
|
||||
docker compose \
|
||||
@@ -143,7 +146,7 @@ cp .env.example .env
|
||||
docker compose --profile local-db up -d
|
||||
```
|
||||
|
||||
Если используется внешний PostgreSQL, заполните `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD` и запустите:
|
||||
Если используется внешний PostgreSQL, заполните `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, сначала выполните preflight и backup по [migration runbook](migrations.md), затем запустите:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
@@ -182,9 +185,9 @@ curl -I http://127.0.0.1:3000/
|
||||
CRANK_RESTORE_CONFIRM=restore ./scripts/restore-community.sh /opt/crank /opt/crank/backups/20260721T120000Z
|
||||
```
|
||||
|
||||
- Обновления схемы выполняются под блокировкой, одной транзакцией и фиксируются в `__crank_core_migrations`. Миграции Community должны оставаться обратно совместимыми с предыдущей версией приложения.
|
||||
- Обновления схемы выполняет только one-shot `crank-migrate apply` под canonical transaction advisory lock. `admin-api` и `mcp-server` выполняют read-only compatibility check и не стартуют до успешного migration job. Canonical sequence фиксируется в `__crank_migrations`, legacy ledgers остаются readable; подробности — в [migrations.md](migrations.md).
|
||||
- Не храните реальные секреты в Git.
|
||||
- CD использует неизменяемые теги коммитов и автоматически возвращает прежнюю конфигурацию и образы при провале readiness.
|
||||
- CD использует неизменяемые теги коммитов. После schema migration автоматический возврат старых образов запрещён, пока N/N-1 window не квалифицирован Story 7.2: оператор сохраняет backup и выбирает matching forward image либо доказанное восстановление согласованного комплекта.
|
||||
- `CRANK_PUBLISH_BIND=0.0.0.0` нужен только если reverse proxy работает на другом host.
|
||||
- OTLP Collector и хранилище трасс не входят в Community Compose. Для
|
||||
внешнего приёмника задайте `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`; секретные
|
||||
|
||||
@@ -27,6 +27,19 @@ This repository contains the Community version:
|
||||
- PostgreSQL database;
|
||||
- optional Valkey or Redis for temporary coordination state.
|
||||
|
||||
The executable Community boundary is recorded in
|
||||
[`docs/capability-inventory.json`](../capability-inventory.json). Only
|
||||
`implemented` denotes a delivered flow; `planned`, `gap`, and `blocked` do not
|
||||
count as ready. Resources, Prompts, background Tasks, and Load Runs are planned
|
||||
targets and are not advertised as implemented in the current version.
|
||||
|
||||
The verified brownfield snapshot is recorded in
|
||||
[`docs/capability-baseline/manifest.json`](../capability-baseline/manifest.json).
|
||||
It binds the inventory, required surfaces, taxonomy, bounded manual checklist,
|
||||
and sanitized results by exact SHA-256. A full pass requires
|
||||
`implemented + automated + pass`; flaky, skipped, not-run, and manual-only
|
||||
evidence remain non-pass.
|
||||
|
||||
## Documentation
|
||||
|
||||
The main documentation is currently maintained in Russian:
|
||||
@@ -38,6 +51,9 @@ The main documentation is currently maintained in Russian:
|
||||
- [MCP interface](../mcp-interface.md)
|
||||
- [Admin API](../admin-api.md)
|
||||
- [Runtime configuration](../runtime-config.md)
|
||||
- [Runtime configuration machine schema](../schemas/runtime-config.schema.json)
|
||||
- [PostgreSQL migration contract](migrations.md) ([full operator contract in Russian](../migrations.md))
|
||||
- [Migration machine sequence](../schemas/migration-sequence.json)
|
||||
- [Troubleshooting](../troubleshooting.md)
|
||||
|
||||
## License
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# PostgreSQL migrations
|
||||
|
||||
Crank has one append-only migration authority in `crank-registry`. The Admin and MCP services run a read-only compatibility preflight; only the one-shot `crank-migrate` process may execute DDL.
|
||||
|
||||
For an existing installation, always run: read-only `preflight`, verified PostgreSQL and artifact-storage backup, `plan --check`, controlled `apply`, then a final `preflight`. Exit code `2` from CLI preflight means migration is required; exit code `1` blocks mutation until the reported condition is resolved.
|
||||
|
||||
Source command:
|
||||
|
||||
```bash
|
||||
cargo run -p admin-api --bin crank-migrate -- plan --check
|
||||
docker compose -f deploy/community/docker-compose.yml \
|
||||
--env-file deploy/community/.env.example \
|
||||
run --rm migrate crank-migrate preflight
|
||||
```
|
||||
|
||||
The migrator reads only database configuration and retries connection for a bounded startup window. Diagnostics contain stable `code`, `stage`, nullable `version`, and `recovery`, never raw SQL, driver output, database URLs, credentials, or row data.
|
||||
|
||||
Published migrations are immutable and checksummed. Partial schema, unknown extension provenance, checksum drift, and future versions fail closed. Automatic down migrations, `--force`, destructive rollback, and arbitrary SQL input are not supported. Full N/N-1 upgrade and rollback qualification belongs to Story 7.2.
|
||||
|
||||
Version 3 adds nullable canonical Trace ID storage and partial Request/Trace indexes. New application writes provide both identities; historical rows remain honestly nullable and are never assigned fabricated traces.
|
||||
|
||||
For the complete ledger inventory, recovery table, and authoring rules, see the canonical [Russian operator contract](../migrations.md).
|
||||
+16
-1
@@ -36,6 +36,22 @@ MCP-клиент
|
||||
- PostgreSQL как основное хранилище;
|
||||
- опциональный Valkey или Redis для служебного кэша.
|
||||
|
||||
Исполняемая граница Community описана в
|
||||
[`docs/capability-inventory.json`](./capability-inventory.json). Только
|
||||
`implemented` означает доступную возможность; `planned`, `gap` и `blocked` не
|
||||
считаются готовностью. Resources, Prompts, фоновые Tasks и Load Runs пока
|
||||
являются planned target, а не возможностями текущей версии.
|
||||
|
||||
Фактический brownfield baseline закреплён в
|
||||
[`docs/capability-baseline/manifest.json`](./capability-baseline/manifest.json).
|
||||
Manifest проверяет SHA-256 inventory, required surfaces, taxonomy, bounded
|
||||
manual checklist и sanitized results. Flaky, skipped, not-run и manual-only
|
||||
evidence не считаются полным pass; дефекты остаются связаны с flow и owner.
|
||||
|
||||
PostgreSQL schema изменяет только controlled one-shot команда. Admin API и MCP
|
||||
при startup выполняют read-only compatibility check; операторский порядок и
|
||||
failure contract описаны в [`docs/migrations.md`](./migrations.md).
|
||||
|
||||
## Демо при первом запуске
|
||||
|
||||
В примерах окружения включен `CRANK_DEMO_SEED=true`. После первого запуска Crank создает:
|
||||
@@ -47,4 +63,3 @@ MCP-клиент
|
||||
- пример записи в журнале вызовов.
|
||||
|
||||
Демо можно отключить, указав `CRANK_DEMO_SEED=false`.
|
||||
|
||||
|
||||
@@ -274,4 +274,6 @@ CRANK_MCP_REFRESH_MS=5000
|
||||
- `400 Bad Request` - неверный MCP-заголовок, session id или JSON-RPC payload.
|
||||
- `429 Too Many Requests` - сработал rate limit.
|
||||
|
||||
Runtime-ошибки инструмента возвращаются как структурированный MCP tool error с кодом, сообщением и `request_id`.
|
||||
Runtime-ошибки инструмента возвращаются как структурированный MCP tool error с кодом,
|
||||
сообщением, `request_id` и отдельным `trace_id`. Транспортные ответы также содержат
|
||||
`x-request-id` и `x-trace-id`; отклонённые входные значения в них не отражаются.
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# Миграции PostgreSQL
|
||||
|
||||
Crank использует единственную append-only migration authority в `crank-registry`. `admin-api` и `mcp-server` выполняют только read-only preflight. DDL применяет one-shot binary `crank-migrate`, который Community Compose запускает до readiness сервисов.
|
||||
|
||||
## Безопасная последовательность оператора
|
||||
|
||||
Для source Compose замените `<compose>` на:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/community/docker-compose.yml --env-file deploy/community/.env.example
|
||||
```
|
||||
|
||||
Для image Compose используйте `docker compose -f deploy/community/docker-compose.images.yml --env-file .env`. Перед обновлением уже работающей установки выполните строго:
|
||||
|
||||
1. Read-only preflight: `<compose> run --rm migrate crank-migrate preflight`. Exit `0` означает current, exit `2` — ожидаемую `migration_required`; exit `1` запрещает mutation до устранения причины.
|
||||
2. Создайте и проверьте согласованный backup PostgreSQL и artifact storage. Для первой пустой установки зафиксируйте, что восстанавливать нечего.
|
||||
3. Проверьте immutable plan: `cargo run -p admin-api --bin crank-migrate -- plan --check` в source checkout либо `<compose> run --rm migrate crank-migrate plan` для образа.
|
||||
4. Примените sequence: `<compose> run --rm migrate crank-migrate apply`.
|
||||
5. Повторите preflight и убедитесь в `{"status":"current","version":3}`.
|
||||
6. Только теперь запускайте long-running services: `<compose> up -d`.
|
||||
|
||||
Обычный `up` также содержит обязательный migration job, но при upgrade он не заменяет предварительные preflight и backup. Migrator делает до десяти bounded попыток подключения с секундной паузой и затем безопасно завершается ошибкой.
|
||||
|
||||
Команда читает только `CRANK_DATABASE_URL`/`POSTGRES_*`. Master key, session secret, bootstrap password, MCP credentials и другие service secrets не входят в её config projection.
|
||||
|
||||
## Фактический brownfield inventory
|
||||
|
||||
| Источник | Исторический владелец/lock | Известный контракт |
|
||||
|---|---|---|
|
||||
| `__crank_core_migrations` | `crank-registry`, session lock `0x4352414e4b` | columns `version, description, checksum, applied_at`; v1 checksum `crank-community-baseline-v1` |
|
||||
| `__crank_mcp_migrations` | MCP session store, session lock `0x4352414e4b4d4350` | columns `version, checksum, applied_at`; v1 checksum `mcp-transport-sessions-v1` |
|
||||
| `__crank_ext_migrations` | прежний `RegistryExtension`, без общего lock | legacy columns `extension_name, version, applied_at`; checksum отсутствовал |
|
||||
| `__crank_migrations` | canonical `MigrationAuthority`, transaction lock `0x4352414e4b4d4947` | append-only sequence с version/name/checksum/phase/compatibility |
|
||||
| `__crank_migration_legacy_audit` | canonical `MigrationAuthority` | только доказуемо сопоставленное legacy provenance |
|
||||
|
||||
Legacy extension row без зарегистрированного exact `(name, version, checksum)` несовместим. Community пока не публиковала extension migrations, поэтому authority не выдумывает им checksum и блокирует такие строки с `legacy_conflict`.
|
||||
|
||||
## Контракт sequence
|
||||
|
||||
Machine plan находится в [`schemas/migration-sequence.json`](schemas/migration-sequence.json) и проверяется командой:
|
||||
|
||||
```bash
|
||||
cargo run -p admin-api --bin crank-migrate -- plan --check
|
||||
```
|
||||
|
||||
- V1 — immutable brownfield baseline с историческим ledger token и отдельным exact-source SHA-256.
|
||||
- V2 — единый exact-byte expand SQL artifact, создающий canonical ledgers и MCP session schema; его SHA-256 закреплён в executable descriptor.
|
||||
- V3 — append-only expand для независимого nullable `invocation_logs.trace_id`, canonical-format constraint и partial request/trace indexes; исторические строки остаются `NULL` без fabricated backfill.
|
||||
- Каждая версия имеет contiguous `i64` version, стабильное имя, lowercase SHA-256, owner, phase, explicit readable schema min/max и backfill policy.
|
||||
- `migrate` требует bounded cursor/batch policy; `contract` дополнительно требует tracked compatibility evidence и закрытого окна.
|
||||
- Добавление descriptor без executable implementation блокируется `invalid_contract` до DB I/O.
|
||||
|
||||
Legacy ledgers остаются readable. Down migration, destructive automatic rollback, ledger rewrite, `--force` и arbitrary SQL/path input отсутствуют. Полная N/N-1 upgrade/rollback qualification остаётся Story 7.2.
|
||||
|
||||
## Диагностика и восстановление
|
||||
|
||||
CLI/stderr возвращают bounded JSON: `code`, `stage`, nullable numeric `version`, `recovery`. Database URL, credentials, raw SQL/driver body, row values и host paths не выводятся.
|
||||
|
||||
| Code | Значение | Безопасное действие |
|
||||
|---|---|---|
|
||||
| `schema_missing` | Service startup увидел пустую schema | Запустить controlled migration; не разрешать runtime DDL |
|
||||
| `migration_required` | Schema отстаёт; preflight CLI завершает работу с exit `2` | Проверить backup и выполнить controlled `apply` |
|
||||
| `checksum_mismatch` | Artifact и ledger не совпали | Сначала проверить immutable application image/release manifest; восстанавливать БД только после доказанной ledger corruption |
|
||||
| `partial_sequence` | Relation/ledger/structural fingerprint неполон | Не чинить вручную; сопоставить backup и matching artifact |
|
||||
| `future_version` | База новее приложения | Установить matching application; не откатывать schema автоматически |
|
||||
| `legacy_conflict` | Legacy provenance невозможно доказать | Сохранить backup и привлечь оператора |
|
||||
| `lock_timeout` | Другой migration runner удерживает canonical lock | Дождаться завершения и повторить preflight |
|
||||
| `apply_failed` | Transaction migration откатилась | Проверить matching artifact/backup, затем повторить preflight |
|
||||
| `storage_unavailable` | PostgreSQL/transport недоступен | Проверить сеть/TLS/права; секреты в diagnostic не копировать |
|
||||
| `config_invalid` | Database-only config невалиден | Исправить указанный config contract |
|
||||
| `invalid_command` | Неизвестная CLI команда/аргумент | Использовать только `plan`, `preflight`, `apply` |
|
||||
| `contract_drift` | Committed machine plan расходится с Rust authority | Перегенерировать только для новой append-only version и проверить diff |
|
||||
| `invalid_contract` | Descriptor/implementation/window/evidence несовместимы | Исправить authoring contract до любого DB I/O |
|
||||
|
||||
## Правила разработчика
|
||||
|
||||
- DDL, SQL migration assets и canonical advisory lock разрешены только в `crank-registry::migrations`.
|
||||
- Schema развивается `expand → bounded/resumable migrate → evidence-gated contract`.
|
||||
- Опубликованные source bytes/checksums не редактируются: добавляется новая version.
|
||||
- Для каждой version обязательны fresh/current/concurrent/corrupt/rollback/data-preservation tests и explicit Community scope scan.
|
||||
+20
-12
@@ -15,6 +15,7 @@
|
||||
"target": "admin_api::request_context",
|
||||
"event": "admin.request.completed",
|
||||
"request_id": "019...",
|
||||
"trace_id": "0af7651916cd43dd8448eb211c80319c",
|
||||
"fields": {
|
||||
"method": "GET",
|
||||
"route": "/api/operations",
|
||||
@@ -38,14 +39,14 @@ Admin API и MCP принимают `x-request-id` как непрозрачны
|
||||
отсутствует или содержит пробелы, управляющие символы, `,`, `;`, не-ASCII
|
||||
символы либо больше 128 байт, Crank создаёт UUIDv7.
|
||||
|
||||
Один идентификатор:
|
||||
Request ID и отдельный Trace ID:
|
||||
|
||||
- возвращается в `x-request-id` успешного или ошибочного ответа;
|
||||
- записывается в корневой span входного запроса;
|
||||
- передаётся в runtime;
|
||||
- возвращаются в `x-request-id`/`x-trace-id` успешного или ошибочного ответа;
|
||||
- записываются в корневой span входного запроса;
|
||||
- типизированно передаются в runtime;
|
||||
- заменяет статические или полученные из mapping значения
|
||||
`x-request-id` и `x-correlation-id` перед исходящим REST-запросом;
|
||||
- сохраняется в прикладной истории вызова.
|
||||
- сохраняются в прикладной истории вызова.
|
||||
|
||||
`request id` не является `trace id` и не подменяет распределённую
|
||||
трассировку.
|
||||
@@ -214,15 +215,22 @@ series и расход памяти измеряются в истории 1.8;
|
||||
## Распределённые трассы
|
||||
|
||||
Crank принимает и передаёт стандартный W3C `traceparent` на границах Admin
|
||||
API, MCP и исходящих REST-вызовов. `x-request-id` остаётся отдельным
|
||||
идентификатором запроса. Baggage не извлекается и не передаётся.
|
||||
API, MCP и исходящих REST-вызовов. Ровно один canonical parent принимается;
|
||||
duplicate, malformed, uppercase и zero-ID значения заменяются новым local
|
||||
trace без echo входа. `x-request-id` остаётся отдельным идентификатором
|
||||
запроса, а `x-trace-id` — безопасным локальным support ID. Caller
|
||||
`tracestate` ограничен 512 байтами/32 members, baggage — 8192 байтами/64
|
||||
members; Community allowlist пуста, поэтому они не извлекаются и не
|
||||
передаются.
|
||||
|
||||
Экспорт отключён по умолчанию: при пустых
|
||||
`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` и `OTEL_EXPORTER_OTLP_ENDPOINT`
|
||||
provider, batch processor и фоновый поток не создаются. После включения
|
||||
используется только OTLP/HTTP binary protobuf. Community Compose не включает
|
||||
Collector или хранилище трасс: оператор подключает внешний совместимый
|
||||
приёмник.
|
||||
`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` и `OTEL_EXPORTER_OTLP_ENDPOINT` local
|
||||
provider сохраняет span topology и Trace ID, но exporter, batch processor,
|
||||
фоновая очередь и сетевой трафик не создаются. Поэтому response, runtime и
|
||||
Invocation History получают Trace ID независимо от sampling/export. После
|
||||
включения используется только OTLP/HTTP binary protobuf. Community Compose
|
||||
не включает Collector или хранилище трасс: оператор подключает внешний
|
||||
совместимый приёмник.
|
||||
|
||||
Уровень эксплуатационных журналов не отключает трассы. В OTLP попадают
|
||||
только явно отмеченные spans с внутренней целью `crank::trace`; события
|
||||
|
||||
+81
-4
@@ -2,6 +2,70 @@
|
||||
|
||||
Crank настраивается через переменные окружения. Один и тот же набор переменных используется при запуске из исходников и при запуске готовых Docker-образов.
|
||||
|
||||
<!-- BEGIN GENERATED CRANK RUNTIME CONFIG -->
|
||||
|
||||
| Environment | Semantic path | Process | Type/unit | Default | Bounds | Sensitivity | Mode |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| `CRANK_DATABASE_URL` | `database.url` | `Shared` | `url/-` | `blank` | `-` | `Secret` | `Effective` |
|
||||
| `POSTGRES_HOST` | `database.host` | `Shared` | `string/-` | `postgres` | `-` | `Internal` | `Effective` |
|
||||
| `POSTGRES_PORT` | `database.port` | `Shared` | `u16/port` | `5432` | `1..=65535` | `Public` | `Effective` |
|
||||
| `POSTGRES_DB` | `database.name` | `Shared` | `string/-` | `crank` | `-` | `Internal` | `Effective` |
|
||||
| `POSTGRES_USER` | `database.user` | `Shared` | `string/-` | `crank` | `-` | `Internal` | `Effective` |
|
||||
| `POSTGRES_PASSWORD` | `database.password` | `Shared` | `secret/-` | `configured` | `-` | `Secret` | `Effective` |
|
||||
| `POSTGRES_MAX_CONNECTIONS` | `database.pool.max_connections` | `Shared` | `u32/connections` | `20` | `1..=1024` | `Public` | `Effective` |
|
||||
| `POSTGRES_MIN_CONNECTIONS` | `database.pool.min_connections` | `Shared` | `u32/connections` | `2` | `0..=1024` | `Public` | `Effective` |
|
||||
| `POSTGRES_ACQUIRE_TIMEOUT_MS` | `database.pool.acquire_timeout_ms` | `Shared` | `u64/milliseconds` | `5000` | `1..=300000` | `Public` | `Effective` |
|
||||
| `POSTGRES_IDLE_TIMEOUT_MS` | `database.pool.idle_timeout_ms` | `Shared` | `u64/milliseconds` | `600000` | `1000..=86400000` | `Public` | `Effective` |
|
||||
| `POSTGRES_MAX_LIFETIME_MS` | `database.pool.max_lifetime_ms` | `Shared` | `u64/milliseconds` | `1800000` | `1000..=86400000` | `Public` | `Effective` |
|
||||
| `CRANK_MASTER_KEY` | `runtime.master_key` | `Shared` | `secret/-` | `required/blank` | `-` | `Secret` | `Effective` |
|
||||
| `CRANK_BASE_URL` | `runtime.base_url` | `Shared` | `url/-` | `blank` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_RUNTIME_MAX_CONCURRENT_UNARY` | `runtime.max_concurrent_unary` | `Shared` | `u32/requests` | `64` | `1..=65535` | `Public` | `Effective` |
|
||||
| `CRANK_CACHE_BACKEND` | `cache.backend` | `Shared` | `enum/-` | `memory` | `-` | `Public` | `Effective` |
|
||||
| `CRANK_CACHE_URL` | `cache.url` | `Shared` | `url/-` | `blank` | `-` | `Secret` | `Effective` |
|
||||
| `CRANK_CACHE_DEFAULT_TTL_MS` | `cache.default_ttl_ms` | `Shared` | `u64/milliseconds` | `blank` | `1..=86400000` | `Public` | `DeprecatedNoEffect` |
|
||||
| `CRANK_OUTBOUND_ALLOWED_HOSTS` | `outbound.allowed_hosts` | `Shared` | `host_list/-` | `` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_OUTBOUND_DENIED_HOSTS` | `outbound.denied_hosts` | `Shared` | `host_list/-` | `` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_OUTBOUND_MAX_RESPONSE_BYTES` | `outbound.max_response_bytes` | `Shared` | `u64/bytes` | `4194304` | `1..=67108864` | `Public` | `Effective` |
|
||||
| `CRANK_ENVIRONMENT` | `observability.environment` | `Shared` | `label/-` | `development` | `-` | `Public` | `Effective` |
|
||||
| `CRANK_LOG_LEVEL` | `observability.log_filter` | `Shared` | `string/-` | `blank` | `-` | `Public` | `Effective` |
|
||||
| `CRANK_SENTRY_DSN` | `observability.sentry_dsn` | `Shared` | `url/-` | `blank` | `-` | `Secret` | `Effective` |
|
||||
| `CRANK_METRICS_ENABLED` | `observability.metrics.enabled` | `Shared` | `bool/-` | `true` | `-` | `Public` | `Effective` |
|
||||
| `CRANK_METRICS_BEARER_TOKEN` | `observability.metrics.bearer_token` | `Shared` | `secret/-` | `blank` | `-` | `Secret` | `Effective` |
|
||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `observability.otlp.endpoint` | `Shared` | `url/-` | `blank` | `-` | `Internal` | `Effective` |
|
||||
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | `observability.otlp.traces_endpoint` | `Shared` | `url/-` | `blank` | `-` | `Internal` | `Effective` |
|
||||
| `OTEL_EXPORTER_OTLP_PROTOCOL` | `observability.otlp.protocol` | `Shared` | `enum/-` | `http/protobuf` | `-` | `Public` | `Effective` |
|
||||
| `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` | `observability.otlp.traces_protocol` | `Shared` | `enum/-` | `blank` | `-` | `Public` | `Effective` |
|
||||
| `OTEL_EXPORTER_OTLP_TIMEOUT` | `observability.otlp.timeout` | `Shared` | `duration/milliseconds` | `10000` | `1..=300000` | `Public` | `Effective` |
|
||||
| `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | `observability.otlp.traces_timeout` | `Shared` | `duration/milliseconds` | `blank` | `1..=300000` | `Public` | `Effective` |
|
||||
| `OTEL_EXPORTER_OTLP_HEADERS` | `observability.otlp.headers` | `Shared` | `headers/-` | `blank` | `-` | `Secret` | `Effective` |
|
||||
| `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | `observability.otlp.traces_headers` | `Shared` | `headers/-` | `blank` | `-` | `Secret` | `Effective` |
|
||||
| `OTEL_BSP_MAX_QUEUE_SIZE` | `observability.otlp.max_queue_size` | `Shared` | `u32/spans` | `2048` | `1..=65536` | `Public` | `Effective` |
|
||||
| `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` | `observability.otlp.max_export_batch_size` | `Shared` | `u32/spans` | `512` | `1..=65536` | `Public` | `Effective` |
|
||||
| `OTEL_BSP_SCHEDULE_DELAY` | `observability.otlp.schedule_delay` | `Shared` | `duration/milliseconds` | `5000` | `1..=300000` | `Public` | `Effective` |
|
||||
| `OTEL_BSP_EXPORT_TIMEOUT` | `observability.otlp.export_timeout` | `Shared` | `duration/milliseconds` | `30000` | `1..=300000` | `Public` | `Effective` |
|
||||
| `CRANK_ADMIN_BIND` | `admin.bind` | `AdminApi` | `socket/-` | `0.0.0.0:3001` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_ADMIN_METRICS_BIND` | `admin.metrics_bind` | `AdminApi` | `socket/-` | `127.0.0.1:9464` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_STORAGE_ROOT` | `admin.storage_root` | `AdminApi` | `absolute_path/-` | `/var/lib/crank/storage` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_ADMIN_RATE_LIMIT_RPS` | `admin.rate_limit.rps` | `AdminApi` | `u32/requests_per_second` | `30` | `1..=100000` | `Public` | `Effective` |
|
||||
| `CRANK_ADMIN_RATE_LIMIT_BURST` | `admin.rate_limit.burst` | `AdminApi` | `u32/requests` | `60` | `1..=1000000` | `Public` | `Effective` |
|
||||
| `CRANK_INVOCATION_LOG_RETENTION_DAYS` | `admin.invocation_log_retention_days` | `AdminApi` | `u32/days` | `30` | `1..=36500` | `Public` | `Effective` |
|
||||
| `CRANK_SESSION_SECRET` | `admin.session.secret` | `AdminApi` | `secret/-` | `required/blank` | `-` | `Secret` | `Effective` |
|
||||
| `CRANK_PASSWORD_PEPPER` | `admin.password_pepper` | `AdminApi` | `secret/-` | `required/blank` | `-` | `Secret` | `Effective` |
|
||||
| `CRANK_SESSION_TTL_HOURS` | `admin.session.ttl_hours` | `AdminApi` | `u32/hours` | `24` | `1..=8760` | `Public` | `Effective` |
|
||||
| `CRANK_TRUST_FORWARDED_HEADERS` | `admin.trust_forwarded_headers` | `AdminApi` | `bool/-` | `false` | `-` | `Public` | `Effective` |
|
||||
| `CRANK_BOOTSTRAP_ADMIN_EMAIL` | `admin.bootstrap.email` | `AdminApi` | `string/-` | `required/blank` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_BOOTSTRAP_ADMIN_PASSWORD` | `admin.bootstrap.password` | `AdminApi` | `secret/-` | `required/blank` | `-` | `Secret` | `Effective` |
|
||||
| `CRANK_BOOTSTRAP_ADMIN_DISPLAY_NAME` | `admin.bootstrap.display_name` | `AdminApi` | `string/-` | `Crank Owner` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_DEMO_SEED` | `admin.demo_seed` | `AdminApi` | `bool/-` | `false` | `-` | `Public` | `Effective` |
|
||||
| `CRANK_MCP_BIND` | `mcp.bind` | `McpServer` | `socket/-` | `0.0.0.0:3002` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_MCP_METRICS_BIND` | `mcp.metrics_bind` | `McpServer` | `socket/-` | `127.0.0.1:9465` | `-` | `Internal` | `Effective` |
|
||||
| `CRANK_MCP_REFRESH_MS` | `mcp.refresh_ms` | `McpServer` | `u64/milliseconds` | `5000` | `100..=3600000` | `Public` | `Effective` |
|
||||
| `CRANK_MCP_RATE_LIMIT_RPS` | `mcp.rate_limit.rps` | `McpServer` | `u32/requests_per_second` | `60` | `1..=100000` | `Public` | `Effective` |
|
||||
| `CRANK_MCP_RATE_LIMIT_BURST` | `mcp.rate_limit.burst` | `McpServer` | `u32/requests` | `120` | `1..=1000000` | `Public` | `Effective` |
|
||||
| `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS` | `runtime.max_concurrent_sessions` | `McpServer` | `u32/sessions` | `16` | `1..=65535` | `Public` | `Effective` |
|
||||
|
||||
<!-- END GENERATED CRANK RUNTIME CONFIG -->
|
||||
|
||||
## PostgreSQL
|
||||
|
||||
Обязательные параметры:
|
||||
@@ -22,6 +86,13 @@ Crank настраивается через переменные окружен
|
||||
|
||||
Если используется PgBouncer, укажите его адрес в `POSTGRES_HOST` и порт в `POSTGRES_PORT`.
|
||||
|
||||
`CRANK_DATABASE_URL` — compatibility-форма для существующих установок. Она
|
||||
содержит credentials и поэтому никогда не выводится в diagnostics или
|
||||
fingerprint. URL нельзя смешивать с явно заданными `POSTGRES_HOST`,
|
||||
`POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER` или `POSTGRES_PASSWORD`:
|
||||
конфликт останавливает startup. Для новых установок canonical-формой остаются
|
||||
раздельные `POSTGRES_*` параметры.
|
||||
|
||||
## HTTP-сервисы
|
||||
|
||||
- `CRANK_ADMIN_BIND` - адрес `admin-api`, например `0.0.0.0:3001`.
|
||||
@@ -79,11 +150,9 @@ Demo seed идемпотентный: повторный старт не соз
|
||||
## Runtime limits
|
||||
|
||||
- `CRANK_RUNTIME_MAX_CONCURRENT_UNARY`
|
||||
- `CRANK_RUNTIME_MAX_CONCURRENT_WINDOW`
|
||||
- `CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS`
|
||||
- `CRANK_RUNTIME_MAX_CONCURRENT_JOBS`
|
||||
|
||||
Эти настройки ограничивают параллельное выполнение операций и служебных задач.
|
||||
Эти настройки ограничивают параллельное выполнение unary-запросов и MCP-сессий.
|
||||
|
||||
## Исходящие HTTP-запросы
|
||||
|
||||
@@ -124,9 +193,12 @@ CRANK_CACHE_BACKEND=memory
|
||||
```env
|
||||
CRANK_CACHE_BACKEND=valkey
|
||||
CRANK_CACHE_URL=redis://valkey:6379/0
|
||||
CRANK_CACHE_DEFAULT_TTL_MS=60000
|
||||
```
|
||||
|
||||
`CRANK_CACHE_DEFAULT_TTL_MS` в прежних шаблонах не имел runtime consumer.
|
||||
Непустое значение теперь отклоняется как deprecated no-effect configuration;
|
||||
TTL задаётся владельцем конкретного cache operation.
|
||||
|
||||
Внешний кэш используется для служебного краткоживущего состояния: rate limiting, replay guard и опубликованные каталоги MCP-инструментов.
|
||||
|
||||
## Логи
|
||||
@@ -141,6 +213,11 @@ CRANK_CACHE_DEFAULT_TTL_MS=60000
|
||||
Поля с паролями, токенами, ключами, cookie, authorization, query, полным телом
|
||||
или результатом очищаются до сериализации.
|
||||
|
||||
`crank-migrate` использует только database-поля этого контракта. Ему не
|
||||
требуются и не должны передаваться master key, session/bootstrap secrets,
|
||||
runtime, metrics или OTLP configuration. Команды и recovery contract описаны
|
||||
в [migrations.md](migrations.md).
|
||||
|
||||
Пример:
|
||||
|
||||
```env
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://crank.local/schemas/capability-baseline.schema.json",
|
||||
"title": "Crank Community Capability Baseline Manifest",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schema_version",
|
||||
"baseline_version",
|
||||
"artifacts"
|
||||
],
|
||||
"properties": {
|
||||
"schema_version": {
|
||||
"const": 1
|
||||
},
|
||||
"baseline_version": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]{4}\\.[0-9]{2}\\.[0-9]{2}\\.[1-9][0-9]*$"
|
||||
},
|
||||
"artifacts": {
|
||||
"type": "array",
|
||||
"minItems": 5,
|
||||
"maxItems": 5,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"$ref": "#/$defs/artifact"
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"artifact": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"kind",
|
||||
"path",
|
||||
"sha256"
|
||||
],
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"inventory",
|
||||
"required_surfaces",
|
||||
"taxonomy",
|
||||
"checklist",
|
||||
"results"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 1024,
|
||||
"pattern": "^(?!/)(?!.*//)(?!.*(?:^|/)\\.\\.?($|/))(?!.*\\\\).+$"
|
||||
},
|
||||
"sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9a-f]{64}$"
|
||||
}
|
||||
}
|
||||
},
|
||||
"taxonomy": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["baseline_version", "implementation_statuses", "execution_verdicts", "evidence_modes", "full_pass"],
|
||||
"properties": {
|
||||
"baseline_version": {"type": "string", "pattern": "^[0-9]{4}\\.[0-9]{2}\\.[0-9]{2}\\.[1-9][0-9]*$"},
|
||||
"implementation_statuses": {"type": "array", "minItems": 4, "maxItems": 4, "uniqueItems": true, "items": {"enum": ["implemented", "planned", "gap", "blocked"]}},
|
||||
"execution_verdicts": {"type": "array", "minItems": 6, "maxItems": 6, "uniqueItems": true, "items": {"enum": ["pass", "fail", "blocked", "skipped", "flaky", "not_run"]}},
|
||||
"evidence_modes": {"type": "array", "minItems": 2, "maxItems": 2, "uniqueItems": true, "items": {"enum": ["automated", "manual_only"]}},
|
||||
"manual_only_rule": {"type": "string", "minLength": 1, "maxLength": 2048},
|
||||
"non_pass_rule": {"type": "string", "minLength": 1, "maxLength": 2048},
|
||||
"full_pass": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["implementation_status", "execution_verdict", "evidence_mode"],
|
||||
"properties": {
|
||||
"implementation_status": {"const": "implemented"},
|
||||
"execution_verdict": {"const": "pass"},
|
||||
"evidence_mode": {"const": "automated"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "command_id", "flow_ids", "execution_verdict", "evidence_mode", "accepted", "source_report_sha256", "source_revision", "environment_class", "collector"],
|
||||
"properties": {
|
||||
"id": {"type": "string", "minLength": 1, "maxLength": 128},
|
||||
"command_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
||||
"flow_ids": {"type": "array", "minItems": 1, "maxItems": 1000, "uniqueItems": true, "items": {"type": "string", "minLength": 1, "maxLength": 128}},
|
||||
"execution_verdict": {"enum": ["pass", "fail", "blocked", "skipped", "flaky", "not_run"]},
|
||||
"evidence_mode": {"enum": ["automated", "manual_only"]},
|
||||
"accepted": {"type": "boolean"},
|
||||
"source_report_sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
|
||||
"source_revision": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
|
||||
"environment_class": {"type": "string", "minLength": 1, "maxLength": 64},
|
||||
"collector": {"const": "capability-baseline-collector-v1"},
|
||||
"summary": {"type": "object", "maxProperties": 16},
|
||||
"safe_outcome": {"type": "object", "maxProperties": 16}
|
||||
}
|
||||
},
|
||||
"defect": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "severity", "steps", "contract", "owner", "flow_ids", "next_action"],
|
||||
"properties": {
|
||||
"id": {"type": "string", "minLength": 1, "maxLength": 128},
|
||||
"severity": {"enum": ["Critical", "High", "Medium", "Low"]},
|
||||
"steps": {"type": "array", "minItems": 1, "maxItems": 20, "items": {"type": "string", "minLength": 1, "maxLength": 1024}},
|
||||
"contract": {"type": "string", "minLength": 1, "maxLength": 2048},
|
||||
"owner": {"type": "string", "minLength": 1, "maxLength": 128},
|
||||
"flow_ids": {"type": "array", "minItems": 1, "maxItems": 1000, "uniqueItems": true, "items": {"type": "string", "minLength": 1, "maxLength": 128}},
|
||||
"next_action": {"type": "string", "minLength": 1, "maxLength": 2048}
|
||||
}
|
||||
},
|
||||
"manual_result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["check_id", "evidence_mode", "execution_verdict", "flow_ids", "next_evidence"],
|
||||
"properties": {
|
||||
"check_id": {"type": "string", "pattern": "^UI-[0-9]{2}$"},
|
||||
"evidence_mode": {"const": "manual_only"},
|
||||
"execution_verdict": {"enum": ["pass", "fail", "blocked", "skipped", "flaky", "not_run"]},
|
||||
"flow_ids": {"type": "array", "minItems": 1, "maxItems": 1000, "uniqueItems": true, "items": {"type": "string", "minLength": 1, "maxLength": 128}},
|
||||
"next_evidence": {"type": "string", "minLength": 1, "maxLength": 2048}
|
||||
}
|
||||
},
|
||||
"results": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["baseline_version", "source_revision", "environment_class", "runs", "manual_results", "defects"],
|
||||
"properties": {
|
||||
"baseline_version": {"type": "string", "maxLength": 32},
|
||||
"source_revision": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
|
||||
"environment_class": {"type": "string", "minLength": 1, "maxLength": 64},
|
||||
"runs": {"type": "array", "maxItems": 1000, "items": {"$ref": "#/$defs/run"}},
|
||||
"manual_results": {"type": "array", "maxItems": 1000, "items": {"$ref": "#/$defs/manual_result"}},
|
||||
"defects": {"type": "array", "maxItems": 1000, "items": {"$ref": "#/$defs/defect"}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://crank.local/schemas/capability-inventory.schema.json",
|
||||
"title": "Crank Community Capability Inventory",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schema_version",
|
||||
"product",
|
||||
"flows"
|
||||
],
|
||||
"properties": {
|
||||
"schema_version": {
|
||||
"const": 1
|
||||
},
|
||||
"product": {
|
||||
"const": "crank-community"
|
||||
},
|
||||
"flows": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 10000,
|
||||
"items": {
|
||||
"$ref": "#/$defs/flow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"flow": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"id",
|
||||
"type",
|
||||
"requirements",
|
||||
"user_outcome",
|
||||
"owner",
|
||||
"status",
|
||||
"capabilities",
|
||||
"evidence"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 128,
|
||||
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"ui",
|
||||
"api",
|
||||
"mcp"
|
||||
]
|
||||
},
|
||||
"requirements": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 64,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 128,
|
||||
"pattern": "^FR-[1-9][0-9]*$"
|
||||
}
|
||||
},
|
||||
"user_outcome": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 4096,
|
||||
"pattern": "[\\s\\S]*\\S[\\s\\S]*"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 256,
|
||||
"pattern": "[\\s\\S]*\\S[\\s\\S]*"
|
||||
},
|
||||
"status": {
|
||||
"enum": [
|
||||
"implemented",
|
||||
"planned",
|
||||
"gap",
|
||||
"blocked"
|
||||
]
|
||||
},
|
||||
"capabilities": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 16,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"enum": [
|
||||
"tools",
|
||||
"resources",
|
||||
"prompts",
|
||||
"tasks",
|
||||
"load_runs"
|
||||
]
|
||||
}
|
||||
},
|
||||
"evidence": {
|
||||
"$ref": "#/$defs/evidence"
|
||||
},
|
||||
"notes": {
|
||||
"type": "string",
|
||||
"maxLength": 4096
|
||||
}
|
||||
}
|
||||
},
|
||||
"evidence": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"automated",
|
||||
"manual"
|
||||
],
|
||||
"properties": {
|
||||
"automated": {
|
||||
"$ref": "#/$defs/evidencePaths"
|
||||
},
|
||||
"manual": {
|
||||
"$ref": "#/$defs/evidencePaths"
|
||||
}
|
||||
}
|
||||
},
|
||||
"evidencePaths": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 64,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 1024,
|
||||
"pattern": "^(?!/)(?!.*//)(?!.*(?:^|/)\\.\\.?($|/))(?!.*\\\\).+$"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"schema_version":1,"sequence":[{"backfill":{"kind":"none"},"checksum":"crank-community-baseline-v1","compatibility":"legacy-baseline","contract_evidence":null,"name":"community-baseline-v1","owner":"crank-registry","phase":"expand","readable_schema_max":1,"readable_schema_min":1,"source_digest":"eb1656fc5b4b5be9ee390d237d1d58e4b2274ae5ba9b7ba06a2f3f860dfda675","transactional":true,"version":1},{"backfill":{"kind":"none"},"checksum":"1908b97ca7fe8a85d146b0eebf007d5018a9ff406cb099614270f3428ec1db48","compatibility":"n-minus-one-readable","contract_evidence":null,"name":"legacy-consolidation-v2","owner":"crank-registry","phase":"expand","readable_schema_max":2,"readable_schema_min":1,"source_digest":"1908b97ca7fe8a85d146b0eebf007d5018a9ff406cb099614270f3428ec1db48","transactional":true,"version":2},{"backfill":{"kind":"none"},"checksum":"36487625503a8d4d8f18d5771c3c9b6705f845e267acbfcb7244c330f640cd94","compatibility":"n-minus-one-readable","contract_evidence":null,"name":"request-trace-identity-v3","owner":"crank-registry","phase":"expand","readable_schema_max":3,"readable_schema_min":2,"source_digest":"36487625503a8d4d8f18d5771c3c9b6705f845e267acbfcb7244c330f640cd94","transactional":true,"version":3}]}
|
||||
@@ -0,0 +1,898 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"generated_by": "crank-config",
|
||||
"fields": [
|
||||
{
|
||||
"semantic_path": "database.url",
|
||||
"env_name": "CRANK_DATABASE_URL",
|
||||
"process": "shared",
|
||||
"value_type": "url",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": "legacy URL form",
|
||||
"rules": [
|
||||
"takes precedence over generated default-valued POSTGRES_HOST/PORT/DB/USER/PASSWORD",
|
||||
"conflicts with any non-default decomposed database value"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.host",
|
||||
"env_name": "POSTGRES_HOST",
|
||||
"process": "shared",
|
||||
"value_type": "string",
|
||||
"unit": null,
|
||||
"default": "postgres",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.port",
|
||||
"env_name": "POSTGRES_PORT",
|
||||
"process": "shared",
|
||||
"value_type": "u16",
|
||||
"unit": "port",
|
||||
"default": "5432",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.name",
|
||||
"env_name": "POSTGRES_DB",
|
||||
"process": "shared",
|
||||
"value_type": "string",
|
||||
"unit": null,
|
||||
"default": "crank",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.user",
|
||||
"env_name": "POSTGRES_USER",
|
||||
"process": "shared",
|
||||
"value_type": "string",
|
||||
"unit": null,
|
||||
"default": "crank",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.password",
|
||||
"env_name": "POSTGRES_PASSWORD",
|
||||
"process": "shared",
|
||||
"value_type": "secret",
|
||||
"unit": null,
|
||||
"default": "configured",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.pool.max_connections",
|
||||
"env_name": "POSTGRES_MAX_CONNECTIONS",
|
||||
"process": "shared",
|
||||
"value_type": "u32",
|
||||
"unit": "connections",
|
||||
"default": "20",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 1024,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": [
|
||||
"must be >= min_connections"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.pool.min_connections",
|
||||
"env_name": "POSTGRES_MIN_CONNECTIONS",
|
||||
"process": "shared",
|
||||
"value_type": "u32",
|
||||
"unit": "connections",
|
||||
"default": "2",
|
||||
"required": false,
|
||||
"minimum": 0,
|
||||
"maximum": 1024,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": [
|
||||
"must be <= max_connections"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.pool.acquire_timeout_ms",
|
||||
"env_name": "POSTGRES_ACQUIRE_TIMEOUT_MS",
|
||||
"process": "shared",
|
||||
"value_type": "u64",
|
||||
"unit": "milliseconds",
|
||||
"default": "5000",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 300000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.pool.idle_timeout_ms",
|
||||
"env_name": "POSTGRES_IDLE_TIMEOUT_MS",
|
||||
"process": "shared",
|
||||
"value_type": "u64",
|
||||
"unit": "milliseconds",
|
||||
"default": "600000",
|
||||
"required": false,
|
||||
"minimum": 1000,
|
||||
"maximum": 86400000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "database.pool.max_lifetime_ms",
|
||||
"env_name": "POSTGRES_MAX_LIFETIME_MS",
|
||||
"process": "shared",
|
||||
"value_type": "u64",
|
||||
"unit": "milliseconds",
|
||||
"default": "1800000",
|
||||
"required": false,
|
||||
"minimum": 1000,
|
||||
"maximum": 86400000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "runtime.master_key",
|
||||
"env_name": "CRANK_MASTER_KEY",
|
||||
"process": "shared",
|
||||
"value_type": "secret",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": true,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "runtime.base_url",
|
||||
"env_name": "CRANK_BASE_URL",
|
||||
"process": "shared",
|
||||
"value_type": "url",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "runtime.max_concurrent_unary",
|
||||
"env_name": "CRANK_RUNTIME_MAX_CONCURRENT_UNARY",
|
||||
"process": "shared",
|
||||
"value_type": "u32",
|
||||
"unit": "requests",
|
||||
"default": "64",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "cache.backend",
|
||||
"env_name": "CRANK_CACHE_BACKEND",
|
||||
"process": "shared",
|
||||
"value_type": "enum",
|
||||
"unit": null,
|
||||
"default": "memory",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": "redis value is deprecated in favor of valkey",
|
||||
"rules": [
|
||||
"external backend requires cache.url"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "cache.url",
|
||||
"env_name": "CRANK_CACHE_URL",
|
||||
"process": "shared",
|
||||
"value_type": "url",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": [
|
||||
"forbidden with memory backend"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "cache.default_ttl_ms",
|
||||
"env_name": "CRANK_CACHE_DEFAULT_TTL_MS",
|
||||
"process": "shared",
|
||||
"value_type": "u64",
|
||||
"unit": "milliseconds",
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 86400000,
|
||||
"sensitivity": "public",
|
||||
"mode": "deprecated_no_effect",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "outbound.allowed_hosts",
|
||||
"env_name": "CRANK_OUTBOUND_ALLOWED_HOSTS",
|
||||
"process": "shared",
|
||||
"value_type": "host_list",
|
||||
"unit": null,
|
||||
"default": "",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "outbound.denied_hosts",
|
||||
"env_name": "CRANK_OUTBOUND_DENIED_HOSTS",
|
||||
"process": "shared",
|
||||
"value_type": "host_list",
|
||||
"unit": null,
|
||||
"default": "",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": [
|
||||
"deny entries override allow entries"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "outbound.max_response_bytes",
|
||||
"env_name": "CRANK_OUTBOUND_MAX_RESPONSE_BYTES",
|
||||
"process": "shared",
|
||||
"value_type": "u64",
|
||||
"unit": "bytes",
|
||||
"default": "4194304",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 67108864,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.environment",
|
||||
"env_name": "CRANK_ENVIRONMENT",
|
||||
"process": "shared",
|
||||
"value_type": "label",
|
||||
"unit": null,
|
||||
"default": "development",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.log_filter",
|
||||
"env_name": "CRANK_LOG_LEVEL",
|
||||
"process": "shared",
|
||||
"value_type": "string",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.sentry_dsn",
|
||||
"env_name": "CRANK_SENTRY_DSN",
|
||||
"process": "shared",
|
||||
"value_type": "url",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.metrics.enabled",
|
||||
"env_name": "CRANK_METRICS_ENABLED",
|
||||
"process": "shared",
|
||||
"value_type": "bool",
|
||||
"unit": null,
|
||||
"default": "true",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": "yes/no/on/off spellings are deprecated",
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.metrics.bearer_token",
|
||||
"env_name": "CRANK_METRICS_BEARER_TOKEN",
|
||||
"process": "shared",
|
||||
"value_type": "secret",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": [
|
||||
"required when an enabled metrics bind is non-loopback"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.endpoint",
|
||||
"env_name": "OTEL_EXPORTER_OTLP_ENDPOINT",
|
||||
"process": "shared",
|
||||
"value_type": "url",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.traces_endpoint",
|
||||
"env_name": "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
|
||||
"process": "shared",
|
||||
"value_type": "url",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": [
|
||||
"overrides generic OTLP endpoint"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.protocol",
|
||||
"env_name": "OTEL_EXPORTER_OTLP_PROTOCOL",
|
||||
"process": "shared",
|
||||
"value_type": "enum",
|
||||
"unit": null,
|
||||
"default": "http/protobuf",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.traces_protocol",
|
||||
"env_name": "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL",
|
||||
"process": "shared",
|
||||
"value_type": "enum",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.timeout",
|
||||
"env_name": "OTEL_EXPORTER_OTLP_TIMEOUT",
|
||||
"process": "shared",
|
||||
"value_type": "duration",
|
||||
"unit": "milliseconds",
|
||||
"default": "10000",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 300000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.traces_timeout",
|
||||
"env_name": "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT",
|
||||
"process": "shared",
|
||||
"value_type": "duration",
|
||||
"unit": "milliseconds",
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 300000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.headers",
|
||||
"env_name": "OTEL_EXPORTER_OTLP_HEADERS",
|
||||
"process": "shared",
|
||||
"value_type": "headers",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.traces_headers",
|
||||
"env_name": "OTEL_EXPORTER_OTLP_TRACES_HEADERS",
|
||||
"process": "shared",
|
||||
"value_type": "headers",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.max_queue_size",
|
||||
"env_name": "OTEL_BSP_MAX_QUEUE_SIZE",
|
||||
"process": "shared",
|
||||
"value_type": "u32",
|
||||
"unit": "spans",
|
||||
"default": "2048",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 65536,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.max_export_batch_size",
|
||||
"env_name": "OTEL_BSP_MAX_EXPORT_BATCH_SIZE",
|
||||
"process": "shared",
|
||||
"value_type": "u32",
|
||||
"unit": "spans",
|
||||
"default": "512",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 65536,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": [
|
||||
"must be <= max_queue_size"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.schedule_delay",
|
||||
"env_name": "OTEL_BSP_SCHEDULE_DELAY",
|
||||
"process": "shared",
|
||||
"value_type": "duration",
|
||||
"unit": "milliseconds",
|
||||
"default": "5000",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 300000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "observability.otlp.export_timeout",
|
||||
"env_name": "OTEL_BSP_EXPORT_TIMEOUT",
|
||||
"process": "shared",
|
||||
"value_type": "duration",
|
||||
"unit": "milliseconds",
|
||||
"default": "30000",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 300000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.bind",
|
||||
"env_name": "CRANK_ADMIN_BIND",
|
||||
"process": "admin_api",
|
||||
"value_type": "socket",
|
||||
"unit": null,
|
||||
"default": "0.0.0.0:3001",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.metrics_bind",
|
||||
"env_name": "CRANK_ADMIN_METRICS_BIND",
|
||||
"process": "admin_api",
|
||||
"value_type": "socket",
|
||||
"unit": null,
|
||||
"default": "127.0.0.1:9464",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.storage_root",
|
||||
"env_name": "CRANK_STORAGE_ROOT",
|
||||
"process": "admin_api",
|
||||
"value_type": "absolute_path",
|
||||
"unit": null,
|
||||
"default": "/var/lib/crank/storage",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.rate_limit.rps",
|
||||
"env_name": "CRANK_ADMIN_RATE_LIMIT_RPS",
|
||||
"process": "admin_api",
|
||||
"value_type": "u32",
|
||||
"unit": "requests_per_second",
|
||||
"default": "30",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 100000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.rate_limit.burst",
|
||||
"env_name": "CRANK_ADMIN_RATE_LIMIT_BURST",
|
||||
"process": "admin_api",
|
||||
"value_type": "u32",
|
||||
"unit": "requests",
|
||||
"default": "60",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 1000000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": [
|
||||
"must be >= admin rate RPS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.invocation_log_retention_days",
|
||||
"env_name": "CRANK_INVOCATION_LOG_RETENTION_DAYS",
|
||||
"process": "admin_api",
|
||||
"value_type": "u32",
|
||||
"unit": "days",
|
||||
"default": "30",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 36500,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.session.secret",
|
||||
"env_name": "CRANK_SESSION_SECRET",
|
||||
"process": "admin_api",
|
||||
"value_type": "secret",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": true,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.password_pepper",
|
||||
"env_name": "CRANK_PASSWORD_PEPPER",
|
||||
"process": "admin_api",
|
||||
"value_type": "secret",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": true,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.session.ttl_hours",
|
||||
"env_name": "CRANK_SESSION_TTL_HOURS",
|
||||
"process": "admin_api",
|
||||
"value_type": "u32",
|
||||
"unit": "hours",
|
||||
"default": "24",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 8760,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.trust_forwarded_headers",
|
||||
"env_name": "CRANK_TRUST_FORWARDED_HEADERS",
|
||||
"process": "admin_api",
|
||||
"value_type": "bool",
|
||||
"unit": null,
|
||||
"default": "false",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": "yes/no/on/off spellings are deprecated",
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.bootstrap.email",
|
||||
"env_name": "CRANK_BOOTSTRAP_ADMIN_EMAIL",
|
||||
"process": "admin_api",
|
||||
"value_type": "string",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": true,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.bootstrap.password",
|
||||
"env_name": "CRANK_BOOTSTRAP_ADMIN_PASSWORD",
|
||||
"process": "admin_api",
|
||||
"value_type": "secret",
|
||||
"unit": null,
|
||||
"default": null,
|
||||
"required": true,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "secret",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.bootstrap.display_name",
|
||||
"env_name": "CRANK_BOOTSTRAP_ADMIN_DISPLAY_NAME",
|
||||
"process": "admin_api",
|
||||
"value_type": "string",
|
||||
"unit": null,
|
||||
"default": "Crank Owner",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "admin.demo_seed",
|
||||
"env_name": "CRANK_DEMO_SEED",
|
||||
"process": "admin_api",
|
||||
"value_type": "bool",
|
||||
"unit": null,
|
||||
"default": "false",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": "yes/no/on/off spellings are deprecated",
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "mcp.bind",
|
||||
"env_name": "CRANK_MCP_BIND",
|
||||
"process": "mcp_server",
|
||||
"value_type": "socket",
|
||||
"unit": null,
|
||||
"default": "0.0.0.0:3002",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "mcp.metrics_bind",
|
||||
"env_name": "CRANK_MCP_METRICS_BIND",
|
||||
"process": "mcp_server",
|
||||
"value_type": "socket",
|
||||
"unit": null,
|
||||
"default": "127.0.0.1:9465",
|
||||
"required": false,
|
||||
"minimum": null,
|
||||
"maximum": null,
|
||||
"sensitivity": "internal",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "mcp.refresh_ms",
|
||||
"env_name": "CRANK_MCP_REFRESH_MS",
|
||||
"process": "mcp_server",
|
||||
"value_type": "u64",
|
||||
"unit": "milliseconds",
|
||||
"default": "5000",
|
||||
"required": false,
|
||||
"minimum": 100,
|
||||
"maximum": 3600000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "mcp.rate_limit.rps",
|
||||
"env_name": "CRANK_MCP_RATE_LIMIT_RPS",
|
||||
"process": "mcp_server",
|
||||
"value_type": "u32",
|
||||
"unit": "requests_per_second",
|
||||
"default": "60",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 100000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
},
|
||||
{
|
||||
"semantic_path": "mcp.rate_limit.burst",
|
||||
"env_name": "CRANK_MCP_RATE_LIMIT_BURST",
|
||||
"process": "mcp_server",
|
||||
"value_type": "u32",
|
||||
"unit": "requests",
|
||||
"default": "120",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 1000000,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": [
|
||||
"must be >= MCP rate RPS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"semantic_path": "runtime.max_concurrent_sessions",
|
||||
"env_name": "CRANK_RUNTIME_MAX_CONCURRENT_SESSIONS",
|
||||
"process": "mcp_server",
|
||||
"value_type": "u32",
|
||||
"unit": "sessions",
|
||||
"default": "16",
|
||||
"required": false,
|
||||
"minimum": 1,
|
||||
"maximum": 65535,
|
||||
"sensitivity": "public",
|
||||
"mode": "effective",
|
||||
"compatibility": null,
|
||||
"rules": []
|
||||
}
|
||||
],
|
||||
"deployment_only_fields": [
|
||||
"COMPOSE_PROJECT_NAME",
|
||||
"POSTGRES_PUBLISH_BIND",
|
||||
"POSTGRES_PUBLISH_PORT",
|
||||
"CRANK_ADMIN_API_IMAGE",
|
||||
"CRANK_MCP_SERVER_IMAGE",
|
||||
"CRANK_UI_IMAGE",
|
||||
"CRANK_PUBLISH_BIND",
|
||||
"CRANK_ADMIN_PUBLISH_PORT",
|
||||
"CRANK_MCP_PUBLISH_PORT",
|
||||
"CRANK_UI_PUBLISH_PORT",
|
||||
"VALKEY_PUBLISH_BIND",
|
||||
"VALKEY_PUBLISH_PORT"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user