chore: consolidate documentation and clean repository

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Даня Архипов
2026-08-01 18:29:15 +00:00
parent 4413f01ce4
commit 13ce16bedc
596 changed files with 501 additions and 45214 deletions

View File

@@ -1,22 +0,0 @@
import { describe, expect, it } from 'vitest';
import { OZON_CRITERIA } from './criteria';
import { SCENARIOS } from './scenarios';
const scenarioIds = new Set(SCENARIOS.map((scenario) => scenario.id));
describe('OZON criteria', () => {
it('contains evidence and valid scenario references', () => {
expect(OZON_CRITERIA.length).toBeGreaterThan(0);
for (const criterion of OZON_CRITERIA) {
expect(criterion.title).toBeTruthy();
expect(criterion.status).toMatch(/covered|partially covered|demo step available/);
expect(criterion.evidence).toBeTruthy();
expect(criterion.relatedDoc).toBeTruthy();
expect(criterion.relatedScenarioIds.length).toBeGreaterThan(0);
for (const scenarioId of criterion.relatedScenarioIds) {
expect(scenarioIds.has(scenarioId)).toBe(true);
}
}
});
});

View File

@@ -1,108 +0,0 @@
import type { OzonCriterion } from '../domain/types';
export const OZON_CRITERIA: OzonCriterion[] = [
{
id: 'category-correctness',
title: 'Category correctness',
status: 'covered',
evidence: 'Classifier tests and decision tree prove B/C/D outcomes for mock SKUs.',
relatedScenarioIds: ['normal_flow', 'oversized_item', 'round_object'],
relatedDoc: 'docs/SCENARIOS.md',
},
{
id: 'classification-rules',
title: 'Classification rules: dimensions, roundness, priority',
status: 'covered',
evidence: 'ClassificationPanel shows thresholds, actual values, PASS/FAIL and C priority.',
relatedScenarioIds: ['oversized_item', 'round_object', 'c_priority', 'boundary_dimensions'],
relatedDoc: 'docs/ARCHITECTURE.md',
},
{
id: 'boundary-cases',
title: 'Boundary cases',
status: 'covered',
evidence: 'Boundary dimensions scenario and tests cover max boundary and min-width violation.',
relatedScenarioIds: ['boundary_dimensions'],
relatedDoc: 'docs/SCENARIOS.md',
},
{
id: 'physical-routing',
title: 'Physical routing B/C/D',
status: 'covered',
evidence: 'SorterScene displays B straight route, C lower route and D upper route with commands.',
relatedScenarioIds: ['normal_flow', 'oversized_item', 'round_object'],
relatedDoc: 'docs/DEMO_SCRIPT.md',
},
{
id: 'manipulation-logic',
title: 'Manipulation logic',
status: 'covered',
evidence: 'Stop-gate and pusher states are tied to state machine routes.',
relatedScenarioIds: ['oversized_item', 'round_object'],
relatedDoc: 'docs/ARCHITECTURE.md',
},
{
id: 'geometry-variety',
title: 'Geometry variety',
status: 'covered',
evidence: 'Mock items include boxes, pouf, plate, bottle, cylinder, pen and boundary box.',
relatedScenarioIds: ['normal_flow', 'round_object', 'boundary_dimensions'],
relatedDoc: 'docs/SCENARIOS.md',
},
{
id: 'safety-emergency',
title: 'Safety / emergency stop',
status: 'demo step available',
evidence: 'Emergency stop scenario enters EMERGENCY_STOP and requires Reset.',
relatedScenarioIds: ['emergency_stop'],
relatedDoc: 'docs/DEMO_SCRIPT.md',
},
{
id: 'cycle-time-throughput',
title: 'Cycle time and throughput',
status: 'covered',
evidence: 'Metrics cards show processed count, avg cycle time and throughput.',
relatedScenarioIds: ['normal_flow', 'close_items'],
relatedDoc: 'docs/ARCHITECTURE.md',
},
{
id: 'timing-synchronization',
title: 'Timing synchronization',
status: 'covered',
evidence: 'CycleTimeline shows state timestamps, durations and active/done status.',
relatedScenarioIds: ['normal_flow', 'close_items'],
relatedDoc: 'docs/ARCHITECTURE.md',
},
{
id: 'fault-handling',
title: 'Fault handling',
status: 'demo step available',
evidence: 'Jam scenario enters FAULT, logs fault and stops conveyor.',
relatedScenarioIds: ['jam', 'low_confidence'],
relatedDoc: 'docs/JURY_QA.md',
},
{
id: 'cv-actuator-integration',
title: 'CV-to-actuator integration',
status: 'covered',
evidence: 'Pseudo-CV packet feeds classification, which emits ROUTE_TO_* actuator commands.',
relatedScenarioIds: ['normal_flow', 'low_confidence'],
relatedDoc: 'docs/ARCHITECTURE.md',
},
{
id: 'engineering-realism',
title: 'Engineering realism',
status: 'partially covered',
evidence: 'Scaled 2D layout, sensor latency, PID imitation and event trace are present; real hardware is out of MVP scope.',
relatedScenarioIds: ['normal_flow', 'jam', 'emergency_stop'],
relatedDoc: 'docs/JURY_QA.md',
},
{
id: 'reproducibility-docs',
title: 'Reproducibility / docs',
status: 'covered',
evidence: 'README and docs describe architecture, demo script, scenarios and jury Q&A.',
relatedScenarioIds: ['normal_flow', 'boundary_dimensions'],
relatedDoc: 'docs/DEMO_SCRIPT.md',
},
];

