@agent-teams/docs-protocol-agent-teams 0.0.0
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/CHANGELOG.md +5 -0
- package/LICENSE +201 -0
- package/README.md +24 -0
- package/assets/catalog.json +1 -0
- package/assets/docs-protocol.yml +14 -0
- package/assets/history/sha256-097df9fe1b90ab45f73389c8b69736f8a54d4199b09536d586222b5a7f0fbb09/caller.yml +13 -0
- package/assets/history/sha256-3e53262efc8a530b532380dac21d876456473d3b88aba20889a1d24823bf3a1b/caller.yml +14 -0
- package/assets/history/sha256-51d3f02a352ce2c3b0a4068a86b6899a57ab54b0a876c468e3fb3e536519caca/caller.yml +14 -0
- package/assets/history/sha256-641265ef9ecff59c16482fdae1bc8fc56002b5a4a1ee34b102438d0ca08a86a3/skill.md +29 -0
- package/assets/history/sha256-7907195753506e4b0f0e89eb3f6e495bacbd79e9b9913c9f60fc4a07dffb22e5/caller.yml +14 -0
- package/assets/history/sha256-7b31cd257532247f64c55a014dc926c601e4d742176cfb8513b6b0d8ab48213e/skill.md +28 -0
- package/assets/history/sha256-d697c5c7c9bcfccfc006fcf7e4d4cc8e7c629f9689781b9b0b50f30d82bc019e/caller.yml +14 -0
- package/assets/history/sha256-f21dc19277a4ba24bcef90a7071c9cf50adf144769f42d6f74ff4eac9ef117cf/caller.yml +14 -0
- package/assets/history/sha256-fd633c3c6337e5cfe51a9f36989bb654381634c5ab4add9e4da71fe40ab4e0dd/caller.yml +14 -0
- package/assets/transition-catalog.json +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -0
- package/dist/composition/managed-cli-input.d.ts +11 -0
- package/dist/composition/managed-cli-input.d.ts.map +1 -0
- package/dist/composition/managed-cli-input.js +52 -0
- package/dist/composition/managed-cli-input.js.map +1 -0
- package/dist/composition/managed-cli.d.ts +2 -0
- package/dist/composition/managed-cli.d.ts.map +1 -0
- package/dist/composition/managed-cli.js +17 -0
- package/dist/composition/managed-cli.js.map +1 -0
- package/dist/composition/qualification-cli.d.ts +2 -0
- package/dist/composition/qualification-cli.d.ts.map +1 -0
- package/dist/composition/qualification-cli.js +119 -0
- package/dist/composition/qualification-cli.js.map +1 -0
- package/dist/consumer-integration/adapters/agents-route-adapter-v1.d.ts +10 -0
- package/dist/consumer-integration/adapters/agents-route-adapter-v1.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/agents-route-adapter-v1.js +99 -0
- package/dist/consumer-integration/adapters/agents-route-adapter-v1.js.map +1 -0
- package/dist/consumer-integration/adapters/bounded-repository-topology.d.ts +8 -0
- package/dist/consumer-integration/adapters/bounded-repository-topology.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/bounded-repository-topology.js +80 -0
- package/dist/consumer-integration/adapters/bounded-repository-topology.js.map +1 -0
- package/dist/consumer-integration/adapters/consumer-integration-node-error.d.ts +5 -0
- package/dist/consumer-integration/adapters/consumer-integration-node-error.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/consumer-integration-node-error.js +9 -0
- package/dist/consumer-integration/adapters/consumer-integration-node-error.js.map +1 -0
- package/dist/consumer-integration/adapters/consumer-integration-schema-validator.d.ts +4 -0
- package/dist/consumer-integration/adapters/consumer-integration-schema-validator.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/consumer-integration-schema-validator.js +51 -0
- package/dist/consumer-integration/adapters/consumer-integration-schema-validator.js.map +1 -0
- package/dist/consumer-integration/adapters/consumer-upgrade-file-projectors.d.ts +21 -0
- package/dist/consumer-integration/adapters/consumer-upgrade-file-projectors.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/consumer-upgrade-file-projectors.js +145 -0
- package/dist/consumer-integration/adapters/consumer-upgrade-file-projectors.js.map +1 -0
- package/dist/consumer-integration/adapters/foundation-known-file-transaction.d.ts +3 -0
- package/dist/consumer-integration/adapters/foundation-known-file-transaction.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/foundation-known-file-transaction.js +7 -0
- package/dist/consumer-integration/adapters/foundation-known-file-transaction.js.map +1 -0
- package/dist/consumer-integration/adapters/github-cohort-authority-reader.d.ts +21 -0
- package/dist/consumer-integration/adapters/github-cohort-authority-reader.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/github-cohort-authority-reader.js +215 -0
- package/dist/consumer-integration/adapters/github-cohort-authority-reader.js.map +1 -0
- package/dist/consumer-integration/adapters/node-consumer-integration-repository.d.ts +13 -0
- package/dist/consumer-integration/adapters/node-consumer-integration-repository.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/node-consumer-integration-repository.js +213 -0
- package/dist/consumer-integration/adapters/node-consumer-integration-repository.js.map +1 -0
- package/dist/consumer-integration/adapters/node-consumer-repository-files.d.ts +11 -0
- package/dist/consumer-integration/adapters/node-consumer-repository-files.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/node-consumer-repository-files.js +81 -0
- package/dist/consumer-integration/adapters/node-consumer-repository-files.js.map +1 -0
- package/dist/consumer-integration/adapters/node-consumer-upgrade-sandbox.d.ts +19 -0
- package/dist/consumer-integration/adapters/node-consumer-upgrade-sandbox.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/node-consumer-upgrade-sandbox.js +307 -0
- package/dist/consumer-integration/adapters/node-consumer-upgrade-sandbox.js.map +1 -0
- package/dist/consumer-integration/adapters/package-consumer-asset-catalog.d.ts +5 -0
- package/dist/consumer-integration/adapters/package-consumer-asset-catalog.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/package-consumer-asset-catalog.js +150 -0
- package/dist/consumer-integration/adapters/package-consumer-asset-catalog.js.map +1 -0
- package/dist/consumer-integration/adapters/pnpm-lockfile-policy-v1.d.ts +3 -0
- package/dist/consumer-integration/adapters/pnpm-lockfile-policy-v1.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/pnpm-lockfile-policy-v1.js +37 -0
- package/dist/consumer-integration/adapters/pnpm-lockfile-policy-v1.js.map +1 -0
- package/dist/consumer-integration/adapters/pnpm-lockfile-validator-v1.d.ts +3 -0
- package/dist/consumer-integration/adapters/pnpm-lockfile-validator-v1.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/pnpm-lockfile-validator-v1.js +120 -0
- package/dist/consumer-integration/adapters/pnpm-lockfile-validator-v1.js.map +1 -0
- package/dist/consumer-integration/adapters/pnpm-manifest-adapter-v1.d.ts +15 -0
- package/dist/consumer-integration/adapters/pnpm-manifest-adapter-v1.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/pnpm-manifest-adapter-v1.js +189 -0
- package/dist/consumer-integration/adapters/pnpm-manifest-adapter-v1.js.map +1 -0
- package/dist/consumer-integration/adapters/pnpm-runtime-closure-v1.d.ts +8 -0
- package/dist/consumer-integration/adapters/pnpm-runtime-closure-v1.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/pnpm-runtime-closure-v1.js +245 -0
- package/dist/consumer-integration/adapters/pnpm-runtime-closure-v1.js.map +1 -0
- package/dist/consumer-integration/adapters/strict-json-record.d.ts +3 -0
- package/dist/consumer-integration/adapters/strict-json-record.d.ts.map +1 -0
- package/dist/consumer-integration/adapters/strict-json-record.js +27 -0
- package/dist/consumer-integration/adapters/strict-json-record.js.map +1 -0
- package/dist/consumer-integration/application/model/consumer-integration-execution.d.ts +11 -0
- package/dist/consumer-integration/application/model/consumer-integration-execution.d.ts.map +1 -0
- package/dist/consumer-integration/application/model/consumer-integration-execution.js +2 -0
- package/dist/consumer-integration/application/model/consumer-integration-execution.js.map +1 -0
- package/dist/consumer-integration/application/model/consumer-upgrade-execution.d.ts +18 -0
- package/dist/consumer-integration/application/model/consumer-upgrade-execution.d.ts.map +1 -0
- package/dist/consumer-integration/application/model/consumer-upgrade-execution.js +2 -0
- package/dist/consumer-integration/application/model/consumer-upgrade-execution.js.map +1 -0
- package/dist/consumer-integration/application/policies/consumer-integration-assets.d.ts +58 -0
- package/dist/consumer-integration/application/policies/consumer-integration-assets.d.ts.map +1 -0
- package/dist/consumer-integration/application/policies/consumer-integration-assets.js +154 -0
- package/dist/consumer-integration/application/policies/consumer-integration-assets.js.map +1 -0
- package/dist/consumer-integration/application/policies/consumer-integration-authority-guards.d.ts +4 -0
- package/dist/consumer-integration/application/policies/consumer-integration-authority-guards.d.ts.map +1 -0
- package/dist/consumer-integration/application/policies/consumer-integration-authority-guards.js +23 -0
- package/dist/consumer-integration/application/policies/consumer-integration-authority-guards.js.map +1 -0
- package/dist/consumer-integration/application/policies/consumer-integration-desired-state.d.ts +4 -0
- package/dist/consumer-integration/application/policies/consumer-integration-desired-state.d.ts.map +1 -0
- package/dist/consumer-integration/application/policies/consumer-integration-desired-state.js +153 -0
- package/dist/consumer-integration/application/policies/consumer-integration-desired-state.js.map +1 -0
- package/dist/consumer-integration/application/policies/consumer-integration-prior-cohort.d.ts +14 -0
- package/dist/consumer-integration/application/policies/consumer-integration-prior-cohort.d.ts.map +1 -0
- package/dist/consumer-integration/application/policies/consumer-integration-prior-cohort.js +186 -0
- package/dist/consumer-integration/application/policies/consumer-integration-prior-cohort.js.map +1 -0
- package/dist/consumer-integration/application/ports/consumer-integration-lifecycle.d.ts +31 -0
- package/dist/consumer-integration/application/ports/consumer-integration-lifecycle.d.ts.map +1 -0
- package/dist/consumer-integration/application/ports/consumer-integration-lifecycle.js +2 -0
- package/dist/consumer-integration/application/ports/consumer-integration-lifecycle.js.map +1 -0
- package/dist/consumer-integration/application/ports/consumer-integration-planners.d.ts +35 -0
- package/dist/consumer-integration/application/ports/consumer-integration-planners.d.ts.map +1 -0
- package/dist/consumer-integration/application/ports/consumer-integration-planners.js +2 -0
- package/dist/consumer-integration/application/ports/consumer-integration-planners.js.map +1 -0
- package/dist/consumer-integration/application/ports/consumer-upgrade.d.ts +28 -0
- package/dist/consumer-integration/application/ports/consumer-upgrade.d.ts.map +1 -0
- package/dist/consumer-integration/application/ports/consumer-upgrade.js +2 -0
- package/dist/consumer-integration/application/ports/consumer-upgrade.js.map +1 -0
- package/dist/consumer-integration/application/use-cases/plan-consumer-integration.d.ts +15 -0
- package/dist/consumer-integration/application/use-cases/plan-consumer-integration.d.ts.map +1 -0
- package/dist/consumer-integration/application/use-cases/plan-consumer-integration.js +350 -0
- package/dist/consumer-integration/application/use-cases/plan-consumer-integration.js.map +1 -0
- package/dist/consumer-integration/application/use-cases/run-consumer-integration.d.ts +29 -0
- package/dist/consumer-integration/application/use-cases/run-consumer-integration.d.ts.map +1 -0
- package/dist/consumer-integration/application/use-cases/run-consumer-integration.js +139 -0
- package/dist/consumer-integration/application/use-cases/run-consumer-integration.js.map +1 -0
- package/dist/consumer-integration/application/use-cases/upgrade-consumer-integration.d.ts +13 -0
- package/dist/consumer-integration/application/use-cases/upgrade-consumer-integration.d.ts.map +1 -0
- package/dist/consumer-integration/application/use-cases/upgrade-consumer-integration.js +134 -0
- package/dist/consumer-integration/application/use-cases/upgrade-consumer-integration.js.map +1 -0
- package/dist/consumer-integration/composition/consumer-integration-cli.d.ts +3 -0
- package/dist/consumer-integration/composition/consumer-integration-cli.d.ts.map +1 -0
- package/dist/consumer-integration/composition/consumer-integration-cli.js +241 -0
- package/dist/consumer-integration/composition/consumer-integration-cli.js.map +1 -0
- package/dist/consumer-integration/composition/consumer-integration-planner.d.ts +19 -0
- package/dist/consumer-integration/composition/consumer-integration-planner.d.ts.map +1 -0
- package/dist/consumer-integration/composition/consumer-integration-planner.js +14 -0
- package/dist/consumer-integration/composition/consumer-integration-planner.js.map +1 -0
- package/dist/consumer-integration/composition/node-consumer-integration.d.ts +26 -0
- package/dist/consumer-integration/composition/node-consumer-integration.d.ts.map +1 -0
- package/dist/consumer-integration/composition/node-consumer-integration.js +38 -0
- package/dist/consumer-integration/composition/node-consumer-integration.js.map +1 -0
- package/dist/consumer-integration/domain/model.d.ts +111 -0
- package/dist/consumer-integration/domain/model.d.ts.map +1 -0
- package/dist/consumer-integration/domain/model.js +2 -0
- package/dist/consumer-integration/domain/model.js.map +1 -0
- package/dist/consumer-integration/generated/canonical-assets.d.ts +5 -0
- package/dist/consumer-integration/generated/canonical-assets.d.ts.map +1 -0
- package/dist/consumer-integration/generated/canonical-assets.js +6 -0
- package/dist/consumer-integration/generated/canonical-assets.js.map +1 -0
- package/dist/consumer-integration/index.d.ts +12 -0
- package/dist/consumer-integration/index.d.ts.map +1 -0
- package/dist/consumer-integration/index.js +7 -0
- package/dist/consumer-integration/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/qualification/index.d.ts +3 -0
- package/dist/qualification/index.d.ts.map +1 -0
- package/dist/qualification/index.js +2 -0
- package/dist/qualification/index.js.map +1 -0
- package/dist/qualification/managed-command-envelope-validator.d.ts +14 -0
- package/dist/qualification/managed-command-envelope-validator.d.ts.map +1 -0
- package/dist/qualification/managed-command-envelope-validator.js +33 -0
- package/dist/qualification/managed-command-envelope-validator.js.map +1 -0
- package/dist/qualification/qualification-v2-runner.d.ts +4 -0
- package/dist/qualification/qualification-v2-runner.d.ts.map +1 -0
- package/dist/qualification/qualification-v2-runner.js +344 -0
- package/dist/qualification/qualification-v2-runner.js.map +1 -0
- package/dist/qualification/v2-contract.d.ts +91 -0
- package/dist/qualification/v2-contract.d.ts.map +1 -0
- package/dist/qualification/v2-contract.js +2 -0
- package/dist/qualification/v2-contract.js.map +1 -0
- package/package.json +66 -0
- package/schemas/docs-consumer-integration-execution/v1.schema.json +29 -0
- package/schemas/docs-consumer-integration-plan/v1.schema.json +63 -0
- package/schemas/docs-consumer-integration-profile/v1.schema.json +110 -0
- package/schemas/docs-consumer-integration-profile/v2.schema.json +283 -0
- package/schemas/docs-consumer-managed-state/v1.schema.json +99 -0
- package/schemas/docs-consumer-upgrade-execution/v1.schema.json +44 -0
- package/schemas/docs-protocol-command-envelope/v1.schema.json +239 -0
- package/schemas/docs-protocol-command-envelope/v2.schema.json +285 -0
- package/schemas/docs-protocol-command-envelope/v3.schema.json +529 -0
- package/schemas/docs-protocol-profile/v1.schema.json +46 -0
- package/schemas/docs-protocol-profile/v2.schema.json +46 -0
- package/schemas/docs-protocol-qualification/v2.schema.json +78 -0
- package/schemas/docs-protocol-qualification-receipt/v2.schema.json +113 -0
- package/schemas/qualified-docs-cohort/v1.schema.json +96 -0
- package/skills/docs/SKILL.md +29 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundation-known-file-transaction.d.ts","sourceRoot":"","sources":["../../../src/consumer-integration/adapters/foundation-known-file-transaction.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,kCAAkC,EACnC,MAAM,wDAAwD,CAAC;AAEhE,eAAO,MAAM,8BAA8B,EAAE,kCAKzC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { applyKnownFileTransaction, inspectKnownFileTransactionBarrier, recoverKnownFileTransaction } from "@agent-teams/repository-mutation";
|
|
2
|
+
export const foundationKnownFileTransaction = Object.freeze({
|
|
3
|
+
inspect: inspectKnownFileTransactionBarrier,
|
|
4
|
+
apply: applyKnownFileTransaction,
|
|
5
|
+
recover: recoverKnownFileTransaction
|
|
6
|
+
});
|
|
7
|
+
//# sourceMappingURL=foundation-known-file-transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundation-known-file-transaction.js","sourceRoot":"","sources":["../../../src/consumer-integration/adapters/foundation-known-file-transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,kCAAkC,EAClC,2BAA2B,EAC5B,MAAM,kCAAkC,CAAC;AAM1C,MAAM,CAAC,MAAM,8BAA8B,GACzC,MAAM,CAAC,MAAM,CAAC;IACZ,OAAO,EAAE,kCAAkC;IAC3C,KAAK,EAAE,yBAAyB;IAChC,OAAO,EAAE,2BAA2B;CACrC,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ConsumerUpgradeAuthorityReader } from "../application/ports/consumer-upgrade.js";
|
|
2
|
+
import type { ConsumerIntegrationDesiredStateV1, ConsumerUpgradeAuthorityV1 } from "../domain/model.js";
|
|
3
|
+
type AuthorityFetch = (input: string | URL | globalThis.Request, init?: RequestInit) => Promise<Response>;
|
|
4
|
+
export declare function projectQualifiedCohortAuthority(input: {
|
|
5
|
+
readonly cohortId: string;
|
|
6
|
+
readonly registry: Record<string, unknown>;
|
|
7
|
+
readonly repository: ConsumerIntegrationDesiredStateV1["repository"];
|
|
8
|
+
readonly revision: string;
|
|
9
|
+
}): ConsumerUpgradeAuthorityV1;
|
|
10
|
+
export declare class GitHubCohortAuthorityReader implements ConsumerUpgradeAuthorityReader {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(fetcher?: AuthorityFetch);
|
|
13
|
+
read(options: {
|
|
14
|
+
readonly cohortId: string;
|
|
15
|
+
readonly repository: ConsumerIntegrationDesiredStateV1["repository"];
|
|
16
|
+
readonly revision?: string;
|
|
17
|
+
}): Promise<ConsumerUpgradeAuthorityV1>;
|
|
18
|
+
}
|
|
19
|
+
export declare const githubCohortAuthorityReader: ConsumerUpgradeAuthorityReader;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=github-cohort-authority-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-cohort-authority-reader.d.ts","sourceRoot":"","sources":["../../../src/consumer-integration/adapters/github-cohort-authority-reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8BAA8B,EAC/B,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EACV,iCAAiC,EACjC,0BAA0B,EAE3B,MAAM,oBAAoB,CAAC;AAkB5B,KAAK,cAAc,GAAG,CACpB,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,UAAU,CAAC,OAAO,EACxC,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAAC;AA+OvB,wBAAgB,+BAA+B,CAAC,KAAK,EAAE;IACrD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,iCAAiC,CAAC,YAAY,CAAC,CAAC;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,GAAG,0BAA0B,CAsB7B;AAED,qBAAa,2BAA4B,YAAW,8BAA8B;;IAGhF,YAAmB,OAAO,GAAE,cAAiC,EAE5D;IAEY,IAAI,CAAC,OAAO,EAAE;QACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,UAAU,EAAE,iCAAiC,CAAC,YAAY,CAAC,CAAC;QACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;KAC5B,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAgBtC;CACF;AAED,eAAO,MAAM,2BAA2B,EAAE,8BACQ,CAAC"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { assertQualifiedDocsCohortBindingV1 } from "../application/policies/consumer-integration-desired-state.js";
|
|
2
|
+
import { ConsumerIntegrationNodeError } from "./consumer-integration-node-error.js";
|
|
3
|
+
import { parseJsonRecord } from "./strict-json-record.js";
|
|
4
|
+
const AUTHORITY_REPOSITORY = "agent-teams-ai/.github";
|
|
5
|
+
const AUTHORITY_PATH = "governance/docs-qualified-cohorts.json";
|
|
6
|
+
const AUTHORITY_API = `https://api.github.com/repos/${AUTHORITY_REPOSITORY}`;
|
|
7
|
+
const AUTHORITY_RAW = `https://raw.githubusercontent.com/${AUTHORITY_REPOSITORY}`;
|
|
8
|
+
const GIT_SHA = /^(?!0{40}$)[0-9a-f]{40}$/u;
|
|
9
|
+
const MAXIMUM_AUTHORITY_BYTES = 8 * 1024 * 1024;
|
|
10
|
+
const MANAGED_PACKAGES = [
|
|
11
|
+
"@agent-teams/docs-protocol",
|
|
12
|
+
"@agent-teams/engineering-foundation"
|
|
13
|
+
];
|
|
14
|
+
function record(value, subject) {
|
|
15
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) ||
|
|
16
|
+
Object.getPrototypeOf(value) !== Object.prototype) {
|
|
17
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", `${subject} must be one plain object.`);
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function array(value, subject) {
|
|
22
|
+
if (!Array.isArray(value) || value.length > 4096) {
|
|
23
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", `${subject} must be one bounded array.`);
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
function string(value, subject) {
|
|
28
|
+
if (typeof value !== "string" || value.length === 0 || value.length > 4096 ||
|
|
29
|
+
value.includes("\u0000")) {
|
|
30
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", `${subject} must be one bounded string.`);
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
async function responseBytes(response, subject) {
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_UNAVAILABLE", `${subject} returned HTTP ${response.status}.`);
|
|
37
|
+
}
|
|
38
|
+
const declared = Number(response.headers.get("content-length") ?? "0");
|
|
39
|
+
if (Number.isFinite(declared) && declared > MAXIMUM_AUTHORITY_BYTES) {
|
|
40
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", `${subject} exceeds the authority size limit.`);
|
|
41
|
+
}
|
|
42
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
43
|
+
if (bytes.byteLength === 0 || bytes.byteLength > MAXIMUM_AUTHORITY_BYTES) {
|
|
44
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", `${subject} has invalid or overlong bytes.`);
|
|
45
|
+
}
|
|
46
|
+
return bytes;
|
|
47
|
+
}
|
|
48
|
+
function timeoutSignal() {
|
|
49
|
+
return AbortSignal.timeout(20_000);
|
|
50
|
+
}
|
|
51
|
+
async function resolveAuthorityRevision(fetcher) {
|
|
52
|
+
const bytes = await responseBytes(await fetcher(`${AUTHORITY_API}/commits/main`, {
|
|
53
|
+
headers: { Accept: "application/vnd.github+json", "User-Agent": "agent-teams-docs" },
|
|
54
|
+
redirect: "error",
|
|
55
|
+
signal: timeoutSignal()
|
|
56
|
+
}), "Central authority revision");
|
|
57
|
+
const response = parseJsonRecord(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
58
|
+
const revision = response["sha"];
|
|
59
|
+
if (typeof revision !== "string" || !GIT_SHA.test(revision)) {
|
|
60
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", "Central authority did not resolve one exact Git revision.");
|
|
61
|
+
}
|
|
62
|
+
return revision;
|
|
63
|
+
}
|
|
64
|
+
async function readAuthorityRegistry(fetcher, revision) {
|
|
65
|
+
const bytes = await responseBytes(await fetcher(`${AUTHORITY_RAW}/${revision}/${AUTHORITY_PATH}`, {
|
|
66
|
+
headers: { Accept: "application/json", "User-Agent": "agent-teams-docs" },
|
|
67
|
+
redirect: "error",
|
|
68
|
+
signal: timeoutSignal()
|
|
69
|
+
}), "Central Cohort registry");
|
|
70
|
+
try {
|
|
71
|
+
return parseJsonRecord(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", "Central Cohort registry is not strict duplicate-free UTF-8 JSON.", { cause: error });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function selectedLifecycleState(events, cohortId) {
|
|
78
|
+
const selected = events.map((value) => record(value, "Cohort lifecycle event"))
|
|
79
|
+
.filter((event) => event["cohort_id"] === cohortId)
|
|
80
|
+
.map((event) => {
|
|
81
|
+
const sequence = event["sequence"];
|
|
82
|
+
if (!Number.isSafeInteger(sequence) || Number(sequence) < 1) {
|
|
83
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", `${cohortId} has an invalid lifecycle sequence.`);
|
|
84
|
+
}
|
|
85
|
+
return { event, sequence: Number(sequence) };
|
|
86
|
+
})
|
|
87
|
+
.toSorted((left, right) => left.sequence - right.sequence);
|
|
88
|
+
if (new Set(selected.map(({ sequence }) => sequence)).size !== selected.length) {
|
|
89
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", `${cohortId} has duplicate lifecycle sequences.`);
|
|
90
|
+
}
|
|
91
|
+
const qualification = selected.filter(({ event }) => event["state"] === "QUALIFIED");
|
|
92
|
+
const last = selected.at(-1);
|
|
93
|
+
if (qualification.length !== 1 || last === undefined) {
|
|
94
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", `${cohortId} does not have one immutable QUALIFIED lifecycle event.`);
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
qualificationEventDigest: string(qualification[0].event["event_digest"], "QUALIFIED event digest"),
|
|
98
|
+
state: string(last.event["state"], "Current Cohort lifecycle state")
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function assertSelectable(source, state, repository) {
|
|
102
|
+
if (state === "RECOMMENDED") {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const canaries = array(source["canary_repositories"], "Cohort canary repositories")
|
|
106
|
+
.map((entry) => record(entry, "Cohort canary repository"));
|
|
107
|
+
if (["QUALIFIED", "CANARY"].includes(state) && canaries.some((entry) => String(entry["repository_id"]) === repository.id)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_COHORT_NOT_SELECTABLE", `${String(source["cohort_id"])} is ${state} and is not selectable for repository ${repository.id}.`);
|
|
111
|
+
}
|
|
112
|
+
function packageProjection(source) {
|
|
113
|
+
const entries = array(source["packages"], "Cohort packages")
|
|
114
|
+
.map((value) => record(value, "Cohort package"));
|
|
115
|
+
const packageByName = new Map(entries.map((entry) => [entry["name"], entry]));
|
|
116
|
+
if (entries.length !== MANAGED_PACKAGES.length ||
|
|
117
|
+
packageByName.size !== MANAGED_PACKAGES.length ||
|
|
118
|
+
MANAGED_PACKAGES.some((name) => !packageByName.has(name))) {
|
|
119
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_INVALID", "Qualified Cohort must select exactly the two managed packages.");
|
|
120
|
+
}
|
|
121
|
+
const docs = packageByName.get(MANAGED_PACKAGES[0]);
|
|
122
|
+
const foundation = packageByName.get(MANAGED_PACKAGES[1]);
|
|
123
|
+
return {
|
|
124
|
+
docsProtocol: {
|
|
125
|
+
version: string(docs["version"], "Docs Protocol version"),
|
|
126
|
+
integrity: string(docs["integrity"], "Docs Protocol integrity")
|
|
127
|
+
},
|
|
128
|
+
engineeringFoundation: {
|
|
129
|
+
version: string(foundation["version"], "Foundation version"),
|
|
130
|
+
integrity: string(foundation["integrity"], "Foundation integrity")
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function cohortProjection(source, qualificationEventDigest) {
|
|
135
|
+
const workflow = record(source["reusable_workflow"], "Cohort reusable workflow");
|
|
136
|
+
const assets = record(source["assets"], "Cohort assets");
|
|
137
|
+
const skill = record(assets["skill"], "Cohort Skill asset");
|
|
138
|
+
const caller = record(assets["caller_workflow"], "Cohort caller workflow asset");
|
|
139
|
+
const assetCatalog = record(assets["asset_catalog"], "Cohort asset catalog");
|
|
140
|
+
const transitionCatalog = record(assets["transition_catalog"], "Cohort transition catalog");
|
|
141
|
+
const runtime = record(source["runtime"], "Cohort runtime");
|
|
142
|
+
const runtimeClosure = record(source["runtime_closure"], "Cohort runtime closure");
|
|
143
|
+
const schemas = record(source["schemas"], "Cohort schemas");
|
|
144
|
+
const projection = {
|
|
145
|
+
schemaVersion: 1,
|
|
146
|
+
cohortId: string(source["cohort_id"], "Cohort ID"),
|
|
147
|
+
channel: string(source["channel"], "Cohort channel"),
|
|
148
|
+
recordDigest: string(source["record_digest"], "Cohort record digest"),
|
|
149
|
+
qualificationEventDigest,
|
|
150
|
+
eligibleAfter: string(source["eligible_after"], "Cohort eligibility timestamp"),
|
|
151
|
+
upgradeFrom: array(source["upgrade_from"], "Cohort upgrade origins").map((entry) => string(entry, "Cohort upgrade origin")),
|
|
152
|
+
rollbackTo: array(source["rollback_to"], "Cohort rollback targets").map((entry) => string(entry, "Cohort rollback target")),
|
|
153
|
+
packages: packageProjection(source),
|
|
154
|
+
workflow: {
|
|
155
|
+
repository: string(workflow["repository"], "Workflow repository"),
|
|
156
|
+
path: string(workflow["path"], "Workflow path"),
|
|
157
|
+
revision: string(workflow["revision"], "Workflow revision"),
|
|
158
|
+
blobSha: string(workflow["blob_sha"], "Workflow blob SHA")
|
|
159
|
+
},
|
|
160
|
+
assets: {
|
|
161
|
+
skillDigest: string(skill["digest"], "Skill digest"),
|
|
162
|
+
callerWorkflowDigest: string(caller["rendered_digest"], "Caller workflow digest"),
|
|
163
|
+
assetCatalogDigest: string(assetCatalog["digest"], "Asset catalog digest"),
|
|
164
|
+
transitionCatalogDigest: string(transitionCatalog["digest"], "Transition catalog digest")
|
|
165
|
+
},
|
|
166
|
+
schemas: {
|
|
167
|
+
consumerIntegration: schemas["consumer_integration"],
|
|
168
|
+
managedState: schemas["managed_state"],
|
|
169
|
+
docsProtocol: schemas["docs_protocol"]
|
|
170
|
+
},
|
|
171
|
+
runtime: {
|
|
172
|
+
node: string(runtime["node"], "Node runtime"),
|
|
173
|
+
pnpm: string(runtime["pnpm"], "pnpm runtime"),
|
|
174
|
+
runtimeClosureDigest: string(runtimeClosure["digest"], "Runtime closure digest")
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
assertQualifiedDocsCohortBindingV1(projection);
|
|
178
|
+
return Object.freeze(projection);
|
|
179
|
+
}
|
|
180
|
+
export function projectQualifiedCohortAuthority(input) {
|
|
181
|
+
const matches = array(input.registry["cohorts"], "Qualified Cohorts")
|
|
182
|
+
.map((value) => record(value, "Qualified Cohort"))
|
|
183
|
+
.filter((cohort) => cohort["cohort_id"] === input.cohortId);
|
|
184
|
+
if (matches.length !== 1) {
|
|
185
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_COHORT_UNKNOWN", `${input.cohortId} is not one exact central Cohort.`);
|
|
186
|
+
}
|
|
187
|
+
const source = matches[0];
|
|
188
|
+
const lifecycle = selectedLifecycleState(array(input.registry["events"], "Cohort lifecycle events"), input.cohortId);
|
|
189
|
+
assertSelectable(source, lifecycle.state, input.repository);
|
|
190
|
+
return Object.freeze({
|
|
191
|
+
repository: AUTHORITY_REPOSITORY,
|
|
192
|
+
path: AUTHORITY_PATH,
|
|
193
|
+
revision: input.revision,
|
|
194
|
+
cohort: cohortProjection(source, lifecycle.qualificationEventDigest)
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
export class GitHubCohortAuthorityReader {
|
|
198
|
+
#fetcher;
|
|
199
|
+
constructor(fetcher = globalThis.fetch) {
|
|
200
|
+
this.#fetcher = fetcher;
|
|
201
|
+
}
|
|
202
|
+
async read(options) {
|
|
203
|
+
if (options.revision !== undefined && !GIT_SHA.test(options.revision)) {
|
|
204
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_REVISION_INVALID", "Authority revision must be one nonzero lowercase Git SHA.");
|
|
205
|
+
}
|
|
206
|
+
const revision = await resolveAuthorityRevision(this.#fetcher);
|
|
207
|
+
if (options.revision !== undefined && options.revision !== revision) {
|
|
208
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_AUTHORITY_REVISION_STALE", "Requested authority revision is not the current protected main revision.");
|
|
209
|
+
}
|
|
210
|
+
const registry = await readAuthorityRegistry(this.#fetcher, revision);
|
|
211
|
+
return projectQualifiedCohortAuthority({ ...options, registry, revision });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
export const githubCohortAuthorityReader = Object.freeze(new GitHubCohortAuthorityReader());
|
|
215
|
+
//# sourceMappingURL=github-cohort-authority-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-cohort-authority-reader.js","sourceRoot":"","sources":["../../../src/consumer-integration/adapters/github-cohort-authority-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ConsumerIntegrationDesiredStateV1, ConsumerIntegrationSnapshot } from "../domain/model.js";
|
|
2
|
+
import type { ConsumerIntegrationInputReader } from "../application/ports/consumer-integration-lifecycle.js";
|
|
3
|
+
export { ConsumerIntegrationNodeError } from "./consumer-integration-node-error.js";
|
|
4
|
+
export declare function readConsumerIntegrationInput(options: {
|
|
5
|
+
readonly consumerRoot: string;
|
|
6
|
+
readonly integrationProfilePath?: string;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
readonly desired: ConsumerIntegrationDesiredStateV1;
|
|
9
|
+
readonly root: string;
|
|
10
|
+
readonly snapshot: ConsumerIntegrationSnapshot;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const nodeConsumerIntegrationInputReader: ConsumerIntegrationInputReader;
|
|
13
|
+
//# sourceMappingURL=node-consumer-integration-repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-consumer-integration-repository.d.ts","sourceRoot":"","sources":["../../../src/consumer-integration/adapters/node-consumer-integration-repository.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iCAAiC,EAEjC,2BAA2B,EAC5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,8BAA8B,EAC/B,MAAM,wDAAwD,CAAC;AAiChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AA4MpF,wBAAsB,4BAA4B,CAAC,OAAO,EAAE;IAC1D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAC1C,GAAG,OAAO,CAAC;IACV,QAAQ,CAAC,OAAO,EAAE,iCAAiC,CAAC;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,2BAA2B,CAAC;CAChD,CAAC,CAsED;AAED,eAAO,MAAM,kCAAkC,EAAE,8BACM,CAAC"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { realpath } from "node:fs/promises";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import { assertConsumerIntegrationProfileSchema } from "./consumer-integration-schema-validator.js";
|
|
5
|
+
import { ConsumerIntegrationNodeError } from "./consumer-integration-node-error.js";
|
|
6
|
+
import { assertQualifiedPnpmLockfileV1 } from "./pnpm-lockfile-validator-v1.js";
|
|
7
|
+
import { parseJsonRecord } from "./strict-json-record.js";
|
|
8
|
+
import { scanConsumerRepositoryTopology } from "./bounded-repository-topology.js";
|
|
9
|
+
import { canonicalConsumerRoot, INTEGRATION_PROFILE_PATH, MAXIMUM_LOCKFILE_BYTES, MAXIMUM_MANAGED_ASSET_BYTES, MAXIMUM_MANIFEST_BYTES, MAXIMUM_PROFILE_BYTES, readStableConsumerFile, sameConsumerFileObservation } from "./node-consumer-repository-files.js";
|
|
10
|
+
function executeGit(root, args, maximumBytes) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
execFile("git", [...args], {
|
|
13
|
+
cwd: root,
|
|
14
|
+
encoding: "utf8",
|
|
15
|
+
maxBuffer: maximumBytes
|
|
16
|
+
}, (error, stdout) => {
|
|
17
|
+
if (error === null) {
|
|
18
|
+
resolve(stdout);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
reject(error);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export { ConsumerIntegrationNodeError } from "./consumer-integration-node-error.js";
|
|
27
|
+
function assertSingleIntegrationTopology(topology) {
|
|
28
|
+
if (topology.lockfiles.length !== 1 || topology.lockfiles[0] !== "pnpm-lock.yaml") {
|
|
29
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_NESTED_LOCKFILE_UNSUPPORTED", "V1 requires exactly one root pnpm-lock.yaml and no nested lockfiles.");
|
|
30
|
+
}
|
|
31
|
+
if (topology.integrationProfiles.length !== 1 ||
|
|
32
|
+
topology.integrationProfiles[0] !== INTEGRATION_PROFILE_PATH) {
|
|
33
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_MULTIPLE_INTEGRATION_UNITS", `V1 requires exactly one integration profile at ${INTEGRATION_PROFILE_PATH}.`);
|
|
34
|
+
}
|
|
35
|
+
if (topology.pnpmfiles.length > 0) {
|
|
36
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_PNPMFILE_UNSUPPORTED", "V1 does not permit .pnpmfile.cjs in the integration repository.");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function assertGitRepositoryRoot(root) {
|
|
40
|
+
let gitRoot;
|
|
41
|
+
try {
|
|
42
|
+
gitRoot = await realpath((await executeGit(root, ["rev-parse", "--show-toplevel"], 64 * 1024)).trim());
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_GIT_ROOT_INVALID", "Consumer root must be the exact top-level directory of one Git repository.", { cause: error });
|
|
46
|
+
}
|
|
47
|
+
if (gitRoot !== root) {
|
|
48
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_GIT_ROOT_INVALID", "Consumer root must equal the Git repository top-level directory.");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function assertNestedAgentsAuthority(topology, governedRoots) {
|
|
52
|
+
const nested = topology.agents.filter((path) => path !== "AGENTS.md");
|
|
53
|
+
const conflicting = governedRoots === undefined
|
|
54
|
+
? nested
|
|
55
|
+
: nested.filter((path) => {
|
|
56
|
+
const authorityRoot = dirname(path);
|
|
57
|
+
return governedRoots.some((docsRoot) => authorityRoot === docsRoot ||
|
|
58
|
+
authorityRoot.startsWith(`${docsRoot}/`) ||
|
|
59
|
+
docsRoot.startsWith(`${authorityRoot}/`));
|
|
60
|
+
});
|
|
61
|
+
if (conflicting.length > 0) {
|
|
62
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_NESTED_AGENTS_UNSUPPORTED", `Nested AGENTS.md overlaps governed documentation authority: ${conflicting.join(", ")}.`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function rejectPrototypeKeys(value, path = "integration profile") {
|
|
66
|
+
if (Array.isArray(value)) {
|
|
67
|
+
value.forEach((entry, index) => {
|
|
68
|
+
rejectPrototypeKeys(entry, `${path}[${index}]`);
|
|
69
|
+
});
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (typeof value !== "object" || value === null) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
76
|
+
if (["__proto__", "constructor", "prototype"].includes(key)) {
|
|
77
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_PROFILE_INVALID", `${path}.${key} is forbidden.`);
|
|
78
|
+
}
|
|
79
|
+
rejectPrototypeKeys(entry, `${path}.${key}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function assertGitHubRuntimeIdentity(desired) {
|
|
83
|
+
const runtimeId = process.env["GITHUB_REPOSITORY_ID"];
|
|
84
|
+
const runtimeName = process.env["GITHUB_REPOSITORY"];
|
|
85
|
+
if (runtimeId !== undefined && runtimeId !== desired.repository.id) {
|
|
86
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_REPOSITORY_ID_MISMATCH", "GitHub runtime repository ID does not match the committed integration profile.");
|
|
87
|
+
}
|
|
88
|
+
if (runtimeName !== undefined && runtimeName.toLowerCase() !==
|
|
89
|
+
desired.repository.nameWithOwner.toLowerCase()) {
|
|
90
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_REPOSITORY_NAME_MISMATCH", "GitHub runtime repository name does not match the committed integration profile.");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function assertQualifiedPnpmRoot(root) {
|
|
94
|
+
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
95
|
+
if (major !== 24 || (minor ?? 0) < 18) {
|
|
96
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_UNSUPPORTED_NODE", "V1 check and plan require Node >=24.18.0 <25.");
|
|
97
|
+
}
|
|
98
|
+
const manifestObservation = await readStableConsumerFile(root, "package.json", MAXIMUM_MANIFEST_BYTES, true);
|
|
99
|
+
if (manifestObservation.state !== "file") {
|
|
100
|
+
throw new Error("unreachable");
|
|
101
|
+
}
|
|
102
|
+
let manifest;
|
|
103
|
+
try {
|
|
104
|
+
manifest = parseJsonRecord(Buffer.from(manifestObservation.bytes).toString("utf8"));
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_MANIFEST_INVALID", error instanceof Error ? error.message : "package.json is invalid.", { cause: error });
|
|
108
|
+
}
|
|
109
|
+
const packageManager = manifest["packageManager"];
|
|
110
|
+
const match = typeof packageManager === "string"
|
|
111
|
+
? /^pnpm@(11)\.([0-9]+)\.([0-9]+)(?:\+sha512\.[A-Za-z0-9+/=]+)?$/u.exec(packageManager)
|
|
112
|
+
: null;
|
|
113
|
+
if (match === null || Number(match[2]) < 17) {
|
|
114
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_UNSUPPORTED_PACKAGE_MANAGER", "V1 requires one exact root packageManager declaration within >=11.17.0 <12.");
|
|
115
|
+
}
|
|
116
|
+
const nodeVersion = await readStableConsumerFile(root, ".node-version", 128, true);
|
|
117
|
+
if (nodeVersion.state !== "file" ||
|
|
118
|
+
!/^24\.(?:1[89]|[2-9][0-9])\.[0-9]+\n?$/u.test(Buffer.from(nodeVersion.bytes).toString("utf8"))) {
|
|
119
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_NODE_VERSION_GATE_INVALID", ".node-version must pin one exact Node version within >=24.18.0 <25.");
|
|
120
|
+
}
|
|
121
|
+
await readStableConsumerFile(root, "pnpm-lock.yaml", MAXIMUM_LOCKFILE_BYTES, true);
|
|
122
|
+
for (const path of ["package-lock.json", "yarn.lock", "bun.lock", "bun.lockb"]) {
|
|
123
|
+
if ((await readStableConsumerFile(root, path, 1024, false)).state !== "absent") {
|
|
124
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_UNSUPPORTED_PACKAGE_MANAGER", `Multiple or unsupported package-manager evidence is present: ${path}.`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async function assertSnapshotStillStable(input) {
|
|
129
|
+
const paths = [
|
|
130
|
+
["integrationProfile", INTEGRATION_PROFILE_PATH, MAXIMUM_PROFILE_BYTES, true],
|
|
131
|
+
["lockfile", "pnpm-lock.yaml", MAXIMUM_LOCKFILE_BYTES, true],
|
|
132
|
+
["packageManifest", "package.json", MAXIMUM_MANIFEST_BYTES, true],
|
|
133
|
+
["agents", "AGENTS.md", MAXIMUM_MANAGED_ASSET_BYTES, false],
|
|
134
|
+
["skill", input.desired.skillPath, MAXIMUM_MANAGED_ASSET_BYTES, false],
|
|
135
|
+
["callerWorkflow", input.desired.callerWorkflowPath, MAXIMUM_MANAGED_ASSET_BYTES, false],
|
|
136
|
+
["managedState", input.desired.managedStatePath, MAXIMUM_MANAGED_ASSET_BYTES, false]
|
|
137
|
+
];
|
|
138
|
+
const reread = await Promise.all(paths.map(([, path, maximum, required]) => readStableConsumerFile(input.root, path, maximum, required)));
|
|
139
|
+
const unstable = paths.find(([key], index) => !sameConsumerFileObservation(input.snapshot[key], reread[index]));
|
|
140
|
+
if (unstable !== undefined) {
|
|
141
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_SNAPSHOT_UNSTABLE", `Consumer integration input changed while the repository snapshot was assembled: ${unstable[1]}.`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function assertQualifiedLockfile(root, desired) {
|
|
145
|
+
const observation = await readStableConsumerFile(root, "pnpm-lock.yaml", MAXIMUM_LOCKFILE_BYTES, true);
|
|
146
|
+
if (observation.state !== "file") {
|
|
147
|
+
throw new Error("unreachable");
|
|
148
|
+
}
|
|
149
|
+
assertQualifiedPnpmLockfileV1(observation.bytes, desired);
|
|
150
|
+
return observation;
|
|
151
|
+
}
|
|
152
|
+
export async function readConsumerIntegrationInput(options) {
|
|
153
|
+
const root = await canonicalConsumerRoot(options.consumerRoot);
|
|
154
|
+
await assertGitRepositoryRoot(root);
|
|
155
|
+
const topology = await scanConsumerRepositoryTopology(root);
|
|
156
|
+
assertSingleIntegrationTopology(topology);
|
|
157
|
+
await assertQualifiedPnpmRoot(root);
|
|
158
|
+
const profilePath = options.integrationProfilePath ?? INTEGRATION_PROFILE_PATH;
|
|
159
|
+
if (profilePath !== INTEGRATION_PROFILE_PATH) {
|
|
160
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_PROFILE_PATH_UNSUPPORTED", `V1 requires the integration profile at ${INTEGRATION_PROFILE_PATH}.`);
|
|
161
|
+
}
|
|
162
|
+
const profile = await readStableConsumerFile(root, profilePath, MAXIMUM_PROFILE_BYTES, true);
|
|
163
|
+
if (profile.state !== "file") {
|
|
164
|
+
throw new Error("unreachable");
|
|
165
|
+
}
|
|
166
|
+
let desired;
|
|
167
|
+
let lockfile;
|
|
168
|
+
try {
|
|
169
|
+
const parsed = parseJsonRecord(Buffer.from(profile.bytes).toString("utf8"));
|
|
170
|
+
rejectPrototypeKeys(parsed);
|
|
171
|
+
await assertConsumerIntegrationProfileSchema(parsed);
|
|
172
|
+
if (parsed.schemaVersion === 2) {
|
|
173
|
+
const { qualification: _qualification, ...v1 } = parsed;
|
|
174
|
+
desired = { ...v1, schemaVersion: 1 };
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
desired = parsed;
|
|
178
|
+
}
|
|
179
|
+
assertNestedAgentsAuthority(topology, desired.governedDocsRoots);
|
|
180
|
+
assertGitHubRuntimeIdentity(desired);
|
|
181
|
+
lockfile = await assertQualifiedLockfile(root, desired);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
if (error instanceof ConsumerIntegrationNodeError) {
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_PROFILE_INVALID", error instanceof Error ? error.message : "Integration profile is invalid.", { cause: error });
|
|
188
|
+
}
|
|
189
|
+
const [packageManifest, agents, skill, callerWorkflow, managedState] = await Promise.all([
|
|
190
|
+
readStableConsumerFile(root, "package.json", MAXIMUM_MANIFEST_BYTES, true),
|
|
191
|
+
readStableConsumerFile(root, "AGENTS.md", MAXIMUM_MANAGED_ASSET_BYTES, false),
|
|
192
|
+
readStableConsumerFile(root, desired.skillPath, MAXIMUM_MANAGED_ASSET_BYTES, false),
|
|
193
|
+
readStableConsumerFile(root, desired.callerWorkflowPath, MAXIMUM_MANAGED_ASSET_BYTES, false),
|
|
194
|
+
readStableConsumerFile(root, desired.managedStatePath, MAXIMUM_MANAGED_ASSET_BYTES, false)
|
|
195
|
+
]);
|
|
196
|
+
const snapshot = {
|
|
197
|
+
integrationProfile: profile,
|
|
198
|
+
lockfile,
|
|
199
|
+
packageManifest,
|
|
200
|
+
agents,
|
|
201
|
+
skill,
|
|
202
|
+
callerWorkflow,
|
|
203
|
+
managedState
|
|
204
|
+
};
|
|
205
|
+
await assertSnapshotStillStable({ root, desired, snapshot });
|
|
206
|
+
return {
|
|
207
|
+
desired,
|
|
208
|
+
root,
|
|
209
|
+
snapshot
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
export const nodeConsumerIntegrationInputReader = Object.freeze({ read: readConsumerIntegrationInput });
|
|
213
|
+
//# sourceMappingURL=node-consumer-integration-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-consumer-integration-repository.js","sourceRoot":"","sources":["../../../src/consumer-integration/adapters/node-consumer-integration-repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ConsumerIntegrationFileObservation } from "../domain/model.js";
|
|
2
|
+
export declare const MAXIMUM_PROFILE_BYTES: number;
|
|
3
|
+
export declare const MAXIMUM_MANIFEST_BYTES: number;
|
|
4
|
+
export declare const MAXIMUM_MANAGED_ASSET_BYTES: number;
|
|
5
|
+
export declare const MAXIMUM_LOCKFILE_BYTES: number;
|
|
6
|
+
export declare const MAXIMUM_WORKSPACE_BYTES: number;
|
|
7
|
+
export declare const INTEGRATION_PROFILE_PATH = "architecture/foundation/docs-consumer-integration.json";
|
|
8
|
+
export declare function canonicalConsumerRoot(consumerRoot: string): Promise<string>;
|
|
9
|
+
export declare function readStableConsumerFile(root: string, repositoryPath: string, maximumBytes: number, required: boolean): Promise<ConsumerIntegrationFileObservation>;
|
|
10
|
+
export declare function sameConsumerFileObservation(left: ConsumerIntegrationFileObservation, right: ConsumerIntegrationFileObservation): boolean;
|
|
11
|
+
//# sourceMappingURL=node-consumer-repository-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-consumer-repository-files.d.ts","sourceRoot":"","sources":["../../../src/consumer-integration/adapters/node-consumer-repository-files.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,kCAAkC,EACnC,MAAM,oBAAoB,CAAC;AAG5B,eAAO,MAAM,qBAAqB,QAAa,CAAC;AAChD,eAAO,MAAM,sBAAsB,QAAc,CAAC;AAClD,eAAO,MAAM,2BAA2B,QAAkB,CAAC;AAC3D,eAAO,MAAM,sBAAsB,QAAmB,CAAC;AACvD,eAAO,MAAM,uBAAuB,QAAkB,CAAC;AACvD,eAAO,MAAM,wBAAwB,2DACqB,CAAC;AAoB3D,wBAAsB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBjF;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,kCAAkC,CAAC,CA8C7C;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,kCAAkC,EACxC,KAAK,EAAE,kCAAkC,GACxC,OAAO,CAIT"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { lstat, open, realpath } from "node:fs/promises";
|
|
3
|
+
import { isAbsolute, relative, resolve as resolvePath, sep } from "node:path";
|
|
4
|
+
import { ConsumerIntegrationNodeError } from "./consumer-integration-node-error.js";
|
|
5
|
+
export const MAXIMUM_PROFILE_BYTES = 256 * 1024;
|
|
6
|
+
export const MAXIMUM_MANIFEST_BYTES = 1024 * 1024;
|
|
7
|
+
export const MAXIMUM_MANAGED_ASSET_BYTES = 8 * 1024 * 1024;
|
|
8
|
+
export const MAXIMUM_LOCKFILE_BYTES = 32 * 1024 * 1024;
|
|
9
|
+
export const MAXIMUM_WORKSPACE_BYTES = 2 * 1024 * 1024;
|
|
10
|
+
export const INTEGRATION_PROFILE_PATH = "architecture/foundation/docs-consumer-integration.json";
|
|
11
|
+
function errorCode(error) {
|
|
12
|
+
return error instanceof Error && "code" in error
|
|
13
|
+
? error.code
|
|
14
|
+
: undefined;
|
|
15
|
+
}
|
|
16
|
+
function contained(root, repositoryPath) {
|
|
17
|
+
const absolute = resolvePath(root, repositoryPath);
|
|
18
|
+
const relation = relative(root, absolute);
|
|
19
|
+
if (relation === ".." || relation.startsWith(`..${sep}`) || isAbsolute(relation)) {
|
|
20
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_PATH_ESCAPE", `Consumer integration path escapes the repository root: ${repositoryPath}.`);
|
|
21
|
+
}
|
|
22
|
+
return absolute;
|
|
23
|
+
}
|
|
24
|
+
export async function canonicalConsumerRoot(consumerRoot) {
|
|
25
|
+
const requested = resolvePath(consumerRoot);
|
|
26
|
+
let metadata;
|
|
27
|
+
try {
|
|
28
|
+
metadata = await lstat(requested);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_ROOT_INVALID", "Consumer root is unavailable or is not a real directory.", { cause: error });
|
|
32
|
+
}
|
|
33
|
+
if (metadata.isSymbolicLink() || !metadata.isDirectory()) {
|
|
34
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_ROOT_INVALID", "Consumer root must be one real directory.");
|
|
35
|
+
}
|
|
36
|
+
return realpath(requested);
|
|
37
|
+
}
|
|
38
|
+
export async function readStableConsumerFile(root, repositoryPath, maximumBytes, required) {
|
|
39
|
+
const path = contained(root, repositoryPath);
|
|
40
|
+
let handle;
|
|
41
|
+
try {
|
|
42
|
+
handle = await open(path, constants.O_RDONLY |
|
|
43
|
+
(process.platform === "win32" ? 0 : constants.O_NOFOLLOW));
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (!required && errorCode(error) === "ENOENT") {
|
|
47
|
+
return { state: "absent" };
|
|
48
|
+
}
|
|
49
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_INPUT_MISSING", `Required consumer integration input is unavailable: ${repositoryPath}.`, { cause: error });
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const before = await handle.stat({ bigint: true });
|
|
53
|
+
if (!before.isFile() || before.nlink > 1n || before.size > BigInt(maximumBytes)) {
|
|
54
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_INPUT_INVALID", `Consumer integration input must be one bounded, non-hardlinked regular file: ${repositoryPath}.`);
|
|
55
|
+
}
|
|
56
|
+
const bytes = await handle.readFile();
|
|
57
|
+
const [after, pathState, canonical] = await Promise.all([
|
|
58
|
+
handle.stat({ bigint: true }),
|
|
59
|
+
lstat(path, { bigint: true }),
|
|
60
|
+
realpath(path)
|
|
61
|
+
]);
|
|
62
|
+
if (pathState.isSymbolicLink() || canonical !== path ||
|
|
63
|
+
before.dev !== after.dev || before.ino !== after.ino ||
|
|
64
|
+
before.birthtimeNs !== after.birthtimeNs || before.ctimeNs !== after.ctimeNs ||
|
|
65
|
+
before.mtimeNs !== after.mtimeNs || before.size !== after.size ||
|
|
66
|
+
pathState.dev !== after.dev || pathState.ino !== after.ino ||
|
|
67
|
+
bytes.byteLength !== Number(after.size)) {
|
|
68
|
+
throw new ConsumerIntegrationNodeError("DOCS_CONSUMER_INPUT_UNSTABLE", `Consumer integration input changed during observation: ${repositoryPath}.`);
|
|
69
|
+
}
|
|
70
|
+
return { state: "file", bytes, mode: Number(after.mode) & 0o777 };
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
await handle.close();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function sameConsumerFileObservation(left, right) {
|
|
77
|
+
return left.state === right.state && (left.state === "absent" ||
|
|
78
|
+
(right.state === "file" && left.mode === right.mode &&
|
|
79
|
+
Buffer.from(left.bytes).equals(Buffer.from(right.bytes))));
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=node-consumer-repository-files.js.map
|