Skip to main content

threadlight-safe-check

Use when a Threadlight pilot needs design, pre-deploy or post-deploy completeness checks: manifest drift, missing resources, orphan modules, placeholder images, failed jobs, missing telemetry, or selected runtime governance requiring deployed enforcement evidence. Not for deployment orchestration (threadlight-deploy) or general agent evaluations (foundry-evals).

설치로 이동

소스 정보

저장소
aiappsgbb/threadlight-skills
최근 소스 활동
2026년 9월 25일 12:59
감지된 SKILL.md 언어
영어
스타
1
포크
5

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
22 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
threadlight-safe-check
description
Use when a Threadlight pilot needs design, pre-deploy or post-deploy completeness checks: manifest drift, missing resources, orphan modules, placeholder images, failed jobs, missing telemetry, or selected runtime governance requiring deployed enforcement evidence. Not for deployment orchestration (threadlight-deploy) or general agent evaluations (foundry-evals).
metadata
{"version":"1.4.0"}
## Presenter-ready consumer gate An explicit `delivery_profile: presenter-ready` adds the [presenter-ready contract](../../docs/presenter-ready.md), consumed from a complete catalog with `skills/_shared`. Design, Deploy and this checker use the same [`presenter-deployment-pin.json`](../_shared/presenter-deployment-pin.json). Validate the selected consumer's real manifest location, protocol, environment list/map and runtime root; reject active competing manifests. This profile's native layout supersedes the legacy `agent.yaml`/mandatory-Bicep assumptions below, not existing resource, reachability or selected-governance gates. Pre-deploy validates the packaged service inventory. Post-deploy retains its live checks and separately consumes process journey evidence; a green completeness manifest does not imply script-verified or human-accepted. Use `python3 -m skills._shared.presenter --root <pilot>` for that read-only assessment. # Threadlight Safe Check — three lifecycle gates, one CLI The single mandatory completeness gate for any threadlight pilot. Replaces ad-hoc Phase 3 / Phase 3.5 checks scattered through `threadlight-deploy` with one consolidated CLI you invoke at three lifecycle points: ``` post-design → SPEC <-> manifest.json deployment_manifest contract pre-deploy → manifest <-> azure.yaml services <-> infra/main.bicep <-> src/<dir>/ post-deploy → manifest <-> az resource list <-> channel reachability ``` > **Why this skill exists.** A recent investigation-style PoC > shipped with **`aca-bot: yes`, `aca-job: yes`, `workspace-ui: yes`** > in SPEC § 11c — and zero bot resources, zero jobs, zero workspace ACAs > in the deployed resource group. `azd up` returned 0. Eval scores > looked plausible. The gap was caught by the user opening the Azure > Portal and noticing missing tiles. **A consolidated, mandatory gate > would have caught this in 30 seconds.** That gate is this skill. > > **And then it shipped again, differently.** A later pilot > using the `fetch-container-image` pattern had every resource type > present in the resource group — > `safe-check` returned `gaps: []` ✅ — but the MCP container was > running `mcr.microsoft.com/azuredocs/containerapps-helloworld:latest` > (Bicep had hard-coded the placeholder; `azd deploy mcp` was never > run after the provision), and the deadline-watcher cron had > 13 consecutive `Failed` executions. Structural-only checks aren't > enough. The post-deploy phase now also runs **behavioural** checks: > deployed images must NOT match the azuredocs placeholder regex, > and no scheduled job may have its last 5 executions all `Failed`. ## What this skill does NOT replace - **Invocation testing** of the agent → use `foundry-evals` - **Authoring** the manifest → use `threadlight-design` (its `deployment_manifest{}` JSON block in `specs/manifest.json` is the contract this skill consumes) - **Running `azd up`** → use `threadlight-deploy`. This skill is invoked **before** and **after** `azd up`, never instead of. ## When to invoke | Lifecycle point | Phase | What's checked | Gate result | |---|---|---|---| | After SPEC + AGENTS.md drafted | `--phase design` | `specs/manifest.json` contains `deployment_manifest{}`; SPEC § 11c rows match `module_selectors` keys | Drift / fail | | Before `azd up` | `--phase pre-deploy` | Every `yes` selector → wired in `azure.yaml` + `infra/main.bicep` + has `src/<dir>/Dockerfile`; no orphan Bicep / src folders | Fail-fast | | After `azd up` returns 0 | `--phase post-deploy` | Every `expected_resource_types` entry in `az resource list`; required ACA roles by name pattern; **every deployed image is the real image (NOT the azuredocs placeholder)**; **no scheduled job has its last 5 executions all `Failed`**; all `channels` reach HTTP/JWT-OK; `scheduled_jobs` cron correct | **The non-negotiable gate.** Empty `gaps[]` = PoC complete | Each phase emits a JSON manifest under `tests/` so the gate is auditable and re-readable later (CI, demo prep, postmortem): - `tests/safe-check-design-manifest.json` - `tests/safe-check-predeploy-manifest.json` - `tests/postdeploy-manifest.json` *(name preserved for backwards-compat with the prior `threadlight-deploy` Phase 3.5 manifest)* All three manifests have a top-level `"gaps": []`. **Empty array = pass.** ## Selected runtime governance The host protocol and enforcement producer are separate selections. MAF Responses can use the gateway producer for an explicitly generated gateway-only contract; it must not be treated as a local Agent Hooks producer. Static checks retain the actual MAF host/helper and staged signed gateway association. No native-probe assets or native database permissions are inferred from the framework name. This changes routing, not the proof boundary: `governance_probe_noop` never proves a business write, OBO or long-lived approval. When the SPEC selects governance, resource presence alone is insufficient. Explicit `off` and unselected legacy projects add no governance network calls. Invalid selected configuration is not off: it fails closed. Legacy v2 evidence never passes new runtime readiness. This is binding evidence, **not whole-agent** certification. - **Pre-deploy:** verify the exact selected adapter, packaged code/configuration, bundle integrity, required controls and service bindings. Before an image exists, record `pre-image` and explicit unverified image/deployment facts; never call a static declaration enforced. Intentionally unbound read tools are not missing adapters and must not be auto-selected or removed. - **Post-deploy:** use the installed collector and the operator's protected `.threadlight/governance-probe.json`. A Key Vault verified registry must explicitly declare **`probe_safe: true`** for **`governance_probe_noop`**. Without it, do not invoke the model or improvise a business operation, even with `--force`. Missing setup is an unverified governance gap. - Register fresh, independent allow/deny UUIDs at both producer and fixture before invoking the actual hosted agent. Require terminal producer states, an authenticated Task 8 receipt, one allow effect and zero deny effects. Ignored prompts, replay, unavailable dependencies, wrong scope or changed deployment remain unverified. Model text is never an oracle. - Dedicated noop proof **cannot certify business bindings** or other lifecycle points. Those remain unverified without their own explicit safe live evidence. Do not promote local tests, CTK results or packaging into deployed proof. - Preserve every existing non-governance gap. `governance_health`, `governance_probes` and `governance_gaps` supplement—not replace—`gaps`. Saved collector JSON is payload-free evidence, **not remote attestation**. See [collector installation, inputs and limits](references/governance-probe.md) and the [actual producer contract](references/probe-fixture/README.md). The collector independently observes ARM/Foundry tenant/subscription/RG, version/image/principal and closed configuration before and after invocation. Pin the parent with `--subscription` and `--rg`; constrain tenant through the deployment manifest and independently checked account context. Never derive the expected parent from the probe configuration. Every deployment attempt needs fresh after-deployment proof, not current mtime or a reused nonce. Readiness rechecks the full signed envelope/key, bundle and current configuration against previously verified evidence. Changed signatures invalidate it. Required audit uses remote ACK; local overlay fsync is not hosted durability. --- ## Kratos-export adaptation (manifest still required) A **Kratos-exported project** (`src/hosted-agent/` + `use-cases/<x>/`, trimmed `infra/`) can be adapted by the **coding agent**. The Python gate still requires a manifest; recognizing the directory shape does not bypass `_load_manifest`. See [`docs/KRATOS-BRIDGE.md`](../../docs/KRATOS-BRIDGE.md#adapt-before-safe-check). - **Author the deployment contract explicitly.** Inspect compiled Bicep, `azure.yaml` and use-case sources. Use the [`threadlight-design` manifest schema/example](../threadlight-design/SKILL.md#5-specsmanifestjson) to create `specs/manifest.json` with a `deployment_manifest` object and reviewed resource types, selectors, services/roles, integrations, jobs and channels. Run `threadlight-safe-check --phase design --manifest specs/manifest.json` from the export root after installing the supported package. - **There is no `--from-infra` flag.** Missing/invalid manifest or missing `deployment_manifest` still means **exit code 2**. Do not fabricate empty manifests or postdeploy proof. - **Trimmed infra is intentional, not automatically passing.** Do not add APIM/frontend expectations merely because another template has them; retain any actually selected customer network/governance requirement. Derive `required_aca_roles` from deployed Container App resources, not from the presence of a hosted-agent source directory. - **`evals/` absence is expected** pre-backfill (Kratos `_SKIP_DIRS`); it is not a deploy defect. `threadlight-deploy` Kratos-export mode backfills it. After adaptation, run postdeploy with `--manifest specs/manifest.json`, explicit approved `--subscription` / `--rg`, and review `tests/postdeploy-manifest.json`. The gate still fails genuine contract gaps; omission from the export does not waive readiness obligations. --- ## CLI ```bash # From repo root python3 tests/safe_check.py --phase design # after threadlight-design Phase 1-3 python3 tests/safe_check.py --phase pre-deploy # immediately before azd up python3 tests/safe_check.py --phase post-deploy # immediately after azd up returns 0 ``` Exit codes: | Code | Meaning | |---|---| | `0` | Gate passed (gaps empty) | | `1` | Gate failed (gaps non-empty); manifest written with details | | `2` | Missing prerequisite (no `specs/manifest.json`, no `deployment_manifest{}` block, env vars missing) | | `3` | Tooling error (Azure auth, `az` not on PATH, etc.) | Optional flags: ```bash --rg <name> # override AZURE_RESOURCE_GROUP env var (post-deploy) --subscription <id-or-name> # post-deploy account; defaults to current CLI account --manifest <path> # override default specs/manifest.json --out <dir> # override default tests/ output dir --quiet # only print final OK / FAIL line + exit code ``` --- ## Files in this skill ``` threadlight-safe-check/ ├── SKILL.md (this file) ├── scripts/ │ └── safe_check.py (single-file Python module — the CLI) └── tests/ └── test_safe_check.py (integration_binding_gaps + example parity) ``` The legacy CLI remains a copyable file. Selected governance additionally requires the portable `threadlight-governance-safe-check` package; copying only the CLI never silently skips a selected governance gate. Run the shipped tests standalone (no pytest required): ```bash python3 skills/threadlight-safe-check/tests/test_safe_check.py # or, with pytest: python3 -m pytest skills/threadlight-safe-check/tests/ -q ``` `test_safe_check.py` also asserts the example copy shipped as `examples/returns-triage-governed/tests/safe_check.py` stays **byte-for-byte** identical to `scripts/safe_check.py`, so the two never drift. --- ## Phase 1 — `--phase design` (post-design check) **Inputs:** `specs/SPEC.md`, `specs/manifest.json` **Asserts:** 1. `specs/manifest.json` exists and parses as JSON. 2. Top-level `deployment_manifest{}` block present (added by `threadlight-design` Phase 3 — see `threadlight-design/SKILL.md` §3 for the schema). 3. `deployment_manifest.module_selectors` is a `dict[str, "yes"|"no"]` covering every selector named in SPEC § 11c table. 4. `deployment_manifest.services[]` lists every service that needs a container image; every entry has `name`, `host`, `src`. 5. `deployment_manifest.scheduled_jobs[]` listed iff `aca-job: yes`. 6. `deployment_manifest.channels[]` lists every Human Interaction channel from SPEC § 8. 7. `deployment_manifest.expected_resource_types[]` non-empty and contains the canonical `Microsoft.*` type for every `yes` selector per the table in **Selector → resource type map** below. **Common gaps caught:** - SPEC § 11c says `aca-bot: yes` but `module_selectors` doesn't list it (drift between SPEC text and manifest contract) - `services[]` references `src/workspace` but SPEC § 8 has no UI channel (orphan service) - `expected_resource_types[]` missing `Microsoft.BotService/botServices` even though `aca-bot: yes` (selector mapping incomplete) --- ## Phase 2 — `--phase pre-deploy` (pre-`azd up` check) **Inputs:** `specs/manifest.json`, `azure.yaml`, `infra/main.bicep`, `infra/**/*.bicep`, `src/**/Dockerfile` **Asserts:** Three-column matrix per `yes` selector — every column populated: | Selector | `azure.yaml` services | `infra/main.bicep` module ref | `src/<dir>/` Dockerfile | |---|---|---|---| | `aca-mcp` | `name: mcp`, `host: containerapp`, `project: ./src/mcp` | `module mcpApp '...container-app.bicep'` with `serviceName: 'mcp'` | `src/mcp/Dockerfile` + `server.py` | | `aca-bot` | `name: bot`, `host: containerapp`, `project: ./src/bot` | `module botApp '...container-app.bicep'` with `serviceName: 'bot'` **AND** `module botService 'bot/bot-service.bicep'` | `src/bot/Dockerfile` + `bot.py` + `app.py` + `teams_package/manifest.json` | | `aca-job` | `name: <job>`, `host: containerapp`, `project: ./src/jobs/<job>` | `module job 'jobs/aca-job.bicep'` (or equivalent under `infra/jobs/`) | `src/jobs/<job>/Dockerfile` + `main.py` (cron entrypoint) | | `workspace-ui` | `name: workspace`, `host: containerapp`, `project: ./src/workspace` | `module workspaceApp '...container-app.bicep'` with `serviceName: 'workspace'` | `src/workspace/Dockerfile` + ACA-served HTML/SPA. **NOT a static `index.html` only.** | | `foundry-iq-index` | n/a (provisioned by hook) | `module knowledge 'modules/ai-search.bicep'` (the index) | `scripts/postprovision.py` calls `provision_knowledge_base()` | Plus **two orphan checks** (caught orphan `infra/bot/aca.bicep` files left for an entire deploy cycle): 1. **Bicep-module orphan check.** Every `infra/<dir>/*.bicep` (excluding `core/`, `modules/`) must be referenced from `infra/main.bicep` via `module ... '<path>'`. Otherwise → orphan; either wire or delete. 2. **`src/`-folder orphan check.** Every `src/<dir>/` must map to a declared `azure.yaml` service (or be `src/agent/` which has its own host). Otherwise → orphan; either wire or delete. **Common gaps caught:** - `aca-bot: yes` but `azure.yaml` has no `bot` service → silent partial PoC - `infra/bot/aca.bicep` exists but no `module botApp` line in
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기