View File

@@ -1,17 +0,0 @@
import { describe, expect, it } from 'vitest';
import { DEMO_STEPS } from './demoSteps';
import { SCENARIOS } from './scenarios';
const scenarioIds = new Set(SCENARIOS.map((scenario) => scenario.id));
describe('demo steps', () => {
it('have required narrative fields and valid scenarios', () => {
for (const step of DEMO_STEPS) {
expect(step.id).toBeTruthy();
expect(step.title).toBeTruthy();
expect(scenarioIds.has(step.scenarioId)).toBe(true);
expect(step.relatedCriteria.length).toBeGreaterThan(0);
expect(step.presenterPhrase).toBeTruthy();
}
});
});

View File

@@ -1,137 +0,0 @@
import type { DemoStep } from '../domain/types';
export const DEMO_STEPS: DemoStep[] = [
{
id: 'system-overview',
title: 'System overview',
scenarioId: 'normal_flow',
preferredAction: 'reset',
focusArea: 'scene',
explanation: 'The line is presented as detection -> classification -> actuator command -> physical route.',
whatToWatch: 'Scaled SVG scene, sensor positions, stop-gate, pushers and B/C/D routing arrows.',
juryValue: 'Shows that the project is an engineering simulation of a sorting cell, not a decorative animation.',
relatedCriteria: ['engineering-realism', 'cv-actuator-integration', 'physical-routing'],
presenterPhrase: 'We model the whole loop: the item is detected, classified by rules, converted to an actuator command and routed physically.',
},
{
id: 'normal-item-to-b',
title: 'Normal item to B',
scenarioId: 'normal_flow',
preferredAction: 'step',
focusArea: 'classification',
explanation: 'A regular box passes dimensions and roundness checks, so it stays on the main sorter path.',
whatToWatch: 'Decision tree PASS/PASS and ROUTE_TO_B command in the scene and event log.',
juryValue: 'Proves the happy path and shows category correctness for standard goods.',
relatedCriteria: ['category-correctness', 'classification-rules', 'physical-routing'],
presenterPhrase: 'For a normal SKU, dimensions pass and circular section is not detected, so the gate opens to B.',
},
{
id: 'oversized-to-c',
title: 'Oversized item to C',
scenarioId: 'oversized_item',
preferredAction: 'step',
focusArea: 'classification',
explanation: 'Oversized goods fail the first rule and are routed to roll-cage C before shape is considered.',
whatToWatch: 'Dimensions FAIL, category C, pusher C and route arrow to the lower roll-cage.',
juryValue: 'Shows rule priority and safe diversion for non-compliant dimensions.',
relatedCriteria: ['classification-rules', 'boundary-cases', 'manipulation-logic'],
presenterPhrase: 'C has priority because geometry safety is checked before shape: this item cannot continue on the main sorter.',
},
{
id: 'round-object-to-d',
title: 'Round object to D',
scenarioId: 'round_object',
preferredAction: 'step',
focusArea: 'scene',
explanation: 'Roundness K > 0.8 after valid dimensions sends the item to D for repack/shape issue handling.',
whatToWatch: 'Roundness FAIL for B, category D and the upper route/pusher D command.',
juryValue: 'Shows how the circle-section rule becomes a physical route.',
relatedCriteria: ['classification-rules', 'geometry-variety', 'physical-routing'],
presenterPhrase: 'The dimensions fit, but roundness is high, so the system sends it to D for do-upakovka.',
},
{
id: 'c-priority-oversized-round',
title: 'C priority oversized + round',
scenarioId: 'c_priority',
preferredAction: 'step',
focusArea: 'classification',
explanation: 'Item is both oversized and round; dimensions are checked first so category is C, not D.',
whatToWatch: 'DIM FAIL, K high, category C, ROUTE_TO_C active, route D inactive.',
juryValue: 'Proves C-priority rule for Track 3.',
relatedCriteria: ['classification-rules', 'boundary-cases', 'physical-routing'],
presenterPhrase: 'Even though the item is round, dimensions fail first, so we route only to C.',
},
{
id: 'boundary-dimensions',
title: 'Boundary dimensions',
scenarioId: 'boundary_dimensions',
preferredAction: 'step',
focusArea: 'classification',
explanation: 'Items at the edge of the allowed envelope prove the rule implementation is stable.',
whatToWatch: '450 x 320 x 320 passes, while width 9 mm fails min width and goes to C.',
juryValue: 'Shows deterministic boundary behavior rather than visual guessing.',
relatedCriteria: ['boundary-cases', 'category-correctness', 'reproducibility-docs'],
presenterPhrase: 'The exact boundary is accepted, but one millimeter below minimum width is rejected.',
},
{
id: 'low-confidence-fallback',
title: 'Low confidence fallback',
scenarioId: 'low_confidence',
preferredAction: 'step',
focusArea: 'eventLog',
explanation: 'Low pseudo-CV confidence raises a warning but does not block rule-based classification.',
whatToWatch: 'Warning message, fallback note and final category in classification/event log.',
juryValue: 'Shows graceful degradation when CV is uncertain.',
relatedCriteria: ['cv-actuator-integration', 'fault-handling', 'classification-rules'],
presenterPhrase: 'CV confidence is low, so we flag it, but dimensions and roundness still produce a deterministic decision.',
},
{
id: 'close-items-queue',
title: 'Close items queue',
scenarioId: 'close_items',
preferredAction: 'start',
focusArea: 'timeline',
explanation: 'Close spacing creates a queue warning and items are still processed one cycle at a time.',
whatToWatch: 'Queue length, queue delay, spacing warning and sequential timeline.',
juryValue: 'Shows robustness for a common operational issue without overcomplicated physics.',
relatedCriteria: ['timing-synchronization', 'cycle-time-throughput', 'fault-handling'],
presenterPhrase: 'The line detects close spacing, holds the queue and keeps the state machine deterministic.',
},
{
id: 'jam-fault-handling',
title: 'Jam / fault handling',
scenarioId: 'jam',
preferredAction: 'step',
focusArea: 'safety',
explanation: 'A jam at the stop-gate moves the system to FAULT and stops the conveyor.',
whatToWatch: 'FAULT state, red scene overlay, PID target 0 and Reset required.',
juryValue: 'Shows fail-safe behavior and operator recovery path.',
relatedCriteria: ['fault-handling', 'safety-emergency', 'pid-synchronization'],
presenterPhrase: 'When the gate jams, the safest command is to stop motion and require reset.',
},
{
id: 'emergency-stop',
title: 'Emergency stop',
scenarioId: 'emergency_stop',
preferredAction: 'step',
focusArea: 'safety',
explanation: 'Emergency stop interrupts the line and brings motion toward zero.',
whatToWatch: 'EMERGENCY_STOP state, stopped conveyor and PID speed falling to zero.',
juryValue: 'Shows explicit safety handling for abnormal operation.',
relatedCriteria: ['safety-emergency', 'fault-handling', 'engineering-realism'],
presenterPhrase: 'Emergency stop is not another route; it is a safety state that freezes the line until reset.',
},
{
id: 'performance-sync',
title: 'Performance and synchronization',
scenarioId: 'normal_flow',
preferredAction: 'start',
focusArea: 'pid',
explanation: 'Timeline, latency cards and PID graph show how the simulated control loop stays synchronized.',
whatToWatch: 'CycleTimeline, CV latency, actuator latency, throughput and PID speed curve.',
juryValue: 'Shows that the demo explains timing and throughput, not only classification.',
relatedCriteria: ['cycle-time-throughput', 'timing-synchronization', 'engineering-realism'],
presenterPhrase: 'Here we close the loop: decisions are timestamped, actuators have latency and conveyor control is visible.',
},
];

