diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 669b6c50..bcb2f081 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,6 +38,14 @@ dotnet run --file src/catalogutil.cs -- ./docs/ ./outputs/ 대상 서비스의 이용 자체에 로그인이 필요한 것은 무방하지만, 설치 파일을 내려받기 위해 로그인이 필요한 항목은 수록하지 않습니다. +## 스킬의 필수 실행 의존성과 등재 기준 + +`main` 공개 카탈로그는 실제 테스트를 위해 BOK, KOSIS와 계산기의 고정 스크립트를 격리 평가 대상으로 제공합니다. 활성 항목 6개 중 기존 운영 호환 후보 3개와 스크립트 평가 후보 3개를 구분하며 스크립트 후보를 운영 호환성 통과로 승격하지 않습니다. [앱 PR #322](https://github.com/yourtablecloth/TableCloth/pull/322)는 아직 반영하지 않았으므로 현재 제품 대화는 설치한 스크립트의 자동 실행을 지원하지 않습니다. 실행 결과는 [AppContainer 평가 보고서](docs/APP_CONTAINER_POC.ko.md)와 [영문 보고서](docs/APP_CONTAINER_POC.md)에 기록합니다. 이 예외는 MCP 연결이나 사용자 자격 증명 경로의 접수 재개를 포함하지 않습니다. + +스킬 등록과 고정 버전 갱신에는 [현재 호스트의 등재 기준과 검증 기록](docs/SKILL_ELIGIBILITY.ko.md), [English criteria and verification](docs/SKILL_ELIGIBILITY.md)을 적용합니다. 현재 식탁보 대화는 `shell_tool=false`와 `unified_exec=false`를 유지하며 설치한 Python과 Node 스크립트 실행이나 MCP 서버 자동 설정을 지원하지 않습니다. 스크립트가 없는 진입점도 별도 MCP나 하위 스킬이 필수이면 실행 의존성을 기록합니다. 런타임 설치, `SKILL.md` 존재와 모델의 답변만으로 기능 실행 성공을 표시하지 않습니다. + +PR에는 고정 원본, 필수 실행 경로, 사용 가능한 호스트 기능, 설치와 발견 결과, 실제 실행한 범위와 미검증 범위를 구분해 적습니다. 현재 호스트가 필수 단계를 지원하지 않는 후보는 사유와 XML 블록 전체를 주석으로 보존합니다. 새 활성 ID와 `Source.Ref`는 검증 기록의 두 언어 문서 및 `src/testskills.cs`의 등재 허용 목록과 함께 검토합니다. 카탈로그 검사를 통과해도 원본 스킬의 실행 성공을 뜻하지 않습니다. + ## 환경 변수로 자격 증명을 받는 신규 스킬의 접수 보류 사용자 API 키, 토큰이나 클라이언트 시크릿을 환경 변수로 전달받는 신규 스킬의 등록 접수를 현재 보류합니다. 환경 변수의 비밀값은 평문 노출과 자식 프로세스 상속의 위험이 있으며 식탁보의 스킬별 자격 증명 저장 및 전달 기능은 아직 구현하지 않았습니다. [TableCloth #321](https://github.com/yourtablecloth/TableCloth/issues/321)의 대응 기능 개발과 검증을 마친 뒤 접수를 재개합니다. diff --git a/README.md b/README.md index 02434c99..233fc7de 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ - [docs/Catalog.xml](docs/Catalog.xml): 각 기관, 서비스 웹 사이트마다 필요로 하는 추가 소프트웨어들의 목록을 저장하고 관리하는 XML 파일입니다. - XML 파일 편집은 [Microsoft XML Notepad](https://microsoft.github.io/XmlNotepad/)를 사용하시는 것을 권장합니다. -- [docs/SkillCatalog.xml](docs/SkillCatalog.xml): 설치할 수 있는 원격 스킬과 고정 원본을 관리합니다. 항목 추가, 주석을 통한 제거 및 버전 갱신 방식은 [원격 스킬 카탈로그 안내](docs/SkillCatalog.README.ko.md)를 참고하실 수 있습니다. +- [docs/SkillCatalog.xml](docs/SkillCatalog.xml): 원격 스킬과 고정 원본을 관리합니다. `main` 공개 카탈로그는 실제 테스트를 위해 운영 후보 3개와 고정 스크립트 평가 후보 3개를 제공합니다. 스크립트 후보를 운영 호환성 통과로 승격하지 않습니다. [앱 PR #322](https://github.com/yourtablecloth/TableCloth/pull/322)는 아직 반영하지 않았으므로 현재 제품 대화는 설치한 스크립트의 자동 실행을 지원하지 않습니다. [AppContainer 평가 결과](docs/APP_CONTAINER_POC.ko.md), [English evaluation report](docs/APP_CONTAINER_POC.md)에서 실측과 미검증 범위를 설명합니다. [등재 기준과 기존 활성 8개 검증 기록](docs/SKILL_ELIGIBILITY.ko.md), [English criteria and verification](docs/SKILL_ELIGIBILITY.md)에서 파일 설치와 실제 실행 범위를 구분합니다. 항목 추가, 주석을 통한 보류 및 버전 갱신 방식은 [원격 스킬 카탈로그 안내](docs/SkillCatalog.README.ko.md)에서 설명합니다. - [docs/sites.xml](docs/sites.xml): Internet Explorer Mode로 띄우려는 웹 사이트들의 목록을 저장하고 관리하는 XML 파일입니다. (식탁보 0.5.5 버전부터 사용) - XML 파일 편집은 [Microsoft XML Notepad](https://microsoft.github.io/XmlNotepad/)를 사용하시는 것을 권장합니다. - Microsoft Edge 그룹 정책에서 주소를 직접 지정하여 설정을 적용할 수 있습니다. diff --git a/docs/APP_CONTAINER_POC.ko.md b/docs/APP_CONTAINER_POC.ko.md new file mode 100644 index 00000000..4961d581 --- /dev/null +++ b/docs/APP_CONTAINER_POC.ko.md @@ -0,0 +1,71 @@ +# AppContainer 스킬 평가 결과 + +[English](APP_CONTAINER_POC.md) | [스킬 등재 기준](SKILL_ELIGIBILITY.ko.md) | [카탈로그 관리 안내](SkillCatalog.README.ko.md) + +2026년 10월 25일에 AppContainer PoC는 Windows 빌드 26300 x64에서 중계기, 실행과 정책 검사 46개를 모두 통과했습니다. 별도의 Codex 0.156.1 검증은 고정된 로컬 Responses 응답 2회를 사용해 MCP와 AppContainer를 거친 계산기 호출을 완료했습니다. 실제 모델 추론과 인증은 수행하지 않았습니다. + +고정 스킬의 어댑터, 격리 실행, 공개 서비스 표본 조회, CLI 도구 연결과 보존한 증거를 설명합니다. `main` 공개 카탈로그는 실제 테스트를 위해 고정 스크립트 후보 3개를 제공합니다. 이번 결과로 해당 후보를 운영 호환성 통과로 승격하지 않습니다. + +공개 평가와 원본 범위부터 살펴보겠습니다. 이후 작업 프로세스의 제한, 측정 결과, Codex 연결, 증거 기록과 남은 검증을 순서대로 정리하겠습니다. + +## 공개 평가 카탈로그와 고정 원본의 범위 + +`main` 공개 카탈로그는 실제 테스트를 위해 기존 운영 후보 3개에 격리 평가용 고정 스크립트 후보 3개를 추가해 총 6개를 활성화합니다. 나머지 블록 9개는 주석을 유지합니다. 스크립트 후보의 공개가 운영 호환성 통과를 뜻하지는 않습니다. 식탁보 구현은 `poc/appcontainer-skill-runner` 분기의 [앱 PR #322](https://github.com/yourtablecloth/TableCloth/pull/322)에서 제공하며 아직 제품에 반영하지 않았습니다. 현재 제품 대화는 `shell_tool=false`와 `unified_exec=false`를 유지하며 이번 중계기의 자동 등록이나 설치한 스크립트의 자동 실행을 지원하지 않습니다. [카탈로그 등재 기준](SKILL_ELIGIBILITY.ko.md)과 [TableCloth #321](https://github.com/yourtablecloth/TableCloth/issues/321)의 자격 증명 접수 보류 정책도 계속 적용합니다. + +| 평가 스크립트 | 고정 원본 커밋 | 실행 경로의 변경 | +| --- | --- | --- | +| [BOK ECOS](https://github.com/NomaDamas/k-skill/tree/0102e5133865f00886e37ac8cf39a49e2c7a3d39/bok-ecos-stats) | `0102e5133865f00886e37ac8cf39a49e2c7a3d39` | 원본 `scripts/bok_ecos.py` 직접 호출 | +| [KOSIS](https://github.com/NomaDamas/k-skill/tree/0102e5133865f00886e37ac8cf39a49e2c7a3d39/kosis-stats) | `0102e5133865f00886e37ac8cf39a49e2c7a3d39` | 원본 `scripts/run_kosis_stats.py` 직접 호출 | +| [금융 및 생활 계산기](https://github.com/yourtablecloth/tablecloth-calculators/tree/877b58cf0741db21342445f2b3fcb54ad1ada85c) | `877b58cf0741db21342445f2b3fcb54ad1ada85c` | 원본 `scripts/calculate.py`에 stdin JSON 전달 | + +BOK와 KOSIS의 `SKILL.md`는 `npx` 지침 로더를 필수 단계로 안내합니다. 이번 실험에서는 고정 지침을 읽고 원본 Python 보조 스크립트를 수정 없이 직접 호출했습니다. 원래의 npm 로더 절차를 실행하거나 검증하지 않았습니다. Node.js는 고정한 로컬 fixture로 검사했으며 원본 npm 패키지를 실행하지 않았습니다. 구현 저장소의 `tools/appcontainer-skill-poc/skills/ORIGINS.json`은 원본 라이선스와 함께 보존한 파일 31개의 고정 Git blob 일치를 기록합니다. + +## 호스트 중계기와 작업 프로세스의 제한 + +호스트 소유 MCP 중계기는 등록한 ID와 크기를 제한한 JSON 입력만 받습니다. 모델이 지정한 실행 경로, 셸 명령이나 소스 코드는 받지 않습니다. 실행 직전에 인터프리터와 스크립트의 해시를 다시 검사합니다. Python은 `-I -S -B -X utf8`을 사용하며 Node fixture는 고정 진입 파일을 사용합니다. 네이티브 실행기는 AppContainer 토큰을 확인하고 소유 디렉터리의 ACL과 Job Object로 실행 시간, 메모리, 프로세스 수와 출력을 제한합니다. Microsoft의 [AppContainer 격리 문서](https://learn.microsoft.com/en-us/windows/win32/secauthz/appcontainer-isolation)에서 기반 자원 접근 모델을 설명합니다. + +일반 중계기는 네트워크 capability를 부여하지 않으며 네트워크가 필요한 등록을 거절합니다. 검증한 작업 프로세스는 소유한 임시 홈과 작업 디렉터리 및 비운 환경을 사용했습니다. 비공개 합성 파일 접근 거부, 상속 값 제외, 자식 프로세스 제한, UTF-8 왕복 처리, 취소, 시간과 메모리 및 출력 제한, 표본 ACL 원복과 실행별 작업 디렉터리 제거를 통과했습니다. 일반 AppContainer는 호스트 커널을 공유하며 ACL이 애플리케이션 패키지에 이미 허용한 호스트 자원은 접근할 수 있습니다. 이번 검사만으로 VM 수준의 경계나 모든 호스트 파일의 읽기 차단을 입증하지 않습니다. + +별도 공개 API 평가기는 호스트가 고정한 명령에 범용 `internetClient` capability를 부여했습니다. 도메인 허용 목록은 적용하지 않았습니다. 서비스 조회 성공만으로 모델이 임의 URL을 선택하는 네트워크 정책까지 검증하지는 않습니다. 작업 프로세스 검사나 카탈로그 활성화로 일반 셸, npm 설치나 임의 패키지 갱신을 허용하지 않습니다. + +## 실행 검사와 공개 서비스의 측정 결과 + +최종 평가 기록은 최상위 검사 수와 그 안에서 실행한 단위 테스트 수를 구분합니다. + +| 검증 | 관찰한 결과 | 범위 | +| --- | --- | --- | +| 오프라인 중계기 검사 | 20개 전체 통과 | 입력, 등록, 해시, 전송과 실패 처리 | +| 실행과 정책 검사 | 26개 전체 통과 | AppContainer의 Python과 Node, 대조군, 제한, 정리와 공개 서비스 2개 | +| 통합 평가 | 46개 전체 통과 | 앞선 20개와 26개의 합계 | +| 계산기 원본 단위 테스트 | 28개 전체 통과 | AppContainer에서 실행하며 최상위 26개 중 한 검사에 포함 | +| BOK 원본 단위 테스트 | 19개 전체 통과 | AppContainer에서 실행하며 최상위 26개 중 한 검사에 포함 | +| ManagedAi Release 회귀 검사 | 197개 전체 통과 | 별도로 다시 실행한 앱 회귀 검사 | + +계산기 사례는 할인, 퍼센트, 윤년 날짜 보정, 고정 시차의 날짜 경계 이동, BMI 수치와 금리 0% 대출을 포함했습니다. KOSIS의 고정 dry-run과 Node JSON fixture도 통과했습니다. 이 표본은 계산기 전체 연산이나 원래의 KOSIS 단위 테스트 전체를 포함하지 않습니다. + +실제 서비스 표본에서 [BOK 보조 스크립트](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/bok-ecos-stats/scripts/bok_ecos.py)는 공개 `sample` 키로 ECOS 결과 1행을 받았습니다. [KOSIS 보조 스크립트](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/kosis-stats/scripts/run_kosis_stats.py)는 공유 `k-skill-proxy.nomadamas.org`를 통해 `인구` 검색 결과 1행을 받았습니다. 사용자 API 키는 전달하지 않았습니다. 프록시 접근성과 서버 측 자격 증명은 외부 서비스에 의존합니다. KOSIS 직접 호출과 대용량 조회의 자격 증명 경로는 검사하지 않았습니다. + +## 고정된 로컬 응답을 사용한 실제 Codex 연결 + +고정 CLI는 계산기를 namespace `mcp__tablecloth_skill_poc`와 정규화한 함수 이름 `tablecloth_calculators`로 광고했습니다. 로컬 HTTP 수신기는 고정 함수 호출 하나를 반환하고 실제 도구 출력을 받은 뒤 최종 응답을 보냈습니다. CLI의 MCP 완료 이벤트는 원래 도구 이름 `tablecloth-calculators`를 기록했습니다. 작업 프로세스는 `wasAppContainer=true`, 종료 코드 0과 할인 결과 `80.00`을 반환했습니다. + +격리 프로필은 `approval_policy="never"`, `shell_tool=false`와 `unified_exec=false`를 유지했습니다. 호스트 소유의 등록한 계산기 한 개에만 도구별 `approval_mode="approve"`를 명시했습니다. 서버 기본값은 `prompt`이며 활성 도구 목록도 해당 계산기 한 개로 제한했습니다. 허위 읽기 전용 annotation은 사용하지 않았습니다. OpenAI의 [MCP 설정 안내](https://developers.openai.com/codex/mcp)에서 도구별 승인 제어를 설명하며 [함수 호출 안내](https://developers.openai.com/api/docs/guides/function-calling#defining-namespaces)에서 namespace 구성을 설명합니다. + +이번 실행은 loopback Responses 요청 2회, 실제 모델 추론 0회와 인증 시도 0회를 기록했습니다. 기존 인증을 복사하지 않았으며 새 Codex 홈에 인증 파일을 만들지 않았습니다. 설정, manifest와 계산기 해시도 유지했습니다. 미리 정한 응답으로 실제 CLI와 중계기의 연결 및 격리 실행을 검증한 범위로 한정합니다. 실제 모델의 도구 선택과 운영 식탁보 대화의 자동 실행은 미검증으로 남깁니다. + +## 증거 기록과 플랫폼 검증 범위 + +아래 기록은 로컬 식탁보 작업 공간의 `Artifacts/appcontainer-skill-poc/` 아래에 보존합니다. 카탈로그 게시 자산에는 포함하지 않습니다. 구현과 재현 안내는 식탁보 구현 분기의 `tools/appcontainer-skill-poc/`에서 관리합니다. + +| 기록 | SHA-256 | 기록 범위 | +| --- | --- | --- | +| `evaluation-public-api.json` | `5489b04ad12cbce500cfab5e41b904d113a00206e5fccd9829bce835fa48fdfa` | 실제 서비스 표본 2개를 포함한 최종 46개 검사 | +| `codex-probe-evidence.json` | `4c283d01b2d355407c0af708c8b389b1b9d44b024f82b8e3590aa8c57f06daeb` | 고정된 로컬 응답을 사용한 고정 CLI 도구 연결 성공 | + +실측 호스트는 Windows NT `10.0.26300.0`, x64를 보고합니다. Python 3.14.9와 Node.js 24.22.1을 준비해 사용했습니다. Windows 10과 ARM64는 실측하지 않았으며 네이티브 API의 제공 여부만으로 호환성을 판단하지 않습니다. 기존 [스킬 8개 설치 감사](skill-eligibility-audit-2026-10-25.json)는 변경하지 않았으며 당시의 설치와 발견 범위 및 ACL 제한을 유지합니다. 이전 fixture 519개를 새로운 AppContainer 실행 검사로 다시 합산하지 않습니다. + +## 현재 판단과 남은 검증 + +여기까지 정리하면 이번 PoC는 실측 호스트에서 제한한 스크립트 실행과 고정 응답을 사용한 CLI 및 MCP 연결을 확인했습니다. [등재 기준](SKILL_ELIGIBILITY.ko.md)은 이 근거와 운영 통합, 실제 모델 동작 및 플랫폼 확장을 구분합니다. 공개 카탈로그의 고정 스크립트 후보 3개는 평가 범위를 유지하며 MCP 의존 항목과 자격 증명 의존 후보의 보류도 유지합니다. + +운영 적용은 앱 통합, 네트워크 정책, 취소와 정리 동작의 검토, 대상 플랫폼 검증과 별도로 허용한 실제 모델 검사를 전제로 판단합니다. 당장의 결과로 고정 스크립트 3개의 추가 평가를 이어갈 수 있습니다. 일반 셸을 활성화하거나 런타임 설치만으로 출시한 대화의 스크립트 실행을 지원한다고 표시하지 않습니다. diff --git a/docs/APP_CONTAINER_POC.md b/docs/APP_CONTAINER_POC.md new file mode 100644 index 00000000..ecf02fba --- /dev/null +++ b/docs/APP_CONTAINER_POC.md @@ -0,0 +1,71 @@ +# AppContainer skill evaluation results + +[한국어](APP_CONTAINER_POC.ko.md) | [Eligibility criteria](SKILL_ELIGIBILITY.md) | [Catalog lifecycle](SkillCatalog.README.md) + +On October 25, 2026, the AppContainer proof of concept passed 46 of 46 broker, execution and policy checks on Windows build 26300 x64. A separate pinned Codex 0.156.1 run completed a calculator call through MCP and AppContainer using two deterministic loopback Responses replies. No real model inference or authentication participated. + +This report covers the pinned skill adaptations, contained execution, public-service samples, CLI routing and retained evidence. The public `main` catalog provides the three pinned script candidates for hands-on testing. These outcomes do not promote them to production compatibility. + +The publication and source boundary come first, followed by worker controls, measured results, Codex routing, evidence records and remaining qualification work. + +## Public evaluation catalog and pinned source boundary + +The public `main` catalog contains six active entries for hands-on testing: the three existing production candidates and three pinned script candidates for isolated evaluation. Nine other blocks remain commented out. Publishing the script candidates does not qualify them for production compatibility. The corresponding TableCloth implementation uses `poc/appcontainer-skill-runner` in [application PR #322](https://github.com/yourtablecloth/TableCloth/pull/322), which has not been integrated. The current product chat retains `shell_tool=false` and `unified_exec=false`; it does not automatically register this broker or execute installed scripts. The [catalog criteria](SKILL_ELIGIBILITY.md) and credential deferral in [TableCloth #321](https://github.com/yourtablecloth/TableCloth/issues/321) continue to apply. + +| Evaluated script | Pinned upstream commit | Execution adaptation | +| --- | --- | --- | +| [BOK ECOS](https://github.com/NomaDamas/k-skill/tree/0102e5133865f00886e37ac8cf39a49e2c7a3d39/bok-ecos-stats) | `0102e5133865f00886e37ac8cf39a49e2c7a3d39` | Direct call to the original `scripts/bok_ecos.py` | +| [KOSIS](https://github.com/NomaDamas/k-skill/tree/0102e5133865f00886e37ac8cf39a49e2c7a3d39/kosis-stats) | `0102e5133865f00886e37ac8cf39a49e2c7a3d39` | Direct call to the original `scripts/run_kosis_stats.py` | +| [Everyday calculators](https://github.com/yourtablecloth/tablecloth-calculators/tree/877b58cf0741db21342445f2b3fcb54ad1ada85c) | `877b58cf0741db21342445f2b3fcb54ad1ada85c` | Original `scripts/calculate.py`, JSON input on stdin | + +The BOK and KOSIS `SKILL.md` files require an `npx` instruction loader. This experiment read the pinned instructions and called their Python helpers directly without modifying those helpers. It did not run or qualify the original npm loader workflow. Node.js coverage used a fixed local fixture, not an upstream npm package. The copies retain their upstream licenses and 31 matching pinned Git blobs in the implementation's `tools/appcontainer-skill-poc/skills/ORIGINS.json`. + +## Host broker and contained worker controls + +The host-owned MCP broker accepts registered IDs and bounded JSON inputs, not model-provided executable paths, shell commands or source code. It rechecks interpreter and script hashes before execution. Python uses `-I -S -B -X utf8`; the Node fixture has a fixed entry file. The native runner verifies an AppContainer token, uses owned-directory ACL grants and a Job Object, and bounds time, memory, process count and output. Microsoft's [AppContainer isolation documentation](https://learn.microsoft.com/en-us/windows/win32/secauthz/appcontainer-isolation) describes the underlying resource-access model. + +The normal broker grants no network capability and rejects network-required registrations. Its tested workers received owned temporary home and work directories with a cleared environment. Private synthetic-file denial, inherited-value exclusion, child-process limits, UTF-8 round trips, cancellation, timeout, memory/output limits, sampled ACL restoration and per-run workspace removal passed. Ordinary AppContainer shares the host kernel, and host resources whose ACLs already permit application packages can remain accessible. These tests do not establish a VM boundary or universal denial of host-file reads. + +The separate public-API evaluator granted broad `internetClient` capability to fixed host-owned commands. It had no domain allowlist. Its successful service reads do not establish a network policy suitable for model-selected arbitrary URLs. Neither the worker test nor catalog activation grants general shell execution, npm installation or arbitrary package updates. + +## Measured execution and service results + +The final evaluation record separates top-level checks from the unit-test counts executed inside two of those checks. + +| Verification | Observed result | Scope | +| --- | --- | --- | +| Offline broker checks | 20/20 | Input, registration, hash, transport and failure handling | +| Execution and policy checks | 26/26 | Contained Python/Node, control cases, limits, cleanup and two public-service cases | +| Combined evaluation | 46/46 | The preceding 20 and 26 checks | +| Calculator upstream unit tests | 28/28 | AppContainer run; included in one of the 26 checks | +| BOK upstream unit tests | 19/19 | AppContainer run; included in one of the 26 checks | +| ManagedAi Release regression suite | 197/197 | Separate application regression run | + +The calculator cases covered discounts, percentages, leap-day adjustment, fixed-offset date rollover, numeric BMI and a zero-rate loan. KOSIS's fixed dry run and the Node JSON fixture also passed. These samples do not cover every calculator operation or the original KOSIS unit suite. + +For the live samples, the [BOK helper](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/bok-ecos-stats/scripts/bok_ecos.py) returned one row from ECOS using its public `sample` key. The [KOSIS helper](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/kosis-stats/scripts/run_kosis_stats.py) returned one search row for `인구` through the shared `k-skill-proxy.nomadamas.org` service. No user API key was supplied. Proxy availability and server-side credentials remain external dependencies. Direct KOSIS and big-data credential paths were not tested. + +## Actual Codex routing with deterministic local replies + +The pinned CLI advertised the calculator under namespace `mcp__tablecloth_skill_poc` and normalized function name `tablecloth_calculators`. A local HTTP listener sent one fixed function call and then a final reply after receiving the actual tool output. The CLI completed its MCP event using original tool name `tablecloth-calculators`; the worker reported `wasAppContainer=true`, exit code 0 and discount result `80.00`. + +The isolated profile kept `approval_policy="never"`, `shell_tool=false` and `unified_exec=false`. Only the host-owned registered calculator received an explicit per-tool `approval_mode="approve"`; the server default remained `prompt` and its enabled-tool list contained that one calculator. No false read-only annotation was used. OpenAI documents these controls in the [MCP configuration guide](https://developers.openai.com/codex/mcp), and the [function-calling guide](https://developers.openai.com/api/docs/guides/function-calling#defining-namespaces) describes namespace grouping. + +This run made two loopback Responses requests, zero real model inferences and zero authentication attempts. It copied no existing authentication and created no auth file in its new Codex home. Configuration, manifest and calculator hashes remained unchanged. It verifies actual CLI-to-broker routing and contained execution with predetermined replies. Real model tool selection and automatic execution in production TableCloth chat remain unverified. + +## Evidence records and platform limits + +The following records remain under the local TableCloth workspace's `Artifacts/appcontainer-skill-poc/` directory. They are not published as catalog assets. The source and reproduction guide reside in `tools/appcontainer-skill-poc/` of the TableCloth implementation branch. + +| Record | SHA-256 | Recorded scope | +| --- | --- | --- | +| `evaluation-public-api.json` | `5489b04ad12cbce500cfab5e41b904d113a00206e5fccd9829bce835fa48fdfa` | Final 46-check run, including the two live service samples | +| `codex-probe-evidence.json` | `4c283d01b2d355407c0af708c8b389b1b9d44b024f82b8e3590aa8c57f06daeb` | Successful pinned CLI routing with deterministic local replies | + +The measured host reports Windows NT `10.0.26300.0`, x64. It staged Python 3.14.9 and Node.js 24.22.1. Windows 10 and ARM64 were not measured; native API availability does not establish compatibility there. The earlier [eight-skill installation audit](skill-eligibility-audit-2026-10-25.json) remains unchanged and retains its original installation/discovery scope and ACL limitation. Its prior 519 fixtures are not recounted as new AppContainer execution tests. + +## Current decision and remaining qualification + +The PoC establishes bounded script execution and deterministic CLI/MCP routing on the measured host. The [eligibility criteria](SKILL_ELIGIBILITY.md) continue to separate that evidence from production integration, live model behavior and broader platform qualification. The three pinned script candidates published in the public catalog retain evaluation-only scope; MCP-dependent and credential-dependent deferred candidates remain inactive. + +Production use still depends on reviewed application integration, network policy, cancellation and cleanup behavior, platform qualification and a separately authorized real-model test. The immediate result supports further evaluation of the three exact script pins. It does not activate a general shell or convert runtime installation into script support in the shipped chat. diff --git a/docs/SKILL_ELIGIBILITY.ko.md b/docs/SKILL_ELIGIBILITY.ko.md new file mode 100644 index 00000000..f3def803 --- /dev/null +++ b/docs/SKILL_ELIGIBILITY.ko.md @@ -0,0 +1,81 @@ +# 스킬 등재 기준과 고정 원본 검증 + +[English](SKILL_ELIGIBILITY.md) | [카탈로그 관리 안내](SkillCatalog.README.ko.md) | [기여 안내](../CONTRIBUTING.md) + +2026년 10월 25일 기준으로 현재 식탁보 대화는 `shell_tool=false`와 `unified_exec=false`를 유지합니다. 설치한 스킬의 Python과 Node 스크립트 실행이나 MCP 서버 자동 설정을 지원하지 않습니다. 카탈로그 커밋 `12b1622da1b69ec1d24c0729bbebd70cbb19a902`의 활성 항목 8개를 검토한 운영 기준에서는 호환 후보 3개를 남기고 나머지 5개를 보류했습니다. `main` 공개 카탈로그는 실제 AppContainer 격리 테스트를 위해 고정 스크립트 후보 3개를 다시 활성화해 총 6개를 제공합니다. 스크립트 후보를 운영 호환성 통과로 승격하지 않습니다. [앱 PR #322](https://github.com/yourtablecloth/TableCloth/pull/322)는 아직 반영하지 않았으므로 현재 제품 대화는 설치한 스크립트의 자동 실행을 지원하지 않습니다. MCP 의존 항목 2개와 자격 증명이 필요한 후보의 주석은 유지합니다. + +등재 조건, 고정 버전별 판단, 실제 설치와 발견 결과, 앱 회귀 검사와 재검증 절차를 설명합니다. 패키지 처리의 성공과 필수 기능의 실행 지원을 구분합니다. + +등재 기준부터 살펴보겠습니다. 이후 고정 원본 8개와 확보한 근거를 대조하고 항목 편집 및 카탈로그 검사 절차를 정리하겠습니다. 실제 서비스와 모델을 통한 기능 실행은 이번 검증에서 제외합니다. + +## 필수 실행 경로를 기준으로 한 등재 + +PoC 예외는 아래 표의 BOK, KOSIS와 계산기 고정 커밋에만 적용합니다. `testskills.cs`의 허용 목록은 공개 카탈로그에서 해당 후보의 평가용 제공을 허용하며 카탈로그 검사 성공만으로 AppContainer 격리, 서비스 접근이나 AI 대화의 도구 실행을 입증하지 않습니다. [AppContainer 별도 평가 보고서](APP_CONTAINER_POC.ko.md)는 검사 46개 통과와 고정 로컬 응답을 사용한 실제 CLI 및 MCP 연결을 기록합니다. 실제 모델의 도구 선택이나 운영 통합까지 입증하지는 않습니다. 이전 원본 8개 감사와 앱 검사 519개는 당시의 범위를 유지하는 기존 근거로 구분합니다. + +기존 [원본과 설치 조건](SkillCatalog.README.ko.md)을 계속 적용합니다. 공개 GitHub 저장소, 40자리 고정 커밋, 유효한 `SKILL.md`와 같은 커밋의 라이선스 보존을 전제로 실행 조건을 함께 검토합니다. + +활성 항목은 대화에 제공한 자료를 다루는 지침이나 기존 식탁보 호스트 브리지로 핵심 기능을 제공합니다. 고정 원본, 라이선스와 필수 의존성을 함께 검토합니다. `SKILL.md`를 읽거나 파일을 내려받았다는 사실과 모델의 그럴듯한 답변만으로 기능 실행의 성공을 판단하지 않습니다. Python이나 Node 런타임을 설치해도 현재 AI 대화에 실행 도구를 등록하지는 않습니다. + +스킬의 필수 절차에 Python, Node, shell이나 `npx` 실행이 있으면 현재 대화와 호환되지 않습니다. 설치 폴더에 스크립트가 없어도 필요한 MCP 서버와 도구를 연결하지 않았다면 같은 기준으로 보류합니다. 호스트 브리지 스킬은 호스트가 제공하는 제한된 보고서를 해석하며 일반 셸 실행 권한을 얻지 않습니다. 보고서가 없거나 로컬 Windows 기능을 지원하지 않는 경우에는 그 제한을 설명합니다. + +자격 증명 정책도 함께 적용합니다. [TableCloth #321](https://github.com/yourtablecloth/TableCloth/issues/321)의 대응 기능 개발과 검증을 마칠 때까지 환경 변수로 사용자 API 키, 토큰과 클라이언트 시크릿을 받는 신규 스킬의 접수를 보류합니다. 키 없는 기능이 있어도 실행 의존성 검토를 생략하지 않습니다. [기여 정책](../CONTRIBUTING.md)에 따라 시스템과 사용자 환경 변수, `.env` 파일이나 대화 입력으로 자격 증명을 받는 우회 안내도 제공하지 않습니다. + +## 기존 활성 스킬 8개의 고정 버전 검토 + +각 행에 고정 원본과 필수 절차의 검토 결과를 기록했습니다. [설치 검증 기록](skill-eligibility-audit-2026-10-25.json)은 8개 모두의 설치, 출처와 라이선스 보존, Codex의 발견, 활성화 전환과 제거 성공도 기록합니다. 호환 후보라는 표기는 실제 서비스 호출, 인증서 검사, Sandbox 작업이나 모델을 통한 실행 성공을 뜻하지 않습니다. 출처 링크는 이동하는 브랜치 대신 카탈로그의 고정 커밋을 가리킵니다. + +| 스킬 | 고정 원본 커밋 | 필수 실행 경로 | 현재 판단 | +| --- | --- | --- | --- | +| [official-report-skillset](https://github.com/mouseco/k-gov-skills/blob/a55816b9b44e8391576204a095bf6337940d80f3/skills/official-report-skillset/SKILL.md) | `a55816b9b44e8391576204a095bf6337940d80f3` | 지침과 참고 문서 2개로 제공한 사실을 초안으로 구성 | 호환 후보, 활성 유지 | +| [tablecloth-certificate-expiry](https://github.com/yourtablecloth/tablecloth-certificate-expiry/blob/9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2/SKILL.md) | `9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2` | 사용자 동의를 받은 호스트 브리지가 만료 건수를 전달하고 Codex가 해석 | 호환 후보, 활성 유지 | +| [tablecloth-windows-sandbox](https://github.com/yourtablecloth/tablecloth-windows-sandbox/blob/b9e52bcd303624dbba81e7de66a3f56344e922fe/SKILL.md) | `b9e52bcd303624dbba81e7de66a3f56344e922fe` | 호스트 브리지가 허용한 작업 결과를 전달하며 Windows 호환 조건 적용 | 호환 후보, 활성 유지 | +| [bok-ecos-stats](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/bok-ecos-stats/SKILL.md) | `0102e5133865f00886e37ac8cf39a49e2c7a3d39` | 필수 `npx` 지침 로더와 Python 보조 스크립트 실행 | 운영 비호환, PoC 평가에서만 활성 | +| [kosis-stats](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/kosis-stats/SKILL.md) | `0102e5133865f00886e37ac8cf39a49e2c7a3d39` | 필수 `npx` 지침 로더와 Python 보조 스크립트 실행 | 운영 비호환, PoC 평가에서만 활성 | +| [tablecloth-calculators](https://github.com/yourtablecloth/tablecloth-calculators/blob/877b58cf0741db21342445f2b3fcb54ad1ada85c/SKILL.md) | `877b58cf0741db21342445f2b3fcb54ad1ada85c` | 동봉한 `scripts/calculate.py` 실행을 요구하며 추측 결과로 대체 금지 | 운영 비호환, PoC 평가에서만 활성 | +| [korean-jangbu-for](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/skills/korean-jangbu-for/SKILL.md) | `592f6d7c7be138ae578be9ed6769239cc527ddea` | 별도 Python MCP 서버와 하위 스킬 6개가 필요하며 설치 진입점에는 `SKILL.md`만 존재 | 비호환, 주석 보류 | +| [korean-law-mcp](https://github.com/chrisryugj/korean-law-mcp/blob/4ccedb0dc89fce164493ffc9019b5ad35cb9b782/skills/korean-law/SKILL.md) | `4ccedb0dc89fce164493ffc9019b5ad35cb9b782` | 별도로 연결한 `korean-law` MCP 조회와 인용 검증 도구 사용 | 비호환, 주석 보류 | + +보고서 스킬의 고정 [참고 문서 디렉터리](https://github.com/mouseco/k-gov-skills/tree/a55816b9b44e8391576204a095bf6337940d80f3/skills/official-report-skillset/references)에는 스크립트나 MCP 의존성이 없습니다. 대화 초안을 지원하며 로컬 문서 자동 읽기나 HWP, Word 파일 내보내기는 포함하지 않습니다. 장부 스킬의 [Python 프로젝트](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/mcp-server/pyproject.toml)와 하위 스킬은 설치한 진입점 경로 밖에 있습니다. LLM 보조 분류도 MCP가 전달한 마스킹 거래와 저장 도구를 전제합니다. + +## 검증 단계와 미검증 범위 + +검증 기록에서는 다음 결과를 구분합니다. + +1. 고정 경로, 진입점, 라이선스와 필수 절차를 정적으로 검토합니다. +2. 격리한 프로필에서 실제 설치 관리자, 출처 보존과 Codex의 스킬 발견을 검증합니다. +3. 기존 실행 정책 아래에서 보고서 처리와 호스트 브리지 fixture의 앱 동작을 검증합니다. +4. 실제 AI 대화에서 필요한 도구 호출과 반환 결과로 기능 실행을 검증합니다. + +[검증 JSON](skill-eligibility-audit-2026-10-25.json)은 8개 모두에 대해 2단계의 설치, Codex 0.156.1 `skills/list` 발견, 활성화 전환과 제거 성공을 기록합니다. 네이티브 앱 서버 프로세스 1회를 실행했으며 모델과 스킬 스크립트 호출, 실제 서비스 호출, 인증서 검사, Sandbox 상태 변경과 런타임 변경은 각각 0회입니다. 고유 임시 저장소도 제거했습니다. MCP 의존 진입점을 발견했다고 해서 해당 MCP 도구를 연결한 것으로 판단하지 않습니다. + +실제 Windows 프로필의 ACL 설정 함수는 검증 토큰의 권한을 거부했습니다. 이후 artifact 전용 프로필에 원래의 `WindowsManagedAiProfile.Configuration`을 그대로 저장하고 두 실행 기능을 false로 유지한 상태에서 검증했습니다. 따라서 위 설정에서 설치와 발견 동작을 확인한 결과로 한정하며 프로필 ACL이나 운영 보안 검증의 성공으로 표시하지 않습니다. + +3단계의 로컬 Release 회귀 검사에서는 ManagedAi 197개와 앱 322개가 모두 통과해 총 519개를 확인했습니다. 앱 검사는 호스트 브리지 fixture, 대화, 두 탭 UI와 설치한 스킬 관리를 포함합니다. 원본 TRX 기록은 `managed-ai-removal.trx`와 `app-runtime-removal.trx`로 보존합니다. Fixture 성공만으로 실제 인증서 접근, Sandbox 작업이나 모델을 통한 스크립트 실행을 입증하지 않습니다. Spork는 변경하지 않았으며 이번 변경으로 다시 실행하지 않았습니다. + +4단계는 미검증으로 남깁니다. 기존 스킬 8개 설치 감사에서는 실제 서비스 API, 인증서 검사, Sandbox 작업이나 모델을 호출하지 않았습니다. 후속 [AppContainer 보고서](APP_CONTAINER_POC.ko.md)는 실제 모델 추론 없이 수행한 격리 실행과 고정 공개 서비스 표본 2개를 별도로 기록합니다. 단위 테스트나 직접 실행한 `codex sandbox` 하위 프로세스의 성공만으로 모델의 도구 등록이나 식탁보 대화의 자동 스크립트 실행을 판단하지 않습니다. 이번 카탈로그 검토는 실행 설정을 변경하지 않습니다. + +## 등재와 버전 변경 시 재검토 + +활성 항목을 추가하기 전에 고정 원본, 핵심 기능, 필수 실행 의존성, 사용 가능한 호스트 기능, 검증한 범위와 미검증 범위를 기록합니다. `Source.Ref`를 바꿀 때도 같은 내용을 다시 검토합니다. 진입점 파일을 유지한 채 원본 버전이 새로운 실행 의존성을 도입할 수 있습니다. 새 활성 ID나 고정 버전은 [testskills.cs](../src/testskills.cs)의 등재 허용 목록과 두 언어의 검증표에 함께 반영합니다. + +현재 호스트가 필수 단계를 수행할 수 없으면 사유와 XML 블록 전체를 주석으로 보존합니다. 런타임이나 빠진 도구를 설치할 수 있다는 설명을 연동 완료로 표시하지 않습니다. 필요한 앱 기능을 구현하고 독립 검증한 뒤 다시 등재를 검토합니다. 원격 보류 후에도 기존 로컬 설치를 관리할 수 있으며 [카탈로그 관리 안내](SkillCatalog.README.ko.md)에서 수명 주기를 설명합니다. + +## 카탈로그 검사의 범위 + +스키마와 [checkskills.cs](../src/checkskills.cs)는 원본과 라이선스 좌표를 검사합니다. [testskills.cs](../src/testskills.cs)는 현재 등재한 고정 원본을 제한하고 PoC 스크립트 예외의 정확한 고정 버전과 미연결 MCP 및 자격 증명 후보의 재활성화 차단, 원시 XML 블록의 주석 처리를 검증합니다. 호환 후보의 제거는 허용합니다. XML에 실행 유형이나 검토 상태 필드를 추가하지 않습니다. + +저장소 루트에서 카탈로그 전용 검사를 실행할 수 있습니다. + +```text +dotnet run --file src/checkskills.cs -- docs/SkillCatalog.xml docs/SkillCatalog.xsd +dotnet run --file src/testskills.cs -- docs/SkillCatalog.xsd +dotnet run --file src/catalogutil.cs -- docs/ outputs/ +``` + +검사 성공은 카탈로그 구조, 등재 정책과 생성 결과의 일치를 확인합니다. 원본 스킬 실행이나 앱 런타임 지원을 입증하지는 않습니다. [PR 워크플로](../.github/workflows/skill-catalog.yml)와 [게시 워크플로](../.github/workflows/publish.yml)는 카탈로그 검사를 실행하며 실제 기능 검증은 별도로 진행합니다. + +## 현재 판단과 재검증 범위 + +여기까지 정리하면 카탈로그는 대화 초안 지침과 기존 호스트 보고서 해석을 활성 후보로 남깁니다. [원본 8개 검증](skill-eligibility-audit-2026-10-25.json)은 패키지 설치, 발견과 관리의 성공을 확인하며 필수 의존성에 따른 등재 판단과 구분합니다. 운영 기준에서는 비호환 항목 5개를 보류합니다. `main` 공개 카탈로그는 실제 테스트를 위해 고정 스크립트 후보 3개를 추가로 활성화하며 MCP 항목 2개의 주석은 유지합니다. [AppContainer 평가](APP_CONTAINER_POC.ko.md)는 실측한 x64 호스트의 격리 실행과 고정 응답을 사용한 CLI 연결을 기록합니다. 실제 모델 실행과 운영 호환성은 미검증으로 유지합니다. + +사용자는 기존 로컬 설치를 계속 관리할 수 있습니다. 새로운 실행 경로나 MCP 지원은 앱 기능 개발과 검증을 마친 뒤 재등재를 판단합니다. 기여자는 고정 원본 표와 검증 단계를 기준으로 패키지 갱신과 실행 기능 지원의 변화를 구분할 수 있습니다. diff --git a/docs/SKILL_ELIGIBILITY.md b/docs/SKILL_ELIGIBILITY.md new file mode 100644 index 00000000..3353dc47 --- /dev/null +++ b/docs/SKILL_ELIGIBILITY.md @@ -0,0 +1,81 @@ +# Skill eligibility and pinned-source verification + +[한국어](SKILL_ELIGIBILITY.ko.md) | [Catalog lifecycle](SkillCatalog.README.md) | [Contributing](../CONTRIBUTING.md) + +As of October 25, 2026, the current TableCloth chat keeps `shell_tool=false` and `unified_exec=false`. It does not support executing installed-skill Python or Node scripts or automatically configuring an MCP server. This review covers the eight active entries in catalog commit `12b1622da1b69ec1d24c0729bbebd70cbb19a902`. The production baseline retains three eligible candidates and defers five. The public `main` catalog reactivates the three pinned script candidates for hands-on AppContainer evaluation, for six active entries in total. This publication does not qualify the scripts for production compatibility. [Application PR #322](https://github.com/yourtablecloth/TableCloth/pull/322) has not been integrated, so automatic script execution remains unsupported in the current product chat. Both MCP-dependent entries and credential-dependent candidates remain commented out. + +This record covers eligibility criteria, pinned-source decisions, installation/discovery results and application regression tests. It distinguishes successful package handling from a supported feature execution path. + +The current-host criteria come first, followed by the eight pinned sources and their evidence. Entry changes and catalog checks follow; live service and model-driven execution remain outside this verification. + +## Eligibility depends on the required execution path + +The PoC exception applies only to the exact BOK, KOSIS and calculator commits in the table below. The allowlist in `testskills.cs` permits their publication for evaluation in the public catalog; catalog checks do not qualify AppContainer isolation, service access or AI-conversation tool execution. The separate [AppContainer evaluation report](APP_CONTAINER_POC.md) now records 46/46 checks and actual pinned CLI/MCP routing driven by deterministic local replies. It does not establish real model selection or production integration. The earlier eight-source audit and 519 application tests remain historical evidence with their original scope. + +The existing [source and installation requirements](SkillCatalog.README.md) continue to apply: a public GitHub repository, a fixed 40-character commit, a valid `SKILL.md`, and preservation of the license from that same commit. The execution criteria below add to those requirements. + +An active entry supplies its core function through instructions over conversation-provided material or an existing TableCloth host bridge. The fixed source, license and required dependencies are reviewed together. A readable `SKILL.md`, a successful download or a plausible model response does not prove that the function ran. Installing a Python or Node runtime does not register an execution tool in the current AI conversation. + +Python, Node, shell and `npx` execution required by a skill's workflow remain incompatible with the current chat. MCP-dependent instructions also remain incompatible when the necessary server and tools are not connected, even if their installed folder contains no script. Host-bridge skills interpret the host's bounded report; they do not acquire general shell access. Missing reports and unsupported local Windows features remain explicit limitations. + +The credential policy is an additional requirement. New environment-delivered API keys, tokens and client secrets remain deferred until [TableCloth #321](https://github.com/yourtablecloth/TableCloth/issues/321) is implemented and verified. A keyless path does not waive execution prerequisites. The [contribution policy](../CONTRIBUTING.md) excludes system/user environment variables, `.env` files and chat prompts as credential workarounds. + +## Review of all eight previously active pinned skills + +Each row records the fixed source and the result of reviewing its required workflow. The [installation audit](skill-eligibility-audit-2026-10-25.json) also records successful installation, provenance/license preservation, native discovery, enable/disable and removal for all eight. “Eligible candidate” does not claim a successful live service, certificate scan, Sandbox operation or model-driven execution. Source links use the exact catalog commit, rather than a moving branch. + +| Skill | Pinned source commit | Required execution path | Current decision | +| --- | --- | --- | --- | +| [official-report-skillset](https://github.com/mouseco/k-gov-skills/blob/a55816b9b44e8391576204a095bf6337940d80f3/skills/official-report-skillset/SKILL.md) | `a55816b9b44e8391576204a095bf6337940d80f3` | Instructions and two local reference documents; draft from supplied facts | Eligible candidate, active | +| [tablecloth-certificate-expiry](https://github.com/yourtablecloth/tablecloth-certificate-expiry/blob/9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2/SKILL.md) | `9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2` | Existing host bridge supplies consented expiry counts; Codex interprets the report | Eligible candidate, active | +| [tablecloth-windows-sandbox](https://github.com/yourtablecloth/tablecloth-windows-sandbox/blob/b9e52bcd303624dbba81e7de66a3f56344e922fe/SKILL.md) | `b9e52bcd303624dbba81e7de66a3f56344e922fe` | Existing host bridge supplies an allowlisted operation result; compatible Windows support applies | Eligible candidate, active | +| [bok-ecos-stats](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/bok-ecos-stats/SKILL.md) | `0102e5133865f00886e37ac8cf39a49e2c7a3d39` | Mandatory `npx` instruction loader and Python helper execution | Production incompatible; active only for PoC evaluation | +| [kosis-stats](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/kosis-stats/SKILL.md) | `0102e5133865f00886e37ac8cf39a49e2c7a3d39` | Mandatory `npx` instruction loader and Python helper execution | Production incompatible; active only for PoC evaluation | +| [tablecloth-calculators](https://github.com/yourtablecloth/tablecloth-calculators/blob/877b58cf0741db21342445f2b3fcb54ad1ada85c/SKILL.md) | `877b58cf0741db21342445f2b3fcb54ad1ada85c` | Execute packaged `scripts/calculate.py`; no guessed-result fallback | Production incompatible; active only for PoC evaluation | +| [korean-jangbu-for](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/skills/korean-jangbu-for/SKILL.md) | `592f6d7c7be138ae578be9ed6769239cc527ddea` | Separate Python MCP server and six sibling skills; installed entry contains only `SKILL.md` | Incompatible, commented out | +| [korean-law-mcp](https://github.com/chrisryugj/korean-law-mcp/blob/4ccedb0dc89fce164493ffc9019b5ad35cb9b782/skills/korean-law/SKILL.md) | `4ccedb0dc89fce164493ffc9019b5ad35cb9b782` | Separately connected `korean-law` MCP search and citation-verification tools | Incompatible, commented out | + +The report-writing skill has no script or MCP dependency in its pinned [reference directory](https://github.com/mouseco/k-gov-skills/tree/a55816b9b44e8391576204a095bf6337940d80f3/skills/official-report-skillset/references). Its scope covers conversation drafts, not automatic local-document reading or HWP/Word export. Jangbu's [Python project](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/mcp-server/pyproject.toml) and sibling skills are outside its installed source directory. Its LLM-assisted classification still depends on MCP-provided masked transactions and persistence tools. + +## Evidence levels and unverified behavior + +Keep these outcomes separate in qualification records: + +1. Static source and structure inspection: pinned paths, manifest, license and required workflow. +2. Installation and discovery: production installer, preserved provenance and native Codex skill discovery in an isolated profile. +3. Application behavior: report handling and host-bridge fixtures with the existing execution policy. +4. Live feature execution: the actual required tool call and its result in the intended AI conversation. + +The [audit JSON](skill-eligibility-audit-2026-10-25.json) reaches level 2 for all eight pinned entries: installation, native Codex 0.156.1 `skills/list` discovery, enable/disable and removal succeeded. It records one native app-server process, no model or skill-script calls, no live service calls, no certificate scans, no Sandbox state changes, no runtime mutations and removal of its unique temporary store. Successful discovery includes MCP-dependent manifests and does not establish that their MCP tools are connected. + +The production Windows profile's ACL setter rejected the audit token. The audit instead stored the exact `WindowsManagedAiProfile.Configuration` in an artifact-owned profile with both execution features false. This verifies the listed installation/discovery behavior in that configuration; it is not a successful profile ACL or production-security qualification. + +At level 3, the local Release suites passed 197/197 ManagedAi tests and 322/322 application tests, 519 total. The application suite includes host-bridge fixtures, chat, two-tab UI and installed-skill management. The retained TRX records are `managed-ai-removal.trx` and `app-runtime-removal.trx`. Fixture success does not establish real certificate access, live Sandbox operations or model-driven script execution. Spork was unchanged and was not rerun for this change. + +Level 4 remains unverified: the earlier eight-skill installation audit made no real service API requests, certificate scans, Sandbox operations or model calls. The later [AppContainer report](APP_CONTAINER_POC.md) separately records contained execution and two fixed public-service samples without real model inference. Unit tests or a direct `codex sandbox` subprocess do not establish model tool registration or automatic script execution in TableCloth chat. Changing execution settings is outside this catalog review. + +## Adding, updating and deferring entries + +Document the fixed source, core function, required execution dependencies, available host mechanism, tested scope and unverified scope before activating an entry. Recheck these facts when `Source.Ref` changes. A source update can introduce an executable dependency even when the manifest still exists. New active IDs and revisions also update the qualification table in [testskills.cs](../src/testskills.cs) and both language versions of this record. + +If the current host cannot perform a required step, preserve the entire XML block as a comment with its reason. Do not describe optional installation of runtimes or missing tools as completed integration. Reconsider an entry after the necessary application mechanism is implemented and independently verified. Existing local installations remain manageable after catalog deferral, as described in the [lifecycle guide](SkillCatalog.README.md). + +## Catalog checks and their limits + +The schema and [checkskills.cs](../src/checkskills.cs) check source and license coordinates. [testskills.cs](../src/testskills.cs) additionally guards the current qualified pinned sources, limits the PoC script exceptions to their exact pins and rejects reactivation of unconnected MCP or credential-dependent candidates, and checks raw-block commenting. It allows removal of qualified entries. No execution-type field or review state is added to the XML. + +Run the catalog-only checks from the repository root: + +```text +dotnet run --file src/checkskills.cs -- docs/SkillCatalog.xml docs/SkillCatalog.xsd +dotnet run --file src/testskills.cs -- docs/SkillCatalog.xsd +dotnet run --file src/catalogutil.cs -- docs/ outputs/ +``` + +Successful checks establish catalog structure, policy consistency and generated output. They do not execute upstream skills or establish application runtime support. The [PR workflow](../.github/workflows/skill-catalog.yml) and [publication workflow](../.github/workflows/publish.yml) run the catalog checks; runtime qualification remains a separate activity. + +## Current decisions and later requalification + +The catalog keeps instruction-only drafting and existing host-report interpretation as active candidates. The [eight-source audit](skill-eligibility-audit-2026-10-25.json) establishes package installation, discovery and management separately from the dependency-based eligibility decisions. The production baseline defers five incompatible entries. The public `main` catalog additionally activates the three pinned script candidates for hands-on evaluation; both MCP entries remain commented out. The [AppContainer evaluation](APP_CONTAINER_POC.md) records contained execution and deterministic CLI routing on the measured x64 host. Real model execution and production compatibility remain unverified. + +Users can continue managing existing local installations. Future execution or MCP support requires application work and verification before a candidate is reactivated. Contributors can use the pinned-source table and evidence levels to distinguish a package update from a newly supported execution path. diff --git a/docs/SkillCatalog.README.ko.md b/docs/SkillCatalog.README.ko.md index 474858a4..1e46c3d4 100644 --- a/docs/SkillCatalog.README.ko.md +++ b/docs/SkillCatalog.README.ko.md @@ -2,7 +2,7 @@ [English](SkillCatalog.README.md) -2026년 10월 25일 기준으로 [SkillCatalog.xml](SkillCatalog.xml)은 스킬 8개를 활성 항목으로 제공합니다. 초기 목록에서 보류한 후보 5개와 `SKILL.md`가 없는 MCP 후보 2개는 XML 주석으로 보존합니다. +2026년 10월 25일 기준으로 `main` 공개 카탈로그의 [SkillCatalog.xml](SkillCatalog.xml)은 실제 테스트를 위해 운영 후보 3개와 격리 평가용 고정 스크립트 후보 3개를 활성화해 총 6개를 제공합니다. 나머지 후보 9개는 XML 주석으로 보존합니다. 스크립트 후보의 공개가 운영 호환성 통과를 뜻하지는 않습니다. [앱 PR #322](https://github.com/yourtablecloth/TableCloth/pull/322)는 아직 반영하지 않았으므로 현재 제품 대화는 설치한 스크립트의 자동 실행이나 MCP 서버 자동 설정을 지원하지 않습니다. [AppContainer 평가 보고서](APP_CONTAINER_POC.ko.md)에서 격리 실행과 고정 응답을 사용한 CLI 연결 성공을 기록하며 실제 모델 선택과 운영 AI 대화의 통합은 미검증으로 유지합니다. [등재 기준과 고정 원본 검증](SKILL_ELIGIBILITY.ko.md)에서 파일 설치, 스킬 발견과 실제 기능 실행을 구분합니다. 이 문서는 항목 추가와 제거, 고정 버전 갱신, 실행 선행 조건, 라이선스 및 게시 전 검증을 다룹니다. 활성 `Skill` 요소는 별도 검토 상태 없이 설치 대상으로 표시합니다. @@ -10,7 +10,7 @@ ## 활성 요소와 주석을 통한 항목 관리 -활성 항목의 등록 방식을 살펴보겠습니다. `Skill` 요소에 고유 ID, 실제 스킬 디렉터리, 전체 커밋 SHA와 같은 저장소 및 커밋의 라이선스 URL을 기록합니다. `Install.Mode`는 `upstream`을 사용하며 목록 상태와 검토 상태 속성은 기록하지 않습니다. +활성 항목의 등록 방식을 살펴보겠습니다. [현재 호스트의 등재 기준](SKILL_ELIGIBILITY.ko.md)에 따라 필수 실행 경로와 검증 범위를 먼저 기록합니다. `Skill` 요소에 고유 ID, 실제 스킬 디렉터리, 전체 커밋 SHA와 같은 저장소 및 커밋의 라이선스 URL을 기록합니다. `Install.Mode`는 `upstream`을 사용하며 목록 상태와 검토 상태 속성은 기록하지 않습니다. 이어서 항목 제거 방식을 짚겠습니다. 해당 `Skill` 요소 전체를 XML 주석으로 감싸고 제거 사유를 짧게 남깁니다. 요소 본문에 연속된 하이픈 두 개가 있으면 `--`로 표기해 블록을 유효한 XML 주석으로 감쌀 수 있습니다. XML 파서는 원래 문자를 읽으며 주석을 설치 목록에 포함하지 않습니다. 원격 목록에서 항목을 제거해도 사용자는 기존 로컬 설치를 계속 관리하거나 제거할 수 있습니다. [현재 XML](SkillCatalog.xml)은 순수 MCP 후보 2개의 블록을 이 방식으로 보존합니다. @@ -22,23 +22,23 @@ ## 고정 커밋을 기준으로 한 업데이트 -같은 스킬을 갱신할 때는 `Id`, `Source.Repository`와 `Source.Path`를 유지합니다. `Source.Ref`를 새 전체 커밋 SHA로 바꾸고 `License.Source`도 같은 커밋으로 갱신합니다. 식탁보는 설치한 원본 커밋과 카탈로그 커밋을 비교해 업데이트를 제공합니다. +같은 스킬을 갱신할 때는 `Id`, `Source.Repository`와 `Source.Path`를 유지합니다. `Source.Ref`를 새 전체 커밋 SHA로 바꾸고 `License.Source`도 같은 커밋으로 갱신합니다. 활성화하기 전에 필수 의존성을 다시 검토하고 검증 기록과 회귀 검사의 허용 목록을 함께 갱신합니다. 식탁보는 설치한 원본 커밋과 카탈로그 커밋을 비교해 업데이트를 제공합니다. -다만 원본 지침이 실행 중 내려받는 패키지는 자체 버전 동작을 따릅니다. [NomaDamas 원본](https://github.com/NomaDamas/k-skill/tree/0102e5133865f00886e37ac8cf39a49e2c7a3d39)의 스킬은 현재 `npx` CLI로 지침을 읽으므로 Git 커밋 고정만으로 해당 CLI의 배포 버전까지 고정하지는 않습니다. +다만 원본 지침이 실행 중 내려받는 패키지는 자체 버전 동작을 따릅니다. 주석으로 보류한 [NomaDamas 원본](https://github.com/NomaDamas/k-skill/tree/0102e5133865f00886e37ac8cf39a49e2c7a3d39)의 후보는 `npx` CLI로 지침을 읽으므로 Git 커밋 고정만으로 해당 CLI의 배포 버전까지 고정하지는 않습니다. ## 스킬 파일 설치와 실행 선행 조건 -설치 관리자는 스킬 파일을 복사하고 같은 커밋의 라이선스를 `LICENSE.upstream`으로 보존합니다. 런타임, MCP 서버 등록과 API 키는 별도로 설정합니다. `Network`는 스킬 실행 시 네트워크 의존성을 나타내며 원격 설치에는 항상 다운로드를 사용합니다. +설치 관리자는 스킬 파일을 복사하고 같은 커밋의 라이선스를 `LICENSE.upstream`으로 보존합니다. 파일 설치만으로 런타임, MCP 서버나 API 키를 설정하지 않으며 현재 AI 대화의 실행 권한도 바꾸지 않습니다. `Network`는 스킬 실행 시 네트워크 의존성을 나타내며 원격 설치에는 항상 다운로드를 사용합니다. [공동인증서 만료 스킬](https://github.com/yourtablecloth/tablecloth-certificate-expiry)과 [Windows Sandbox 스킬](https://github.com/yourtablecloth/tablecloth-windows-sandbox)은 별도 저장소에서 배포하며 기본 구성에는 포함하지 않습니다. 추가 API 키 없이 식탁보 호스트가 제공한 로컬 보고서를 해석합니다. 인증서 조회는 사용자 동의를 받은 건수 요약으로 제한하며 Sandbox 작업은 호환되는 Windows 환경과 식탁보 호스트 브리지를 요구합니다. 원본 AGPL과 별도 상용 라이선스 문의 안내를 보존합니다. -[금융 및 생활 계산기](https://github.com/yourtablecloth/tablecloth-calculators)는 Python 3.11 이상과 표준 라이브러리만 사용합니다. 계산 스크립트는 사용자 입력값을 사용하며 API 키, 외부 데이터 조회와 추가 패키지 다운로드를 요구하지 않습니다. 설치한 스킬의 Python 스크립트 실행을 허용하는 호스트가 필요하며 이전 식탁보 빌드에 런타임만 설치해도 실행 권한을 추가하지는 않습니다. `Network="none"`은 계산 스크립트의 조건을 나타내며 Codex 대화는 기존 온라인 연결을 사용합니다. 원본 저장소의 [저작권 준수 기준](https://github.com/yourtablecloth/tablecloth-calculators/blob/main/docs/COPYRIGHT.ko.md)에서 독립 구현, 출처 기록과 기여 범위를 설명합니다. +PoC 평가에서만 활성화한 [금융 및 생활 계산기](https://github.com/yourtablecloth/tablecloth-calculators)는 Python 3.11 이상과 표준 라이브러리만 사용합니다. 계산 스크립트는 사용자 입력값을 사용하며 API 키, 외부 데이터 조회와 추가 패키지 다운로드를 요구하지 않습니다. 현재 식탁보 대화는 필요한 스크립트 실행 경로를 제공하지 않으며 런타임을 설치해도 이 제한은 유지합니다. `Network="none"`은 계산 스크립트의 조건을 나타내며 Codex 대화는 기존 온라인 연결을 사용합니다. 고정 원본의 [저작권 준수 기준](https://github.com/yourtablecloth/tablecloth-calculators/blob/877b58cf0741db21342445f2b3fcb54ad1ada85c/docs/COPYRIGHT.ko.md)도 해당 후보에 계속 적용합니다. -[법령 스킬](https://github.com/chrisryugj/korean-law-mcp/blob/4ccedb0dc89fce164493ffc9019b5ad35cb9b782/skills/korean-law/SKILL.md)은 파일 설치 후 별도 `korean-law` MCP 서버와 법제처 API 인증키를 사용합니다. [장부 스킬](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/skills/korean-jangbu-for/SKILL.md)도 진입점 외에 MCP 서버와 하위 스킬을 사용합니다. 각 항목의 `Notes`에서 실행 조건을 확인할 수 있습니다. +주석으로 보류한 [법령 스킬](https://github.com/chrisryugj/korean-law-mcp/blob/4ccedb0dc89fce164493ffc9019b5ad35cb9b782/skills/korean-law/SKILL.md)은 별도로 연결한 `korean-law` MCP 서버를 사용합니다. [장부 스킬](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/skills/korean-jangbu-for/SKILL.md)도 설치한 진입점 경로 밖의 Python MCP 서버와 하위 스킬을 사용합니다. 스크립트 파일이 없는 진입점도 필수 도구에 따라 실행 의존성을 판단합니다. ## 원본 라이선스와 데이터 이용 조건 -활성 항목은 [NomaDamas MIT](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/LICENSE), [kimlawtech Apache-2.0](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/LICENSE), [chrisryugj MIT](https://github.com/chrisryugj/korean-law-mcp/blob/4ccedb0dc89fce164493ffc9019b5ad35cb9b782/LICENSE)와 [mouseco MIT](https://github.com/mouseco/k-gov-skills/blob/a55816b9b44e8391576204a095bf6337940d80f3/LICENSE)를 원본 고정 커밋에서 참조합니다. +주석으로 보존한 후보까지 포함한 원본 라이선스는 [NomaDamas MIT](https://github.com/NomaDamas/k-skill/blob/0102e5133865f00886e37ac8cf39a49e2c7a3d39/LICENSE), [kimlawtech Apache-2.0](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/LICENSE), [chrisryugj MIT](https://github.com/chrisryugj/korean-law-mcp/blob/4ccedb0dc89fce164493ffc9019b5ad35cb9b782/LICENSE)와 [mouseco MIT](https://github.com/mouseco/k-gov-skills/blob/a55816b9b44e8391576204a095bf6337940d80f3/LICENSE)를 고정 커밋에서 참조합니다. 식탁보 호스트 브리지 원본은 앞 절에서 설명한 AGPL과 상용 문의 안내를 보존합니다. 또한 mouseco의 [출처 기록](https://github.com/mouseco/k-gov-skills/blob/a55816b9b44e8391576204a095bf6337940d80f3/docs/attribution.md)은 후보 4개를 직접 작성한 스킬로 구분합니다. API 응답 데이터와 참조 도구에는 각 원 출처의 조건을 적용합니다. 카탈로그는 자격증명을 저장하거나 원본 코드를 실행하지 않습니다. @@ -46,10 +46,10 @@ [SkillCatalog.xsd](SkillCatalog.xsd)는 고정 커밋과 라이선스 URL을 필수로 요구하고 활성 항목을 최대 256개로 제한합니다. [checkskills.cs](../src/checkskills.cs)는 XML 크기를 512 KiB로 제한하며 라이선스 URL의 저장소 및 커밋 일치와 경로를 검사합니다. 디렉터리 이름 내부의 점은 허용하지만 끝점은 거부합니다. 루트 표시 `.`는 계속 허용합니다. -저장소 루트에서 `dotnet run --file src/checkskills.cs -- docs/SkillCatalog.xml docs/SkillCatalog.xsd`와 `dotnet run --file src/testskills.cs -- docs/SkillCatalog.xsd`를 실행할 수 있습니다. [PR 워크플로](../.github/workflows/skill-catalog.yml)와 [Pages 워크플로](../.github/workflows/publish.yml)가 두 검사를 함께 실행합니다. 기존 카탈로그 빌더는 `docs`를 복사해 `https://catalog.yourtablecloth.app/SkillCatalog.xml`에 게시합니다. +저장소 루트에서 `dotnet run --file src/checkskills.cs -- docs/SkillCatalog.xml docs/SkillCatalog.xsd`와 `dotnet run --file src/testskills.cs -- docs/SkillCatalog.xsd`를 실행할 수 있습니다. 두 번째 도구는 현재 등재한 ID와 고정 원본도 제한하므로 목록을 바꿀 때 [검증 기록](SKILL_ELIGIBILITY.ko.md)을 함께 갱신합니다. [PR 워크플로](../.github/workflows/skill-catalog.yml)와 [Pages 워크플로](../.github/workflows/publish.yml)가 두 검사를 함께 실행합니다. 기존 카탈로그 빌더는 `docs`를 복사해 `https://catalog.yourtablecloth.app/SkillCatalog.xml`에 게시합니다. 이 검사는 원본 스킬을 실행하지 않습니다. ## 카탈로그와 로컬 설치의 수명 주기 여기까지 정리하면 활성 XML 요소가 설치 목록을 구성하고 고정 커밋의 변경이 업데이트를 구분합니다. XML 주석은 원본 기록을 남기면서 항목을 목록에서 제거합니다. -원격 항목 편집은 앞으로 제공할 설치와 업데이트에 영향을 줍니다. 사용자는 기존 로컬 설치를 계속 관리할 수 있습니다. MCP 서버와 API 키 같은 실행 조건은 각 스킬의 `Notes`와 원본 문서에 따라 설정할 수 있습니다. +원격 항목 편집은 앞으로 제공할 설치와 업데이트에 영향을 줍니다. 사용자는 기존 로컬 설치를 계속 관리할 수 있습니다. 활성화 여부는 각 스킬의 필수 실행 경로와 현재 호스트의 지원 범위를 기준으로 판단합니다. diff --git a/docs/SkillCatalog.README.md b/docs/SkillCatalog.README.md index f5ccf996..0a67967b 100644 --- a/docs/SkillCatalog.README.md +++ b/docs/SkillCatalog.README.md @@ -4,11 +4,11 @@ ## Installable catalog entries -As of October 25, 2026, [SkillCatalog.xml](SkillCatalog.xml) contains eight active skill entries. Each active `Skill` element offers an upstream skill for installation. There are no listing or review states. The catalog retains seven other candidates as XML comments: five deferred from the initial catalog and two MCP candidates whose pinned repositories provide no `SKILL.md`. +As of October 25, 2026, the public `main` catalog provides six active entries in [SkillCatalog.xml](SkillCatalog.xml) for hands-on testing: the three production candidates and three pinned script candidates for isolated evaluation. Nine other candidates remain as XML comments. Publishing the script candidates does not qualify them for production compatibility. [Application PR #322](https://github.com/yourtablecloth/TableCloth/pull/322) has not been integrated, so the current product chat does not automatically execute installed scripts or configure MCP servers. The [AppContainer evaluation report](APP_CONTAINER_POC.md) records contained execution and deterministic CLI routing; real model selection and production AI-conversation integration remain unverified. The [eligibility criteria and pinned-source verification](SKILL_ELIGIBILITY.md) distinguish file installation, native discovery and actual feature execution. There are no listing or review states. ## Adding and removing a skill -Add an active `Skill` element with a stable ID, an existing upstream skill directory, a full commit SHA and a license URL pinned to that same repository and commit. `Install.Mode` is `upstream`. To remove a skill from the remote catalog, comment out its entire `Skill` element and record a short reason outside or inside that comment. Encode consecutive hyphens in element text as `--` so the raw block can become a valid XML comment; XML readers preserve the original text. XML comments never become marketplace entries. A catalog removal leaves existing local installations available to manage and remove. +Activate a skill after documenting its required execution path and qualification under the [current-host criteria](SKILL_ELIGIBILITY.md). Record a stable ID, an existing upstream skill directory, a full commit SHA and a license URL pinned to that same repository and commit. `Install.Mode` is `upstream`. To remove or defer a skill, comment out its entire `Skill` element and record a short reason outside or inside that comment. Encode consecutive hyphens in element text as `--` so the raw block can become a valid XML comment; XML readers preserve the original text. XML comments never become marketplace entries. A catalog removal leaves existing local installations available to manage and remove. ## Deferral of new skills that receive credentials through environment variables @@ -18,15 +18,15 @@ For functionality that works independently without a user key, specify the suppo ## Pinned versions and updates -Keep `Id`, `Source.Repository` and `Source.Path` unchanged when updating the same skill. Change `Source.Ref` to the new full commit SHA and change `License.Source` to the matching commit. The application compares the installed source commit with the current catalog commit to offer an update. A pinned Git commit does not pin packages downloaded later by upstream instructions. The NomaDamas skills currently load instructions through an `npx` CLI, so those packages have their own version behavior. +Keep `Id`, `Source.Repository` and `Source.Path` unchanged when updating the same skill. Change `Source.Ref` to the new full commit SHA and change `License.Source` to the matching commit. Recheck required dependencies and update the qualification record and regression allowlist before activating that revision. The application compares the installed source commit with the current catalog commit to offer an update. A pinned Git commit does not pin packages downloaded later by upstream instructions. The commented NomaDamas candidates load instructions through an `npx` CLI, so those packages have their own version behavior. ## Skill files and execution prerequisites -Installing a skill copies its files and preserves the pinned license as `LICENSE.upstream`. It does not install runtimes, register MCP servers or configure API keys. The [Korean law skill](https://github.com/chrisryugj/korean-law-mcp/blob/4ccedb0dc89fce164493ffc9019b5ad35cb9b782/skills/korean-law/SKILL.md) is installable as a skill file and requires a separately configured `korean-law` MCP server. The [jangbu entry](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/skills/korean-jangbu-for/SKILL.md) also depends on a separate MCP server and sibling skills. Each entry's `Notes` lists the relevant prerequisites. `Network` describes execution; remote installation always downloads files. +Installing a skill copies its files and preserves the pinned license as `LICENSE.upstream`. It does not install runtimes, register MCP servers or configure API keys. The commented [Korean law skill](https://github.com/chrisryugj/korean-law-mcp/blob/4ccedb0dc89fce164493ffc9019b5ad35cb9b782/skills/korean-law/SKILL.md) requires a separately connected `korean-law` MCP server. The commented [jangbu entry](https://github.com/kimlawtech/korean-jangbu-for/blob/592f6d7c7be138ae578be9ed6769239cc527ddea/skills/korean-jangbu-for/SKILL.md) depends on a Python MCP server and sibling skills outside its installed path. A manifest without a script is not automatically an instruction-only skill. `Network` describes execution; remote installation always downloads files. The optional [certificate-expiry skill](https://github.com/yourtablecloth/tablecloth-certificate-expiry) and [Windows Sandbox skill](https://github.com/yourtablecloth/tablecloth-windows-sandbox) are distributed in separate repositories and are not preinstalled. They require no additional API keys and interpret local reports supplied by a compatible TableCloth host bridge. Certificate checks require user consent and share counts only. Sandbox operations also require compatible Windows Sandbox support. The original AGPL license and commercial-license contact notice are preserved. -The optional [everyday calculators](https://github.com/yourtablecloth/tablecloth-calculators) use Python 3.11 or newer and only the standard library. The script calculates from user-supplied values without API keys, external data queries or package downloads. It requires a host that permits installed-skill Python scripts; runtime installation alone does not enable execution in an older TableCloth build. `Network="none"` describes the calculation script, while Codex chat still uses its normal online connection. The repository's [copyright policy](https://github.com/yourtablecloth/tablecloth-calculators/blob/main/docs/COPYRIGHT.md) defines original implementation, attribution and contribution boundaries. +The PoC-evaluation-only [everyday calculators](https://github.com/yourtablecloth/tablecloth-calculators) use Python 3.11 or newer and only the standard library. The script calculates from user-supplied values without API keys, external data queries or package downloads. The current TableCloth chat does not supply its required script-execution path, even when a runtime is installed. `Network="none"` describes the calculation script, while Codex chat still uses its normal online connection. The pinned repository's [copyright policy](https://github.com/yourtablecloth/tablecloth-calculators/blob/877b58cf0741db21342445f2b3fcb54ad1ada85c/docs/COPYRIGHT.md) remains applicable to that candidate. ## License and source boundaries @@ -36,4 +36,4 @@ The pinned licenses identify [NomaDamas MIT](https://github.com/NomaDamas/k-skil [SkillCatalog.xsd](SkillCatalog.xsd) requires immutable references and license sources, limits the catalog to 256 active entries and rejects review attributes. [checkskills.cs](../src/checkskills.cs) also limits the XML to 512 KiB, checks source paths and requires each license URL to match the source repository and commit. Directory segments may contain internal dots but cannot end with a dot; the root marker `.` remains valid. The application separately bounds downloads, rejects symlinks, submodules and nested `SKILL.md` files, and verifies Git blob identities before installation. -Run `dotnet run --file src/checkskills.cs -- docs/SkillCatalog.xml docs/SkillCatalog.xsd` and `dotnet run --file src/testskills.cs -- docs/SkillCatalog.xsd` from the repository root. The [PR workflow](../.github/workflows/skill-catalog.yml) and [Pages workflow](../.github/workflows/publish.yml) run both checks. The existing catalog builder copies `docs` to the Pages output, publishing the XML at `https://catalog.yourtablecloth.app/SkillCatalog.xml` without requiring a client-side Git checkout. +Run `dotnet run --file src/checkskills.cs -- docs/SkillCatalog.xml docs/SkillCatalog.xsd` and `dotnet run --file src/testskills.cs -- docs/SkillCatalog.xsd` from the repository root. The latter also guards the currently qualified IDs and pinned sources; update it with the [qualification record](SKILL_ELIGIBILITY.md) when that set changes. The [PR workflow](../.github/workflows/skill-catalog.yml) and [Pages workflow](../.github/workflows/publish.yml) run both checks. The existing catalog builder copies `docs` to the Pages output, publishing the XML at `https://catalog.yourtablecloth.app/SkillCatalog.xml` without requiring a client-side Git checkout. These checks do not execute upstream skills. diff --git a/docs/SkillCatalog.xml b/docs/SkillCatalog.xml index 4acef35a..3c71797a 100644 --- a/docs/SkillCatalog.xml +++ b/docs/SkillCatalog.xml @@ -1,5 +1,6 @@ + + 한국은행 ECOS의 기준금리, 물가, 환율과 통화량 통계를 조회합니다. @@ -21,7 +23,7 @@ ECOS에 직접 연결하며 sample 키 또는 사용자 KSKILL_BOK_ECOS_API_KEY를 사용합니다. sample 키는 호출당 최대 10행으로 제한합니다. 실행에는 Node.js 18 이상, npx CLI와 Python 3.9 이상을 사용합니다. - + + + KOSIS의 인구, 가구, 고용과 물가 통계를 검색하고 조회합니다. @@ -112,7 +119,7 @@ 현재 고정 원본에 SKILL.md가 없습니다. Codex 스킬 어댑터를 제공할 때 이 블록의 주석을 해제할 수 있습니다. - + --> 공공기관 보고서와 내부 결재문서의 구성 및 초안 작성을 지원합니다. @@ -141,6 +148,7 @@ 기본 구성에 포함하지 않는 선택 설치 스킬입니다. 별도 API 키를 요구하지 않습니다. 호환되는 Windows Sandbox 환경과 식탁보 AI의 호스트 브리지가 필요합니다. 호스트가 전달한 list, start, stop, connect, ip 결과를 설명하며 스킬 자체가 wsb.exe를 실행하거나 Windows Sandbox를 설치하지 않습니다. 원본 AGPL 라이선스와 별도 상용 라이선스 문의 안내를 함께 보존합니다. + 사용자 입력으로 퍼센트, 할인, 이자, 대출 상환, 날짜, 고정 시차, 단위와 BMI 수치를 계산합니다. diff --git a/docs/skill-eligibility-audit-2026-10-25.json b/docs/skill-eligibility-audit-2026-10-25.json new file mode 100644 index 00000000..ad110d04 --- /dev/null +++ b/docs/skill-eligibility-audit-2026-10-25.json @@ -0,0 +1,372 @@ +{ + "success": true, + "recordedUtc": "2026-10-25T11:00:54.9190451+00:00", + "catalogSha256": "2e019fe43534e5e2290c6daafad98d494ff904b7c1c1654a08806f33d4fbb616", + "catalogEntries": 8, + "profile": "Exact WindowsManagedAiProfile.Configuration in artifact-owned profile; ACL setter excluded after current execution token rejected SetSecurityInfo", + "shellTool": false, + "unifiedExec": false, + "codexVersion": "0.156.1", + "discoverySucceeded": true, + "discoveryFailure": null, + "modelCalls": 0, + "skillScriptCalls": 0, + "liveServiceCalls": 0, + "hostCertificateScans": 0, + "sandboxStateChanges": 0, + "qualification": "Live pinned installation, provenance/license, enable/disable, native skills/list discovery, and removal. Functional eligibility uses reviewed execution dependencies. No model inference or live host/service function run.", + "nativeProcessCalls": 1, + "runtimeMutations": 0, + "temporaryStoreRemoved": true, + "Requests": [ + "https://api.github.com/repos/NomaDamas/k-skill/git/commits/0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/git/trees/de5644940d0a6ef709ab780560425a51d06f6684", + "https://api.github.com/repos/NomaDamas/k-skill/git/trees/1b518f0cdf4e857e0d42401f125efd37a5195495", + "https://api.github.com/repos/NomaDamas/k-skill/git/trees/0ea5d34a8bc71d3015134dccac40a5d4cd00395e", + "https://api.github.com/repos/NomaDamas/k-skill/git/trees/1e795b6f569ddaa7e1ec95078765d5fbcf4c03d2", + "https://api.github.com/repos/NomaDamas/k-skill/contents/bok-ecos-stats/SKILL.md?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/bok-ecos-stats/instruction.md?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/bok-ecos-stats/skill.json?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/bok-ecos-stats/tests/test_bok_ecos.py?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/bok-ecos-stats/scripts/bok_ecos.py?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/LICENSE?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/kimlawtech/korean-jangbu-for/git/commits/592f6d7c7be138ae578be9ed6769239cc527ddea", + "https://api.github.com/repos/kimlawtech/korean-jangbu-for/git/trees/a77d516fc2ee9f215fb2dcf1c7ae43ca15f5cacf", + "https://api.github.com/repos/kimlawtech/korean-jangbu-for/git/trees/8725445353da808d31370bdb4bbed6a53592bccc", + "https://api.github.com/repos/kimlawtech/korean-jangbu-for/git/trees/6aa98e2992aacfb17f5f3f393de0c005950d75c8", + "https://api.github.com/repos/kimlawtech/korean-jangbu-for/contents/skills/korean-jangbu-for/SKILL.md?ref=592f6d7c7be138ae578be9ed6769239cc527ddea", + "https://api.github.com/repos/kimlawtech/korean-jangbu-for/contents/LICENSE?ref=592f6d7c7be138ae578be9ed6769239cc527ddea", + "https://api.github.com/repos/chrisryugj/korean-law-mcp/git/commits/4ccedb0dc89fce164493ffc9019b5ad35cb9b782", + "https://api.github.com/repos/chrisryugj/korean-law-mcp/git/trees/f84ec2202641ad3a54bef95c4b174ff5fc37065a", + "https://api.github.com/repos/chrisryugj/korean-law-mcp/git/trees/3046c9e97e067ac9c75c8cfbf370975597285248", + "https://api.github.com/repos/chrisryugj/korean-law-mcp/git/trees/f930c84f587ce9dddf8241a621cdf0358e033c90", + "https://api.github.com/repos/chrisryugj/korean-law-mcp/contents/skills/korean-law/SKILL.md?ref=4ccedb0dc89fce164493ffc9019b5ad35cb9b782", + "https://api.github.com/repos/chrisryugj/korean-law-mcp/contents/LICENSE?ref=4ccedb0dc89fce164493ffc9019b5ad35cb9b782", + "https://api.github.com/repos/NomaDamas/k-skill/git/trees/7aa5cc70617e9e78ba70ed472410f5281a5432ca", + "https://api.github.com/repos/NomaDamas/k-skill/git/trees/a933686ec3a238339778ae38dc5f3ffab386ce09", + "https://api.github.com/repos/NomaDamas/k-skill/git/trees/f132ad1da7721333ae54060ffc876894f24edc2d", + "https://api.github.com/repos/NomaDamas/k-skill/git/trees/72f4bcffb328716c7247ef4da92f1c7358cd36a5", + "https://api.github.com/repos/NomaDamas/k-skill/git/trees/8c0c5f2d51914c8088ed644033dd0c0db8603ba1", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/SKILL.md?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/instruction.md?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/skill.json?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/tests/__init__.py?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/tests/test_run_kosis_stats.py?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/tests/fixtures/data_response.json?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/tests/fixtures/meta_response.json?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/tests/fixtures/search_response.json?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/scripts/run_kosis_stats.py?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/NomaDamas/k-skill/contents/kosis-stats/references/kosis-openapi-guide.md?ref=0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "https://api.github.com/repos/mouseco/k-gov-skills/git/commits/a55816b9b44e8391576204a095bf6337940d80f3", + "https://api.github.com/repos/mouseco/k-gov-skills/git/trees/6f9998603ca9dc30a16a0945050f2ed44c3b67e8", + "https://api.github.com/repos/mouseco/k-gov-skills/git/trees/f0021146ef30286629146f4e49bad7356ea0805d", + "https://api.github.com/repos/mouseco/k-gov-skills/git/trees/c634d0634b9ed246562d015feee7e7794a868a08", + "https://api.github.com/repos/mouseco/k-gov-skills/git/trees/bd71d8f3c9f54bd9474849962cdb4f9bc06b5ef8", + "https://api.github.com/repos/mouseco/k-gov-skills/contents/skills/official-report-skillset/SKILL.md?ref=a55816b9b44e8391576204a095bf6337940d80f3", + "https://api.github.com/repos/mouseco/k-gov-skills/contents/skills/official-report-skillset/references/document-types.md?ref=a55816b9b44e8391576204a095bf6337940d80f3", + "https://api.github.com/repos/mouseco/k-gov-skills/contents/skills/official-report-skillset/references/quality-checklist.md?ref=a55816b9b44e8391576204a095bf6337940d80f3", + "https://api.github.com/repos/mouseco/k-gov-skills/contents/LICENSE?ref=a55816b9b44e8391576204a095bf6337940d80f3", + "https://api.github.com/repos/yourtablecloth/tablecloth-certificate-expiry/git/commits/9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2", + "https://api.github.com/repos/yourtablecloth/tablecloth-certificate-expiry/git/trees/71a1844022af1cad2a0a43af0e6ace1f3309456d", + "https://api.github.com/repos/yourtablecloth/tablecloth-certificate-expiry/contents/LICENSE-AGPL?ref=9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2", + "https://api.github.com/repos/yourtablecloth/tablecloth-certificate-expiry/contents/LICENSE-COMMERCIAL?ref=9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2", + "https://api.github.com/repos/yourtablecloth/tablecloth-certificate-expiry/contents/README.ko.md?ref=9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2", + "https://api.github.com/repos/yourtablecloth/tablecloth-certificate-expiry/contents/README.md?ref=9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2", + "https://api.github.com/repos/yourtablecloth/tablecloth-certificate-expiry/contents/SKILL.md?ref=9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2", + "https://api.github.com/repos/yourtablecloth/tablecloth-windows-sandbox/git/commits/b9e52bcd303624dbba81e7de66a3f56344e922fe", + "https://api.github.com/repos/yourtablecloth/tablecloth-windows-sandbox/git/trees/921cd139fb06faa24b88deed6a6cbb2228718522", + "https://api.github.com/repos/yourtablecloth/tablecloth-windows-sandbox/contents/LICENSE-AGPL?ref=b9e52bcd303624dbba81e7de66a3f56344e922fe", + "https://api.github.com/repos/yourtablecloth/tablecloth-windows-sandbox/contents/LICENSE-COMMERCIAL?ref=b9e52bcd303624dbba81e7de66a3f56344e922fe", + "https://api.github.com/repos/yourtablecloth/tablecloth-windows-sandbox/contents/README.ko.md?ref=b9e52bcd303624dbba81e7de66a3f56344e922fe", + "https://api.github.com/repos/yourtablecloth/tablecloth-windows-sandbox/contents/README.md?ref=b9e52bcd303624dbba81e7de66a3f56344e922fe", + "https://api.github.com/repos/yourtablecloth/tablecloth-windows-sandbox/contents/SKILL.md?ref=b9e52bcd303624dbba81e7de66a3f56344e922fe", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/git/commits/877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/git/trees/1be78b99dcbd4753134464fc4d99c55b0473e9ae", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/git/trees/490a193d563ddc4eb4d55af9b25d34098e2f7d32", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/git/trees/7191519602ffeb3636fd57a351454d3b9f558140", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/git/trees/a106c18c91658c9a7a11c57a00dfb4ccec64d74f", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/git/trees/f92871598c4ff0f391f6315e0e2aa507d8a3f26f", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/git/trees/6951701241cbfc82832bb995d1b2a82a2ff11011", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/git/trees/468de5136704d1a9b38b4e1d5397d03ef1aa02d2", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/.gitignore?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/CONTRIBUTING.ko.md?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/CONTRIBUTING.md?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/LICENSE-AGPL?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/LICENSE-COMMERCIAL?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/README.ko.md?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/README.md?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/SKILL.md?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/tests/test_calculate.py?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/scripts/calculate.py?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/references/operations.md?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/docs/COPYRIGHT.ko.md?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/docs/COPYRIGHT.md?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c", + "https://api.github.com/repos/yourtablecloth/tablecloth-calculators/contents/.github/workflows/test.yml?ref=877b58cf0741db21342445f2b3fcb54ad1ada85c" + ], + "skills": [ + { + "Id": "bok-ecos-stats", + "Ref": "0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "Repository": "https://github.com/NomaDamas/k-skill", + "SourcePath": "bok-ecos-stats", + "InstalledWithProvenanceAndLicense": true, + "TogglePassed": true, + "NativeDiscovered": true, + "RemovalPassed": true, + "Files": [ + ".tablecloth-source.json", + "instruction.md", + "LICENSE.upstream", + "scripts/bok_ecos.py", + "skill.json", + "SKILL.md", + "tests/test_bok_ecos.py" + ], + "Hashes": { + ".tablecloth-source.json": "24ed60d0cb23627fda41c5b079fb310b8ae5b8b6fcbfae831ced2c9621862058", + "instruction.md": "d03421a7339ecd4b2bbf38aab21bf482bd09f90bda59d0c5b2d0ab08ae9d828f", + "LICENSE.upstream": "1126322e2cc8d165adc4c792eeb195717de2bcc7b39be1ce77959d78e87ef685", + "scripts/bok_ecos.py": "849629392ea51f7ee2fe42e14bc463828b858c60bf3b343d2eefa96766d01e28", + "skill.json": "7d4a48e21ef038da7fafac9b56c6a0508b58a0a1f4584cff1a2b728c304ce12c", + "SKILL.md": "761e08cd63c9840385a7184eb96c85d7e02ac915e998585be882a1cf2433d80c", + "tests/test_bok_ecos.py": "3ef800b1203908c1a9053f1488716969fff4ef9bc21304f93db6f512ba46bf72" + }, + "Failure": null, + "RequiredExecution": "Node CLI and Python helper", + "CurrentHostCompatible": false, + "DiscoveredName": "bok-ecos-stats" + }, + { + "Id": "korean-jangbu-for", + "Ref": "592f6d7c7be138ae578be9ed6769239cc527ddea", + "Repository": "https://github.com/kimlawtech/korean-jangbu-for", + "SourcePath": "skills/korean-jangbu-for", + "InstalledWithProvenanceAndLicense": true, + "TogglePassed": true, + "NativeDiscovered": true, + "RemovalPassed": true, + "Files": [ + ".tablecloth-source.json", + "LICENSE.upstream", + "SKILL.md" + ], + "Hashes": { + ".tablecloth-source.json": "b30f1bdfddeaf0885f42da8df59164e294733c479c41cb6f95a744edef14c43a", + "LICENSE.upstream": "1594cef69754c2de20c830ea145c9c27be899269b8a9cc42cfe47d4878376a64", + "SKILL.md": "567d3c0ba59f071eae8652f848f50aa5abff72e9906e3238783a64a36d34bcc4" + }, + "Failure": null, + "RequiredExecution": "External MCP server and child skills", + "CurrentHostCompatible": false, + "DiscoveredName": "korean-jangbu-for" + }, + { + "Id": "korean-law-mcp", + "Ref": "4ccedb0dc89fce164493ffc9019b5ad35cb9b782", + "Repository": "https://github.com/chrisryugj/korean-law-mcp", + "SourcePath": "skills/korean-law", + "InstalledWithProvenanceAndLicense": true, + "TogglePassed": true, + "NativeDiscovered": true, + "RemovalPassed": true, + "Files": [ + ".tablecloth-source.json", + "LICENSE.upstream", + "SKILL.md" + ], + "Hashes": { + ".tablecloth-source.json": "f4da8b0be8d65272a3f44116b7ceadff09d517c4e3c3dbe325866344f11c4422", + "LICENSE.upstream": "762ebd1a320d004e2b0d3a6651a66237cb490645d48ad5dfb6db9842870f5bc8", + "SKILL.md": "ea2341b42baea22d9b39108ef2244e1f20c200e7caa63201e72be99b4990e0af" + }, + "Failure": null, + "RequiredExecution": "External MCP server", + "CurrentHostCompatible": false, + "DiscoveredName": "korean-law" + }, + { + "Id": "kosis-stats", + "Ref": "0102e5133865f00886e37ac8cf39a49e2c7a3d39", + "Repository": "https://github.com/NomaDamas/k-skill", + "SourcePath": "kosis-stats", + "InstalledWithProvenanceAndLicense": true, + "TogglePassed": true, + "NativeDiscovered": true, + "RemovalPassed": true, + "Files": [ + ".tablecloth-source.json", + "instruction.md", + "LICENSE.upstream", + "references/kosis-openapi-guide.md", + "scripts/run_kosis_stats.py", + "skill.json", + "SKILL.md", + "tests/__init__.py", + "tests/fixtures/data_response.json", + "tests/fixtures/meta_response.json", + "tests/fixtures/search_response.json", + "tests/test_run_kosis_stats.py" + ], + "Hashes": { + ".tablecloth-source.json": "9496402f6825c146fc20c4db40a5de41f767d56d26344ce50cc9c2aae431afa3", + "instruction.md": "0ec6579cf5dbf9e8b4abb8c8dee461dc3fcbb0a1df23606f788f2412e301d8d7", + "LICENSE.upstream": "1126322e2cc8d165adc4c792eeb195717de2bcc7b39be1ce77959d78e87ef685", + "references/kosis-openapi-guide.md": "0187eb775888e9f73bc4f5260c906a648d62fb5ae1a70bbc2512313b3080aaba", + "scripts/run_kosis_stats.py": "b46674eb9b47ab721974fb9a5d178b8acbe0865614d38e2fd8b9ca6510535801", + "skill.json": "51bcde5ed3cc631ea997907af001eb188ae3c9bfe41d4e07d9fb758e1c80314a", + "SKILL.md": "b5e44f2424287021e0e177f15ef63800426e77d804662ae327240e1b616e7807", + "tests/fixtures/data_response.json": "1452e3f14ee8d4cedac5d7a213f33234cda82876b6c512e3a1407ca9989bb166", + "tests/fixtures/meta_response.json": "27665c17af6b850a26d348051aa0d3da36449c769c1e055d26ca4161ffd42a60", + "tests/fixtures/search_response.json": "e5b00512781ab05a13d7b75e32dec3641e46b8830782d0a0b6502179b5d4ebf0", + "tests/test_run_kosis_stats.py": "eeb911c6837b46f6656e62b67ec0ecd322236d91d4f20df2fce1512aca8fd031", + "tests/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "Failure": null, + "RequiredExecution": "Node CLI and Python helper", + "CurrentHostCompatible": false, + "DiscoveredName": "kosis-stats" + }, + { + "Id": "official-report-skillset", + "Ref": "a55816b9b44e8391576204a095bf6337940d80f3", + "Repository": "https://github.com/mouseco/k-gov-skills", + "SourcePath": "skills/official-report-skillset", + "InstalledWithProvenanceAndLicense": true, + "TogglePassed": true, + "NativeDiscovered": true, + "RemovalPassed": true, + "Files": [ + ".tablecloth-source.json", + "LICENSE.upstream", + "references/document-types.md", + "references/quality-checklist.md", + "SKILL.md" + ], + "Hashes": { + ".tablecloth-source.json": "4acb1e5b3c2ffc3ec8f2a7d35933bdf112a27caf675926b23f89364edded7ba5", + "LICENSE.upstream": "ba00729034ae66311a85495e7ed66eb026ff39b9c6d8d9049ca03e767d774525", + "references/document-types.md": "fab29412639a5f007765ba6dd875bb1137ad596b2b74cccf05327f14603f9589", + "references/quality-checklist.md": "5b820dc18515c45984130d5582ab26d283e4c428d961d791b0e4ac5e15ed6017", + "SKILL.md": "66b49ddabdd7d07b417748f98ce9a32db3852958b6c0baa96f5631fbd095ec20" + }, + "Failure": null, + "RequiredExecution": "Instructions and references only", + "CurrentHostCompatible": true, + "DiscoveredName": "official-report-skillset" + }, + { + "Id": "tablecloth-certificate-expiry", + "Ref": "9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2", + "Repository": "https://github.com/yourtablecloth/tablecloth-certificate-expiry", + "SourcePath": ".", + "InstalledWithProvenanceAndLicense": true, + "TogglePassed": true, + "NativeDiscovered": true, + "RemovalPassed": true, + "Files": [ + ".tablecloth-source.json", + "LICENSE-AGPL", + "LICENSE-COMMERCIAL", + "LICENSE.upstream", + "README.ko.md", + "README.md", + "SKILL.md" + ], + "Hashes": { + ".tablecloth-source.json": "23f47488a5f7b25d4be4ab3c341ae703df996434170f42f6a4842c5b85febfb7", + "LICENSE-AGPL": "8486a10c4393cee1c25392769ddd3b2d6c242d6ec7928e1414efff7dfb2f07ef", + "LICENSE-COMMERCIAL": "25dfbd5e0b546f8df2924c3bd678d919e2366c3d298e8d40bb02994c75e52569", + "LICENSE.upstream": "8486a10c4393cee1c25392769ddd3b2d6c242d6ec7928e1414efff7dfb2f07ef", + "README.ko.md": "1d1594a807dbf32a91d16cafd95652a67942837fea2f5fbe4d29d8524f0ee5e0", + "README.md": "d4d17e845c6a7f6e7fa79729ba44c741211a3bce9ee726d0cfee580df1ffc14f", + "SKILL.md": "389abcbaaf333252fcce0e2a2495d41eb549c3e49a0fba98bef133c89f400460" + }, + "Failure": null, + "RequiredExecution": "Existing TableCloth host bridge", + "CurrentHostCompatible": true, + "DiscoveredName": "tablecloth-certificate-expiry" + }, + { + "Id": "tablecloth-windows-sandbox", + "Ref": "b9e52bcd303624dbba81e7de66a3f56344e922fe", + "Repository": "https://github.com/yourtablecloth/tablecloth-windows-sandbox", + "SourcePath": ".", + "InstalledWithProvenanceAndLicense": true, + "TogglePassed": true, + "NativeDiscovered": true, + "RemovalPassed": true, + "Files": [ + ".tablecloth-source.json", + "LICENSE-AGPL", + "LICENSE-COMMERCIAL", + "LICENSE.upstream", + "README.ko.md", + "README.md", + "SKILL.md" + ], + "Hashes": { + ".tablecloth-source.json": "07fc0d37ec9b549606d3c7b158f1ecdbb216b42eb232e80c6eb506c074fccfda", + "LICENSE-AGPL": "8486a10c4393cee1c25392769ddd3b2d6c242d6ec7928e1414efff7dfb2f07ef", + "LICENSE-COMMERCIAL": "25dfbd5e0b546f8df2924c3bd678d919e2366c3d298e8d40bb02994c75e52569", + "LICENSE.upstream": "8486a10c4393cee1c25392769ddd3b2d6c242d6ec7928e1414efff7dfb2f07ef", + "README.ko.md": "3407340002b5dcfbe4bf1ac9e88f70e638e9ee18613c4cfac129eb3f53b7ade1", + "README.md": "dc3b30155986f3b63079fc94acbd8c55993ca8c2a24e2e970fc88e9bd61fc0dd", + "SKILL.md": "88da9d7a0ee137a10061fcfdc68402ab97bbebffc101de4af3b5466eb7b82f09" + }, + "Failure": null, + "RequiredExecution": "Existing TableCloth host bridge", + "CurrentHostCompatible": true, + "DiscoveredName": "tablecloth-windows-sandbox" + }, + { + "Id": "tablecloth-calculators", + "Ref": "877b58cf0741db21342445f2b3fcb54ad1ada85c", + "Repository": "https://github.com/yourtablecloth/tablecloth-calculators", + "SourcePath": ".", + "InstalledWithProvenanceAndLicense": true, + "TogglePassed": true, + "NativeDiscovered": true, + "RemovalPassed": true, + "Files": [ + ".github/workflows/test.yml", + ".gitignore", + ".tablecloth-source.json", + "CONTRIBUTING.ko.md", + "CONTRIBUTING.md", + "docs/COPYRIGHT.ko.md", + "docs/COPYRIGHT.md", + "LICENSE-AGPL", + "LICENSE-COMMERCIAL", + "LICENSE.upstream", + "README.ko.md", + "README.md", + "references/operations.md", + "scripts/calculate.py", + "SKILL.md", + "tests/test_calculate.py" + ], + "Hashes": { + ".github/workflows/test.yml": "b092d6e2978b4584954e3e0a1ffa3faa3522aedbc2f016399bf22ab5c49e7c02", + ".gitignore": "76dd7170f15879a6209a98c6fec53a5d11872cccdacb0af0c7deb111f6d5de06", + ".tablecloth-source.json": "e1f57d806c002e959fc02adf44e4f67be07c4439ce05d8ebb956c23bc0f9f8bb", + "CONTRIBUTING.ko.md": "37341cd208a95ca536aefe137a00417d702bf66674ff83a86aae8561cb6a8954", + "CONTRIBUTING.md": "cfeeb1a72a500bcdd56cdd3fba2e0e4378ed932d7b83efd77201ff55841b85d7", + "docs/COPYRIGHT.ko.md": "3ba70707c6023d5ee7210ae64025ea06566d1bb3195dc81d53f4d59ea0c58472", + "docs/COPYRIGHT.md": "75b74c6036a55da821680650b5c016cdff02091c547f94c8eee2390c110765e9", + "LICENSE-AGPL": "8486a10c4393cee1c25392769ddd3b2d6c242d6ec7928e1414efff7dfb2f07ef", + "LICENSE-COMMERCIAL": "25dfbd5e0b546f8df2924c3bd678d919e2366c3d298e8d40bb02994c75e52569", + "LICENSE.upstream": "8486a10c4393cee1c25392769ddd3b2d6c242d6ec7928e1414efff7dfb2f07ef", + "README.ko.md": "ad32bdea68339077b549a03ce68f8fc31fc2d2e48f8e06643604f0e077560d53", + "README.md": "322ac45d9a2cd1c36696055442c3e8d23d7cc095f36c83ad7af6255337562504", + "references/operations.md": "3e640b19f7bc9b3a4259568ee1164eb7fc71aee1d3da62c1e2d54830eb089863", + "scripts/calculate.py": "279b627d4350b8895717a6ac3597a6e87cab7a9882004d639251ebbee3e7c947", + "SKILL.md": "c8e9c530096d4ecb4341d3c91a102cf795e24b9075558f2b08fe76cf95f152ed", + "tests/test_calculate.py": "2046e01db92c528e4228d4f03e55a30e7b96800e3cc098b97f279182023bd6ae" + }, + "Failure": null, + "RequiredExecution": "Packaged Python script", + "CurrentHostCompatible": false, + "DiscoveredName": "tablecloth-calculators" + } + ] +} \ No newline at end of file diff --git a/src/testskills.cs b/src/testskills.cs index a73b6560..2972b0ce 100644 --- a/src/testskills.cs +++ b/src/testskills.cs @@ -70,6 +70,46 @@ var catalogText = File.ReadAllText(catalogPath); if (!AcceptsXml(catalogText, schemas, out var originalCount)) throw new XmlException("The catalog fixture must pass schema validation before removal checks."); + var current = XDocument.Parse(catalogText).Root!; + if (!MatchesPocEvaluationSources(current)) + { + failures++; + Console.Error.WriteLine("PoC eligibility: the actual catalog contains an ID or pinned source outside this evaluation branch."); + } + var qualifiedFixture = ProductionFixture(); + var eligibility = new (string Name, Action Change, bool Valid)[] + { + ("qualified pinned catalog", _ => { }, true), + ("removal of a qualified skill", xml => xml.Elements("Skill").First().Remove(), true), + ("all qualified skills removed", xml => xml.RemoveNodes(), true), + ("pinned calculator PoC evaluation only", xml => xml.Add(PinnedSkill("tablecloth-calculators", "https://github.com/yourtablecloth/tablecloth-calculators", ".", "877b58cf0741db21342445f2b3fcb54ad1ada85c")), true), + ("pinned BOK PoC evaluation only", xml => xml.Add(PinnedSkill("bok-ecos-stats", "https://github.com/NomaDamas/k-skill", "bok-ecos-stats", "0102e5133865f00886e37ac8cf39a49e2c7a3d39")), true), + ("pinned KOSIS PoC evaluation only", xml => xml.Add(PinnedSkill("kosis-stats", "https://github.com/NomaDamas/k-skill", "kosis-stats", "0102e5133865f00886e37ac8cf39a49e2c7a3d39")), true), + ("unconnected MCP reactivation", xml => xml.Add(PinnedSkill("korean-law-mcp", "https://github.com/chrisryugj/korean-law-mcp", "skills/korean-law", "4ccedb0dc89fce164493ffc9019b5ad35cb9b782")), false), + ("credential-dependent candidate remains deferred", xml => xml.Add(PinnedSkill("k-dart", "https://github.com/NomaDamas/k-skill", "k-dart", "0102e5133865f00886e37ac8cf39a49e2c7a3d39")), false), + ("unqualified skill insertion", xml => + { + var added = new XElement(xml.Elements("Skill").First()); + added.SetAttributeValue("Id", "unqualified-skill"); + xml.Add(added); + }, false), + ("source update without a matching qualification", xml => + { + var skill = xml.Elements("Skill").First(); + var source = skill.Element("Source")!; + var version = new string('2', 40); + source.SetAttributeValue("Ref", version); + skill.Element("License")!.SetAttributeValue("Source", (string?)source.Attribute("Repository") + "/blob/" + version + "/LICENSE"); + }, false), + }; + foreach (var (name, change, expected) in eligibility) + { + var fixture = new XElement(qualifiedFixture); + change(fixture); + if (Accepts(fixture, schemas) && MatchesPocEvaluationSources(fixture) == expected) continue; + failures++; + Console.Error.WriteLine($"Eligibility '{name}': expected {(expected ? "acceptance" : "rejection")}."); + } var removals = 0; foreach (var (id, start, length) in RawSkillSpans(catalogText)) { @@ -81,7 +121,7 @@ } if (removals != originalCount) throw new XmlException("Could not locate every active raw Skill block."); if (failures != 0) return 1; - Console.WriteLine($"All {cases.Length + lifecycle.Length + removals} path, lifecycle and raw-block removal checks passed."); + Console.WriteLine($"All {cases.Length + lifecycle.Length + eligibility.Length + 1 + removals} path, lifecycle, eligibility and raw-block removal checks passed."); return 0; } catch (Exception e) when (e is XmlException or XmlSchemaException or IOException or UnauthorizedAccessException) @@ -104,6 +144,58 @@ static XElement Fixture() => XElement.Parse(""" static bool Accepts(XElement fixture, XmlSchemaSet schemas) => AcceptsXml(fixture.ToString(), schemas, out _); +// The public catalog additionally allows three pinned scripts for hands-on isolated evaluation. +// Inclusion here does not qualify script execution for production TableCloth chat. +static bool MatchesPocEvaluationSources(XElement catalog) +{ + var qualified = PocEvaluationSources(); + return catalog.Elements("Skill").All(skill => + { + if (!qualified.TryGetValue((string?)skill.Attribute("Id") ?? "", out var expected)) return false; + var source = skill.Element("Source"); + return (string?)source?.Attribute("Repository") == expected.Repository && + (string?)source?.Attribute("Path") == expected.Path && + string.Equals((string?)source?.Attribute("Ref"), expected.Ref, StringComparison.OrdinalIgnoreCase); + }); +} + +static Dictionary ProductionSources() => + new(StringComparer.OrdinalIgnoreCase) + { + ["official-report-skillset"] = ("https://github.com/mouseco/k-gov-skills", "skills/official-report-skillset", "a55816b9b44e8391576204a095bf6337940d80f3"), + ["tablecloth-certificate-expiry"] = ("https://github.com/yourtablecloth/tablecloth-certificate-expiry", ".", "9d2eca6431d1cba34bc872b80fc55fa71fa2dcb2"), + ["tablecloth-windows-sandbox"] = ("https://github.com/yourtablecloth/tablecloth-windows-sandbox", ".", "b9e52bcd303624dbba81e7de66a3f56344e922fe"), + }; + +static Dictionary PocEvaluationSources() +{ + var sources = ProductionSources(); + sources.Add("bok-ecos-stats", ("https://github.com/NomaDamas/k-skill", "bok-ecos-stats", "0102e5133865f00886e37ac8cf39a49e2c7a3d39")); + sources.Add("kosis-stats", ("https://github.com/NomaDamas/k-skill", "kosis-stats", "0102e5133865f00886e37ac8cf39a49e2c7a3d39")); + sources.Add("tablecloth-calculators", ("https://github.com/yourtablecloth/tablecloth-calculators", ".", "877b58cf0741db21342445f2b3fcb54ad1ada85c")); + return sources; +} + +static XElement ProductionFixture() +{ + var catalog = new XElement("SkillCatalog", new XAttribute("Version", "1")); + foreach (var (id, source) in ProductionSources()) + catalog.Add(PinnedSkill(id, source.Repository, source.Path, source.Ref)); + return catalog; +} + +static XElement PinnedSkill(string id, string repository, string path, string version) +{ + var skill = new XElement(Fixture().Element("Skill")!); + skill.SetAttributeValue("Id", id); + var source = skill.Element("Source")!; + source.SetAttributeValue("Repository", repository); + source.SetAttributeValue("Path", path); + source.SetAttributeValue("Ref", version); + skill.Element("License")!.SetAttributeValue("Source", repository + "/blob/" + version + "/LICENSE"); + return skill; +} + static bool AcceptsXml(string fixture, XmlSchemaSet schemas, out int activeCount) { activeCount = 0;