@1aboveio/skills 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +13 -0
- package/.codex-plugin/resources.json +1827 -0
- package/README.md +22 -0
- package/package.json +9 -2
- package/skills/app-dev/airflow/SKILL.md +1 -1
- package/skills/app-dev/airflow/release-check.mjs +3 -1
- package/skills/app-dev/android-foundation/SKILL.md +1 -1
- package/skills/app-dev/android-foundation/release-check.mjs +3 -1
- package/skills/app-dev/app-debug/SKILL.md +1 -1
- package/skills/app-dev/app-debug/release-check.mjs +3 -1
- package/skills/app-dev/better-auth/SKILL.md +1 -1
- package/skills/app-dev/better-auth/release-check.mjs +3 -1
- package/skills/app-dev/data-catalog/SKILL.md +1 -1
- package/skills/app-dev/data-catalog/release-check.mjs +3 -1
- package/skills/app-dev/data-quality/SKILL.md +1 -1
- package/skills/app-dev/data-quality/release-check.mjs +3 -1
- package/skills/app-dev/ios-foundation/SKILL.md +1 -1
- package/skills/app-dev/ios-foundation/release-check.mjs +3 -1
- package/skills/app-dev/monorepo/SKILL.md +1 -1
- package/skills/app-dev/monorepo/release-check.mjs +3 -1
- package/skills/app-dev/nextjs-fullstack/SKILL.md +1 -1
- package/skills/app-dev/nextjs-fullstack/release-check.mjs +3 -1
- package/skills/app-dev/prisma-setup/SKILL.md +1 -1
- package/skills/app-dev/prisma-setup/release-check.mjs +3 -1
- package/skills/app-dev/pyspark/SKILL.md +1 -1
- package/skills/app-dev/pyspark/release-check.mjs +3 -1
- package/skills/app-dev/python-backend/SKILL.md +1 -1
- package/skills/app-dev/python-backend/release-check.mjs +3 -1
- package/skills/app-dev/shadcn/SKILL.md +1 -1
- package/skills/app-dev/shadcn/release-check.mjs +3 -1
- package/skills/app-dev/zod-v4/SKILL.md +1 -1
- package/skills/app-dev/zod-v4/release-check.mjs +3 -1
- package/skills/cicd/cloud-build/SKILL.md +1 -1
- package/skills/cicd/cloud-build/release-check.mjs +3 -1
- package/skills/cicd/cloud-debug/SKILL.md +1 -1
- package/skills/cicd/cloud-debug/release-check.mjs +3 -1
- package/skills/cicd/cloud-deploy/SKILL.md +1 -1
- package/skills/cicd/cloud-deploy/release-check.mjs +3 -1
- package/skills/cicd/docker/SKILL.md +1 -1
- package/skills/cicd/docker/release-check.mjs +3 -1
- package/skills/cicd/github-actions/SKILL.md +1 -1
- package/skills/cicd/github-actions/release-check.mjs +3 -1
- package/skills/cicd/github-flow/SKILL.md +1 -1
- package/skills/cicd/github-flow/release-check.mjs +3 -1
- package/skills/cicd/google-cloud/SKILL.md +1 -1
- package/skills/cicd/google-cloud/release-check.mjs +3 -1
- package/skills/cicd/mergify/SKILL.md +1 -1
- package/skills/cicd/mergify/release-check.mjs +3 -1
- package/skills/cicd/podman/SKILL.md +1 -1
- package/skills/cicd/podman/release-check.mjs +3 -1
- package/skills/content/article-review/SKILL.md +1 -1
- package/skills/content/article-review/release-check.mjs +3 -1
- package/skills/content/article-to-image/SKILL.md +1 -1
- package/skills/content/article-to-image/release-check.mjs +3 -1
- package/skills/content/flowchart-svg/SKILL.md +1 -1
- package/skills/content/flowchart-svg/release-check.mjs +3 -1
- package/skills/content/image-gen/SKILL.md +1 -1
- package/skills/content/image-gen/release-check.mjs +3 -1
- package/skills/content/mermaid/SKILL.md +1 -1
- package/skills/content/mermaid/release-check.mjs +3 -1
- package/skills/content/wechat-article-writer/SKILL.md +1 -1
- package/skills/content/wechat-article-writer/release-check.mjs +3 -1
- package/skills/content/wechat-publisher/SKILL.md +1 -1
- package/skills/content/wechat-publisher/release-check.mjs +3 -1
- package/skills/content/wechat-search/SKILL.md +1 -1
- package/skills/content/wechat-search/release-check.mjs +3 -1
- package/skills/content/xai-search/SKILL.md +88 -13
- package/skills/content/xai-search/release-check.mjs +3 -1
- package/skills/content/xai-search/scripts/xai_search.sh +125 -149
- package/skills/core/distill-writing/SKILL.md +1 -1
- package/skills/core/distill-writing/release-check.mjs +3 -1
- package/skills/core/doc-to-md/SKILL.md +1 -1
- package/skills/core/doc-to-md/release-check.mjs +3 -1
- package/skills/core/editorial-review/SKILL.md +1 -1
- package/skills/core/editorial-review/release-check.mjs +3 -1
- package/skills/core/house-style/SKILL.md +1 -1
- package/skills/core/house-style/release-check.mjs +3 -1
- package/skills/core/plain-language/SKILL.md +1 -1
- package/skills/core/plain-language/release-check.mjs +3 -1
- package/skills/core/polish-cn/SKILL.md +1 -1
- package/skills/core/polish-cn/release-check.mjs +3 -1
- package/skills/core/reg-parser/SKILL.md +1 -1
- package/skills/core/reg-parser/release-check.mjs +3 -1
- package/skills/core/terminology/SKILL.md +1 -1
- package/skills/core/terminology/release-check.mjs +3 -1
- package/skills/core/write-doc/SKILL.md +1 -1
- package/skills/core/write-doc/release-check.mjs +3 -1
- package/skills/engineering/better-review/SKILL.md +1 -1
- package/skills/engineering/better-review/release-check.mjs +3 -1
- package/skills/engineering/contributing/SKILL.md +1 -1
- package/skills/engineering/contributing/release-check.mjs +3 -1
- package/skills/engineering/e2e-test/SKILL.md +1 -1
- package/skills/engineering/e2e-test/release-check.mjs +3 -1
- package/skills/engineering/engineering-runtime/SKILL.md +1 -1
- package/skills/engineering/engineering-runtime/coherence/workflow.json +13 -13
- package/skills/engineering/engineering-runtime/release-check.mjs +3 -1
- package/skills/engineering/engineering-runtime/scripts/installation-resolver.mjs +191 -0
- package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +51 -10
- package/skills/engineering/ensure-coverage/SKILL.md +1 -1
- package/skills/engineering/ensure-coverage/release-check.mjs +3 -1
- package/skills/engineering/golden-path/SKILL.md +1 -1
- package/skills/engineering/golden-path/release-check.mjs +3 -1
- package/skills/engineering/harness-runtime/SKILL.md +1 -1
- package/skills/engineering/harness-runtime/release-check.mjs +3 -1
- package/skills/engineering/resolve-issues/SKILL.md +1 -1
- package/skills/engineering/resolve-issues/references/preflight.md +7 -0
- package/skills/engineering/resolve-issues/references/shared-modules.md +27 -0
- package/skills/engineering/resolve-issues/references/task-plan.md +5 -1
- package/skills/engineering/resolve-issues/release-check.mjs +3 -1
- package/skills/engineering/resolve-issues/scripts/active-installation.mjs +32 -0
- package/skills/engineering/resolve-issues/scripts/install-hooks.mjs +3 -0
- package/skills/engineering/resolve-issues/scripts/rehydrate.mjs +17 -1
- package/skills/engineering/resolve-release/SKILL.md +1 -1
- package/skills/engineering/resolve-release/release-check.mjs +3 -1
- package/skills/engineering/rush-issues/SKILL.md +1 -1
- package/skills/engineering/rush-issues/release-check.mjs +3 -1
- package/skills/engineering/rush-release/SKILL.md +1 -1
- package/skills/engineering/rush-release/release-check.mjs +3 -1
- package/skills/engineering/test-quality/SKILL.md +1 -1
- package/skills/engineering/test-quality/release-check.mjs +3 -1
- package/skills/risk-compliance/compliance-audit/SKILL.md +1 -1
- package/skills/risk-compliance/compliance-audit/release-check.mjs +3 -1
- package/skills/risk-compliance/contract-compare/SKILL.md +1 -1
- package/skills/risk-compliance/contract-compare/release-check.mjs +3 -1
- package/skills/risk-compliance/contract-review/SKILL.md +1 -1
- package/skills/risk-compliance/contract-review/release-check.mjs +3 -1
- package/skills/risk-compliance/doc-authenticity/SKILL.md +1 -1
- package/skills/risk-compliance/doc-authenticity/release-check.mjs +3 -1
- package/skills/risk-compliance/fraud-analysis/SKILL.md +1 -1
- package/skills/risk-compliance/fraud-analysis/release-check.mjs +3 -1
- package/skills/risk-compliance/payment-analysis/SKILL.md +1 -1
- package/skills/risk-compliance/payment-analysis/release-check.mjs +3 -1
- package/skills/risk-compliance/similar-domain/SKILL.md +1 -1
- package/skills/risk-compliance/similar-domain/release-check.mjs +3 -1
- package/skills/risk-compliance/tld-detection/SKILL.md +1 -1
- package/skills/risk-compliance/tld-detection/release-check.mjs +3 -1
- package/skills/app-dev/android-foundation/scripts/device-run.test.mjs +0 -436
- package/skills/app-dev/data-catalog/scripts/data-catalog.test.mjs +0 -36
- package/skills/app-dev/data-quality/scripts/data-quality.test.mjs +0 -12
- package/skills/cicd/github-actions/scripts/ci-run-audit.test.mjs +0 -637
- package/skills/cicd/github-flow/scripts/flow.test.mjs +0 -114
- package/skills/cicd/github-flow/scripts/persist-conventions.test.mjs +0 -108
- package/skills/cicd/mergify/scripts/audit.test.mjs +0 -201
- package/skills/cicd/mergify/scripts/entrypoints.test.mjs +0 -106
- package/skills/cicd/mergify/scripts/pr-620-mergify-comments.fixture.json +0 -30
- package/skills/cicd/mergify/scripts/stack-push.test.mjs +0 -233
- package/skills/cicd/mergify/scripts/watch-pr-delivery.test.mjs +0 -1826
- package/skills/content/image-gen/scripts/credentials.test.mjs +0 -212
- package/skills/content/image-gen/scripts/options.test.mjs +0 -245
- package/skills/content/xai-search/tests/smoke_test.sh +0 -36
- package/skills/core/polish-cn/scripts/polish-cn.test.mjs +0 -244
- package/skills/core/reg-parser/scripts/reg-parser.test.mjs +0 -165
- package/skills/engineering/better-review/scripts/pr-context.test.mjs +0 -168
- package/skills/engineering/better-review/scripts/rereview-scope.test.mjs +0 -587
- package/skills/engineering/better-review/scripts/scan-diff.test.mjs +0 -414
- package/skills/engineering/better-review/scripts/vendor-sync.test.mjs +0 -96
- package/skills/engineering/contributing/scripts/persist-conventions.test.mjs +0 -118
- package/skills/engineering/e2e-test/scripts/presentation-checks.test.mjs +0 -106
- package/skills/engineering/e2e-test/scripts/presentation-perceivability.test.mjs +0 -117
- package/skills/engineering/e2e-test/scripts/presentation-reachability.test.mjs +0 -69
- package/skills/engineering/e2e-test/scripts/presentation-render-health.test.mjs +0 -98
- package/skills/engineering/e2e-test/scripts/presentation-sweep.test.mjs +0 -71
- package/skills/engineering/e2e-test/scripts/presentation-temporal.test.mjs +0 -59
- package/skills/engineering/e2e-test/scripts/project-route-manifest.test.mjs +0 -76
- package/skills/engineering/engineering-runtime/engineering-runtime.test.mjs +0 -68
- package/skills/engineering/engineering-runtime/scripts/invocation-policy.test.mjs +0 -95
- package/skills/engineering/engineering-runtime/scripts/main-module.test.mjs +0 -288
- package/skills/engineering/engineering-runtime/scripts/required-check-plan.test.mjs +0 -96
- package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.test.mjs +0 -96
- package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.test.mjs +0 -47
- package/skills/engineering/ensure-coverage/scripts/ci-audit.test.mjs +0 -86
- package/skills/engineering/ensure-coverage/scripts/coverage-ledger.test.mjs +0 -447
- package/skills/engineering/ensure-coverage/scripts/design-parity.test.mjs +0 -552
- package/skills/engineering/ensure-coverage/scripts/lint-tests.test.mjs +0 -289
- package/skills/engineering/ensure-coverage/scripts/mock-policy-config.test.mjs +0 -119
- package/skills/engineering/golden-path/scripts/golden-path.test.mjs +0 -1457
- package/skills/engineering/harness-runtime/discover-models.test.mjs +0 -363
- package/skills/engineering/harness-runtime/harness-runtime.test.mjs +0 -967
- package/skills/engineering/harness-runtime/model-catalog-seed.test.mjs +0 -829
- package/skills/engineering/harness-runtime/model-catalog.test.mjs +0 -366
- package/skills/engineering/resolve-issues/scripts/cleanup-runs.test.mjs +0 -280
- package/skills/engineering/resolve-issues/scripts/dropbox.test.mjs +0 -346
- package/skills/engineering/resolve-issues/scripts/findings-reuse.test.mjs +0 -88
- package/skills/engineering/resolve-issues/scripts/github-reviews.test.mjs +0 -264
- package/skills/engineering/resolve-issues/scripts/install-hooks.test.mjs +0 -79
- package/skills/engineering/resolve-issues/scripts/issue-tree.test.mjs +0 -107
- package/skills/engineering/resolve-issues/scripts/manual-invocation.test.mjs +0 -14
- package/skills/engineering/resolve-issues/scripts/next-actions-capacity.test.mjs +0 -149
- package/skills/engineering/resolve-issues/scripts/next-actions.test.mjs +0 -915
- package/skills/engineering/resolve-issues/scripts/plan-sync.test.mjs +0 -156
- package/skills/engineering/resolve-issues/scripts/preflight-models.test.mjs +0 -448
- package/skills/engineering/resolve-issues/scripts/ready-check.test.mjs +0 -217
- package/skills/engineering/resolve-issues/scripts/rehydrate.test.mjs +0 -91
- package/skills/engineering/resolve-issues/scripts/review-verdict.test.mjs +0 -1060
- package/skills/engineering/resolve-issues/scripts/size-check.test.mjs +0 -458
- package/skills/engineering/resolve-release/scripts/apply.test.mjs +0 -99
- package/skills/engineering/resolve-release/scripts/dark-flags.test.mjs +0 -100
- package/skills/engineering/resolve-release/scripts/flow.test.mjs +0 -340
- package/skills/engineering/resolve-release/scripts/green-head.test.mjs +0 -101
- package/skills/engineering/resolve-release/scripts/npm-version-absence.test.mjs +0 -426
- package/skills/engineering/resolve-release/scripts/plan-npm.test.mjs +0 -659
- package/skills/engineering/resolve-release/scripts/plan-toml-boundary.test.mjs +0 -317
- package/skills/engineering/resolve-release/scripts/plan-uv.test.mjs +0 -291
- package/skills/engineering/resolve-release/scripts/plan.test.mjs +0 -428
- package/skills/engineering/test-quality/scripts/lint-tests.test.mjs +0 -591
- package/skills/engineering/test-quality/scripts/mock-policy-config.test.mjs +0 -119
- package/skills/engineering/test-quality/scripts/persist-conventions.test.mjs +0 -104
- package/skills/risk-compliance/compliance-audit/scripts/compliance-audit.test.mjs +0 -14
- package/skills/risk-compliance/doc-authenticity/manual-invocation.test.mjs +0 -12
- package/skills/risk-compliance/doc-authenticity/scripts/validate_verdict.test.mjs +0 -212
- package/skills/risk-compliance/tld-detection/scripts/detect_ladders.test.mjs +0 -14
- package/skills/risk-compliance/tld-detection/scripts/detect_streams.test.mjs +0 -14
- package/skills/risk-compliance/tld-detection/tests/test_detect_ladders.py +0 -134
- package/skills/risk-compliance/tld-detection/tests/test_detect_streams.py +0 -520
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: e2e-test
|
|
3
3
|
description: "Playwright end-to-end standard: the 3-tier suite (render-health / functional / journey), generated route manifest, and presentation sweep. Use when browser routes or user flows ship or change, or a Playwright test flakes. NOT for non-browser tests, defining what to test (ensure-coverage), the curated ALIVE/DEAD golden-path gate (golden-path), or CI workflow YAML (github-actions)."
|
|
4
|
-
release-version: 0.
|
|
4
|
+
release-version: 0.44.0
|
|
5
5
|
---
|
|
6
6
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
7
7
|
# E2E Testing Standard
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { spawnSync } from 'node:child_process';
|
|
3
3
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
-
import { dirname, join } from 'node:path';
|
|
5
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
|
|
8
8
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -46,6 +46,8 @@ function writeCache(path, value) {
|
|
|
46
46
|
|
|
47
47
|
function main(now = Date.now()) {
|
|
48
48
|
if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
|
|
49
|
+
const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
|
|
50
|
+
if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
|
|
49
51
|
const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
|
|
50
52
|
const name = frontmatterValue(skill, 'name');
|
|
51
53
|
const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
|
|
@@ -3,7 +3,7 @@ name: engineering-runtime
|
|
|
3
3
|
description: Internal support package for shared Engineering Workflow executable behavior. Never select or invoke this package as a user capability.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
user-invocable: false
|
|
6
|
-
release-version: 0.
|
|
6
|
+
release-version: 0.44.0
|
|
7
7
|
---
|
|
8
8
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
9
9
|
# Engineering Runtime
|
|
@@ -369,7 +369,7 @@
|
|
|
369
369
|
"repository": "1aboveio/ai",
|
|
370
370
|
"revision": "main"
|
|
371
371
|
},
|
|
372
|
-
"contentDigest": "
|
|
372
|
+
"contentDigest": "ae8ace5c97889e14e669829d72a92bd90d593ba1099c4bd690c98eca8b9c94e3",
|
|
373
373
|
"digestExcludes": []
|
|
374
374
|
},
|
|
375
375
|
{
|
|
@@ -382,7 +382,7 @@
|
|
|
382
382
|
"repository": "1aboveio/ai",
|
|
383
383
|
"revision": "main"
|
|
384
384
|
},
|
|
385
|
-
"contentDigest": "
|
|
385
|
+
"contentDigest": "ddf8e11e23f667cdc677c9d70edb6ed59da53b5a0b82af29f6be36eda35861c2",
|
|
386
386
|
"digestExcludes": []
|
|
387
387
|
},
|
|
388
388
|
{
|
|
@@ -395,7 +395,7 @@
|
|
|
395
395
|
"repository": "1aboveio/ai",
|
|
396
396
|
"revision": "main"
|
|
397
397
|
},
|
|
398
|
-
"contentDigest": "
|
|
398
|
+
"contentDigest": "0e3c87b01b5c337a7628ae5ba5c78a3b208ab404b8d848e4d8299f221224726d",
|
|
399
399
|
"digestExcludes": []
|
|
400
400
|
},
|
|
401
401
|
{
|
|
@@ -408,7 +408,7 @@
|
|
|
408
408
|
"repository": "1aboveio/ai",
|
|
409
409
|
"revision": "main"
|
|
410
410
|
},
|
|
411
|
-
"contentDigest": "
|
|
411
|
+
"contentDigest": "de98656af030369ea229112e90f441626863dcca5e21f2f358e26041d0624f3e",
|
|
412
412
|
"digestExcludes": []
|
|
413
413
|
},
|
|
414
414
|
{
|
|
@@ -421,7 +421,7 @@
|
|
|
421
421
|
"repository": "1aboveio/ai",
|
|
422
422
|
"revision": "main"
|
|
423
423
|
},
|
|
424
|
-
"contentDigest": "
|
|
424
|
+
"contentDigest": "c4f55e7aed013006d00fde40504db87c32c48ca8b04ef4aeacf9c7fe31995fed",
|
|
425
425
|
"digestExcludes": []
|
|
426
426
|
},
|
|
427
427
|
{
|
|
@@ -434,7 +434,7 @@
|
|
|
434
434
|
"repository": "1aboveio/ai",
|
|
435
435
|
"revision": "main"
|
|
436
436
|
},
|
|
437
|
-
"contentDigest": "
|
|
437
|
+
"contentDigest": "7ec336f6920ec1195fbe08b40234ac72f8213a3b94f575e2c463108b36884a25",
|
|
438
438
|
"digestExcludes": []
|
|
439
439
|
},
|
|
440
440
|
{
|
|
@@ -447,7 +447,7 @@
|
|
|
447
447
|
"repository": "1aboveio/ai",
|
|
448
448
|
"revision": "main"
|
|
449
449
|
},
|
|
450
|
-
"contentDigest": "
|
|
450
|
+
"contentDigest": "845c78252f5308aa71b8eaabc80718c25a772d016d5d74eb888737cd7ffbe664",
|
|
451
451
|
"digestExcludes": []
|
|
452
452
|
},
|
|
453
453
|
{
|
|
@@ -460,7 +460,7 @@
|
|
|
460
460
|
"repository": "1aboveio/ai",
|
|
461
461
|
"revision": "main"
|
|
462
462
|
},
|
|
463
|
-
"contentDigest": "
|
|
463
|
+
"contentDigest": "0c9e35d5014ebd7b4512aeb7705cd39977252ccaa639821fa87f8f463364b613",
|
|
464
464
|
"digestExcludes": []
|
|
465
465
|
},
|
|
466
466
|
{
|
|
@@ -473,7 +473,7 @@
|
|
|
473
473
|
"repository": "1aboveio/ai",
|
|
474
474
|
"revision": "main"
|
|
475
475
|
},
|
|
476
|
-
"contentDigest": "
|
|
476
|
+
"contentDigest": "1c5c3dd92653706d7ca78926f10dbf266e4be4a807e6759ea6e8560b3be72f24",
|
|
477
477
|
"digestExcludes": []
|
|
478
478
|
},
|
|
479
479
|
{
|
|
@@ -486,7 +486,7 @@
|
|
|
486
486
|
"repository": "1aboveio/ai",
|
|
487
487
|
"revision": "main"
|
|
488
488
|
},
|
|
489
|
-
"contentDigest": "
|
|
489
|
+
"contentDigest": "d4f589fdb746755388a47eef8d34670a631584fac2bd32af1550da741434b4d6",
|
|
490
490
|
"digestExcludes": []
|
|
491
491
|
},
|
|
492
492
|
{
|
|
@@ -499,7 +499,7 @@
|
|
|
499
499
|
"repository": "1aboveio/ai",
|
|
500
500
|
"revision": "main"
|
|
501
501
|
},
|
|
502
|
-
"contentDigest": "
|
|
502
|
+
"contentDigest": "d8b6513b1259b3b91f81c4ac9e9ebe66c2c3735534326ee793b99dc305dc3897",
|
|
503
503
|
"digestExcludes": []
|
|
504
504
|
},
|
|
505
505
|
{
|
|
@@ -512,13 +512,13 @@
|
|
|
512
512
|
"repository": "1aboveio/ai",
|
|
513
513
|
"revision": "main"
|
|
514
514
|
},
|
|
515
|
-
"contentDigest": "
|
|
515
|
+
"contentDigest": "bf49dc85c84e81e6561b6682003709bb792f4309a295cddad2c5e97e5e85f5b1",
|
|
516
516
|
"digestExcludes": [
|
|
517
517
|
"coherence/workflow.json"
|
|
518
518
|
]
|
|
519
519
|
}
|
|
520
520
|
],
|
|
521
|
-
"releaseIdentity": "
|
|
521
|
+
"releaseIdentity": "a7f5ec670bb7b0f8dcfb585c5de1d5cfd0bd55799d72e994034674c7c84f5c40",
|
|
522
522
|
"lifecycleAuthority": "native-skills-cli",
|
|
523
523
|
"repairRecipe": {
|
|
524
524
|
"id": "engineering-workflow-dependency-first",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { spawnSync } from 'node:child_process';
|
|
3
3
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
-
import { dirname, join } from 'node:path';
|
|
5
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
|
|
8
8
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -46,6 +46,8 @@ function writeCache(path, value) {
|
|
|
46
46
|
|
|
47
47
|
function main(now = Date.now()) {
|
|
48
48
|
if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
|
|
49
|
+
const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
|
|
50
|
+
if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
|
|
49
51
|
const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
|
|
50
52
|
const name = frontmatterValue(skill, 'name');
|
|
51
53
|
const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, lstatSync, readFileSync, realpathSync } from 'node:fs';
|
|
3
|
+
import { isAbsolute, join, relative, resolve } from 'node:path';
|
|
4
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
5
|
+
import { contentDigest, contentFiles, firstPartySource } from './workflow-coherence.mjs';
|
|
6
|
+
import { reviewedSourceInjections } from './invocation-policy.mjs';
|
|
7
|
+
import { isMainModule } from './main-module.mjs';
|
|
8
|
+
|
|
9
|
+
export const NATIVE_METADATA_PATH = '.codex-plugin/resources.json';
|
|
10
|
+
export const NATIVE_PLUGIN_NAME = '1aboveio-skills';
|
|
11
|
+
const SHA256 = /^[a-f0-9]{64}$/;
|
|
12
|
+
const NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
13
|
+
export const sha256 = (bytes) => createHash('sha256').update(bytes).digest('hex');
|
|
14
|
+
|
|
15
|
+
function freeze(value) {
|
|
16
|
+
if (value && typeof value === 'object') {
|
|
17
|
+
for (const child of Object.values(value)) freeze(child);
|
|
18
|
+
Object.freeze(value);
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function containedPath(root, path) {
|
|
24
|
+
if (!isAbsolute(root) || typeof path !== 'string' || !path || isAbsolute(path)
|
|
25
|
+
|| path.includes('\\') || path.split('/').some((part) => !part || part === '.' || part === '..')) {
|
|
26
|
+
throw new Error('Invalid installation root or relative resource path');
|
|
27
|
+
}
|
|
28
|
+
const target = resolve(root, path);
|
|
29
|
+
if (relative(root, target).startsWith('..')) throw new Error('Resource escapes selected installation');
|
|
30
|
+
// Reject links at every component, including the root. No cache or shared-store fallback.
|
|
31
|
+
if (realpathSync(root) !== root) throw new Error('Selected installation root changed or is ambiguous');
|
|
32
|
+
let current = root;
|
|
33
|
+
for (const part of path.split('/')) {
|
|
34
|
+
current = join(current, part);
|
|
35
|
+
if (lstatSync(current).isSymbolicLink()) throw new Error(`Resource symlink is not supported: ${path}`);
|
|
36
|
+
}
|
|
37
|
+
return target;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function metadataIdentity(metadata) {
|
|
41
|
+
const { releaseIdentity, ...body } = metadata;
|
|
42
|
+
return sha256(JSON.stringify(body));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function validateResourceMetadata(metadata) {
|
|
46
|
+
if (metadata?.schemaVersion !== 1 || metadata.pluginName !== NATIVE_PLUGIN_NAME
|
|
47
|
+
|| metadata.packageName !== '@1aboveio/skills' || !SHA256.test(metadata.releaseIdentity ?? '')
|
|
48
|
+
|| metadataIdentity(metadata) !== metadata.releaseIdentity || !Array.isArray(metadata.members)
|
|
49
|
+
|| metadata.members.length === 0) throw new Error('Invalid native resource metadata identity');
|
|
50
|
+
const names = new Set();
|
|
51
|
+
const paths = new Set();
|
|
52
|
+
for (const member of metadata.members) {
|
|
53
|
+
if (!NAME.test(member.canonicalName ?? '') || names.has(member.canonicalName)
|
|
54
|
+
|| !SHA256.test(member.contentDigest ?? '') || !member.expectedSource
|
|
55
|
+
|| !Array.isArray(member.digestExcludes) || !member.resourceDigests
|
|
56
|
+
|| (firstPartySource(member.expectedSource) && !SHA256.test(member.resourceDigests['SKILL.md'] ?? ''))) throw new Error('Invalid or duplicate resource member');
|
|
57
|
+
names.add(member.canonicalName);
|
|
58
|
+
const source = member.expectedSource;
|
|
59
|
+
if (firstPartySource(source)) {
|
|
60
|
+
if (source.id !== 'first-party' || source.repository !== '1aboveio/ai' || source.revision !== 'main'
|
|
61
|
+
|| !NAME.test(member.packageId ?? '') || member.bundlePath !== `skills/${member.packageId}/${member.canonicalName}`
|
|
62
|
+
|| paths.has(member.bundlePath)) throw new Error('Invalid first-party resource ownership');
|
|
63
|
+
paths.add(member.bundlePath);
|
|
64
|
+
} else if (source.type !== 'external' || !SHA256.test(member.contentDigest)
|
|
65
|
+
|| !/^[a-f0-9]{40}$/.test(source.revision ?? '') || !source.repository) {
|
|
66
|
+
throw new Error('Invalid pinned external identity');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return metadata;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function readPinnedMetadata(root, path, digest, identity) {
|
|
73
|
+
const bytes = readFileSync(containedPath(root, path));
|
|
74
|
+
if (sha256(bytes) !== digest) throw new Error('Resource metadata digest mismatch');
|
|
75
|
+
const metadata = validateResourceMetadata(JSON.parse(bytes));
|
|
76
|
+
if (metadata.releaseIdentity !== identity) throw new Error('Selected release identity mismatch');
|
|
77
|
+
return metadata;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Callers obtain these pins from a verified artifact or trusted generation, not the mutable
|
|
81
|
+
// package group index. The JSON descriptor is safe to persist in a run and pass to workers.
|
|
82
|
+
export function selectInstallation({ layout, root, metadataPath, metadataDigest, releaseIdentity, externalRoots = {} }) {
|
|
83
|
+
if (!['source', 'installed', 'bundle'].includes(layout) || typeof root !== 'string' || !isAbsolute(root)
|
|
84
|
+
|| !SHA256.test(metadataDigest ?? '') || !SHA256.test(releaseIdentity ?? '')) {
|
|
85
|
+
throw new Error('Select one absolute installation root and expected metadata/release identities');
|
|
86
|
+
}
|
|
87
|
+
const canonicalRoot = realpathSync(root);
|
|
88
|
+
if (canonicalRoot !== root) throw new Error('Selected installation root changed or is ambiguous');
|
|
89
|
+
const path = metadataPath ?? (layout === 'bundle' ? NATIVE_METADATA_PATH : null);
|
|
90
|
+
const metadata = readPinnedMetadata(canonicalRoot, path, metadataDigest, releaseIdentity);
|
|
91
|
+
const roots = {};
|
|
92
|
+
for (const [name, mapping] of Object.entries(externalRoots)) {
|
|
93
|
+
const member = metadata.members.find((candidate) => candidate.canonicalName === name);
|
|
94
|
+
if (!member || firstPartySource(member.expectedSource) || !isAbsolute(mapping?.root ?? '')
|
|
95
|
+
|| !isDeepStrictEqual(mapping.expectedSource, member.expectedSource)) {
|
|
96
|
+
throw new Error(`Unknown or unpinned external root: ${name}`);
|
|
97
|
+
}
|
|
98
|
+
const externalRoot = realpathSync(mapping.root);
|
|
99
|
+
if (externalRoot !== mapping.root || externalRoot === canonicalRoot
|
|
100
|
+
|| Object.values(roots).some((entry) => entry.root === externalRoot)) {
|
|
101
|
+
throw new Error(`Ambiguous external root: ${name}`);
|
|
102
|
+
}
|
|
103
|
+
roots[name] = { root: externalRoot, expectedSource: structuredClone(mapping.expectedSource) };
|
|
104
|
+
}
|
|
105
|
+
return freeze({ layout, root: canonicalRoot, metadataPath: path, metadataDigest, releaseIdentity, externalRoots: roots });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function installationMetadata(installation) {
|
|
109
|
+
const selected = selectInstallation(installation);
|
|
110
|
+
return freeze(readPinnedMetadata(selected.root, selected.metadataPath, selected.metadataDigest, selected.releaseIdentity));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function memberPath(installation, member) {
|
|
114
|
+
if (!firstPartySource(member.expectedSource)) {
|
|
115
|
+
const mapping = installation.externalRoots?.[member.canonicalName];
|
|
116
|
+
if (!mapping || !isDeepStrictEqual(mapping.expectedSource, member.expectedSource)) {
|
|
117
|
+
throw new Error(`Missing pinned external dependency: ${member.canonicalName}`);
|
|
118
|
+
}
|
|
119
|
+
// The explicit external root is the member itself, not a directory to search.
|
|
120
|
+
containedPath(mapping.root, 'SKILL.md');
|
|
121
|
+
return mapping.root;
|
|
122
|
+
}
|
|
123
|
+
return containedPath(installation.root, installation.layout === 'bundle' ? member.bundlePath
|
|
124
|
+
: installation.layout === 'installed' ? member.canonicalName : member.sourcePath);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function resolveResource(installation, canonicalName, resource = 'SKILL.md', { hostIdentity = null } = {}) {
|
|
128
|
+
const selected = selectInstallation(installation);
|
|
129
|
+
const metadata = installationMetadata(selected);
|
|
130
|
+
const member = metadata.members.find((candidate) => candidate.canonicalName === canonicalName);
|
|
131
|
+
if (!member) throw new Error(`Unknown canonical skill: ${canonicalName}`);
|
|
132
|
+
if (firstPartySource(member.expectedSource) && !Object.hasOwn(member.resourceDigests, resource)) {
|
|
133
|
+
throw new Error(`Unknown resource: ${canonicalName}/${resource}`);
|
|
134
|
+
}
|
|
135
|
+
const directory = memberPath(selected, member);
|
|
136
|
+
let injected = [];
|
|
137
|
+
if (!firstPartySource(member.expectedSource) && member.invocationPolicy) {
|
|
138
|
+
try { injected = reviewedSourceInjections(directory, member.invocationPolicy); } catch { /* Raw upstream is also allowed. */ }
|
|
139
|
+
}
|
|
140
|
+
const digestOptions = { exclude: member.digestExcludes, published: firstPartySource(member.expectedSource), injected };
|
|
141
|
+
const actual = contentDigest(directory, digestOptions);
|
|
142
|
+
if (actual !== member.contentDigest) throw new Error(`Modified skill resources: ${canonicalName}`);
|
|
143
|
+
const pinned = Object.hasOwn(member.resourceDigests, resource);
|
|
144
|
+
if (!pinned && !contentFiles(directory, digestOptions).some((file) => file.relativePath === resource)) {
|
|
145
|
+
throw new Error(`Unverified resource: ${canonicalName}/${resource}`);
|
|
146
|
+
}
|
|
147
|
+
const path = containedPath(directory, resource);
|
|
148
|
+
const actualResourceDigest = sha256(readFileSync(path));
|
|
149
|
+
if (pinned && actualResourceDigest !== member.resourceDigests[resource]) {
|
|
150
|
+
throw new Error(`Modified resource: ${canonicalName}/${resource}`);
|
|
151
|
+
}
|
|
152
|
+
return freeze({ canonicalName, hostIdentity, path, directory, expectedSource: structuredClone(member.expectedSource),
|
|
153
|
+
contentDigest: actual, resourceDigest: actualResourceDigest, releaseIdentity: selected.releaseIdentity, installation: selected });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function workerResources(installation, requests) {
|
|
157
|
+
if (!Array.isArray(requests) || requests.length === 0) throw new Error('Worker resources must be explicit');
|
|
158
|
+
return freeze(requests.map(({ canonicalName, resource, hostIdentity }) =>
|
|
159
|
+
resolveResource(installation, canonicalName, resource, { hostIdentity })));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function diagnoseOverlap(installation, sharedRoot) {
|
|
163
|
+
if (!isAbsolute(sharedRoot ?? '')) throw new Error('Overlap diagnosis needs an explicit shared root');
|
|
164
|
+
return installationMetadata(installation).members.filter((member) => firstPartySource(member.expectedSource)
|
|
165
|
+
&& existsSync(join(sharedRoot, member.canonicalName, 'SKILL.md')))
|
|
166
|
+
.map((member) => ({ canonicalName: member.canonicalName, selected: memberPath(installation, member),
|
|
167
|
+
shared: join(sharedRoot, member.canonicalName), requiresExplicitSelection: true }));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Identify only the fixed bundle ancestor of a known executing skill. Never scan caches.
|
|
171
|
+
export function executingBundleRoot(skillDirectory) {
|
|
172
|
+
const root = resolve(skillDirectory, '../../..');
|
|
173
|
+
try {
|
|
174
|
+
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
175
|
+
if (pkg.name === '@1aboveio/skills' && existsSync(join(root, NATIVE_METADATA_PATH))
|
|
176
|
+
&& relative(root, skillDirectory).startsWith('skills/')) return root;
|
|
177
|
+
} catch { /* Source and flat installations have no bundle marker. */ }
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (isMainModule(import.meta.url)) {
|
|
182
|
+
try {
|
|
183
|
+
const [command, descriptor, name, resource] = process.argv.slice(2);
|
|
184
|
+
const selected = JSON.parse(readFileSync(descriptor, 'utf8'));
|
|
185
|
+
const result = command === 'select' ? selectInstallation(selected)
|
|
186
|
+
: command === 'resolve' ? resolveResource(selected, name, resource)
|
|
187
|
+
: command === 'overlap' ? diagnoseOverlap(selected, name) : null;
|
|
188
|
+
if (!result) throw new Error('Usage: installation-resolver.mjs <select|resolve|overlap> <descriptor.json> [canonical-name|shared-root] [resource]');
|
|
189
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
190
|
+
} catch (error) { process.stderr.write(`${error.message}\n`); process.exitCode = 1; }
|
|
191
|
+
}
|
|
@@ -3,6 +3,7 @@ import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
|
3
3
|
import { isAbsolute, join, normalize, relative } from 'node:path';
|
|
4
4
|
import { isDeepStrictEqual } from 'node:util';
|
|
5
5
|
|
|
6
|
+
import { containedPath, resolveResource, selectInstallation } from './installation-resolver.mjs';
|
|
6
7
|
import { reviewedSourceInjections } from './invocation-policy.mjs';
|
|
7
8
|
import { isMainModule } from './main-module.mjs';
|
|
8
9
|
import {
|
|
@@ -190,6 +191,7 @@ function collectFiles(baseDir, currentDir, excludedPaths, files, published) {
|
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
/**
|
|
194
|
+
* List the exact digest-covered files, including reviewed replacements for invocation overlays.
|
|
193
195
|
* @param {object} [options]
|
|
194
196
|
* @param {string[]} [options.exclude] member-relative paths to omit
|
|
195
197
|
* @param {object[]} [options.injected] generated content to digest instead of reading from disk
|
|
@@ -198,13 +200,17 @@ function collectFiles(baseDir, currentDir, excludedPaths, files, published) {
|
|
|
198
200
|
* published release; left off for external members, whose authority is the reviewed upstream tree
|
|
199
201
|
* byte for byte. See {@link publishedContentExcluded}.
|
|
200
202
|
*/
|
|
201
|
-
export function
|
|
203
|
+
export function contentFiles(directory, { exclude = [], injected = [], published = false } = {}) {
|
|
202
204
|
const files = [];
|
|
203
205
|
const excluded = new Set(exclude);
|
|
204
206
|
for (const file of injected) excluded.add(file.relativePath);
|
|
205
207
|
collectFiles(directory, directory, excluded, files, published);
|
|
206
208
|
for (const file of injected) files.push({ relativePath: file.relativePath, contents: file.contents });
|
|
207
|
-
files.sort((left, right) => left.relativePath.localeCompare(right.relativePath));
|
|
209
|
+
return files.sort((left, right) => left.relativePath.localeCompare(right.relativePath));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export function contentDigest(directory, options = {}) {
|
|
213
|
+
const files = contentFiles(directory, options);
|
|
208
214
|
const hash = createHash('sha256');
|
|
209
215
|
for (const file of files) {
|
|
210
216
|
hash.update(file.relativePath);
|
|
@@ -354,9 +360,10 @@ function validateManifest(manifest) {
|
|
|
354
360
|
}
|
|
355
361
|
|
|
356
362
|
function memberDirectory(member, options) {
|
|
357
|
-
if (options.
|
|
363
|
+
if (options.installation) return resolveResource(options.installation, member.installName).directory;
|
|
364
|
+
if (options.layout === 'installed') return containedPath(options.skillsRoot, member.installName);
|
|
358
365
|
const sourceRoot = options.sourceRoots?.[member.expectedSource.id];
|
|
359
|
-
return sourceRoot ?
|
|
366
|
+
return sourceRoot ? containedPath(sourceRoot, member.sourcePath) : null;
|
|
360
367
|
}
|
|
361
368
|
|
|
362
369
|
function missingManifestResult(layout, code, detail, invokedSkills) {
|
|
@@ -380,11 +387,32 @@ function missingManifestResult(layout, code, detail, invokedSkills) {
|
|
|
380
387
|
}
|
|
381
388
|
|
|
382
389
|
export function verifyWorkflowCoherence(options = {}) {
|
|
390
|
+
let result;
|
|
391
|
+
try {
|
|
392
|
+
const installation = options.installation ? selectInstallation(options.installation) : null;
|
|
393
|
+
result = verifySelectedWorkflow({ ...options, ...(installation ? { installation, layout: installation.layout } : {}) });
|
|
394
|
+
} catch (error) {
|
|
395
|
+
result = missingManifestResult(options.installation?.layout ?? options.layout ?? 'installed',
|
|
396
|
+
'installation-invalid', error.message, options.invokedSkills);
|
|
397
|
+
}
|
|
398
|
+
if (options.installation?.layout === 'bundle') {
|
|
399
|
+
result.repairRecipe = null;
|
|
400
|
+
for (const entry of result.findings) entry.repairRecipe = null;
|
|
401
|
+
}
|
|
402
|
+
return result;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function verifySelectedWorkflow(options = {}) {
|
|
383
406
|
const layout = options.layout ?? 'installed';
|
|
384
|
-
if (!['installed', 'source'].includes(layout)) {
|
|
407
|
+
if (!['installed', 'source', 'bundle'].includes(layout) || layout === 'bundle' && !options.installation) {
|
|
385
408
|
return missingManifestResult(layout, 'layout-invalid', 'The requested installation layout is unsupported.', options.invokedSkills);
|
|
386
409
|
}
|
|
387
|
-
const
|
|
410
|
+
const selectedManifest = options.installation
|
|
411
|
+
? resolveResource(options.installation, 'engineering-runtime', 'coherence/workflow.json').path : null;
|
|
412
|
+
if (selectedManifest && options.manifestPath && options.manifestPath !== selectedManifest) {
|
|
413
|
+
throw new Error('A selected installation cannot use another coherence manifest');
|
|
414
|
+
}
|
|
415
|
+
const manifestPath = selectedManifest ?? options.manifestPath ?? (layout === 'installed'
|
|
388
416
|
? join(options.skillsRoot ?? '', 'engineering-runtime', 'coherence', 'workflow.json')
|
|
389
417
|
: join(options.sourceRoots?.['first-party'] ?? '', WORKFLOW_COHERENCE_PATH));
|
|
390
418
|
if (!manifestPath || !existsSync(manifestPath)) {
|
|
@@ -451,7 +479,14 @@ export function verifyWorkflowCoherence(options = {}) {
|
|
|
451
479
|
|
|
452
480
|
const selectedMembers = manifest.members.filter((member) => selectedNames.has(member.installName));
|
|
453
481
|
for (const member of selectedMembers) {
|
|
454
|
-
|
|
482
|
+
let directory;
|
|
483
|
+
try { directory = memberDirectory(member, { ...options, layout }); } catch (error) {
|
|
484
|
+
if (error.code !== 'ENOENT') {
|
|
485
|
+
findings.push(finding({ state: 'missing', code: 'member-resolution-invalid', member: member.installName,
|
|
486
|
+
ownership: member.ownership, expectedSource: member.expectedSource, manifest, detail: error.message }));
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
455
490
|
if (!directory || !existsSync(directory)) {
|
|
456
491
|
findings.push(finding({
|
|
457
492
|
state: 'missing',
|
|
@@ -475,7 +510,7 @@ export function verifyWorkflowCoherence(options = {}) {
|
|
|
475
510
|
// proved `expectedSource` deep-equal to the trusted policy above (`member-source-identity-
|
|
476
511
|
// invalid` returns before this loop), so the derivation reads trusted data, not manifest claims.
|
|
477
512
|
let policyInjections = [];
|
|
478
|
-
if (layout
|
|
513
|
+
if (layout !== 'source' && member.invocationPolicy) {
|
|
479
514
|
try {
|
|
480
515
|
policyInjections = reviewedSourceInjections(directory, member.invocationPolicy);
|
|
481
516
|
} catch {
|
|
@@ -520,7 +555,8 @@ export function verifyWorkflowCoherence(options = {}) {
|
|
|
520
555
|
const memberByName = new Map(manifest.members.map((member) => [member.installName, member]));
|
|
521
556
|
for (const identity of selectedGenerated.values()) {
|
|
522
557
|
const member = memberByName.get(identity.member);
|
|
523
|
-
|
|
558
|
+
let directory = null;
|
|
559
|
+
try { directory = member ? memberDirectory(member, { ...options, layout }) : null; } catch { /* Report missing identity below. */ }
|
|
524
560
|
const generatedPath = directory ? join(directory, identity.path) : null;
|
|
525
561
|
let actualDigest = null;
|
|
526
562
|
if (generatedPath && existsSync(generatedPath)) {
|
|
@@ -555,7 +591,8 @@ export function verifyWorkflowCoherence(options = {}) {
|
|
|
555
591
|
export function runWorkflowCoherenceCli(args) {
|
|
556
592
|
if (args[0] !== 'verify') {
|
|
557
593
|
process.stderr.write(
|
|
558
|
-
'Usage: workflow-coherence.mjs verify --
|
|
594
|
+
'Usage: workflow-coherence.mjs verify --installation <descriptor.json> [--invoked-skill <canonical-name>]...\n'
|
|
595
|
+
+ ' or: workflow-coherence.mjs verify --layout installed --skills-root <path> [--manifest <path>] [--invoked-skill <name>]...\n'
|
|
559
596
|
+ ' or: workflow-coherence.mjs verify --layout source --source-root <id=path>... [--manifest <path>] [--invoked-skill <name>]...\n',
|
|
560
597
|
);
|
|
561
598
|
return 2;
|
|
@@ -570,6 +607,10 @@ export function runWorkflowCoherenceCli(args) {
|
|
|
570
607
|
const key = argument === '--layout' ? 'layout' : argument === '--skills-root' ? 'skillsRoot' : 'manifestPath';
|
|
571
608
|
options[key] = value;
|
|
572
609
|
index += 1;
|
|
610
|
+
} else if (argument === '--installation') {
|
|
611
|
+
if (!value) return 2;
|
|
612
|
+
try { options.installation = JSON.parse(readFileSync(value, 'utf8')); } catch { return 2; }
|
|
613
|
+
index += 1;
|
|
573
614
|
} else if (argument === '--source-root') {
|
|
574
615
|
const separator = value?.indexOf('=') ?? -1;
|
|
575
616
|
if (separator < 1 || separator === value.length - 1) return 2;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: ensure-coverage
|
|
3
3
|
description: "Define or audit behavior-first test criteria — ACs, required test levels, mock/integration/E2E policy — across three axes: breadth (Coverage Ledger), depth (over-mocking), presentation (perceivability of browser surfaces). NOT judging whether a single test is any good (test-quality), authoring browser tests (e2e-test), reviewing a PR (better-review), or delivering issues (resolve-issues)."
|
|
4
4
|
disable-model-invocation: true
|
|
5
|
-
release-version: 0.
|
|
5
|
+
release-version: 0.44.0
|
|
6
6
|
---
|
|
7
7
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
8
8
|
# Ensure Coverage
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { spawnSync } from 'node:child_process';
|
|
3
3
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
-
import { dirname, join } from 'node:path';
|
|
5
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
|
|
8
8
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -46,6 +46,8 @@ function writeCache(path, value) {
|
|
|
46
46
|
|
|
47
47
|
function main(now = Date.now()) {
|
|
48
48
|
if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
|
|
49
|
+
const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
|
|
50
|
+
if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
|
|
49
51
|
const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
|
|
50
52
|
const name = frontmatterValue(skill, 'name');
|
|
51
53
|
const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
|
|
@@ -3,7 +3,7 @@ name: golden-path
|
|
|
3
3
|
description: "Golden-path E2E: the short list of user journeys whose failure blocks a release, kept in a repo as one contract (golden-paths.json) with a generated GOLDEN_PATHS.md and a generated GitHub Actions workflow, and run against a local build or a deployed URL for an ALIVE/DEAD verdict. Use to set golden paths up in a repo ('init golden paths', 'add golden-path CI'), to migrate an older smoke.manifest.json or a hand-built smoke setup ('audit', 'migrate smoke'), to add, change, or remove a golden path, to ask 'is the build alive?' or run them before a PR or release, or when a change touches a flow listed in GOLDEN_PATHS.md. NOT for writing the Playwright specs themselves (e2e-test), deciding what a change must prove (ensure-coverage), or general workflow YAML (github-actions)."
|
|
4
4
|
dependencies:
|
|
5
5
|
- e2e-test
|
|
6
|
-
release-version: 0.
|
|
6
|
+
release-version: 0.44.0
|
|
7
7
|
---
|
|
8
8
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
9
9
|
# Golden path
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { spawnSync } from 'node:child_process';
|
|
3
3
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
-
import { dirname, join } from 'node:path';
|
|
5
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
|
|
8
8
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -46,6 +46,8 @@ function writeCache(path, value) {
|
|
|
46
46
|
|
|
47
47
|
function main(now = Date.now()) {
|
|
48
48
|
if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
|
|
49
|
+
const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
|
|
50
|
+
if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
|
|
49
51
|
const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
|
|
50
52
|
const name = frontmatterValue(skill, 'name');
|
|
51
53
|
const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
|
|
@@ -3,7 +3,7 @@ name: harness-runtime
|
|
|
3
3
|
description: Internal import-only library shared by first-party engineering packages. Not a workflow skill; never select or invoke it as a user capability.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
user-invocable: false
|
|
6
|
-
release-version: 0.
|
|
6
|
+
release-version: 0.44.0
|
|
7
7
|
---
|
|
8
8
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
9
9
|
# Harness Runtime
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { spawnSync } from 'node:child_process';
|
|
3
3
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
-
import { dirname, join } from 'node:path';
|
|
5
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
|
|
8
8
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -46,6 +46,8 @@ function writeCache(path, value) {
|
|
|
46
46
|
|
|
47
47
|
function main(now = Date.now()) {
|
|
48
48
|
if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
|
|
49
|
+
const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
|
|
50
|
+
if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
|
|
49
51
|
const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
|
|
50
52
|
const name = frontmatterValue(skill, 'name');
|
|
51
53
|
const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
|
|
@@ -45,6 +45,13 @@ sub-issues, never a checklist.
|
|
|
45
45
|
|
|
46
46
|
### Compaction hook
|
|
47
47
|
|
|
48
|
+
For a native Codex bundle, first follow [Native Codex selection](shared-modules.md#native-codex-selection).
|
|
49
|
+
The hook command returns `plugin-no-global-hooks` and writes nothing, even without
|
|
50
|
+
`--check`. Do not offer a machine-wide cached-path hook. Preserve the installation
|
|
51
|
+
descriptor in the plan and use the selected copy's recovery command after resume.
|
|
52
|
+
Native host compaction/resume still requires separate client certification.
|
|
53
|
+
The remaining hook instructions apply to standalone installations.
|
|
54
|
+
|
|
48
55
|
**A compaction summary keeps the run's state and drops the skill's rules, so
|
|
49
56
|
a hook makes you read the skills again after every compaction.** Check it:
|
|
50
57
|
|
|
@@ -4,6 +4,33 @@ Use the owning skill for models, review, golden paths, and the merge queue; neve
|
|
|
4
4
|
copy its doctrine here. Resolve a leaf skill from the active skills root only
|
|
5
5
|
for a stage that invokes it, and pass its absolute path.
|
|
6
6
|
|
|
7
|
+
## Native Codex selection
|
|
8
|
+
|
|
9
|
+
For a native bundle invocation, run the invoked copy's
|
|
10
|
+
`scripts/active-installation.mjs capture` before spawning workers. Save its JSON as
|
|
11
|
+
`installation` in this run's task plan and as a run-local `installation.json`.
|
|
12
|
+
Capture reads only the executing bundle's fixed ancestor, never another cache.
|
|
13
|
+
A certifier passes independently verified pins as `capture <expected-pins.json>`;
|
|
14
|
+
ordinary capture starts from the artifact selected by Codex. Neither operation is
|
|
15
|
+
a signature or published-artifact certification.
|
|
16
|
+
|
|
17
|
+
Use `scripts/active-installation.mjs worker <installation.json> <canonical-name>...`
|
|
18
|
+
to obtain verified absolute instruction paths. Resolve other resources through
|
|
19
|
+
`engineering-runtime/scripts/installation-resolver.mjs resolve <installation.json>
|
|
20
|
+
<canonical-name> <member-relative-resource>`. Pass those paths and the unchanged
|
|
21
|
+
installation descriptor in worker briefs. Keep the host's observed namespaced
|
|
22
|
+
identity separate from the canonical catalog name; never strip arbitrary prefixes
|
|
23
|
+
to resolve dependencies. Missing, changed or ambiguous resources stop the affected
|
|
24
|
+
workflow; do not search caches, use a shared namesake, or install dependencies.
|
|
25
|
+
Model slots and reviewer independence still follow the policy below.
|
|
26
|
+
|
|
27
|
+
After compaction or resume, run the selected copy's `scripts/rehydrate.mjs --cwd
|
|
28
|
+
<project>` and read the returned instruction paths in full. It verifies the saved
|
|
29
|
+
installation before returning paths and reports blocked recovery on drift. Native
|
|
30
|
+
bundle invocations do not install global hooks. Scripted recovery alone is not
|
|
31
|
+
proof that a Codex surface triggers it; native host compaction/resume certification
|
|
32
|
+
must pass before that surface is advertised as supported.
|
|
33
|
+
|
|
7
34
|
## Model catalog
|
|
8
35
|
|
|
9
36
|
Owner: [`harness-runtime`](../../harness-runtime/) (catalog doctrine and seed
|