View File

@@ -1,70 +1,182 @@
/**
* Compact tracked production-status summary for the Documentation page.
* Sources: Gate 2C / 2D confirmed decisions. Unverified values are NOT stated as facts.
* Does not import ignored tools/author-exact-v4/out/ at runtime.
* Canonical summary data for `/documentation`.
* Authority: official sources present in-repo → production code → unit tests.
* Unverified / planned items are labeled explicitly — never implied complete.
*/
/** Kept for e2e (`docs-production-status`) and acquisition-pack provenance. */
export const PRODUCTION_STATUS = {
acquisitionPackStatus: 'DATA_ACQUISITION_PACK_READY',
electricalGateStatus: 'BLOCKED_BY_MISSING_PRODUCTION_INPUTS',
productionDesignReady: false,
motorSelected: false,
encoderSelected: false,
diverterApproved: false,
cadReady: false,
gate3Started: false,
webTwinStatus: 'BASELINE_PRESERVED',
unitTests: '196/196',
productionBuild: 'PASS',
contactPhysics: 'NOT_FULLY_VALIDATED',
officialCompliance: 'PARTIAL_SOURCES_PRESENT',
} as const;
/** Confirmed layout facts only (drawing / shared provenance). */
export const CONFIRMED_LAYOUT = {
workspaceMm: { length: 10000, width: 6000 },
conveyorWidthMm: 500,
conveyorHeightMm: 700,
pointACenterlineFromWorkspaceBottomMm: 3000,
authorDiverter: 'ABSENT' as const,
link027029Role: 'STOP_GATE' as const,
modules: ['clean', 'camera', 'sorter'] as const,
receivers: ['B_STRAIGHT', 'ZONE_C', 'ZONE_D'] as const,
} as const;
export const CONFIRMED_COMPONENT_POLICY = {
mg996r: 'PROTOTYPE_ONLY' as const,
vl53l0x: 'NOT_PRODUCTION_OR_SAFETY' as const,
productionMotor: 'NOT_DEFINED' as const,
productionGearbox: 'NOT_DEFINED' as const,
productionDriver: 'NOT_DEFINED' as const,
productionEncoder: 'NOT_SELECTED' as const,
export const CLASSIFIER_BOUNDS = {
status: 'CURRENT_IMPLEMENTATION_VERIFIED_IN_CODE' as const,
officialSourceReference: 'official_sources/doc-1783095831.pdf',
officialSourceParsedThisPass: false,
minExclusiveMm: { width: 10, depth: 10, height: 10 },
maxExclusiveMm: { width: 450, depth: 320, height: 320 },
roundnessThresholdExclusive: 0.8,
display: {
min: '> 10×10×10 мм',
max: '< 450×320×320 мм',
roundness: 'K > 0.8',
},
checkOrder: 'dimensions→C, else circular→D, else B' as const,
} as const;
export const ROLLER_DIAMETER_CONFLICT = {
authorCadIdlerMm: 50,
runtimeIdlerMm: 80,
runtimeDriveMm: 120,
status: 'CONFLICTING' as const,
} as const;
export const CURRENT_BLOCKERS = [
'Отсутствуют производственные параметры двигателя',
'Энкодер не выбран',
'Конфликт диаметров роликов (CAD idler 50 / runtime idler 80 / runtime drive 120)',
'ROOT_BIND не подтверждён',
'Не зафиксирована геометрия junction',
'Отсутствуют товарные нагрузки (масса, COM, трение)',
'Не завершена силовая архитектура',
'Не завершена safety-архитектура',
'Производственный diverter ещё не спроектирован',
export const ROUTE_MAPPING = [
{ category: 'B', physicalRoute: 'STRAIGHT', activeDiverter: 'NONE', signedAngleDeg: 0 },
{ category: 'C', physicalRoute: 'PHYSICAL_LEFT', activeDiverter: 'LEFT', signedAngleDeg: -45 },
{ category: 'D', physicalRoute: 'PHYSICAL_RIGHT', activeDiverter: 'RIGHT', signedAngleDeg: 45 },
] as const;
export const GATE_STATUS_BOARD = [
{ gate: '0 BASELINE', status: 'PASS' },
{ gate: '1 AUTHOR STRUCTURE', status: 'PASS' },
{ gate: '2 KINEMATICS', status: 'BLOCKED' },
{ gate: '2A source discovery', status: 'NO_AUTHOR_DIVERTER_SOURCE' },
{ gate: '2B engineering spec', status: 'ARCHITECTURE_RESELECTION_REQUIRED' },
{ gate: '2C production electrical', status: 'BLOCKED_BY_MISSING_PRODUCTION_INPUTS' },
{ gate: '2D data acquisition pack', status: 'DATA_ACQUISITION_PACK_READY' },
{ gate: '3 AUTHOR_EXACT / production CAD', status: 'NOT_STARTED' },
export const DIVERTER_KINEMATICS = {
rotationDurationSec: 0.5,
openingSafetyMarginSec: 0.15,
contactPlaneS: 1.0538,
clearPlaneS: 1.6,
phases: ['READY', 'ARMED', 'OPENING', 'HOLDING', 'CLOSING'] as const,
productBound: true,
oneActiveProduct: true,
closeAfterRearClear: true,
generatedMechanismActive: false,
} as const;
export const CAD_PROVENANCE = {
authorFcstd: '3d_models/conveer.FCStd',
authorSha256: '90c1844a4ca05e26def783d6130fc4b993430dde14307534ef8fbb21c9fac2e6',
runtimeGlb: 'public/models/sorter/conveyor-clean.glb',
runtimeSha256: '1dc7a8d7891bfe756e277ad5368df74cb73410156b2fe0f92845afb8a56f285a',
authorServosInSorterModule: true,
generatedMechanismInactive: true,
hornTransmissionInGlb: 'ABSENT_OR_INCOMPLETE' as const,
} as const;
export const PHYSICS_STATUS = {
implemented: [
'Runtime product motion on belt (domain pose + Rapier handoff)',
'Product-associated diverter route timing (productId-bound)',
'Synchronized CAD diverter visual / kinematic targets',
'CCD enabled for light/thin SKUs in runtime and headless sim',
'Visual/physics spawn gating via product asset preload',
],
notFullyValidated: [
'Complete contact-only routing through CAD diverters',
'Belt surface velocity exactly 1 m/s with tangential drive',
'Calibrated friction / mass / COM per SKU',
'Fully physical continuous conveyor loop',
'Receiver capture under all item classes',
],
planned: [
'Visual full belt loop with surface-velocity coupling',
'Controlled tangential friction at 1 m/s',
'Dynamic rigid bodies for divert segment with fixed timestep',
'Per-SKU collider, damping, and friction profiles',
],
} as const;
export const VALIDATION_BOARD = [
{ item: 'Unit tests', status: '196/196 PASS' },
{ item: 'Production build', status: 'PASS' },
{ item: 'Active routes / + /documentation', status: 'PASS' },
{ item: 'conveyor-clean.glb checksum', status: 'PASS' },
{ item: 'Author FCStd checksum', status: 'PASS' },
{ item: 'Frozen diverter angles / 0.50 s', status: 'PASS' },
{ item: 'Full contact physics', status: 'NOT_FULLY_VALIDATED' },
] as const;
export const OFFICIAL_SOURCE_MATRIX = [
{
source: 'input_info/doc-1783009063.pdf',
purpose: 'Allowed software list',
present: true,
canonical: true,
usage: 'Stack compliance reference',
},
{
source: 'input_info/doc-1783009942.pdf',
purpose: 'Workspace / zone scheme',
present: true,
canonical: true,
usage: 'Layout provenance (workspace 10×6 m)',
},
{
source: 'input_info/doc-1783011400.pdf',
purpose: 'Track 3 scoring criteria',
present: true,
canonical: true,
usage: 'Jury scoring — not re-parsed this pass',
},
{
source: 'input_info/doc-1782987706.zip',
purpose: 'Official STEP product set',
present: true,
canonical: true,
usage: 'Product geometry source archive',
},
{
source: 'input_info/doc-1782987733.zip',
purpose: 'Official STL product set',
present: true,
canonical: true,
usage: 'Feeds public/models/*.stl',
},
{
source: 'input_info/doc-1783011771.zip',
purpose: 'Official pack archive',
present: true,
canonical: true,
usage: 'Retained official material',
},
{
source: 'official_sources/doc-1783095831.pdf',
purpose: 'Classifier bounds authority cited by code',
present: true,
canonical: true,
usage: 'Referenced by classifier.ts; not re-parsed this pass',
},
{
source: 'input_info/extracted/Постановка_Задача_3_сжато_2.pdf',
purpose: 'Full task brief (historical citation)',
present: false,
canonical: false,
usage: 'MISSING — do not cite as available evidence',
},
] as const;
export const RUNTIME_FLOW = [
'SPAWN',
'CONVEYOR',
'CAMERA',
'CLASSIFICATION',
'ARMED',
'OPENING',
'HOLDING',
'CLOSING',
'RECEIVER',
] as const;
export const CURRENT_LIMITATIONS = [
'Full physical contact sorting through CAD diverters is not fully validated.',
'Belt surface-velocity drive at exactly 1 m/s is planned, not complete.',
'Per-SKU physical parameters still require profiling/calibration.',
'Author CAD horn / transmission incomplete in active GLB.',
'Official compliance is partial: missing extracted task PDF; scoring PDF not re-parsed this pass.',
'Repository retains only the web twin, author CAD, official sources, and active tests.',
] as const;
/** @deprecated alias — historical Gate wording retained for acquisition-pack note */
export const DATA_ACQUISITION_SEQUENCE = ['MEASURE', 'VERIFY', 'FREEZE', 'DESIGN'] as const;
export const OWNER_INPUT_FORM_NOTE =
'Главный документ входных данных владельца: OWNER_PRODUCTION_INPUT_FORM.md (пакет Gate 2D, вне публичного runtime).';

View File

@@ -1,32 +0,0 @@
import { describe, expect, it } from 'vitest';
import { SCENARIOS } from './scenarios';
import type { ScenarioId } from '../domain/types';
const expectedIds: ScenarioId[] = [
'normal_flow',
'oversized_item',
'round_object',
'c_priority',
'boundary_dimensions',
'close_items',
'low_confidence',
'jam',
'emergency_stop',
];
describe('scenarios', () => {
it('contains every expected scenario id', () => {
const ids = SCENARIOS.map((scenario) => scenario.id);
expect(ids).toEqual(expectedIds);
});
it('contains items and demo metadata for every scenario', () => {
for (const scenario of SCENARIOS) {
expect(scenario.items.length).toBeGreaterThan(0);
expect(scenario.goal.length).toBeGreaterThan(0);
expect(scenario.expectedCategorySummary.length).toBeGreaterThan(0);
expect(scenario.demonstrates.length).toBeGreaterThan(0);
}
});
});