sneakoscope 2.0.5 → 2.0.7
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/README.md +12 -4
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/build-manifest.json +37 -8
- package/dist/cli/install-helpers.js +23 -0
- package/dist/commands/codex-app.js +25 -3
- package/dist/commands/doctor.js +19 -4
- package/dist/commands/mad-sks.js +2 -2
- package/dist/core/agents/agent-orchestrator.js +160 -6
- package/dist/core/agents/agent-patch-schema.js +16 -2
- package/dist/core/agents/agent-proof-evidence.js +27 -2
- package/dist/core/agents/agent-worker-pipeline.js +9 -1
- package/dist/core/agents/native-cli-session-swarm.js +25 -4
- package/dist/core/agents/native-cli-worker.js +28 -1
- package/dist/core/agents/native-worker-backend-router.js +19 -1
- package/dist/core/codex-app.js +124 -2
- package/dist/core/codex-control/python-codex-sdk-adapter.js +28 -4
- package/dist/core/commands/naruto-command.js +48 -14
- package/dist/core/feature-registry.js +2 -0
- package/dist/core/fsx.js +1 -1
- package/dist/core/git/git-integration-worktree.js +15 -0
- package/dist/core/git/git-repo-detection.js +72 -0
- package/dist/core/git/git-worktree-cache-policy.js +36 -0
- package/dist/core/git/git-worktree-capability.js +54 -0
- package/dist/core/git/git-worktree-cleanup.js +51 -0
- package/dist/core/git/git-worktree-conflict-resolver.js +13 -0
- package/dist/core/git/git-worktree-diff.js +50 -0
- package/dist/core/git/git-worktree-manager.js +86 -0
- package/dist/core/git/git-worktree-merge-queue.js +55 -0
- package/dist/core/git/git-worktree-patch-envelope.js +35 -0
- package/dist/core/git/git-worktree-pool.js +23 -0
- package/dist/core/git/git-worktree-root.js +52 -0
- package/dist/core/git/git-worktree-runner.js +40 -0
- package/dist/core/hooks-runtime.js +2 -233
- package/dist/core/init.js +8 -8
- package/dist/core/naruto/naruto-active-pool.js +55 -4
- package/dist/core/naruto/naruto-gpt-final-pack.js +2 -0
- package/dist/core/naruto/naruto-work-graph.js +16 -1
- package/dist/core/pipeline-internals/runtime-core.js +1 -1
- package/dist/core/ppt.js +31 -8
- package/dist/core/product-design-app-server.js +410 -0
- package/dist/core/product-design-plugin.js +139 -0
- package/dist/core/routes.js +8 -8
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-naruto-dashboard.js +10 -1
- package/dist/core/zellij/zellij-worker-pane-manager.js +6 -4
- package/dist/scripts/git-worktree-cache-performance-check.js +25 -0
- package/dist/scripts/git-worktree-capability-check.js +27 -0
- package/dist/scripts/git-worktree-cleanup-check.js +27 -0
- package/dist/scripts/git-worktree-diff-export-check.js +43 -0
- package/dist/scripts/git-worktree-manager-check.js +37 -0
- package/dist/scripts/git-worktree-merge-queue-check.js +30 -0
- package/dist/scripts/git-worktree-pool-performance-check.js +20 -0
- package/dist/scripts/lib/git-worktree-fixture.js +33 -0
- package/dist/scripts/naruto-active-pool-check.js +13 -1
- package/dist/scripts/naruto-readonly-routing-check.js +116 -0
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +16 -5
- package/dist/scripts/naruto-worktree-coding-check.js +44 -0
- package/dist/scripts/naruto-worktree-gpt-final-check.js +45 -0
- package/dist/scripts/naruto-worktree-zellij-ui-check.js +28 -0
- package/dist/scripts/product-design-auto-install-check.js +119 -0
- package/dist/scripts/product-design-plugin-routing-check.js +101 -0
- package/dist/scripts/release-parallel-check.js +16 -2
- package/dist/scripts/release-provenance-check.js +21 -0
- package/package.json +17 -3
- package/schemas/git/git-worktree-capability.schema.json +19 -0
- package/schemas/git/git-worktree-manifest.schema.json +36 -0
|
@@ -1,4 +1,39 @@
|
|
|
1
1
|
import { createNarutoGeneration, completeNarutoGeneration } from './naruto-generation-scheduler.js';
|
|
2
|
+
export async function runNarutoActivePool(input) {
|
|
3
|
+
const base = simulateNarutoActivePool(input);
|
|
4
|
+
const allocations = [];
|
|
5
|
+
for (const item of input.graph.work_items) {
|
|
6
|
+
if (!item.write_allowed)
|
|
7
|
+
continue;
|
|
8
|
+
const mode = item.worktree?.mode || input.graph.worktree_policy.mode;
|
|
9
|
+
if (mode !== 'git-worktree') {
|
|
10
|
+
allocations.push({ work_item_id: item.id, mode, allocation_status: 'skipped', blockers: [] });
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (!input.allocateWorktree) {
|
|
14
|
+
allocations.push({ work_item_id: item.id, mode, allocation_status: 'planned', blockers: [] });
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const allocated = await input.allocateWorktree(item);
|
|
18
|
+
allocations.push({
|
|
19
|
+
work_item_id: item.id,
|
|
20
|
+
mode,
|
|
21
|
+
allocation_status: allocated.ok ? 'allocated' : 'planned',
|
|
22
|
+
...(allocated.worktree_path ? { worktree_path: allocated.worktree_path } : {}),
|
|
23
|
+
...(allocated.branch ? { branch: allocated.branch } : {}),
|
|
24
|
+
blockers: allocated.blockers || []
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const allocationBlockers = allocations.flatMap((row) => row.blockers);
|
|
28
|
+
return {
|
|
29
|
+
...base,
|
|
30
|
+
ok: base.ok && allocationBlockers.length === 0,
|
|
31
|
+
worktree_mode: input.graph.worktree_policy.mode,
|
|
32
|
+
worktree_allocation_required_count: allocations.filter((row) => row.mode === 'git-worktree').length,
|
|
33
|
+
worktree_allocations: allocations,
|
|
34
|
+
blockers: [...base.blockers, ...allocationBlockers]
|
|
35
|
+
};
|
|
36
|
+
}
|
|
2
37
|
export function simulateNarutoActivePool(input) {
|
|
3
38
|
const safeActiveWorkers = Math.max(1, input.governor.safe_active_workers);
|
|
4
39
|
const retryLimit = Math.max(0, Math.floor(Number(input.retryLimit ?? 1)));
|
|
@@ -8,18 +43,20 @@ export function simulateNarutoActivePool(input) {
|
|
|
8
43
|
const completed = new Set();
|
|
9
44
|
const failed = new Set();
|
|
10
45
|
const executed = new Map();
|
|
46
|
+
const byId = new Map(input.graph.work_items.map((item) => [item.id, item]));
|
|
11
47
|
const timeline = [];
|
|
12
48
|
let generationIndex = 1;
|
|
13
49
|
let tick = 0;
|
|
14
50
|
let refillEvents = 0;
|
|
15
51
|
let maxObserved = 0;
|
|
52
|
+
let maxObservedWriteLeaseConflicts = 0;
|
|
16
53
|
let conflictItemsEnqueued = 0;
|
|
17
54
|
while (pending.length || active.size) {
|
|
18
55
|
let launched = 0;
|
|
19
56
|
for (;;) {
|
|
20
57
|
if (active.size >= safeActiveWorkers)
|
|
21
58
|
break;
|
|
22
|
-
const next = popRunnable(pending, completed, active);
|
|
59
|
+
const next = popRunnable(pending, completed, active, byId);
|
|
23
60
|
if (!next)
|
|
24
61
|
break;
|
|
25
62
|
const generation = createNarutoGeneration(next, generationIndex, tick);
|
|
@@ -31,6 +68,7 @@ export function simulateNarutoActivePool(input) {
|
|
|
31
68
|
if (launched)
|
|
32
69
|
refillEvents += launched;
|
|
33
70
|
maxObserved = Math.max(maxObserved, active.size);
|
|
71
|
+
maxObservedWriteLeaseConflicts = Math.max(maxObservedWriteLeaseConflicts, countActiveWriteLeaseConflicts(active, byId));
|
|
34
72
|
timeline.push({ tick, active: active.size, pending: pending.length, completed: completed.size, event: launched ? 'refill' : 'wait' });
|
|
35
73
|
const done = [...active.values()].slice(0, Math.max(1, Math.ceil(active.size / 2)));
|
|
36
74
|
if (!done.length && pending.length)
|
|
@@ -42,7 +80,9 @@ export function simulateNarutoActivePool(input) {
|
|
|
42
80
|
if (shouldFail) {
|
|
43
81
|
failed.add(generation.work_item_id);
|
|
44
82
|
conflictItemsEnqueued += 1;
|
|
45
|
-
|
|
83
|
+
const followup = conflictResolutionFollowup(generation.work_item_id, input.graph.work_items.length + conflictItemsEnqueued);
|
|
84
|
+
pending.push(followup);
|
|
85
|
+
byId.set(followup.id, followup);
|
|
46
86
|
}
|
|
47
87
|
else {
|
|
48
88
|
completed.add(generation.work_item_id);
|
|
@@ -57,6 +97,7 @@ export function simulateNarutoActivePool(input) {
|
|
|
57
97
|
...(pending.length ? ['naruto_active_pool_pending_not_drained'] : []),
|
|
58
98
|
...(active.size ? ['naruto_active_pool_active_not_drained'] : []),
|
|
59
99
|
...(maxObserved > safeActiveWorkers ? ['naruto_active_pool_exceeded_safe_workers'] : []),
|
|
100
|
+
...(maxObservedWriteLeaseConflicts > 0 ? ['naruto_active_pool_overlapping_write_leases'] : []),
|
|
60
101
|
...(duplicateExecutionCount > conflictItemsEnqueued ? ['naruto_active_pool_duplicate_execution_without_retry'] : [])
|
|
61
102
|
];
|
|
62
103
|
return {
|
|
@@ -70,11 +111,12 @@ export function simulateNarutoActivePool(input) {
|
|
|
70
111
|
max_observed_active_workers: maxObserved,
|
|
71
112
|
duplicate_execution_count: duplicateExecutionCount,
|
|
72
113
|
conflict_items_enqueued: conflictItemsEnqueued,
|
|
114
|
+
max_observed_write_lease_conflicts: maxObservedWriteLeaseConflicts,
|
|
73
115
|
timeline,
|
|
74
116
|
blockers
|
|
75
117
|
};
|
|
76
118
|
}
|
|
77
|
-
function popRunnable(pending, completed, active) {
|
|
119
|
+
function popRunnable(pending, completed, active, byId) {
|
|
78
120
|
const activeWorkIds = new Set([...active.values()].map((item) => item.work_item_id));
|
|
79
121
|
for (let index = 0; index < pending.length; index += 1) {
|
|
80
122
|
const item = pending[index];
|
|
@@ -85,7 +127,7 @@ function popRunnable(pending, completed, active) {
|
|
|
85
127
|
if (!item.dependencies.every((dep) => completed.has(dep)))
|
|
86
128
|
continue;
|
|
87
129
|
const writeConflict = [...active.values()].some((generation) => {
|
|
88
|
-
const activeItem =
|
|
130
|
+
const activeItem = byId.get(generation.work_item_id);
|
|
89
131
|
return activeItem?.write_paths.some((file) => item.write_paths.includes(file));
|
|
90
132
|
});
|
|
91
133
|
if (writeConflict)
|
|
@@ -95,6 +137,15 @@ function popRunnable(pending, completed, active) {
|
|
|
95
137
|
}
|
|
96
138
|
return null;
|
|
97
139
|
}
|
|
140
|
+
function countActiveWriteLeaseConflicts(active, byId) {
|
|
141
|
+
const counts = new Map();
|
|
142
|
+
for (const generation of active.values()) {
|
|
143
|
+
const item = byId.get(generation.work_item_id);
|
|
144
|
+
for (const file of item?.write_paths || [])
|
|
145
|
+
counts.set(file, (counts.get(file) || 0) + 1);
|
|
146
|
+
}
|
|
147
|
+
return [...counts.values()].filter((count) => count > 1).reduce((sum, count) => sum + count - 1, 0);
|
|
148
|
+
}
|
|
98
149
|
function conflictResolutionFollowup(failedId, index) {
|
|
99
150
|
const id = `NW-CONFLICT-${String(index).padStart(4, '0')}`;
|
|
100
151
|
return {
|
|
@@ -12,6 +12,8 @@ export function buildNarutoGptFinalPack(input) {
|
|
|
12
12
|
},
|
|
13
13
|
role_distribution: input.roleDistribution,
|
|
14
14
|
changed_files: [...new Set((input.changedFiles || []).map(String))],
|
|
15
|
+
worktree_policy: input.worktreePolicy || input.graph.worktree_policy,
|
|
16
|
+
worktree_diffs: (input.worktreeDiffs || []).slice(0, maxPatchEnvelopes).map(redactSecrets),
|
|
15
17
|
patch_envelopes: (input.patchEnvelopes || []).slice(0, maxPatchEnvelopes).map(redactSecrets),
|
|
16
18
|
verification_results: (input.verificationResults || []).slice(0, 200).map(redactSecrets),
|
|
17
19
|
failed_shards: (input.failedShards || []).slice(0, 100).map(redactSecrets),
|
|
@@ -33,6 +33,13 @@ export function buildNarutoWorkGraph(input = {}) {
|
|
|
33
33
|
const basePath = normalizeNarutoPath(input.leaseBasePath || '.sneakoscope/naruto/patch-envelopes');
|
|
34
34
|
const targetPaths = normalizePaths(input.targetPaths || []);
|
|
35
35
|
const readonlyPaths = normalizePaths(input.readonlyPaths || []);
|
|
36
|
+
const worktreePolicy = input.worktreePolicy || {
|
|
37
|
+
mode: 'patch-envelope-only',
|
|
38
|
+
required: false,
|
|
39
|
+
main_repo_root: null,
|
|
40
|
+
worktree_root: null,
|
|
41
|
+
fallback_reason: writeCapable ? 'git_capability_not_evaluated' : 'readonly_or_write_disabled'
|
|
42
|
+
};
|
|
36
43
|
const workItems = [];
|
|
37
44
|
for (let index = 0; index < totalWorkItems; index += 1) {
|
|
38
45
|
const id = `NW-${String(index + 1).padStart(6, '0')}`;
|
|
@@ -64,7 +71,14 @@ export function buildNarutoWorkGraph(input = {}) {
|
|
|
64
71
|
requires_patch_envelope: writePaths.length > 0,
|
|
65
72
|
requires_verification: kind !== 'research' && kind !== 'final_review_input_pack',
|
|
66
73
|
requires_gpt_final: writePaths.length > 0 || kind === 'final_review_input_pack'
|
|
67
|
-
}
|
|
74
|
+
},
|
|
75
|
+
...(writePaths.length > 0 ? {
|
|
76
|
+
worktree: {
|
|
77
|
+
mode: worktreePolicy.mode,
|
|
78
|
+
required: worktreePolicy.required,
|
|
79
|
+
allocation_required: worktreePolicy.mode === 'git-worktree'
|
|
80
|
+
}
|
|
81
|
+
} : {})
|
|
68
82
|
});
|
|
69
83
|
}
|
|
70
84
|
const activeWaves = planNarutoWorkWaves(workItems, Math.max(1, normalizePositiveInt(input.maxActiveWorkers, requestedClones)));
|
|
@@ -88,6 +102,7 @@ export function buildNarutoWorkGraph(input = {}) {
|
|
|
88
102
|
active_waves: activeWaves,
|
|
89
103
|
mixed_work_kinds: mixedWorkKinds,
|
|
90
104
|
write_allowed_count: writeAllowedCount,
|
|
105
|
+
worktree_policy: worktreePolicy,
|
|
91
106
|
ok: blockers.length === 0,
|
|
92
107
|
blockers
|
|
93
108
|
};
|
|
@@ -386,7 +386,7 @@ export function promptPipelineContext(prompt, route = null) {
|
|
|
386
386
|
skillDreamPolicyText(),
|
|
387
387
|
route?.id === 'PPT'
|
|
388
388
|
? `${pptPipelineAllowlistPolicyText()} ${getdesignReferencePolicyText()}`
|
|
389
|
-
: `Design routing: UI/UX
|
|
389
|
+
: `Design routing: UI/UX uses the Codex App Product Design plugin first for get-context/user-context, research/ideate, prototype/image-to-code/url-to-code, audit/design-qa, and share when available. Treat design.md, design-system-builder, design-ui-editor, design-artifact-expert, and getdesign-reference as compatibility fallback only when the Product Design plugin is unavailable or an existing local design.md must be preserved. Image/logo/raster assets use imagegen, which must prefer Codex App built-in image generation documented at ${CODEX_APP_IMAGE_GENERATION_DOC_URL}. ${CODEX_IMAGEGEN_REQUIRED_POLICY} ${getdesignReferencePolicyText()}`,
|
|
390
390
|
triwikiContextTrackingText(),
|
|
391
391
|
triwikiStagePolicyText(),
|
|
392
392
|
stackCurrentDocsPolicyText(),
|
package/dist/core/ppt.js
CHANGED
|
@@ -2,6 +2,7 @@ import path from 'node:path';
|
|
|
2
2
|
import fsp from 'node:fs/promises';
|
|
3
3
|
import { nowIso, readJson, sha256, writeJsonAtomic, writeTextAtomic } from './fsx.js';
|
|
4
4
|
import { AWESOME_DESIGN_MD_REFERENCE, CODEX_APP_IMAGE_GENERATION_DOC_URL, CODEX_IMAGEGEN_EVIDENCE_SOURCE, DESIGN_SYSTEM_SSOT, GETDESIGN_REFERENCE, PPT_CONDITIONAL_SKILL_ALLOWLIST, PPT_PIPELINE_MCP_ALLOWLIST, PPT_PIPELINE_SKILL_ALLOWLIST } from './routes.js';
|
|
5
|
+
import { PRODUCT_DESIGN_LEGACY_DESIGN_FALLBACK_SKILLS, PRODUCT_DESIGN_PIPELINE_STAGES, PRODUCT_DESIGN_PLUGIN, PRODUCT_DESIGN_REQUIRED_SKILLS } from './product-design-plugin.js';
|
|
5
6
|
export const PPT_AUDIENCE_STRATEGY_ARTIFACT = 'ppt-audience-strategy.json';
|
|
6
7
|
export const PPT_GATE_ARTIFACT = 'ppt-gate.json';
|
|
7
8
|
export const PPT_SOURCE_LEDGER_ARTIFACT = 'ppt-source-ledger.json';
|
|
@@ -868,28 +869,48 @@ export function buildPptStyleTokens(contract = {}) {
|
|
|
868
869
|
required_skills: [...PPT_PIPELINE_SKILL_ALLOWLIST],
|
|
869
870
|
conditional_skills: [...PPT_CONDITIONAL_SKILL_ALLOWLIST],
|
|
870
871
|
allowed_mcp_servers: [...PPT_PIPELINE_MCP_ALLOWLIST],
|
|
872
|
+
primary_design_plugin: PRODUCT_DESIGN_PLUGIN.id,
|
|
873
|
+
product_design_tools: [...PRODUCT_DESIGN_REQUIRED_SKILLS],
|
|
874
|
+
product_design_stage_map: [...PRODUCT_DESIGN_PIPELINE_STAGES],
|
|
871
875
|
ignore_installed_out_of_pipeline_skills: true,
|
|
872
|
-
ignored_design_skills_even_if_installed: [
|
|
873
|
-
anti_ai_design_goal: 'prevent AI-like generic presentation design by forcing decisions through audience, sources,
|
|
874
|
-
rule: 'PPT design and render work must use only the route allowlist. Installed skills or MCP servers outside this allowlist are ignored unless the sealed PPT contract explicitly activates a conditional entry.'
|
|
876
|
+
ignored_design_skills_even_if_installed: [...PRODUCT_DESIGN_LEGACY_DESIGN_FALLBACK_SKILLS],
|
|
877
|
+
anti_ai_design_goal: 'prevent AI-like generic presentation design by forcing decisions through Product Design plugin evidence, audience, sources, and route-local style tokens instead of freeform decorative design skills',
|
|
878
|
+
rule: 'PPT design and render work must use Product Design plugin first plus only the route allowlist. Installed skills or MCP servers outside this allowlist are ignored unless the sealed PPT contract explicitly activates a conditional entry.'
|
|
875
879
|
},
|
|
876
880
|
design_ssot: {
|
|
881
|
+
primary_authority: PRODUCT_DESIGN_PLUGIN.id,
|
|
877
882
|
authority: DESIGN_SYSTEM_SSOT.authority_file,
|
|
878
883
|
builder_prompt: DESIGN_SYSTEM_SSOT.builder_prompt,
|
|
879
884
|
route_local_artifact: PPT_STYLE_TOKENS_ARTIFACT,
|
|
880
|
-
|
|
885
|
+
mode: 'product_design_primary_with_local_fallback_cache',
|
|
886
|
+
rule: 'PPT style tokens are a route-local projection of Product Design plugin evidence when available; design.md/getdesign fallback inputs are selected, fused, and applied here rather than kept as independent authorities.'
|
|
887
|
+
},
|
|
888
|
+
product_design_plugin: {
|
|
889
|
+
id: PRODUCT_DESIGN_PLUGIN.id,
|
|
890
|
+
display_name: PRODUCT_DESIGN_PLUGIN.display_name,
|
|
891
|
+
marketplace: PRODUCT_DESIGN_PLUGIN.marketplace,
|
|
892
|
+
marketplace_kind: PRODUCT_DESIGN_PLUGIN.marketplace_kind,
|
|
893
|
+
remote_plugin_id: PRODUCT_DESIGN_PLUGIN.remote_plugin_id,
|
|
894
|
+
app_server_read_params: PRODUCT_DESIGN_PLUGIN.app_server.read_params,
|
|
895
|
+
required_skills: [...PRODUCT_DESIGN_REQUIRED_SKILLS],
|
|
896
|
+
stage_map: [...PRODUCT_DESIGN_PIPELINE_STAGES]
|
|
881
897
|
},
|
|
882
898
|
design_reference_selection: reference,
|
|
883
899
|
source_inputs: [
|
|
900
|
+
{
|
|
901
|
+
id: PRODUCT_DESIGN_PLUGIN.id,
|
|
902
|
+
url: PRODUCT_DESIGN_PLUGIN.marketplace,
|
|
903
|
+
role: 'primary_codex_app_design_plugin'
|
|
904
|
+
},
|
|
884
905
|
{
|
|
885
906
|
id: GETDESIGN_REFERENCE.id,
|
|
886
907
|
url: GETDESIGN_REFERENCE.url,
|
|
887
|
-
role: '
|
|
908
|
+
role: 'fallback_source_input_for_ssot'
|
|
888
909
|
},
|
|
889
910
|
{
|
|
890
911
|
id: AWESOME_DESIGN_MD_REFERENCE.id,
|
|
891
912
|
url: AWESOME_DESIGN_MD_REFERENCE.url,
|
|
892
|
-
role: '
|
|
913
|
+
role: 'fallback_source_input_for_ssot'
|
|
893
914
|
}
|
|
894
915
|
],
|
|
895
916
|
avoid: ['over-designed decoration', 'ornamental gradients', 'nested cards', 'low-contrast gray body text', 'excessive motion or effects'],
|
|
@@ -1130,13 +1151,15 @@ export function buildPptRenderReport({ contract = {}, audience, sourceLedger, fa
|
|
|
1130
1151
|
design_policy_checks: [
|
|
1131
1152
|
{ id: 'information_first', passed: styleTokens.design_policy?.priority === 'information_first' },
|
|
1132
1153
|
{ id: 'restrained_detail', passed: styleTokens.design_policy?.visual_style === 'simple_restrained_detailed' },
|
|
1133
|
-
{ id: '
|
|
1134
|
-
{ id: '
|
|
1154
|
+
{ id: 'product_design_plugin_declared', passed: styleTokens.design_policy?.product_design_plugin?.id === PRODUCT_DESIGN_PLUGIN.id && (styleTokens.design_policy?.product_design_plugin?.required_skills || []).includes('design-qa') },
|
|
1155
|
+
{ id: 'design_ssot_declared', passed: styleTokens.design_policy?.design_ssot?.authority === DESIGN_SYSTEM_SSOT.authority_file && styleTokens.design_policy?.design_ssot?.primary_authority === PRODUCT_DESIGN_PLUGIN.id },
|
|
1156
|
+
{ id: 'curated_design_md_input_fused', passed: (styleTokens.design_policy?.source_inputs || []).some((entry) => entry.url === AWESOME_DESIGN_MD_REFERENCE.url && /fallback_source_input/.test(entry.role || '')) },
|
|
1135
1157
|
{ id: 'concrete_design_reference_selected', passed: Boolean(styleTokens.design_policy?.design_reference_selection?.primary?.id && styleTokens.design_policy?.design_reference_selection?.selected_sources?.length) },
|
|
1136
1158
|
{ id: 'reference_rules_applied_to_tokens', passed: Boolean(styleTokens.layout?.composition && styleTokens.layout?.treatment && styleTokens.design_policy?.design_reference_selection?.applied_token_profile) },
|
|
1137
1159
|
{ id: 'html_uses_reference_layout', passed: typeof html === 'string' && html.includes('decision evidence') && html.includes(styleTokens.layout?.composition || 'presentation-grid') },
|
|
1138
1160
|
{ id: 'ppt_skill_allowlist_enforced', passed: JSON.stringify(styleTokens.design_policy?.pipeline_allowlist?.required_skills || []) === JSON.stringify([...PPT_PIPELINE_SKILL_ALLOWLIST]) },
|
|
1139
1161
|
{ id: 'out_of_pipeline_design_skills_ignored', passed: styleTokens.design_policy?.pipeline_allowlist?.ignore_installed_out_of_pipeline_skills === true && (styleTokens.design_policy?.pipeline_allowlist?.ignored_design_skills_even_if_installed || []).includes('design-artifact-expert') },
|
|
1162
|
+
{ id: 'legacy_design_skills_fallback_only', passed: styleTokens.design_policy?.pipeline_allowlist?.primary_design_plugin === PRODUCT_DESIGN_PLUGIN.id && (styleTokens.design_policy?.pipeline_allowlist?.ignored_design_skills_even_if_installed || []).includes('design-system-builder') },
|
|
1140
1163
|
{ id: 'ppt_mcp_allowlist_scoped', passed: (styleTokens.design_policy?.pipeline_allowlist?.allowed_mcp_servers || []).every((entry) => entry.mcp === 'context7' && /external_documentation/.test(entry.condition || '')) },
|
|
1141
1164
|
{ id: 'no_decorative_overdesign', passed: !String(html).includes('gradient') },
|
|
1142
1165
|
{ id: 'fact_ledger_embedded', passed: typeof html === 'string' && html.includes('ppt-fact-ledger') },
|