# double.digital

Ruslan Vasylev: Independent Software Developer · Spatial Tools, Feb 2024–present.

Turn captured data into 3D reconstructions people can inspect and review.

I am developing double.digital as a repeatable spatial-product workflow. I own the browser interface, APIs, database state and reconstruction orchestration. The implemented processing and review workflow reached staging; the current deployed revision and production adoption are not verified. I use AI coding tools while owning architecture, implementation review, testing and validation.

- Ownership: Product direction · browser workflow · Node APIs · PostgreSQL state · cloud workers
- Delivery: Implemented processing, version comparison and evidence review; reliability repairs verified in staging.
- Workflow: Source files → processing job → reconstruction → browser review → saved evidence

## Projects

- **Spatial reconstruction platform**: 2023–present. Spatial pipeline: capture-source upload, modular reconstruction workflows, geospatial registration and controlled scene sharing. Working platform components and public demos, not a production-complete hosted reconstruction service. Facts: Request → artifact, Review exact versions, Delivery status.

## How does this become a repeatable product?

### Capture → spatial product

Ownership: Product direction and end-to-end workflow design

I’m turning the capture-to-reconstruction workflow into a repeatable spatial product. The implemented path connects ingestion, reconstruction orchestration, browser review and saved evidence.

- Product direction · capture → spatial software
- Ingestion → reconstruction → browser review
- Saved evidence · version comparison · sharing

## How are results compared and reviewed?

### Review exact versions

Ownership: Browser comparison and evidence-basis workflow

The review opens a specific reconstruction version and its source and placement basis. Linked comparisons help inspect differences while the saved assessment remains attached to the exact evidence it used.

- React · TypeScript · Three.js
- Side-by-side · overlay · swipe comparison
- Linked views · exact reconstruction versions
- Saved findings retain source + placement basis

Technologies: React, TypeScript, Three.js, Cesium

### Assessment + corrections

Ownership: Assessment commands, persistence and correction lineage

I pin an assessment to its exact source or result, run, content digest, spatial region and placement snapshot. Retried identical commands are safe; changed commands reject key reuse. Corrections create an explicit revision linked to the previous assessment rather than rewriting its original basis.

- Exact original evidence basis retained
- Replay identical assessment commands safely
- Changed command → reject key reuse
- Explicit corrections link to earlier findings

Technologies: PostgreSQL, SHA-256

### Share + revoke

Ownership: Evidence sharing, access and revocation implementation

I implemented sharing around specific evidence and assessment briefs. A recipient can reopen the evidence they were granted; revocation removes that access without silently rewriting the saved assessment.

- Share specific evidence with a named recipient
- Recipient can discover the shared evidence
- Assessment brief reopens its exact basis
- Revocation removes access · saved assessment stays intact

### Stale viewer responses

Ownership: Browser request/selection correctness

The viewer rejects responses that no longer match the selected capture and reconstruction run. Job source, processing options and pipeline identity remain attached to that run.

- Capture + run identity travel with requests
- Late response cannot replace a newer selection

Technologies: React, TypeScript

## What happens to a submitted scan?

### Request → artifact

Ownership: API-to-worker reconstruction orchestration

I separate upload acceptance from GPU execution. A Batch worker receives the durable job ID, fetches authorized inputs and runs frame extraction, COLMAP and LichtFeld reconstruction. Generated artifacts are verified before browser review.

- Node / Fastify API → processing request
- PostgreSQL → job + asset state
- S3 → source files + generated artifacts
- Lambda / AWS Batch → processing orchestration

Technologies: Node.js, Fastify, PostgreSQL, AWS Batch, S3, FFmpeg, COLMAP, LichtFeld, TypeBox, Lambda

### Managed compute scaling

Ownership: Managed batch-job compute integration

My scaling example is managed compute around batch jobs. It is distinct from running a continuously autoscaled API or a real-time fleet.

- Job-driven GPU processing
- AWS Batch manages compute for queued jobs
- Separate request handling from expensive reconstruction

Technologies: AWS Batch

### Source manifest

Ownership: Source-ingestion and manifest implementation

I preserve source identity and placement evidence before reconstruction: hashes, file type and size, capture lineage, available EXIF/GPS and coordinate-frame evidence. The manifest also identifies the frame set, settings and toolchain versions.

- Original source bytes remain traceable
- Hashes + file metadata + capture lineage
- Available EXIF/GPS + coordinate-frame evidence

Technologies: SHA-256, S3, JSON

### Admission and worker limits

Ownership: Admission policy and worker-process supervision

I bound source count, source bytes and runtime before dispatch and validate a fixed one-GPU Batch profile. Upload scanning runs in a separate supervised child process with a deadline, bounded replies and owned temporary-directory cleanup.

- Fixed one-GPU execution profile
- Supervised upload-scanning process
- Deadline + bounded replies + scratch cleanup

Limits: Fixed execution profile; not automatic model-size routing or a complete security sandbox

Technologies: AWS Batch, Docker, Node.js

### Registration and quality gates

Ownership: Reconstruction validation and component-selection integration

Local reconstruction results retain arbitrary units. Registered packages validate transforms, scale and registration evidence. COLMAP component selection uses registration and reprojection-quality metrics, with corrupt-input and selection tests.

- Keep local units explicit
- Validate registered transforms + scale
- Select valid reconstruction components using quality metrics

Limits: Reconstruction validity; rotation tolerance is dimensionless, not a CAD manufacturing tolerance

Technologies: COLMAP

### API admission and result states

Ownership: API contracts, authorization and processing-state implementation

Routes authenticate the caller and resolve access to the job. Admission returns durable job identity, queued state and execution readiness: 201 for new work or 200 for an idempotent replay. State and artifacts are queried separately. Completion can return 202 while verification is pending, and blocked, retryable, terminal and partial states stay explicit.

