From 5120cdd04fae0aab8c5c555f7b0518e49fd58674 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:56:02 -0300 Subject: [PATCH 01/20] fix(uads): add systems-runtime domain vocabulary --- src/kernel/domains.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/kernel/domains.ts b/src/kernel/domains.ts index 4e2a144..331e500 100644 --- a/src/kernel/domains.ts +++ b/src/kernel/domains.ts @@ -21,6 +21,14 @@ export const DOMAIN_IDS = [ "tokenomics", "mathematics-simulation", "game-systems", + "rust", + "kernel-runtime", + "contracts", + "event-driven-systems", + "state-recovery", + "offline-first", + "testing", + "certification", "documentation", "release", ] as const; From 84b3c1e81d5e6e749ab268fa41fbf9a93f038c3e Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:56:05 -0300 Subject: [PATCH 02/20] fix(uads): add systems runtime specialist function --- src/kernel/specialist-types.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kernel/specialist-types.ts b/src/kernel/specialist-types.ts index 69b69b2..cbff3aa 100644 --- a/src/kernel/specialist-types.ts +++ b/src/kernel/specialist-types.ts @@ -32,7 +32,8 @@ export type SpecialistFunction = | "game-systems" | "documentation" | "release" - | "quality"; + | "quality" + | "systems-runtime"; export type SpecialistActivation = { scopeClasses?: ScopeClass[]; From 10a98b02989fce42fe857f6a859370c5350ba790 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:56:08 -0300 Subject: [PATCH 03/20] fix(uads): allow systems runtime specialist function --- src/kernel/specialist-registry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/specialist-registry.ts b/src/kernel/specialist-registry.ts index 37a13ba..9cc296c 100644 --- a/src/kernel/specialist-registry.ts +++ b/src/kernel/specialist-registry.ts @@ -33,7 +33,7 @@ const FUNCTIONS: SpecialistFunction[] = [ "inspect", "requirements", "architecture", "planning", "implementation", "testing", "independent-review", "security-assurance", "performance-assurance", "reliability-assurance", "checkpoint", "frontend", "backend-api", "database", "mobile", "platform-cloud", "data-ai", "web3-contract", "finance-math", "game-systems", - "documentation", "release", "quality", + "documentation", "release", "quality", "systems-runtime", ]; const PROFILE_KEYS = [ "schema", "schemaVersion", "specialistId", "kind", "status", "purpose", "coveredDomains", "functions", From 7ec01d73b97c60757cab0ec6a6317e310803cc48 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:56:11 -0300 Subject: [PATCH 04/20] fix(uads): extend specialist profile schema for systems domains --- schemas/specialist-profile.schema.json | 280 ++++++++++++++++++++++--- 1 file changed, 255 insertions(+), 25 deletions(-) diff --git a/schemas/specialist-profile.schema.json b/schemas/specialist-profile.schema.json index db6b75c..f3b2182 100644 --- a/schemas/specialist-profile.schema.json +++ b/schemas/specialist-profile.schema.json @@ -4,37 +4,267 @@ "title": "UADS Specialist Profile", "type": "object", "additionalProperties": false, - "required": ["schema", "schemaVersion", "specialistId", "kind", "status", "purpose", "coveredDomains", "functions", "mayImplement", "reviewOnly", "independenceClass", "activation", "requiredInputs", "producesEvidence", "incompatibleWith", "priority", "source", "notes", "profileDigest"], + "required": [ + "schema", + "schemaVersion", + "specialistId", + "kind", + "status", + "purpose", + "coveredDomains", + "functions", + "mayImplement", + "reviewOnly", + "independenceClass", + "activation", + "requiredInputs", + "producesEvidence", + "incompatibleWith", + "priority", + "source", + "notes", + "profileDigest" + ], "properties": { - "schema": { "const": "uads.specialist-profile" }, - "schemaVersion": { "const": "0.9.0" }, - "specialistId": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]{0,95}$" }, - "kind": { "enum": ["core", "domain", "assurance"] }, - "status": { "enum": ["enabled", "disabled", "experimental"] }, - "purpose": { "type": "string", "minLength": 1, "maxLength": 240 }, - "coveredDomains": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "enum": ["general", "requirements", "architecture", "frontend", "backend", "api", "database", "saas", "mobile", "cloud-devops", "security", "quality", "performance", "reliability", "data-ai", "web3", "smart-contracts", "wallets", "finance-economics", "tokenomics", "mathematics-simulation", "game-systems", "documentation", "release"] } }, - "functions": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "enum": ["inspect", "requirements", "architecture", "planning", "implementation", "testing", "independent-review", "security-assurance", "performance-assurance", "reliability-assurance", "checkpoint", "frontend", "backend-api", "database", "mobile", "platform-cloud", "data-ai", "web3-contract", "finance-math", "game-systems", "documentation", "release", "quality"] } }, - "mayImplement": { "type": "boolean" }, - "reviewOnly": { "type": "boolean" }, - "independenceClass": { "enum": ["implementation", "support", "independent-review", "assurance"] }, + "schema": { + "const": "uads.specialist-profile" + }, + "schemaVersion": { + "const": "0.9.0" + }, + "specialistId": { + "type": "string", + "pattern": "^[a-z0-9][a-z0-9-]{0,95}$" + }, + "kind": { + "enum": [ + "core", + "domain", + "assurance" + ] + }, + "status": { + "enum": [ + "enabled", + "disabled", + "experimental" + ] + }, + "purpose": { + "type": "string", + "minLength": 1, + "maxLength": 240 + }, + "coveredDomains": { + "type": "array", + "minItems": 1, + "maxItems": 32, + "uniqueItems": true, + "items": { + "enum": [ + "general", + "requirements", + "architecture", + "frontend", + "backend", + "api", + "database", + "saas", + "mobile", + "cloud-devops", + "security", + "quality", + "performance", + "reliability", + "data-ai", + "web3", + "smart-contracts", + "wallets", + "finance-economics", + "tokenomics", + "mathematics-simulation", + "game-systems", + "documentation", + "release", + "rust", + "kernel-runtime", + "contracts", + "event-driven-systems", + "state-recovery", + "offline-first", + "testing", + "certification" + ] + } + }, + "functions": { + "type": "array", + "minItems": 1, + "maxItems": 32, + "uniqueItems": true, + "items": { + "enum": [ + "inspect", + "requirements", + "architecture", + "planning", + "implementation", + "testing", + "independent-review", + "security-assurance", + "performance-assurance", + "reliability-assurance", + "checkpoint", + "frontend", + "backend-api", + "database", + "mobile", + "platform-cloud", + "data-ai", + "web3-contract", + "finance-math", + "game-systems", + "documentation", + "release", + "quality", + "systems-runtime" + ] + } + }, + "mayImplement": { + "type": "boolean" + }, + "reviewOnly": { + "type": "boolean" + }, + "independenceClass": { + "enum": [ + "implementation", + "support", + "independent-review", + "assurance" + ] + }, "activation": { "type": "object", "additionalProperties": false, "properties": { - "scopeClasses": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "enum": ["trivial", "local", "cross-cutting", "architectural"] } }, - "minRisk": { "enum": ["LOW", "MEDIUM", "HIGH", "CRITICAL"] }, - "domainAny": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 64 } }, - "riskSignalsAny": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 96 } }, - "gatesAny": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 96 } }, - "affectedAreaAny": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 96 } } + "scopeClasses": { + "type": "array", + "maxItems": 32, + "uniqueItems": true, + "items": { + "enum": [ + "trivial", + "local", + "cross-cutting", + "architectural" + ] + } + }, + "minRisk": { + "enum": [ + "LOW", + "MEDIUM", + "HIGH", + "CRITICAL" + ] + }, + "domainAny": { + "type": "array", + "maxItems": 32, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 64 + } + }, + "riskSignalsAny": { + "type": "array", + "maxItems": 32, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 96 + } + }, + "gatesAny": { + "type": "array", + "maxItems": 32, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 96 + } + }, + "affectedAreaAny": { + "type": "array", + "maxItems": 32, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 96 + } + } + } + }, + "requiredInputs": { + "type": "array", + "minItems": 1, + "maxItems": 32, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 160 + } + }, + "producesEvidence": { + "type": "array", + "minItems": 1, + "maxItems": 32, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 160 } }, - "requiredInputs": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 160 } }, - "producesEvidence": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 160 } }, - "incompatibleWith": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]{0,95}$" } }, - "priority": { "type": "integer", "minimum": 0, "maximum": 1000000 }, - "source": { "enum": ["builtin", "user-config", "adapter"] }, - "notes": { "type": ["string", "null"], "maxLength": 1000 }, - "profileDigest": { "type": "string", "pattern": "^[a-f0-9]{64}$" } + "incompatibleWith": { + "type": "array", + "maxItems": 32, + "uniqueItems": true, + "items": { + "type": "string", + "pattern": "^[a-z0-9][a-z0-9-]{0,95}$" + } + }, + "priority": { + "type": "integer", + "minimum": 0, + "maximum": 1000000 + }, + "source": { + "enum": [ + "builtin", + "user-config", + "adapter" + ] + }, + "notes": { + "type": [ + "string", + "null" + ], + "maxLength": 1000 + }, + "profileDigest": { + "type": "string", + "pattern": "^[a-f0-9]{64}$" + } } } From fcec839261f0283dfc7b9c10bb354e9adf2a6877 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:56:52 -0300 Subject: [PATCH 05/20] fix(uads): add systems runtime specialist coverage --- src/kernel/specialist-catalog.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/kernel/specialist-catalog.ts b/src/kernel/specialist-catalog.ts index 32e04ec..63042b1 100644 --- a/src/kernel/specialist-catalog.ts +++ b/src/kernel/specialist-catalog.ts @@ -53,8 +53,8 @@ export const BUILTIN_SPECIALIST_PROFILES: BuiltinProfile[] = [ profile({ specialistId: "software-architect", kind: "core", purpose: "Bound cross-cutting architecture decisions", coveredDomains: ["architecture"], functions: ["architecture"], independenceClass: "support", requiredInputs: ["intake and repository map"], producesEvidence: ["architecture bounds"], priority: 30, notes: "Must not approve its own implementation or invent external capabilities." }), profile({ specialistId: "implementation-planner", kind: "core", purpose: "Produce a bounded executable Work Order plan", coveredDomains: ["general"], functions: ["planning"], independenceClass: "support", requiredInputs: ["intake and routing evidence"], producesEvidence: ["Work Order plan"], priority: 40, notes: "Must not dispatch work outside the selected scope." }), profile({ specialistId: "implementation-agent", kind: "core", purpose: "Apply necessary in-scope product edits", coveredDomains: ["general"], functions: ["implementation"], mayImplement: true, reviewOnly: false, independenceClass: "implementation", requiredInputs: ["Work Order and execution packet"], producesEvidence: ["in-scope change"], priority: 50, notes: "Must not perform approval-gated actions or serve as the sole final reviewer." }), - profile({ specialistId: "test-engineer", kind: "core", purpose: "Design and run focused verification", coveredDomains: ["quality"], functions: ["testing"], independenceClass: "support", requiredInputs: ["Work Order and selected gates"], producesEvidence: ["test evidence"], priority: 60, notes: "Must not self-approve implementation changes." }), - profile({ specialistId: "independent-reviewer", kind: "core", purpose: "Independently review the implementation", coveredDomains: ["quality"], functions: ["independent-review"], independenceClass: "independent-review", requiredInputs: ["diff and gate evidence"], producesEvidence: ["independent review"], priority: 70, notes: "Must use an independent session and must not implement the reviewed change." }), + profile({ specialistId: "test-engineer", kind: "core", purpose: "Design and run focused verification", coveredDomains: ["quality", "testing"], functions: ["testing"], independenceClass: "support", requiredInputs: ["Work Order and selected gates"], producesEvidence: ["test evidence"], priority: 60, notes: "Must not self-approve implementation changes." }), + profile({ specialistId: "independent-reviewer", kind: "core", purpose: "Independently review the implementation", coveredDomains: ["quality", "certification"], functions: ["independent-review"], independenceClass: "independent-review", requiredInputs: ["diff and gate evidence"], producesEvidence: ["independent review"], priority: 70, notes: "Must use an independent session and must not implement the reviewed change." }), profile({ specialistId: "security-reviewer", kind: "assurance", purpose: "Provide security assurance for sensitive changes", coveredDomains: ["security"], functions: ["security-assurance"], independenceClass: "assurance", activation: {}, requiredInputs: ["risk signals and relevant diff"], producesEvidence: ["security review"], priority: 80, notes: "Must not expose secrets or approve by implementing." }), profile({ specialistId: "performance-reviewer", kind: "assurance", purpose: "Provide performance assurance for hot paths", coveredDomains: ["performance"], functions: ["performance-assurance"], independenceClass: "assurance", activation: { domainAny: ["performance"], riskSignalsAny: ["performance-hot-path"] }, requiredInputs: ["hot-path scope and benchmarks"], producesEvidence: ["performance evidence"], priority: 90, notes: "Must not trade correctness or scope controls for a local benchmark result." }), profile({ specialistId: "reliability-reviewer", kind: "assurance", purpose: "Provide reliability and rollback assurance", coveredDomains: ["reliability"], functions: ["reliability-assurance"], independenceClass: "assurance", activation: { domainAny: ["reliability", "database", "cloud-devops"], riskSignalsAny: ["database-migration", "destructive", "infrastructure"] }, requiredInputs: ["dependency and rollback evidence"], producesEvidence: ["reliability review"], priority: 95, notes: "Must not approve irreversible operations without rollback evidence." }), @@ -64,6 +64,7 @@ export const BUILTIN_SPECIALIST_PROFILES: BuiltinProfile[] = [ profile({ specialistId: "backend-api-specialist", kind: "domain", purpose: "Handle backend, API, and SaaS boundaries", coveredDomains: ["backend", "api", "saas"], functions: ["backend-api"], independenceClass: "support", activation: { domainAny: ["backend", "api", "saas"] }, requiredInputs: ["API or service contract"], producesEvidence: ["backend/API verification"], priority: 130, notes: "Must preserve authentication, contract, and data-boundary obligations." }), profile({ specialistId: "database-specialist", kind: "domain", purpose: "Handle database schema and migration safety", coveredDomains: ["database"], functions: ["database"], independenceClass: "support", activation: { domainAny: ["database"] }, requiredInputs: ["schema impact and migration plan"], producesEvidence: ["migration and rollback evidence"], priority: 140, notes: "Must not execute destructive production operations." }), profile({ specialistId: "mobile-client-specialist", kind: "domain", purpose: "Handle mobile client behavior and compatibility", coveredDomains: ["mobile"], functions: ["mobile"], independenceClass: "support", activation: { domainAny: ["mobile"] }, requiredInputs: ["mobile scope and supported clients"], producesEvidence: ["mobile compatibility evidence"], priority: 150, notes: "Must not assume desktop or server behavior is equivalent to mobile behavior." }), + profile({ specialistId: "systems-runtime-specialist", kind: "domain", purpose: "Handle systems language, kernel/runtime, contract, event-driven, state recovery, and offline-first concerns", coveredDomains: ["rust", "kernel-runtime", "contracts", "event-driven-systems", "state-recovery", "offline-first"], functions: ["systems-runtime"], independenceClass: "support", activation: { domainAny: ["rust", "kernel-runtime", "contracts", "event-driven-systems", "state-recovery", "offline-first"] }, requiredInputs: ["runtime architecture, contracts, and state/recovery obligations"], producesEvidence: ["systems/runtime verification guidance"], priority: 155, notes: "Must not replace focused testing, security assurance, or independent certification." }), profile({ specialistId: "platform-cloud-specialist", kind: "domain", purpose: "Handle cloud, DevOps, and release platform concerns", coveredDomains: ["cloud-devops", "release"], functions: ["platform-cloud"], independenceClass: "support", activation: { domainAny: ["cloud-devops"] }, requiredInputs: ["platform scope and deployment constraints"], producesEvidence: ["platform readiness"], priority: 160, notes: "Must not deploy or change paid infrastructure without approval." }), profile({ specialistId: "reliability-specialist", kind: "domain", purpose: "Handle service reliability and operational resilience", coveredDomains: ["reliability"], functions: ["reliability-assurance"], independenceClass: "support", activation: { domainAny: ["reliability"] }, requiredInputs: ["failure modes and dependencies"], producesEvidence: ["reliability plan"], priority: 165, notes: "Must not replace independent assurance for high-risk changes." }), profile({ specialistId: "data-ai-specialist", kind: "domain", purpose: "Handle data and AI pipeline behavior", coveredDomains: ["data-ai"], functions: ["data-ai"], independenceClass: "support", activation: { domainAny: ["data-ai"] }, requiredInputs: ["data flow and quality obligations"], producesEvidence: ["data/AI validation"], priority: 170, notes: "Must not infer model or data-provider behavior without evidence." }), From dac4812184a60f97824d69ac67ee9abe8fd75473 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:56:56 -0300 Subject: [PATCH 06/20] fix(uads): classify foundational runtime work as high risk --- src/kernel/policy.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/kernel/policy.ts b/src/kernel/policy.ts index b3feb28..8f22b5c 100644 --- a/src/kernel/policy.ts +++ b/src/kernel/policy.ts @@ -28,11 +28,14 @@ export function classifyScopeSize(intake: NormalizedIntake): ScopeDecision { scopeClass = "trivial"; reasons.push("isolated presentation change"); } else if ( - includesAny(text, ["architecture", "auth architecture", "storage model", "change the public contract", "public api contract"]) + includesAny(text, ["architecture", "auth architecture", "storage model", "change the public contract", "public api contract"]) || + intake.domainSignals.includes("kernel-runtime") || + (intake.domainSignals.includes("state-recovery") && intake.domainSignals.includes("offline-first")) ) { scopeClass = "architectural"; - reasons.push("public contract or core architecture is in play"); + reasons.push("public contract, kernel/runtime, or core architecture is in play"); } else if ( + intake.domainSignals.length >= 3 || intake.domainSignals.includes("database") || intake.riskSignals.includes("database-migration") || (intake.domainSignals.includes("api") && intake.domainSignals.includes("security")) || @@ -121,6 +124,16 @@ export function classifyRisk(intake: NormalizedIntake, map: RepositoryMap): { le } return { level: "HIGH", reasons }; } + if ( + signals.has("kernel-runtime") || + signals.has("state-recovery") || + signals.has("offline-first") || + signals.has("certification") || + (signals.has("event-driven-systems") && signals.has("contracts")) + ) { + reasons.push("foundational runtime, recovery, offline, contract, or certification surface"); + return { level: "HIGH", reasons }; + } if (signals.has("authentication") || signals.has("public-api") || signals.has("infrastructure")) { reasons.push("auth, public contract, or infrastructure signal"); return { level: "MEDIUM", reasons }; From 92bfb4e2e8a5946be69dee5f5a2314dcab17101a Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:56:59 -0300 Subject: [PATCH 07/20] fix(uads): route systems runtime verification and gates --- src/kernel/routing.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/kernel/routing.ts b/src/kernel/routing.ts index 015d812..5b2c108 100644 --- a/src/kernel/routing.ts +++ b/src/kernel/routing.ts @@ -71,7 +71,7 @@ export const SPECIALISTS: SpecialistDef[] = [ id: "test-engineer", purpose: "Design and run focused tests", activation: "non-docs non-style plans", - domains: ["quality"], + domains: ["quality", "testing"], mayImplement: false, reviewOnly: true, expectedInput: "Work Order + gates", @@ -81,7 +81,7 @@ export const SPECIALISTS: SpecialistDef[] = [ id: "independent-reviewer", purpose: "Independently review implementation", activation: "any plan that includes implementation-agent", - domains: ["quality"], + domains: ["quality", "certification"], mayImplement: false, reviewOnly: true, expectedInput: "diff + gates", @@ -118,6 +118,16 @@ export const SPECIALISTS: SpecialistDef[] = [ expectedInput: "dependencies + rollback evidence", expectedOutput: "reliability review evidence", }, + { + id: "systems-runtime-specialist", + purpose: "Handle systems, kernel/runtime, contracts, event-driven, recovery, and offline-first concerns", + activation: "systems/runtime domain signals", + domains: ["rust", "kernel-runtime", "contracts", "event-driven-systems", "state-recovery", "offline-first"], + mayImplement: false, + reviewOnly: true, + expectedInput: "runtime architecture + contracts + recovery obligations", + expectedOutput: "systems/runtime verification guidance", + }, { id: "checkpoint-manager", purpose: "Persist resume state", @@ -162,6 +172,9 @@ export function selectSpecialists(input: { if (input.intake.riskSignals.includes("performance-hot-path") || input.domains.includes("performance")) { assurance.push("performance-reviewer"); } + if (input.domains.some((id) => ["rust", "kernel-runtime", "contracts", "event-driven-systems", "state-recovery", "offline-first"].includes(id))) { + specialists.push("systems-runtime-specialist"); + } const uniqueSpecialists = unique(specialists); const uniqueAssurance = unique(assurance); @@ -242,6 +255,12 @@ export function selectGates(input: { if (input.intake.riskSignals.includes("performance-hot-path") || input.domains.includes("performance")) { add("performance-check", "hot-path regression check"); } + if (input.domains.includes("contracts") || input.domains.includes("event-driven-systems")) { + add("contract-test", "systems contracts and event boundaries require contract evidence"); + } + if (input.domains.includes("state-recovery") || input.domains.includes("offline-first")) { + add("rollback-validation", "state recovery and offline behavior require rollback/recovery evidence"); + } if (input.risk === "HIGH" || input.risk === "CRITICAL") { add("security-review", "high/critical plans require security assurance"); } From c725de9dd7c017016ce5ff78c553ad1d3a6e0a31 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:57:30 -0300 Subject: [PATCH 08/20] test(uads): cover Forge systems runtime specialist routing --- tests/specialist-routing.test.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/specialist-routing.test.ts b/tests/specialist-routing.test.ts index cd591d8..1580977 100644 --- a/tests/specialist-routing.test.ts +++ b/tests/specialist-routing.test.ts @@ -414,4 +414,34 @@ describe("specialist registry and deterministic routing", () => { selectSpecialistPlan({ ...current, requiredEvidence: ["gate:unit-test"] }).selectionDigest, ); }); + it("covers Forge-style systems runtime domains without NO_DOMAIN_COVERAGE", () => { + const domains = [ + "rust", + "kernel-runtime", + "contracts", + "event-driven-systems", + "state-recovery", + "offline-first", + "testing", + "certification", + ]; + const plan = selectSpecialistPlan(input({ + objective: "Implement a sovereign Rust kernel runtime with contracts, events, recovery, offline operation, testing, and certification", + domains, + scopeClass: "architectural", + riskLevel: "HIGH", + gates: ["unit-test"], + requiredEvidence: ["gate:unit-test"], + })); + expect(plan.status).toBe("SELECTED"); + expect(plan.blockedReasonCodes).not.toContain("NO_DOMAIN_COVERAGE"); + expect(plan.selected.map((item) => item.specialistId)).toEqual( + expect.arrayContaining(["systems-runtime-specialist", "test-engineer"]), + ); + expect(plan.assurance.map((item) => item.specialistId)).toContain("independent-reviewer"); + const covered = new Set(plan.coveredObligations.filter((item) => item.coverageKind === "domain").map((item) => item.obligationId.replace(/^domain:/, ""))); + for (const domain of domains) expect(covered.has(domain)).toBe(true); + }); + + }); From 505ec07f90d27bcab630aeeab673c4ffd9e6c204 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:57:34 -0300 Subject: [PATCH 09/20] test(uads): lock Forge kernel risk and routing regression --- tests/orchestrator-kernel.test.ts | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/orchestrator-kernel.test.ts b/tests/orchestrator-kernel.test.ts index db6920a..8034971 100644 --- a/tests/orchestrator-kernel.test.ts +++ b/tests/orchestrator-kernel.test.ts @@ -229,4 +229,42 @@ describe("orchestrator kernel", { timeout: 90_000 }, () => { }); expect(inspected.map.projectId).toBe("aaaaaaaaaaaaaaaa"); }); + it("classifies foundational Forge-style kernel work as architectural HIGH risk", () => { + const { repo, home } = tempDirs(); + seedRepo(repo); + const planned = runPlan({ + cwd: repo, + uadsHome: home, + intake: normalizeIntake({ + schema: "uads.intake", + schemaVersion: "0.2.0", + objective: "Implement the complete sovereign Forge kernel and contract runtime", + domainSignals: [ + "rust", + "kernel-runtime", + "contracts", + "event-driven-systems", + "state-recovery", + "offline-first", + "testing", + "certification", + ], + riskSignals: [], + affectedAreas: ["kernel", "runtime", "state"], + classifier: "host-structured", + }), + }); + expect(planned.workOrder.scopeClass).toBe("architectural"); + expect(planned.workOrder.riskLevel).toBe("HIGH"); + expect(planned.specialistPlan.status).toBe("SELECTED"); + expect(planned.workOrder.specialists).toContain("systems-runtime-specialist"); + expect(planned.workOrder.assuranceReviewers).toEqual( + expect.arrayContaining(["independent-reviewer", "security-reviewer"]), + ); + expect(planned.workOrder.qualityGates).toEqual( + expect.arrayContaining(["static", "unit-test", "architecture-conformance", "contract-test", "rollback-validation", "security-review"]), + ); + }); + + }); From c5b299a7b1c20d2596c5d45debaedde29b524aa7 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:58:44 -0300 Subject: [PATCH 10/20] fix(uads): add systems runtime host specialist descriptor --- agents/uads-systems-runtime-specialist.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 agents/uads-systems-runtime-specialist.md diff --git a/agents/uads-systems-runtime-specialist.md b/agents/uads-systems-runtime-specialist.md new file mode 100644 index 0000000..81a34a9 --- /dev/null +++ b/agents/uads-systems-runtime-specialist.md @@ -0,0 +1,11 @@ +--- +name: uads-systems-runtime-specialist +description: Review systems-language, kernel/runtime, contract, event-driven, recovery, and offline-first engineering concerns. +--- +# UADS systems runtime specialist + +Analyze only the Work Order domains assigned by UADS for systems/runtime work. + +Focus on Rust or systems-language boundaries, kernel/runtime lifecycle, contracts, event-driven semantics, state/recovery, offline-first behavior, deterministic failure handling, and platform/runtime compatibility. + +Produce bounded implementation guidance and verification obligations. Do not replace the implementation agent, focused test execution, security assurance, reliability assurance, or independent final review. Do not broaden scope beyond the admitted Work Order. From 31fa80bc43f1ae09704a5ca3e0c3aee0968b619d Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:58:50 -0300 Subject: [PATCH 11/20] test(uads): expect systems runtime adapter resource --- src/eval/adapters.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eval/adapters.ts b/src/eval/adapters.ts index 7864dfc..9e60b4f 100644 --- a/src/eval/adapters.ts +++ b/src/eval/adapters.ts @@ -241,7 +241,7 @@ function prepare(fixture: ReturnType): HostDispatchBundle function runCase(id: string): void { if (id === "AD1") { const fixture = install("cursor"); - assertEval(fixture.resources.length === 25, "Cursor catalog was not installed globally"); + assertEval(fixture.resources.length === 26, "Cursor catalog was not installed globally"); assertEval(!fs.existsSync(path.join(fixture.project, ".cursor")), "Cursor install touched the project"); assertEval(fs.existsSync(getHostAdapterStatePath("cursor", fixture.uadsHome)), "Cursor ownership state is missing"); } else if (id === "AD2") { From 33b2a77af0512e49d004ae3a129245695efde63c Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:58:53 -0300 Subject: [PATCH 12/20] docs(uads): document expanded systems specialist catalog --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce9f5a0..c74a317 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This repository is the public open-source UADS product. Releases are published f - Context routing, repository map, dependency/impact map - Token budget manager and cache-first prompt architecture - Provider-neutral model routing, evidence protocol, review ZIP workflow -- Global specialist registry with 25 bounded built-in profiles, deterministic domain/gate/evidence obligation coverage, independent assurance, and semantic stale-plan binding +- Global specialist registry with 26 bounded built-in profiles, deterministic domain/gate/evidence obligation coverage, independent assurance, and semantic stale-plan binding - Common Cursor/Codex/Generic Agent Skills adapters with ownership-safe global installation, sidecar-only Host Dispatch Bundles, and the bounded Host Execution handoff/Receipt Boundary with current-authority revalidation and 32-entry history retention - Two-stage GitHub Direct Review Evidence with exact-SHA CI receipt, canonical workflow artifact, and release cross-checks - Staged implementation roadmap From 8c0cefa696224286652685e80aaac47780bb4945 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:58:57 -0300 Subject: [PATCH 13/20] docs(uads): record systems runtime domain coverage --- docs/03-SCOPE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/03-SCOPE.md b/docs/03-SCOPE.md index 4956e8a..6647c45 100644 --- a/docs/03-SCOPE.md +++ b/docs/03-SCOPE.md @@ -76,7 +76,7 @@ Every Work Order is classified before expansion: Only **NECESSARY** work enters the current Work Order. IMPORTANT/FUTURE items are recommendations. OUT_OF_SCOPE stays excluded. Execution classifies changed paths as in-scope, supporting, out-of-scope, or sensitive. # Specialist scope boundary (Prompt 009) -The built-in catalog contains 11 core roles and 14 domain profiles. Security, performance, and reliability assurance remain distinct from implementation and support. UGAS and game-assets are explicitly outside this catalog and do not receive automatic integration or project footprint. +The built-in catalog contains 11 core roles and 15 domain profiles. Security, performance, and reliability assurance remain distinct from implementation and support. The additional systems-runtime profile covers systems-language, kernel/runtime, contracts, event-driven systems, state recovery, and offline-first engineering without weakening fail-closed routing. UGAS and game-assets are explicitly outside this catalog and do not receive automatic integration or project footprint. Selection uses a bounded minimum-sufficient greedy algorithm. It covers only domains, affected areas, risk signals, gates, dependencies, and evidence obligations present in the Work Order. Missing required coverage blocks dispatch rather than causing an unrelated specialist expansion. From be8bd9e36985aa6daf87bd957518272fa5b1327a Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:59:00 -0300 Subject: [PATCH 14/20] docs(uads): expose systems runtime specialist to host adapters --- agents/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents/README.md b/agents/README.md index d727a1a..93acdb8 100644 --- a/agents/README.md +++ b/agents/README.md @@ -4,6 +4,6 @@ Canonical UADS specialist definitions for the current core registry. Copied to ` Host-invokable core roles: repo-inspector, requirements-engineer, software-architect, implementation-planner, implementation-agent, test-engineer, independent-reviewer, security-reviewer, performance-reviewer, reliability-reviewer, checkpoint-manager. -The bounded domain catalog includes product-requirements-specialist, frontend-specialist, backend-api-specialist, database-specialist, mobile-client-specialist, platform-cloud-specialist, reliability-specialist, data-ai-specialist, web3-contract-specialist, finance-math-specialist, game-systems-specialist, documentation-dx-specialist, release-specialist, and quality-specialist. These descriptors are lean host-facing contracts; they do not invoke providers or grant production authority. +The bounded domain catalog includes product-requirements-specialist, frontend-specialist, backend-api-specialist, database-specialist, mobile-client-specialist, systems-runtime-specialist, platform-cloud-specialist, reliability-specialist, data-ai-specialist, web3-contract-specialist, finance-math-specialist, game-systems-specialist, documentation-dx-specialist, release-specialist, and quality-specialist. These descriptors are lean host-facing contracts; they do not invoke providers or grant production authority. The TypeScript kernel emits routing; hosts/adapters invoke these roles. Do not launch provider APIs from the kernel. From d79ac96b4a928ea73e194d85ea5e08748f6174b9 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:59:29 -0300 Subject: [PATCH 15/20] chore(uads): minimize systems profile schema delta --- schemas/specialist-profile.schema.json | 280 +++---------------------- 1 file changed, 25 insertions(+), 255 deletions(-) diff --git a/schemas/specialist-profile.schema.json b/schemas/specialist-profile.schema.json index f3b2182..a327efc 100644 --- a/schemas/specialist-profile.schema.json +++ b/schemas/specialist-profile.schema.json @@ -4,267 +4,37 @@ "title": "UADS Specialist Profile", "type": "object", "additionalProperties": false, - "required": [ - "schema", - "schemaVersion", - "specialistId", - "kind", - "status", - "purpose", - "coveredDomains", - "functions", - "mayImplement", - "reviewOnly", - "independenceClass", - "activation", - "requiredInputs", - "producesEvidence", - "incompatibleWith", - "priority", - "source", - "notes", - "profileDigest" - ], + "required": ["schema", "schemaVersion", "specialistId", "kind", "status", "purpose", "coveredDomains", "functions", "mayImplement", "reviewOnly", "independenceClass", "activation", "requiredInputs", "producesEvidence", "incompatibleWith", "priority", "source", "notes", "profileDigest"], "properties": { - "schema": { - "const": "uads.specialist-profile" - }, - "schemaVersion": { - "const": "0.9.0" - }, - "specialistId": { - "type": "string", - "pattern": "^[a-z0-9][a-z0-9-]{0,95}$" - }, - "kind": { - "enum": [ - "core", - "domain", - "assurance" - ] - }, - "status": { - "enum": [ - "enabled", - "disabled", - "experimental" - ] - }, - "purpose": { - "type": "string", - "minLength": 1, - "maxLength": 240 - }, - "coveredDomains": { - "type": "array", - "minItems": 1, - "maxItems": 32, - "uniqueItems": true, - "items": { - "enum": [ - "general", - "requirements", - "architecture", - "frontend", - "backend", - "api", - "database", - "saas", - "mobile", - "cloud-devops", - "security", - "quality", - "performance", - "reliability", - "data-ai", - "web3", - "smart-contracts", - "wallets", - "finance-economics", - "tokenomics", - "mathematics-simulation", - "game-systems", - "documentation", - "release", - "rust", - "kernel-runtime", - "contracts", - "event-driven-systems", - "state-recovery", - "offline-first", - "testing", - "certification" - ] - } - }, - "functions": { - "type": "array", - "minItems": 1, - "maxItems": 32, - "uniqueItems": true, - "items": { - "enum": [ - "inspect", - "requirements", - "architecture", - "planning", - "implementation", - "testing", - "independent-review", - "security-assurance", - "performance-assurance", - "reliability-assurance", - "checkpoint", - "frontend", - "backend-api", - "database", - "mobile", - "platform-cloud", - "data-ai", - "web3-contract", - "finance-math", - "game-systems", - "documentation", - "release", - "quality", - "systems-runtime" - ] - } - }, - "mayImplement": { - "type": "boolean" - }, - "reviewOnly": { - "type": "boolean" - }, - "independenceClass": { - "enum": [ - "implementation", - "support", - "independent-review", - "assurance" - ] - }, + "schema": { "const": "uads.specialist-profile" }, + "schemaVersion": { "const": "0.9.0" }, + "specialistId": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]{0,95}$" }, + "kind": { "enum": ["core", "domain", "assurance"] }, + "status": { "enum": ["enabled", "disabled", "experimental"] }, + "purpose": { "type": "string", "minLength": 1, "maxLength": 240 }, + "coveredDomains": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "enum": ["general", "requirements", "architecture", "frontend", "backend", "api", "database", "saas", "mobile", "cloud-devops", "security", "quality", "performance", "reliability", "data-ai", "web3", "smart-contracts", "wallets", "finance-economics", "tokenomics", "mathematics-simulation", "game-systems", "rust", "kernel-runtime", "contracts", "event-driven-systems", "state-recovery", "offline-first", "testing", "certification", "documentation", "release"] } }, + "functions": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "enum": ["inspect", "requirements", "architecture", "planning", "implementation", "testing", "independent-review", "security-assurance", "performance-assurance", "reliability-assurance", "checkpoint", "frontend", "backend-api", "database", "mobile", "platform-cloud", "data-ai", "web3-contract", "finance-math", "game-systems", "documentation", "release", "quality", "systems-runtime"] } }, + "mayImplement": { "type": "boolean" }, + "reviewOnly": { "type": "boolean" }, + "independenceClass": { "enum": ["implementation", "support", "independent-review", "assurance"] }, "activation": { "type": "object", "additionalProperties": false, "properties": { - "scopeClasses": { - "type": "array", - "maxItems": 32, - "uniqueItems": true, - "items": { - "enum": [ - "trivial", - "local", - "cross-cutting", - "architectural" - ] - } - }, - "minRisk": { - "enum": [ - "LOW", - "MEDIUM", - "HIGH", - "CRITICAL" - ] - }, - "domainAny": { - "type": "array", - "maxItems": 32, - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 64 - } - }, - "riskSignalsAny": { - "type": "array", - "maxItems": 32, - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 96 - } - }, - "gatesAny": { - "type": "array", - "maxItems": 32, - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 96 - } - }, - "affectedAreaAny": { - "type": "array", - "maxItems": 32, - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 96 - } - } - } - }, - "requiredInputs": { - "type": "array", - "minItems": 1, - "maxItems": 32, - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 160 - } - }, - "producesEvidence": { - "type": "array", - "minItems": 1, - "maxItems": 32, - "uniqueItems": true, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 160 + "scopeClasses": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "enum": ["trivial", "local", "cross-cutting", "architectural"] } }, + "minRisk": { "enum": ["LOW", "MEDIUM", "HIGH", "CRITICAL"] }, + "domainAny": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 64 } }, + "riskSignalsAny": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 96 } }, + "gatesAny": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 96 } }, + "affectedAreaAny": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 96 } } } }, - "incompatibleWith": { - "type": "array", - "maxItems": 32, - "uniqueItems": true, - "items": { - "type": "string", - "pattern": "^[a-z0-9][a-z0-9-]{0,95}$" - } - }, - "priority": { - "type": "integer", - "minimum": 0, - "maximum": 1000000 - }, - "source": { - "enum": [ - "builtin", - "user-config", - "adapter" - ] - }, - "notes": { - "type": [ - "string", - "null" - ], - "maxLength": 1000 - }, - "profileDigest": { - "type": "string", - "pattern": "^[a-f0-9]{64}$" - } + "requiredInputs": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 160 } }, + "producesEvidence": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 160 } }, + "incompatibleWith": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]{0,95}$" } }, + "priority": { "type": "integer", "minimum": 0, "maximum": 1000000 }, + "source": { "enum": ["builtin", "user-config", "adapter"] }, + "notes": { "type": ["string", "null"], "maxLength": 1000 }, + "profileDigest": { "type": "string", "pattern": "^[a-f0-9]{64}$" } } } From 7bbb4ec7c15b24db97fba22ebadc62fd70f0f379 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 21:07:39 -0300 Subject: [PATCH 16/20] security: update adm-zip to patched 0.6.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b81a559..9c9fa55 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "uads": "node dist/cli.js" }, "dependencies": { - "adm-zip": "^0.6.0", + "adm-zip": "^0.6.1", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "commander": "^12.1.0" From 584d4dcf1da17ac28be4297105b7e8e38385ffc1 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 21:07:43 -0300 Subject: [PATCH 17/20] security: lock adm-zip 0.6.1 --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 854b405..b1c03cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.12.1", "license": "Apache-2.0", "dependencies": { - "adm-zip": "^0.6.0", + "adm-zip": "^0.6.1", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "commander": "^12.1.0" @@ -490,9 +490,9 @@ } }, "node_modules/adm-zip": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.6.0.tgz", - "integrity": "sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.6.1.tgz", + "integrity": "sha512-Xwrja8nx9e5o2N1my4DsKCeKpdrnACyr1wtbPxBDgGzKzKyE9kRtBFA8mWldI+RVlD7CBZNWY/wQ2+ydwOR6kQ==", "license": "MIT", "engines": { "node": ">=14.0" From af1c614d1851e95b35aaf3dd5cf1c87b641d2be2 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 21:13:16 -0300 Subject: [PATCH 18/20] security: inspect raw ZIP central directory names --- src/lib/zip-read.ts | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/lib/zip-read.ts b/src/lib/zip-read.ts index f9f77da..48c8239 100644 --- a/src/lib/zip-read.ts +++ b/src/lib/zip-read.ts @@ -6,6 +6,73 @@ export type ZipEntry = { content: Buffer; }; +const EOCD_SIGNATURE = 0x06054b50; +const CENTRAL_SIGNATURE = 0x02014b50; +const MAX_EOCD_SEARCH = 22 + 0xffff; + +function findEocd(buffer: Buffer): number { + const start = Math.max(0, buffer.length - MAX_EOCD_SEARCH); + for (let offset = buffer.length - 22; offset >= start; offset -= 1) { + if (buffer.readUInt32LE(offset) === EOCD_SIGNATURE) return offset; + } + throw new Error("ZIP end-of-central-directory record is missing"); +} + +/** + * Reads raw central-directory entry names without relying on adm-zip's + * in-memory entry normalization/deduplication. Final-byte inspection uses + * this to preserve duplicate-name and unsafe-path detection across library + * upgrades. + * + * UADS review bundles are intentionally bounded standard ZIP archives. + * ZIP64 is rejected fail-closed here rather than guessed. + */ +export function readZipCentralDirectoryNames(zipPath: string): string[] { + const buffer = fs.readFileSync(zipPath); + if (buffer.length < 22) throw new Error("ZIP is truncated"); + + const eocd = findEocd(buffer); + const diskEntries = buffer.readUInt16LE(eocd + 8); + const totalEntries = buffer.readUInt16LE(eocd + 10); + const centralSize = buffer.readUInt32LE(eocd + 12); + const centralOffset = buffer.readUInt32LE(eocd + 16); + + if ( + diskEntries === 0xffff || + totalEntries === 0xffff || + centralSize === 0xffffffff || + centralOffset === 0xffffffff + ) { + throw new Error("ZIP64 review bundles are not supported"); + } + if (diskEntries !== totalEntries) throw new Error("multi-disk ZIP review bundles are not supported"); + if (centralOffset + centralSize > eocd || centralOffset > buffer.length) { + throw new Error("ZIP central directory bounds are invalid"); + } + + const names: string[] = []; + let offset = centralOffset; + const centralEnd = centralOffset + centralSize; + + for (let index = 0; index < totalEntries; index += 1) { + if (offset + 46 > centralEnd || buffer.readUInt32LE(offset) !== CENTRAL_SIGNATURE) { + throw new Error("ZIP central directory entry is invalid"); + } + const nameLength = buffer.readUInt16LE(offset + 28); + const extraLength = buffer.readUInt16LE(offset + 30); + const commentLength = buffer.readUInt16LE(offset + 32); + const recordLength = 46 + nameLength + extraLength + commentLength; + if (recordLength < 46 || offset + recordLength > centralEnd) { + throw new Error("ZIP central directory entry exceeds declared bounds"); + } + names.push(buffer.subarray(offset + 46, offset + 46 + nameLength).toString("utf8")); + offset += recordLength; + } + + if (offset !== centralEnd) throw new Error("ZIP central directory size does not match parsed entries"); + return names; +} + export function readZip(zipPath: string): Promise { const zip = new AdmZip(zipPath); const entries = zip From 4ca59ba1fea42a5ad7c0ac06be6279fcc8ed74d7 Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 21:13:20 -0300 Subject: [PATCH 19/20] security: preserve duplicate ZIP detection across adm-zip upgrades --- src/lib/inspect-review.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lib/inspect-review.ts b/src/lib/inspect-review.ts index 0e86aef..9f96305 100644 --- a/src/lib/inspect-review.ts +++ b/src/lib/inspect-review.ts @@ -5,7 +5,7 @@ import addFormatsImport from "ajv-formats"; import { EVIDENCE_FILE_NAMES } from "./evidence.js"; import { isUnsafeZipEntryName } from "./exclusions.js"; import { findPackageRoot } from "./version.js"; -import { readZip } from "./zip-read.js"; +import { readZip, readZipCentralDirectoryNames } from "./zip-read.js"; import { containsAbsoluteHostPath, containsUnredactedSecret } from "./secrets.js"; import { validateCanonicalReleaseEvidence } from "./release-review.js"; @@ -95,17 +95,21 @@ export async function inspectReviewBundle( const requireEvidence = options.requireEvidence ?? true; let entries; + let rawNames: string[]; try { + rawNames = readZipCentralDirectoryNames(zipPath) + .filter((name) => !name.endsWith("/")) + .map((name) => name.replace(/\\/g, "/")); entries = await readZip(zipPath); } catch (error) { return { ok: false, errors: [`zip-unreadable: ${error instanceof Error ? error.message : String(error)}`] }; } - const names = entries.map((entry) => entry.name.replace(/\\/g, "/")); - if (new Set(names).size !== names.length) { + if (new Set(rawNames).size !== rawNames.length) { errors.push("duplicate-entry"); } + const names = entries.map((entry) => entry.name.replace(/\\/g, "/")); const nameSet = new Set(names); const required = requireEvidence ? REQUIRED_REVIEW_ENTRIES @@ -117,7 +121,7 @@ export async function inspectReviewBundle( } } - for (const name of names) { + for (const name of rawNames) { if (isUnsafeZipEntryName(name)) { errors.push("unsafe-entry-path"); } From 2d9262813f1bdc3194cdf2ac4f0a44c83d89c8fa Mon Sep 17 00:00:00 2001 From: Clayton nunes <114633702+KayzenRoot@users.noreply.github.com> Date: Tue, 22 Sep 2026 21:17:49 -0300 Subject: [PATCH 20/20] security: fail fast on raw ZIP structural violations --- src/lib/inspect-review.ts | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/lib/inspect-review.ts b/src/lib/inspect-review.ts index 9f96305..0b6e786 100644 --- a/src/lib/inspect-review.ts +++ b/src/lib/inspect-review.ts @@ -94,13 +94,11 @@ export async function inspectReviewBundle( const errors: string[] = []; const requireEvidence = options.requireEvidence ?? true; - let entries; let rawNames: string[]; try { rawNames = readZipCentralDirectoryNames(zipPath) .filter((name) => !name.endsWith("/")) .map((name) => name.replace(/\\/g, "/")); - entries = await readZip(zipPath); } catch (error) { return { ok: false, errors: [`zip-unreadable: ${error instanceof Error ? error.message : String(error)}`] }; } @@ -108,6 +106,20 @@ export async function inspectReviewBundle( if (new Set(rawNames).size !== rawNames.length) { errors.push("duplicate-entry"); } + for (const name of rawNames) { + if (isUnsafeZipEntryName(name)) errors.push("unsafe-entry-path"); + for (const marker of EXCLUDED_ENTRY_MARKERS) { + if (name.includes(marker)) errors.push(`excluded-path-present:${name}`); + } + } + if (errors.length > 0) return { ok: false, errors: [...new Set(errors)] }; + + let entries; + try { + entries = await readZip(zipPath); + } catch (error) { + return { ok: false, errors: [`zip-unreadable: ${error instanceof Error ? error.message : String(error)}`] }; + } const names = entries.map((entry) => entry.name.replace(/\\/g, "/")); const nameSet = new Set(names); @@ -121,17 +133,6 @@ export async function inspectReviewBundle( } } - for (const name of rawNames) { - if (isUnsafeZipEntryName(name)) { - errors.push("unsafe-entry-path"); - } - for (const marker of EXCLUDED_ENTRY_MARKERS) { - if (name.includes(marker)) { - errors.push(`excluded-path-present:${name}`); - } - } - } - const manifestEntry = entries.find((entry) => entry.name.replace(/\\/g, "/") === "review-manifest.json"); if (!manifestEntry) { errors.push("missing-entry:review-manifest.json");