sneakoscope 4.2.0 → 4.3.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/README.md +35 -8
- 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/bin/sks.js +1 -1
- package/dist/cli/command-registry.js +3 -1
- package/dist/cli/ultra-search-command.js +163 -0
- package/dist/cli/xai-command.js +28 -168
- package/dist/core/agents/agent-codex-cockpit.js +3 -3
- package/dist/core/agents/agent-runner-ollama.js +2 -0
- package/dist/core/agents/agent-wrongness.js +1 -1
- package/dist/core/agents/native-worker-backend-router.js +3 -0
- package/dist/core/bench.js +115 -0
- package/dist/core/code-structure.js +399 -11
- package/dist/core/codex-control/codex-app-server-v2-client.js +86 -2
- package/dist/core/codex-control/codex-fake-sdk-adapter.js +67 -9
- package/dist/core/codex-control/codex-reliability-shield.js +26 -5
- package/dist/core/codex-control/codex-task-runner.js +7 -1
- package/dist/core/codex-control/gpt-final-arbiter.js +4 -1
- package/dist/core/codex-control/gpt-final-review-schema.js +58 -0
- package/dist/core/codex-control/model-call-concurrency.js +1 -1
- package/dist/core/codex-native/core-skill-manifest.js +23 -0
- package/dist/core/commands/bench-command.js +11 -2
- package/dist/core/commands/code-structure-command.js +34 -2
- package/dist/core/commands/qa-loop-command.js +23 -7
- package/dist/core/commands/run-command.js +92 -2
- package/dist/core/commands/seo-command.js +130 -0
- package/dist/core/feature-fixtures.js +6 -0
- package/dist/core/feature-registry.js +3 -1
- package/dist/core/fsx.js +1 -1
- package/dist/core/hooks-runtime.js +9 -1
- package/dist/core/init.js +8 -6
- package/dist/core/lean-engineering-policy.js +159 -0
- package/dist/core/pipeline-internals/runtime-core.js +15 -5
- package/dist/core/proof/auto-finalize.js +3 -2
- package/dist/core/proof/proof-schema.js +2 -1
- package/dist/core/proof/proof-writer.js +1 -0
- package/dist/core/proof/route-adapter.js +4 -2
- package/dist/core/proof/route-finalizer.js +35 -3
- package/dist/core/qa-loop/qa-app-server-driver.js +134 -0
- package/dist/core/qa-loop/qa-contract-v2.js +231 -0
- package/dist/core/qa-loop/qa-gate-v2.js +132 -0
- package/dist/core/qa-loop/qa-runtime-artifacts.js +53 -0
- package/dist/core/qa-loop/qa-surface-router.js +114 -0
- package/dist/core/qa-loop/qa-types.js +18 -0
- package/dist/core/qa-loop.js +83 -26
- package/dist/core/release/gate-manifest.js +1 -0
- package/dist/core/release/sla-scheduler.js +1 -1
- package/dist/core/release-parallel-full-coverage.js +1 -1
- package/dist/core/routes.js +96 -14
- package/dist/core/search-visibility/adapter-registry.js +26 -0
- package/dist/core/search-visibility/adapters/next-app.js +6 -0
- package/dist/core/search-visibility/adapters/next-pages.js +6 -0
- package/dist/core/search-visibility/adapters/static-site.js +6 -0
- package/dist/core/search-visibility/analyzers.js +377 -0
- package/dist/core/search-visibility/artifacts.js +183 -0
- package/dist/core/search-visibility/discovery.js +347 -0
- package/dist/core/search-visibility/index.js +199 -0
- package/dist/core/search-visibility/mission.js +67 -0
- package/dist/core/search-visibility/mutation.js +314 -0
- package/dist/core/search-visibility/types.js +2 -0
- package/dist/core/search-visibility/verifier.js +60 -0
- package/dist/core/source-intelligence/source-intelligence-policy.js +45 -26
- package/dist/core/source-intelligence/source-intelligence-proof.js +10 -16
- package/dist/core/source-intelligence/source-intelligence-runner.js +56 -42
- package/dist/core/triwiki/triwiki-affected-graph.js +3 -2
- package/dist/core/trust-kernel/trust-report.js +3 -5
- package/dist/core/ultra-search/index.js +3 -0
- package/dist/core/ultra-search/runtime.js +502 -0
- package/dist/core/ultra-search/types.js +3 -0
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-visual-consistency-check.js +1 -1
- package/dist/scripts/check-architecture.js +40 -7
- package/dist/scripts/check-command-module-budget.js +43 -5
- package/dist/scripts/check-pipeline-budget.js +17 -30
- package/dist/scripts/check-publish-tag.js +33 -6
- package/dist/scripts/check-route-modularity.js +25 -33
- package/dist/scripts/check-runtime-schemas.js +22 -0
- package/dist/scripts/codex-control-all-pipelines-check.js +1 -0
- package/dist/scripts/codex-control-model-capacity-fallback-check.js +53 -0
- package/dist/scripts/config-managed-merge-callsite-coverage-check.js +7 -1
- package/dist/scripts/core-skill-immutable-sync-check.js +3 -2
- package/dist/scripts/core-skill-integrity-blackbox.js +3 -2
- package/dist/scripts/core-skill-manifest-check.js +7 -2
- package/dist/scripts/geo-claim-evidence-check.js +18 -0
- package/dist/scripts/geo-cli-blackbox-check.js +18 -0
- package/dist/scripts/geo-crawler-policy-check.js +16 -0
- package/dist/scripts/geo-llms-txt-optional-check.js +19 -0
- package/dist/scripts/gpt-final-arbiter-check.js +4 -1
- package/dist/scripts/loop-directive-check-lib.js +78 -1
- package/dist/scripts/qa-loop-app-server-driver-check.js +74 -0
- package/dist/scripts/qa-loop-surface-router-check.js +49 -0
- package/dist/scripts/release-check-dynamic-execute.js +1 -1
- package/dist/scripts/release-metadata-1-19-check.js +2 -2
- package/dist/scripts/release-parallel-check.js +17 -2
- package/dist/scripts/release-parallel-full-coverage-check.js +1 -1
- package/dist/scripts/release-readiness-report.js +6 -6
- package/dist/scripts/release-registry-check.js +33 -14
- package/dist/scripts/runtime-ts-rust-boundary-check.js +1 -1
- package/dist/scripts/search-visibility-gate-lib.js +124 -0
- package/dist/scripts/seo-audit-fixture-check.js +16 -0
- package/dist/scripts/seo-canonical-locale-check.js +19 -0
- package/dist/scripts/seo-cli-blackbox-check.js +18 -0
- package/dist/scripts/seo-geo-feature-fixture-quality-check.js +18 -0
- package/dist/scripts/seo-geo-geo-disambiguation-check.js +12 -0
- package/dist/scripts/seo-geo-no-unsupported-ranking-claims-check.js +18 -0
- package/dist/scripts/seo-geo-route-identity-check.js +12 -0
- package/dist/scripts/seo-geo-skill-rich-content-check.js +22 -0
- package/dist/scripts/seo-mutation-rollback-check.js +23 -0
- package/dist/scripts/seo-no-mutation-by-default-check.js +17 -0
- package/dist/scripts/seo-structured-data-visible-content-check.js +19 -0
- package/dist/scripts/sks-1-18-gate-lib.js +2 -2
- package/dist/scripts/sks-3-1-5-directive-check-lib.js +10 -1
- package/dist/scripts/source-intelligence-all-modes-check.js +9 -19
- package/dist/scripts/source-intelligence-policy-check.js +6 -6
- package/dist/scripts/triwiki-affected-graph-check.js +2 -2
- package/dist/scripts/ultra-search-provider-interface-check.js +27 -0
- package/package.json +26 -5
- package/schemas/search-visibility/finding-ledger.schema.json +36 -0
- package/schemas/search-visibility/gate.schema.json +22 -0
- package/schemas/search-visibility/mutation-plan.schema.json +27 -0
- package/schemas/search-visibility/site-inventory.schema.json +21 -0
- package/schemas/search-visibility/verification-report.schema.json +23 -0
- package/dist/core/mcp/xai-mcp-detector.js +0 -157
- package/dist/core/mcp/xai-search-adapter.js +0 -100
- package/dist/scripts/xai-mcp-capability-check.js +0 -14
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
export const LEAN_ENGINEERING_POLICY_ID = 'sks.lean-engineering-policy.v1';
|
|
3
|
+
export const LEAN_DECISION_SCHEMA = 'sks.lean-decision.v1';
|
|
4
|
+
export const LEAN_CHANGE_EVIDENCE_SCHEMA = 'sks.lean-change-evidence.v1';
|
|
5
|
+
export const LEAN_SOLUTION_RUNGS = Object.freeze([
|
|
6
|
+
'skip',
|
|
7
|
+
'reuse-existing',
|
|
8
|
+
'stdlib',
|
|
9
|
+
'native-platform',
|
|
10
|
+
'installed-dependency',
|
|
11
|
+
'single-expression',
|
|
12
|
+
'minimal-custom'
|
|
13
|
+
]);
|
|
14
|
+
const LEAN_ENGINEERING_POLICY_CANONICAL = [
|
|
15
|
+
'Understand the real flow before changing code.',
|
|
16
|
+
'Stop at the highest sufficient rung: skip, reuse existing code, stdlib, native platform, installed dependency, safe single expression, minimal custom code.',
|
|
17
|
+
'Do not add unrequested routes, commands, daemons, dependencies, abstractions, config flags, shims, or hidden fallbacks.',
|
|
18
|
+
'Fix shared root causes instead of duplicating caller-specific symptom guards.',
|
|
19
|
+
'Capability and compatibility fallbacks require one authority, proof, bounded scope, and honest verification level.',
|
|
20
|
+
'Never remove trust-boundary validation, data-loss protection, security, permissions, rollback, accessibility, or explicit user requirements to shrink a diff.',
|
|
21
|
+
'Non-trivial logic needs one smallest runnable check.'
|
|
22
|
+
].join('\n');
|
|
23
|
+
export const LEAN_ENGINEERING_POLICY_HASH = createHash('sha256')
|
|
24
|
+
.update(LEAN_ENGINEERING_POLICY_CANONICAL)
|
|
25
|
+
.digest('hex')
|
|
26
|
+
.slice(0, 16);
|
|
27
|
+
export function leanPolicyReference() {
|
|
28
|
+
return {
|
|
29
|
+
policy_id: LEAN_ENGINEERING_POLICY_ID,
|
|
30
|
+
policy_hash: LEAN_ENGINEERING_POLICY_HASH
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function leanEngineeringCompactText() {
|
|
34
|
+
return [
|
|
35
|
+
`Lean Engineering Policy (${LEAN_ENGINEERING_POLICY_ID}/${LEAN_ENGINEERING_POLICY_HASH}):`,
|
|
36
|
+
'Read the touched flow first, then stop at the highest sufficient rung: skip, reuse existing, stdlib, native platform, installed dependency, safe single expression, minimal custom.',
|
|
37
|
+
'No unrequested route/command/daemon/dependency/abstraction/config flag/shim/hidden fallback; required capability/compatibility fallback needs one authority, proof, and bounded scope.',
|
|
38
|
+
'Fix root cause once, preserve trust-boundary validation/security/rollback/accessibility/user requirements, and leave one runnable check for non-trivial logic.'
|
|
39
|
+
].join('\n');
|
|
40
|
+
}
|
|
41
|
+
export function leanEngineeringLongText() {
|
|
42
|
+
return [
|
|
43
|
+
leanEngineeringCompactText(),
|
|
44
|
+
'Forbidden fallback: silent mock/fixture success, provider contract switching without authority, catch-all empty success, unused future shims, duplicate legacy/new SSOTs, or production proof from test fakes.',
|
|
45
|
+
'Allowed fallback: same contract or explicit narrower contract, capability detection, one selection authority, recorded provider/proof level, honest downgrade when used, and a bounded chain.',
|
|
46
|
+
'Compatibility bridge: one canonical implementation; legacy entry only converts arguments, emits deprecation context, and has a sunset trigger.',
|
|
47
|
+
'Intentional simplification marker: `sks-lean: ceiling=<known limit>; revisit_when=<measurable trigger>; upgrade=<specific path>`.'
|
|
48
|
+
].join('\n');
|
|
49
|
+
}
|
|
50
|
+
export function normalizeLeanDecision(input = {}, defaults = {}) {
|
|
51
|
+
const value = record(input);
|
|
52
|
+
const defaultFallback = defaults.fallback_plan || { kind: 'none', authority: null, justification: null };
|
|
53
|
+
return {
|
|
54
|
+
schema: LEAN_DECISION_SCHEMA,
|
|
55
|
+
policy_id: LEAN_ENGINEERING_POLICY_ID,
|
|
56
|
+
policy_hash: LEAN_ENGINEERING_POLICY_HASH,
|
|
57
|
+
selected_rung: normalizeRung(value.selected_rung, defaults.selected_rung || 'minimal-custom'),
|
|
58
|
+
task_requires_change: booleanValue(value.task_requires_change, defaults.task_requires_change ?? true),
|
|
59
|
+
root_cause_target: nullableString(value.root_cause_target, defaults.root_cause_target ?? null),
|
|
60
|
+
reused_paths: stringArray(value.reused_paths, defaults.reused_paths),
|
|
61
|
+
stdlib_or_native_choice: nullableString(value.stdlib_or_native_choice, defaults.stdlib_or_native_choice ?? null),
|
|
62
|
+
new_dependency_requested: booleanValue(value.new_dependency_requested, defaults.new_dependency_requested ?? false),
|
|
63
|
+
new_dependency_justification: nullableString(value.new_dependency_justification, defaults.new_dependency_justification ?? null),
|
|
64
|
+
new_abstraction_requested: booleanValue(value.new_abstraction_requested, defaults.new_abstraction_requested ?? false),
|
|
65
|
+
new_abstraction_justification: nullableString(value.new_abstraction_justification, defaults.new_abstraction_justification ?? null),
|
|
66
|
+
fallback_plan: normalizeFallbackPlan(value.fallback_plan, defaultFallback),
|
|
67
|
+
expected_changed_paths: stringArray(value.expected_changed_paths, defaults.expected_changed_paths),
|
|
68
|
+
verification_minimum: stringArray(value.verification_minimum, defaults.verification_minimum)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export function validateLeanDecision(input) {
|
|
72
|
+
const value = record(input);
|
|
73
|
+
const issues = [];
|
|
74
|
+
if (value.schema !== LEAN_DECISION_SCHEMA)
|
|
75
|
+
issues.push('schema');
|
|
76
|
+
if (value.policy_id !== LEAN_ENGINEERING_POLICY_ID)
|
|
77
|
+
issues.push('policy_id');
|
|
78
|
+
if (value.policy_hash !== LEAN_ENGINEERING_POLICY_HASH)
|
|
79
|
+
issues.push('policy_hash');
|
|
80
|
+
if (!isLeanSolutionRung(value.selected_rung))
|
|
81
|
+
issues.push('selected_rung');
|
|
82
|
+
if (typeof value.task_requires_change !== 'boolean')
|
|
83
|
+
issues.push('task_requires_change');
|
|
84
|
+
if (!Array.isArray(value.reused_paths))
|
|
85
|
+
issues.push('reused_paths');
|
|
86
|
+
if (!Array.isArray(value.expected_changed_paths))
|
|
87
|
+
issues.push('expected_changed_paths');
|
|
88
|
+
if (!Array.isArray(value.verification_minimum))
|
|
89
|
+
issues.push('verification_minimum');
|
|
90
|
+
const fallback = record(value.fallback_plan);
|
|
91
|
+
if (!isFallbackKind(fallback.kind))
|
|
92
|
+
issues.push('fallback_plan.kind');
|
|
93
|
+
if (fallback.kind !== 'none' && (!fallback.authority || !fallback.justification))
|
|
94
|
+
issues.push('fallback_plan.evidence');
|
|
95
|
+
if (value.new_dependency_requested === true && !value.new_dependency_justification)
|
|
96
|
+
issues.push('new_dependency_justification');
|
|
97
|
+
if (value.new_abstraction_requested === true && !value.new_abstraction_justification)
|
|
98
|
+
issues.push('new_abstraction_justification');
|
|
99
|
+
if (value.selected_rung === 'skip' && value.task_requires_change === true)
|
|
100
|
+
issues.push('skip_requires_no_change');
|
|
101
|
+
if (value.task_requires_change === true && !value.verification_minimum?.length)
|
|
102
|
+
issues.push('verification_minimum_required');
|
|
103
|
+
return { ok: issues.length === 0, issues };
|
|
104
|
+
}
|
|
105
|
+
export function parseLeanSimplificationMarkerLine(text, file = '', line = 0) {
|
|
106
|
+
const match = /^\s*(?:(?:\/\/|#)\s*)sks-lean:\s*(.+)$/i.exec(text);
|
|
107
|
+
if (!match)
|
|
108
|
+
return null;
|
|
109
|
+
const fields = Object.fromEntries((match[1] || '').split(';').map((part) => {
|
|
110
|
+
const [key, ...rest] = part.split('=');
|
|
111
|
+
return [String(key || '').trim(), rest.join('=').trim()];
|
|
112
|
+
}));
|
|
113
|
+
const ceiling = fields.ceiling || null;
|
|
114
|
+
const revisit = fields.revisit_when || null;
|
|
115
|
+
const upgrade = fields.upgrade || null;
|
|
116
|
+
return {
|
|
117
|
+
file,
|
|
118
|
+
line,
|
|
119
|
+
ceiling,
|
|
120
|
+
revisit_when: revisit,
|
|
121
|
+
upgrade,
|
|
122
|
+
status: !revisit ? 'missing-trigger' : !upgrade ? 'missing-upgrade' : 'complete'
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function normalizeFallbackPlan(input, defaults) {
|
|
126
|
+
const value = record(input);
|
|
127
|
+
const kind = isFallbackKind(value.kind) ? value.kind : defaults.kind;
|
|
128
|
+
return {
|
|
129
|
+
kind,
|
|
130
|
+
authority: nullableString(value.authority, defaults.authority),
|
|
131
|
+
justification: nullableString(value.justification, defaults.justification)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function normalizeRung(value, fallback) {
|
|
135
|
+
return isLeanSolutionRung(value) ? value : fallback;
|
|
136
|
+
}
|
|
137
|
+
function isLeanSolutionRung(value) {
|
|
138
|
+
return typeof value === 'string' && LEAN_SOLUTION_RUNGS.includes(value);
|
|
139
|
+
}
|
|
140
|
+
function isFallbackKind(value) {
|
|
141
|
+
return value === 'none' || value === 'capability' || value === 'compatibility' || value === 'fail-closed';
|
|
142
|
+
}
|
|
143
|
+
function stringArray(value, fallback = []) {
|
|
144
|
+
const source = Array.isArray(value) ? value : Array.isArray(fallback) ? fallback : [];
|
|
145
|
+
return source.map((item) => String(item || '').trim()).filter(Boolean);
|
|
146
|
+
}
|
|
147
|
+
function nullableString(value, fallback = null) {
|
|
148
|
+
const text = String(value ?? '').trim();
|
|
149
|
+
if (text)
|
|
150
|
+
return text;
|
|
151
|
+
return fallback;
|
|
152
|
+
}
|
|
153
|
+
function booleanValue(value, fallback) {
|
|
154
|
+
return typeof value === 'boolean' ? value : fallback;
|
|
155
|
+
}
|
|
156
|
+
function record(value) {
|
|
157
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=lean-engineering-policy.js.map
|
|
@@ -26,7 +26,8 @@ import { prepareMadDbMission } from '../mad-db/mad-db-coordinator.js';
|
|
|
26
26
|
import { AGENT_INTAKE_STAGE_ID, AGENT_COUNT } from '../agents/agent-schema.js';
|
|
27
27
|
import { normalizeAgentPolicy, routeRequiresAgentIntake, agentPipelineStage } from '../agents/agent-plan.js';
|
|
28
28
|
import { readAgentGateStatus } from '../agents/agent-gate.js';
|
|
29
|
-
import { CODEX_APP_IMAGE_GENERATION_DOC_URL, CODEX_COMPUTER_USE_EVIDENCE_SOURCE, CODEX_COMPUTER_USE_ONLY_POLICY, CODEX_IMAGEGEN_REQUIRED_POLICY, CODEX_WEB_VERIFICATION_POLICY, FROM_CHAT_IMG_CHECKLIST_ARTIFACT, FROM_CHAT_IMG_COVERAGE_ARTIFACT, FROM_CHAT_IMG_QA_LOOP_ARTIFACT, FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT, FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS, SOLUTION_SCOUT_STAGE_ID, chatCaptureIntakeText, context7RequirementText, dollarCommand, evidenceMentionsForbiddenBrowserAutomation, getdesignReferencePolicyText, hasFromChatImgSignal, hasMadSksSignal, imageUxReviewPipelinePolicyText,
|
|
29
|
+
import { CODEX_APP_IMAGE_GENERATION_DOC_URL, CODEX_COMPUTER_USE_EVIDENCE_SOURCE, CODEX_COMPUTER_USE_ONLY_POLICY, CODEX_IMAGEGEN_REQUIRED_POLICY, CODEX_WEB_VERIFICATION_POLICY, FROM_CHAT_IMG_CHECKLIST_ARTIFACT, FROM_CHAT_IMG_COVERAGE_ARTIFACT, FROM_CHAT_IMG_QA_LOOP_ARTIFACT, FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT, FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS, SOLUTION_SCOUT_STAGE_ID, chatCaptureIntakeText, context7RequirementText, dollarCommand, evidenceMentionsForbiddenBrowserAutomation, getdesignReferencePolicyText, hasFromChatImgSignal, hasMadSksSignal, imageUxReviewPipelinePolicyText, leanEngineeringCompactText, looksLikeProblemSolvingRequest, pptPipelineAllowlistPolicyText, reflectionRequiredForRoute, reasoningInstruction, routeNeedsContext7, routePrompt, routeReasoning, routeRequiresSubagents, solutionScoutPolicyText, stripDollarCommand, stripMadSksSignal, stripVisibleDecisionAnswerBlocks, subagentExecutionPolicyText, stackCurrentDocsPolicyText, triwikiContextTracking, triwikiContextTrackingText, triwikiStagePolicyText } from '../routes.js';
|
|
30
|
+
import { normalizeLeanDecision, validateLeanDecision } from '../lean-engineering-policy.js';
|
|
30
31
|
import { TEAM_DECOMPOSITION_ARTIFACT, TEAM_GRAPH_ARTIFACT, TEAM_INBOX_DIR, TEAM_RUNTIME_TASKS_ARTIFACT, teamRuntimePlanMetadata, teamRuntimeRequiredArtifacts, validateTeamRuntimeArtifacts, writeTeamRuntimeArtifacts } from '../team-dag.js';
|
|
31
32
|
import { formatAgentReasoning, formatRoleCounts, initTeamLive, parseTeamSpecText, teamReasoningPolicy } from '../team-live.js';
|
|
32
33
|
import { evaluateTeamReviewPolicyGate, MIN_TEAM_REVIEWER_LANES, MIN_TEAM_REVIEW_POLICY_TEXT, teamReviewPolicy } from '../team-review-policy.js';
|
|
@@ -93,6 +94,13 @@ export function buildPipelinePlan(input = {}) {
|
|
|
93
94
|
const skipped = stages.filter((stage) => stage.status === 'skipped').map((stage) => stage.id);
|
|
94
95
|
const kept = stages.filter((stage) => stage.status !== 'skipped' && stage.status !== 'not_applicable').map((stage) => stage.id);
|
|
95
96
|
const routeEconomy = routeEconomyPlan(proof);
|
|
97
|
+
const leanDecision = normalizeLeanDecision(input.leanDecision, {
|
|
98
|
+
selected_rung: ['Answer', 'Help', 'Wiki'].includes(route?.id) ? 'skip' : 'minimal-custom',
|
|
99
|
+
task_requires_change: !['Answer', 'Help', 'Wiki'].includes(route?.id),
|
|
100
|
+
root_cause_target: route?.id ? `${route.id} route selected implementation surface` : null,
|
|
101
|
+
expected_changed_paths: input.expectedChangedPaths || input.touchedFiles || [],
|
|
102
|
+
verification_minimum: verification.slice(0, 3).map((item) => String(item || '').trim()).filter(Boolean)
|
|
103
|
+
});
|
|
96
104
|
return {
|
|
97
105
|
schema_version: PIPELINE_PLAN_SCHEMA_VERSION,
|
|
98
106
|
generated_at: nowIso(),
|
|
@@ -135,6 +143,7 @@ export function buildPipelinePlan(input = {}) {
|
|
|
135
143
|
verification,
|
|
136
144
|
invariants: ['no_unrequested_fallback_code', 'ssot_guard', 'listed_verification', 'triwiki_validate_before_final', 'honest_mode'],
|
|
137
145
|
proof_field: proof,
|
|
146
|
+
lean_decision: leanDecision,
|
|
138
147
|
ssot_guard: buildSsotGuard({ route: route?.id || 'SKS', mode: route?.mode || 'SKS', task }),
|
|
139
148
|
route_economy: routeEconomy,
|
|
140
149
|
agent_intake: agentPolicy,
|
|
@@ -193,6 +202,9 @@ export function validatePipelinePlan(plan = {}) {
|
|
|
193
202
|
const routeEconomyLatticeIssues = validateRouteEconomyDecisionLattice(plan.route_economy, plan.proof_field);
|
|
194
203
|
if (routeEconomyLatticeIssues.length)
|
|
195
204
|
issues.push(...routeEconomyLatticeIssues.map((issue) => `route_economy.decision_lattice:${issue}`));
|
|
205
|
+
const leanDecision = validateLeanDecision(plan.lean_decision);
|
|
206
|
+
if (!leanDecision.ok)
|
|
207
|
+
issues.push(...leanDecision.issues.map((issue) => `lean_decision:${issue}`));
|
|
196
208
|
if (plan.no_unrequested_fallback_code !== true || !plan.invariants?.includes('no_unrequested_fallback_code'))
|
|
197
209
|
issues.push('fallback_guard');
|
|
198
210
|
if (!plan.ssot_guard?.required || !plan.invariants?.includes('ssot_guard'))
|
|
@@ -427,10 +439,8 @@ export function promptPipelineContext(prompt, route = null) {
|
|
|
427
439
|
'Stance: infer the user intent aggressively from rough wording, local context, TriWiki, and conservative defaults; do not surface prequestion sheets before work.',
|
|
428
440
|
subagentExecutionPolicyText(route, cleanPrompt),
|
|
429
441
|
solutionScoutPolicyText(cleanPrompt),
|
|
430
|
-
|
|
442
|
+
leanEngineeringCompactText(),
|
|
431
443
|
ssotGuardPolicyText(),
|
|
432
|
-
outcomeRubricPolicyText(),
|
|
433
|
-
speedLanePolicyText(),
|
|
434
444
|
skillDreamPolicyText(),
|
|
435
445
|
route?.id === 'PPT'
|
|
436
446
|
? `${pptPipelineAllowlistPolicyText()} ${getdesignReferencePolicyText()}`
|
|
@@ -456,7 +466,7 @@ export function promptPipelineContext(prompt, route = null) {
|
|
|
456
466
|
if (route?.id === 'ImageUXReview')
|
|
457
467
|
lines.push(`Image UX Review route: ${imageUxReviewPipelinePolicyText()} Use ${IMAGE_UX_REVIEW_POLICY_ARTIFACT}, ${IMAGE_UX_REVIEW_SCREEN_INVENTORY_ARTIFACT}, ${IMAGE_UX_REVIEW_GENERATED_REVIEW_LEDGER_ARTIFACT}, ${IMAGE_UX_REVIEW_ISSUE_LEDGER_ARTIFACT}, ${IMAGE_UX_REVIEW_ITERATION_REPORT_ARTIFACT}, and ${IMAGE_UX_REVIEW_GATE_ARTIFACT} as the route evidence set. The route may suggest safe fixes only when the user requested fixing; otherwise report findings and blockers.`);
|
|
458
468
|
if (route?.id === 'AutoResearch')
|
|
459
|
-
lines.push('AutoResearch route: load autoresearch-loop
|
|
469
|
+
lines.push('AutoResearch route: load autoresearch-loop for experiments and benchmarking. SEO/GEO, discoverability, README, npm, GitHub search visibility, and AI-search visibility should use the first-class $SEO-GEO-OPTIMIZER parent route unless the selected route explicitly needs a child experiment.');
|
|
460
470
|
if (route?.id === 'DB')
|
|
461
471
|
lines.push('DB route: scan/check database risk first; destructive DB operations remain forbidden.');
|
|
462
472
|
if (route?.id === 'MadDB')
|
|
@@ -13,7 +13,7 @@ const AGENT_ARTIFACTS = [
|
|
|
13
13
|
'agents/agent-task-board.json',
|
|
14
14
|
'agents/agent-concurrency-policy.json'
|
|
15
15
|
];
|
|
16
|
-
export async function maybeFinalizeRoute(root, { missionId, route, gateFile = null, gate = null, artifacts = [], claims = [], visualEvidence = null, visual = false, fixClaim = false, requireRelation = false, mock = false, statusHint = null, reason = null, command = null, dbEvidence = null, testEvidence = null, blockers = [], unverified = [], agents = undefined, allowActiveWrongnessPartial = false, failureAnalysis = null } = {}) {
|
|
16
|
+
export async function maybeFinalizeRoute(root, { missionId, route, gateFile = null, gate = null, artifacts = [], claims = [], visualEvidence = null, visual = false, fixClaim = false, requireRelation = false, mock = false, statusHint = null, reason = null, command = null, dbEvidence = null, testEvidence = null, blockers = [], unverified = [], agents = undefined, allowActiveWrongnessPartial = false, failureAnalysis = null, lightweightEvidence = false } = {}) {
|
|
17
17
|
if (!missionId || !route) {
|
|
18
18
|
return { ok: false, skipped: true, reason: 'mission_id_or_route_missing' };
|
|
19
19
|
}
|
|
@@ -62,7 +62,8 @@ export async function maybeFinalizeRoute(root, { missionId, route, gateFile = nu
|
|
|
62
62
|
visualClaim: visual,
|
|
63
63
|
agents,
|
|
64
64
|
allowActiveWrongnessPartial,
|
|
65
|
-
failureAnalysis
|
|
65
|
+
failureAnalysis,
|
|
66
|
+
lightweightEvidence
|
|
66
67
|
});
|
|
67
68
|
return { ...proof, auto_finalized: true, gate_passed: passed, status_hint: finalStatus };
|
|
68
69
|
}
|
|
@@ -74,6 +74,7 @@ export function renderProofMarkdown(proof = {}, validation = validateCompletionP
|
|
|
74
74
|
`- Agents: ${proof.evidence?.agents?.agent_count ?? 0} (${proof.evidence?.agents?.status || 'not_recorded'})`,
|
|
75
75
|
`- TriWiki: ${proof.evidence?.triwiki?.status || 'not_recorded'}`,
|
|
76
76
|
`- Wrongness: ${proof.evidence?.wrongness?.active_count ?? 0} active (${proof.evidence?.wrongness?.high_severity_active ?? 0} high)`,
|
|
77
|
+
`- Lean engineering: ${proof.evidence?.lean_engineering?.semantic_review?.status || proof.evidence?.lean_engineering?.status || 'not_recorded'}`,
|
|
77
78
|
`- Evidence router: ${proof.evidence?.evidence_router?.records ?? 0} record(s)`,
|
|
78
79
|
`- Trust report: ${proof.evidence?.trust_report || 'not_recorded'}`,
|
|
79
80
|
''
|
|
@@ -5,8 +5,8 @@ import { normalizeProofRoute, routeRequiresImageVoxelAnchors } from './route-pro
|
|
|
5
5
|
import { linkProofClaimsToEvidence, proofEvidenceSummary } from '../evidence/evidence-proof-linker.js';
|
|
6
6
|
import { writeTrustArtifactsForProof } from '../trust-kernel/trust-report.js';
|
|
7
7
|
import { enforceRetention } from '../retention.js';
|
|
8
|
-
export async function writeRouteCompletionProof(root, { missionId = null, route = null, status = 'verified_partial', gate = null, summary = {}, artifacts = [], evidence = {}, claims = [], unverified = [], blockers = [], failureAnalysis = null, nextHumanActions = [] } = {}) {
|
|
9
|
-
const collected = await collectProofEvidence(root);
|
|
8
|
+
export async function writeRouteCompletionProof(root, { missionId = null, route = null, status = 'verified_partial', gate = null, summary = {}, artifacts = [], evidence = {}, claims = [], unverified = [], blockers = [], failureAnalysis = null, nextHumanActions = [], lightweightEvidence = false } = {}) {
|
|
9
|
+
const collected = lightweightEvidence ? { files: [] } : await collectProofEvidence(root);
|
|
10
10
|
const normalizedRoute = normalizeProofRoute(route);
|
|
11
11
|
const mergedEvidence = {
|
|
12
12
|
...collected,
|
|
@@ -45,6 +45,8 @@ export async function writeRouteCompletionProof(root, { missionId = null, route
|
|
|
45
45
|
status: normalizedStatus
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
|
+
if (lightweightEvidence)
|
|
49
|
+
return { ...written, trust: null, retention: null };
|
|
48
50
|
if (!missionId)
|
|
49
51
|
return written;
|
|
50
52
|
const firstTrust = await writeTrustArtifactsForProof(root, written.proof);
|
|
@@ -6,7 +6,8 @@ import { readAgentProofEvidence } from '../agents/agent-proof-evidence.js';
|
|
|
6
6
|
import { wrongnessProofEvidence } from '../triwiki-wrongness/wrongness-proof-linker.js';
|
|
7
7
|
import { computerUseStatusReport } from '../computer-use-status.js';
|
|
8
8
|
import { readComputerUseLiveEvidence } from '../computer-use-live-evidence.js';
|
|
9
|
-
|
|
9
|
+
import { leanChangeEvidenceFromReport, scanCodeStructure } from '../code-structure.js';
|
|
10
|
+
export async function finalizeRouteWithProof(root, { missionId, route, gateFile = null, gate = null, artifacts = [], visualEvidence = null, dbEvidence = null, madSksEvidence = null, testEvidence = null, commandEvidence = null, claims = [], unverified = [], blockers = [], statusHint = 'verified_partial', strict = false, mock = false, fixClaim = false, requireRelation = false, visualClaim = undefined, agents = undefined, allowActiveWrongnessPartial = false, failureAnalysis = null, lightweightEvidence = false } = {}) {
|
|
10
11
|
const policy = routeFinalizerPolicy(route, { strict, fixClaim, requireRelation, visualClaim });
|
|
11
12
|
const localBlockers = [...blockers];
|
|
12
13
|
const providedVisualEvidence = visualEvidence;
|
|
@@ -23,9 +24,14 @@ export async function finalizeRouteWithProof(root, { missionId, route, gateFile
|
|
|
23
24
|
localBlockers.push(...(imageEvidence.issues?.length ? imageEvidence.issues : ['image_voxel_anchors_missing']));
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
|
-
const collected = await collectProofEvidence(root);
|
|
27
|
+
const collected = lightweightEvidence ? { files: [] } : await collectProofEvidence(root);
|
|
28
|
+
const leanEngineeringEvidence = await collectLeanEngineeringEvidence(root, lightweightEvidence).catch((err) => ({
|
|
29
|
+
schema: 'sks.lean-change-evidence.v1',
|
|
30
|
+
status: 'not_collected',
|
|
31
|
+
reason: err?.message || String(err || 'unknown_error')
|
|
32
|
+
}));
|
|
27
33
|
const agentEvidence = agents === false ? null : await readAgentProofEvidence(root, missionId).catch(() => null);
|
|
28
|
-
const wrongnessEvidence = await wrongnessProofEvidence(root, missionId, { route: policy.route }).catch(() => null);
|
|
34
|
+
const wrongnessEvidence = lightweightEvidence ? null : await wrongnessProofEvidence(root, missionId, { route: policy.route }).catch(() => null);
|
|
29
35
|
const requiresNativeComputerUseLiveEvidence = ['$Computer-Use', '$CU'].includes(String(policy.route || ''));
|
|
30
36
|
const computerUse = requiresNativeComputerUseLiveEvidence
|
|
31
37
|
? await computerUseStatusReport().catch((err) => ({ schema: 'sks.computer-use-status.v1', status: 'unknown', ok: false, guidance: [err.message], evidence: { status: 'unknown' } }))
|
|
@@ -117,6 +123,7 @@ export async function finalizeRouteWithProof(root, { missionId, route, gateFile
|
|
|
117
123
|
evidence: computerUse.evidence || null,
|
|
118
124
|
live_evidence: computerUseLive?.evidence || null
|
|
119
125
|
} } : {}),
|
|
126
|
+
lean_engineering: leanEngineeringEvidence,
|
|
120
127
|
route_gate: gate || (gateFile ? { source: gateFile } : null)
|
|
121
128
|
};
|
|
122
129
|
return writeRouteCompletionProof(root, {
|
|
@@ -130,6 +137,7 @@ export async function finalizeRouteWithProof(root, { missionId, route, gateFile
|
|
|
130
137
|
unverified: finalUnverified,
|
|
131
138
|
blockers: localBlockers,
|
|
132
139
|
failureAnalysis: resolvedFailureAnalysis,
|
|
140
|
+
lightweightEvidence,
|
|
133
141
|
summary: {
|
|
134
142
|
files_changed: collected.files?.length || 0,
|
|
135
143
|
commands_run: evidence.commands?.length || 0,
|
|
@@ -139,6 +147,30 @@ export async function finalizeRouteWithProof(root, { missionId, route, gateFile
|
|
|
139
147
|
}
|
|
140
148
|
});
|
|
141
149
|
}
|
|
150
|
+
async function collectLeanEngineeringEvidence(root, lightweightEvidence) {
|
|
151
|
+
if (lightweightEvidence) {
|
|
152
|
+
return leanChangeEvidenceFromReport({
|
|
153
|
+
changed_scope: {
|
|
154
|
+
mode: 'lightweight',
|
|
155
|
+
base: 'HEAD',
|
|
156
|
+
changed_files: [],
|
|
157
|
+
files_added: 0,
|
|
158
|
+
files_deleted: 0,
|
|
159
|
+
lines_added: 0,
|
|
160
|
+
lines_deleted: 0,
|
|
161
|
+
net_lines: 0,
|
|
162
|
+
source_files: [],
|
|
163
|
+
entries: []
|
|
164
|
+
},
|
|
165
|
+
semantic_review: {
|
|
166
|
+
status: 'needs-review',
|
|
167
|
+
findings: [{ tag: 'verify', severity: 'review', summary: 'lightweight proof skipped changed-scope code-structure scan' }]
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const report = await scanCodeStructure(root, { changed: true });
|
|
172
|
+
return leanChangeEvidenceFromReport(report);
|
|
173
|
+
}
|
|
142
174
|
function inferRouteFailureAnalysis({ missionId, route, status, blockers, unverified, wrongnessEvidence, imageEvidence, agentEvidence, computerUse, computerUseLive, visualComputerUseDowngrade } = {}) {
|
|
143
175
|
if (status === 'verified' && !blockers?.length && !unverified?.length)
|
|
144
176
|
return null;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { appendJsonlBounded, nowIso, writeJsonAtomic } from '../fsx.js';
|
|
3
|
+
import { QA_ACTION_LEDGER_ARTIFACT, QA_LIVE_SESSION_ARTIFACT, QA_RUNTIME_EVENT_LEDGER_ARTIFACT } from './qa-types.js';
|
|
4
|
+
export async function runQaAppServerDriver(input) {
|
|
5
|
+
const events = [];
|
|
6
|
+
const dispose = input.client.onEvent?.((event) => {
|
|
7
|
+
events.push(event);
|
|
8
|
+
});
|
|
9
|
+
const startedAt = nowIso();
|
|
10
|
+
const blockers = [];
|
|
11
|
+
let threadId = null;
|
|
12
|
+
let turnId = null;
|
|
13
|
+
try {
|
|
14
|
+
await input.client.initialize?.();
|
|
15
|
+
const thread = await input.client.startThread({
|
|
16
|
+
cwd: input.cwd,
|
|
17
|
+
...input.threadStartParams
|
|
18
|
+
});
|
|
19
|
+
threadId = extractThreadId(thread);
|
|
20
|
+
if (!threadId)
|
|
21
|
+
blockers.push('app_server_thread_id_missing');
|
|
22
|
+
if (threadId) {
|
|
23
|
+
const turn = await input.client.startTurn({
|
|
24
|
+
threadId,
|
|
25
|
+
cwd: input.cwd,
|
|
26
|
+
input: [{ type: 'text', text: input.prompt }],
|
|
27
|
+
...input.turnStartParams
|
|
28
|
+
});
|
|
29
|
+
turnId = extractTurnId(turn);
|
|
30
|
+
if (!turnId)
|
|
31
|
+
blockers.push('app_server_turn_id_missing');
|
|
32
|
+
if (input.client.waitForTurnCompletion) {
|
|
33
|
+
const completed = await input.client.waitForTurnCompletion(threadId, turnId, input.timeoutMs);
|
|
34
|
+
events.push({ method: 'turn/completed', params: completed, received_at: nowIso() });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
blockers.push(`app_server_driver_failed:${err instanceof Error ? err.message : String(err)}`);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
dispose?.();
|
|
43
|
+
}
|
|
44
|
+
await writeAppServerEventLedgers(input.missionDir, input.missionId, input.surfaceSelection.selected_surface, threadId, turnId, events);
|
|
45
|
+
const session = {
|
|
46
|
+
schema: 'sks.qa-loop-live-session.v2',
|
|
47
|
+
started_at: startedAt,
|
|
48
|
+
completed_at: nowIso(),
|
|
49
|
+
mission_id: input.missionId,
|
|
50
|
+
status: blockers.length ? 'blocked' : 'completed',
|
|
51
|
+
selected_surface: input.surfaceSelection.selected_surface,
|
|
52
|
+
thread_id: threadId,
|
|
53
|
+
turn_id: turnId,
|
|
54
|
+
event_count: events.length,
|
|
55
|
+
item_event_count: events.filter(isItemEvent).length,
|
|
56
|
+
action_event_count: events.filter(isActionLikeEvent).length,
|
|
57
|
+
observation_event_count: events.filter(isObservationLikeEvent).length,
|
|
58
|
+
blockers,
|
|
59
|
+
unverified: events.some(isActionLikeEvent) ? [] : ['app_server_action_event_unverified'],
|
|
60
|
+
artifacts: {
|
|
61
|
+
runtime_events: QA_RUNTIME_EVENT_LEDGER_ARTIFACT,
|
|
62
|
+
action_ledger: QA_ACTION_LEDGER_ARTIFACT
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
await writeJsonAtomic(path.join(input.missionDir, QA_LIVE_SESSION_ARTIFACT), session);
|
|
66
|
+
return session;
|
|
67
|
+
}
|
|
68
|
+
async function writeAppServerEventLedgers(missionDir, missionId, surface, threadId, turnId, events) {
|
|
69
|
+
for (const event of events) {
|
|
70
|
+
const method = String(event.method || event.type || event.params?.method || 'app_server_event');
|
|
71
|
+
await appendJsonlBounded(path.join(missionDir, QA_RUNTIME_EVENT_LEDGER_ARTIFACT), {
|
|
72
|
+
schema: 'sks.qa-loop-app-server-event.v2',
|
|
73
|
+
ts: nowIso(),
|
|
74
|
+
mission_id: missionId,
|
|
75
|
+
thread_id: event.params?.threadId || event.threadId || threadId,
|
|
76
|
+
turn_id: event.params?.turnId || event.params?.turn?.id || event.turnId || turnId,
|
|
77
|
+
item_id: event.params?.itemId || event.params?.item?.id || event.itemId || null,
|
|
78
|
+
surface,
|
|
79
|
+
kind: method,
|
|
80
|
+
status: 'observed',
|
|
81
|
+
data: redactEvent(event)
|
|
82
|
+
});
|
|
83
|
+
if (isActionLikeEvent(event)) {
|
|
84
|
+
await appendJsonlBounded(path.join(missionDir, QA_ACTION_LEDGER_ARTIFACT), {
|
|
85
|
+
schema: 'sks.qa-loop-action.v2',
|
|
86
|
+
ts: nowIso(),
|
|
87
|
+
mission_id: missionId,
|
|
88
|
+
thread_id: event.params?.threadId || event.threadId || threadId,
|
|
89
|
+
turn_id: event.params?.turnId || event.params?.turn?.id || event.turnId || turnId,
|
|
90
|
+
item_id: event.params?.itemId || event.params?.item?.id || event.itemId || null,
|
|
91
|
+
surface,
|
|
92
|
+
kind: method,
|
|
93
|
+
status: 'observed',
|
|
94
|
+
real: true,
|
|
95
|
+
data: redactEvent(event)
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function extractThreadId(value) {
|
|
101
|
+
const obj = value;
|
|
102
|
+
return stringOrNull(obj?.thread?.id || obj?.threadId || obj?.id);
|
|
103
|
+
}
|
|
104
|
+
function extractTurnId(value) {
|
|
105
|
+
const obj = value;
|
|
106
|
+
return stringOrNull(obj?.turn?.id || obj?.turnId || obj?.id);
|
|
107
|
+
}
|
|
108
|
+
function stringOrNull(value) {
|
|
109
|
+
const text = String(value || '').trim();
|
|
110
|
+
return text || null;
|
|
111
|
+
}
|
|
112
|
+
function isItemEvent(event) {
|
|
113
|
+
return /^item\//.test(String(event.method || event.type || ''));
|
|
114
|
+
}
|
|
115
|
+
function isActionLikeEvent(event) {
|
|
116
|
+
const method = String(event.method || event.type || '');
|
|
117
|
+
return /^item\/.*(?:tool|action|commandExecution|computer|browser|chrome)/i.test(method)
|
|
118
|
+
|| /(?:tool|action|click|type|scroll|navigate|screenshot|observation)/i.test(JSON.stringify(event.params || event));
|
|
119
|
+
}
|
|
120
|
+
function isObservationLikeEvent(event) {
|
|
121
|
+
const method = String(event.method || event.type || '');
|
|
122
|
+
return /observation|completed|screenshot|browser|chrome|computer/i.test(method)
|
|
123
|
+
|| /observation|screenshot|visual|page|window/i.test(JSON.stringify(event.params || event));
|
|
124
|
+
}
|
|
125
|
+
function redactEvent(event) {
|
|
126
|
+
return JSON.parse(JSON.stringify(event, (key, value) => {
|
|
127
|
+
if (/(password|passwd|token|secret|cookie|authorization|credential)/i.test(String(key)))
|
|
128
|
+
return '[REDACTED]';
|
|
129
|
+
if (typeof value === 'string' && /(Bearer\s+[A-Za-z0-9._-]+|sk-[A-Za-z0-9_-]+)/.test(value))
|
|
130
|
+
return '[REDACTED]';
|
|
131
|
+
return value;
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=qa-app-server-driver.js.map
|