- Accepted work is not a verified result
- Authenticate + resolve job access
- Explicit processing / blocked / failure / partial states
- Auth0 JWT authentication + PostgreSQL ownership/access checks

Technologies: Fastify, TypeBox, Auth0, PostgreSQL

## How is unfinished processing recovered?

### Claims + leases

Ownership: Execution claims, leases and reconciliation

The job record tracks who owns an attempt and which provider execution is running. Leases and reconciliation let the control plane identify abandoned work and recover under bounded retry rules.

- Atomic claim + time-limited lease
- Persist provider execution identity
- Reconcile stale / terminal executions
- Bounded attempts + explicit retry / failure state

### Job state and progress

Ownership: Browser status, supervisor and control-plane integration

The browser polls durable job state every ten seconds. Ownership and useful progress are separate: the native supervisor tracks advancing training iterations and detects stalls, while the control plane reconciles expired leases against provider execution state.

- Queued / claimed / completed / failure states
- Native iteration telemetry + stall detection
- Expired leases checked against provider execution

Limits: Iteration progress and provider reconciliation; periodic API heartbeat renewal not established

Technologies: React, PostgreSQL, AWS Batch, CloudWatch, Lambda, EventBridge Scheduler

### Completion and recovery

Ownership: Worker completion, receipt and finalization implementation

The worker uploads outputs and saves the exact completion report before sending it to the API. A lost response can be checked by report hash; after host loss, reconciliation can recover the stored report. A durable finalization queue verifies artifacts and commits them with job state. Attempt, worker, lease and input checks fence stale writers.

- Persist the report before sending it
- Authenticated report-hash readback
- Durable artifact verification + atomic finalization
- PostgreSQL uniqueness, transactions and claim tokens

Limits: Completion recovery; not exactly-once compute or general checkpoint resume

Technologies: S3, SHA-256, PostgreSQL

### Processing telemetry

Ownership: Processing instrumentation and diagnostic integration

Telemetry links jobs and attempts to native-stage durations, iteration progress, errors and optional GPU samples. Settings and image identity remain available for comparing runs.

- Job + attempt correlation
- Native-stage duration + iteration progress
- Structured logs + optional GPU samples
- CloudWatch EMF + Logs Insights

Limits: No distributed tracing or general CAD-result cache claimed

Technologies: CloudWatch, AWS Batch, nvidia-smi

## How did I debug a refused processing request?

### Retry-policy mismatch

Ownership: API/database boundary diagnosis and repair

I traced an apparent duplicate-request error to a mismatch between the API and database retry rules. I tested the real boundary and fixed the policy mismatch while preserving duplicate protection.

- Symptom · fresh request key still returned HTTP 409
- Cause · API policy vs older PostgreSQL attempt limit
- Decision · fix boundary · keep duplicate protection
- Regression · first admission + replay + changed-input rejection
- Result · passed · repair verified in staging

Technologies: PostgreSQL

### Testing blind spot

Ownership: Cross-boundary regression coverage

The route tests mocked the database, so they missed the older SQL rule. I reproduced the refusal with the real API input builder against PostgreSQL and kept that boundary regression with the fix.

- Mocked route tests skipped the real SQL rule
- Real TypeScript input builder → PostgreSQL reproducer
- Keep a regression across the API / database boundary
- Lesson · test the handoff, not only each component

Technologies: TypeScript, PostgreSQL

## How are requests and results tracked?

### Idempotent requests

Ownership: Request identity and idempotent replay

A repeated request should not accidentally create another processing job. The identity checks also need to reject a reused key when the inputs have changed.

- Owner + job type + request key
- Same request → existing job
- Changed input under the same key → reject
- Capture / manifest identity + processing options

### Atomic job admission

Ownership: Transactional job admission

Job admission needs to be atomic so concurrent requests cannot each create work for the same capture. The job and its dispatch state belong in one consistent transaction.

- Lock capture during admission
- Save job + sources + audit event + dispatch signal together
- Prevent overlapping work for an active capture

Technologies: PostgreSQL

### Asset + job lineage

Ownership: Source, job, result and review identity

The database connects a result to the job and source that produced it. A completed processing job and a useful, reviewed reconstruction are separate facts.

- Source data → processing job → output artifact
- Stable version references for review
- Processing status separate from review assessment

### Relational state and object bytes

Ownership: Database and artifact-storage design and implementation

I use PostgreSQL for ownership, jobs, revisions, artifact relationships and transactional state changes; S3 holds large source and result bytes. Versioned JSONB holds variable settings, manifests and diagnostics while retaining relational identities. This reconstruction path does not use a separate document database or vector index.

- PostgreSQL: identities + relationships + transactions
- S3: source and generated bytes
- JSONB: versioned variable metadata

Technologies: PostgreSQL, Supabase, S3, JSONB

### Versioned processing settings

Ownership: Shared processing contracts and admission/completion validation

A shared versioned schema rejects unknown fields. Admission saves the complete settings snapshot and its hash; completion checks what was actually applied. Contract and fixture tests cover the boundary.

- Reject unknown settings
- Persist full snapshot + settings identity
- Check applied settings at completion
- Shared JSON schemas, enums and bounds

Technologies: TypeScript, JSON, SHA-256, PostgreSQL

## What was implemented and verified?

### Delivery status

Ownership: Implementation delivery and historical staging validation

The processing and review workflow reached staging and was inspected in code. Historical delivery and regression checks support that implementation; the current hosted application revision and broad production adoption have not been verified.

- Implemented · browser review + exact-version comparison
- Historical staging delivery · frontend + backend + served assets
- API / database regression · repair verified in staging

