Mirror of the trading repo's resume prompt but anchored on the
platform-side audit work. Any agent (Codex, Claude, Gemini, etc.)
running on this machine can paste in the short prompt at the bottom of
this file and self-bootstrap from the full brief above.
Brief covers:
- Required reads (HANDOVER.md + AUDIT_PLATFORM.md, optionally the
trading repo's HANDOVER for cross-repo context)
- Environment (source ~/.zshrc for GITEA_NPM_TOKEN — without it pnpm
install -r fails on the private @bytelyst/* mobile dep)
- Verification gates with explicit "error count must go down, never
up" rule
- Working-tree state: 3 nomgap WIP files + 1 regenerated lockfile
that the agent must NOT touch
- The P-sweep: 85 pre-existing lint errors, broken down by rule, with
a per-package workflow (one package = one commit) and a suggested
walking order
- Commit conventions matching the prior session
(chore(P-sweep): pnpm --filter <pkg> lint:fix)
- Seven explicit "do not" rules — the most important being do-not-
modify the audit's load-bearing eslint config block (`**/*.cjs` +
`**/scripts/**`) which prevents 45 errors from regressing
- When-to-stop-and-ask criteria so the agent doesn't blindly delete
"unused" exports that downstream repos (trading vendor) consume
Refs: docs/HANDOVER.md, docs/AUDIT_PLATFORM.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Standalone hand-off note pointing the next contributor at:
- Current health snapshot (install/typecheck/test ✅, lint runs but
85 pre-existing errors surfaced)
- The .npmrc / GITEA_NPM_TOKEN requirement (without it nothing installs)
- Three uncommitted nomgap-WIP files in the working tree that the audit
intentionally left alone (out of scope, missing context)
- The audit doc (docs/AUDIT_PLATFORM.md) as the source of truth for
open vs done items
- Suggested next steps (per-package `pnpm --filter <pkg> lint:fix`
sweeps, owned by package maintainers)
- Backup branch reference
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The first `pnpm -r exec eslint .` run was bailing at the very first
package (design-tokens), hiding any lint state in the rest of the 69
workspace packages. This commit fixes the structural blockers so the
pipeline runs end-to-end, then sweeps the small, low-risk lint errors
in the next 4 packages it surfaces. Real lint debt that remains
(85 errors, mostly @typescript-eslint/no-unused-vars across many
unrelated packages) is cataloged in docs/AUDIT_PLATFORM.md for follow-
up by package owners.
Structural fixes (eslint config):
- eslint.config.js (root):
• New flat-config block for **/*.cjs and **/scripts/**/*.{js,cjs}
with Node globals (process, console, require, module, __dirname)
and no-console disabled. CLI scripts legitimately print to
stdout. This alone clears the 45 errors in design-tokens'
validate-tokens.cjs.
• Added XMLHttpRequest + ProgressEvent to browser globals so
feedback-client compiles.
- packages/ui/eslint.config.js:
• Added @typescript-eslint/parser — the package-local override
replaced (didn't merge with) the root config, so TS syntax was
being parsed by espree and erroring on every `interface` /
type import.
• Added ignores for dist/** (root's ignores aren't inherited).
• Extended the files glob to .storybook/**/*.{ts,tsx}.
Mechanical lint fixes (no behaviour change):
- design-tokens/scripts/{validate,token-coverage}.cjs: empty catch
binding (catch (e) → catch).
- feedback-client/src/index.ts:
• captureScreen(): preserve caught error via `{ cause: err }`
on the rethrown Error (preserve-caught-error rule, real bug —
previous chain dropped the original stack).
• captureElement(): rename unused parity params mimeType/quality
to _mimeType/_quality and document why they exist.
- logger/__tests__/logger.test.ts: drop unused `LoggerConfig` import.
- extraction-service/{lib/circuit-breaker,modules/extract/{sidecar-
monitor,usage}}.test.ts: drop 3 unused vitest/type imports.
- tracker-web/__tests__/tracker-proxy.test.ts: rename unused local
`url` → `_url`.
New: docs/AUDIT_PLATFORM.md
Tooling-backed audit summary (pnpm install / typecheck / test / lint
results), classification of remaining lint debt by rule, and an
ordered hand-off plan for package owners to clear the rest with
`pnpm --filter <pkg> lint:fix` followed by an eyeball review.
Verified before commit:
- `pnpm typecheck` → pass (all 69 packages compile)
- `pnpm test` → pass (~2,200 tests across 18+ suites)
- `pnpm lint` → 85 pre-existing errors surfaced (none introduced
by this commit; all in unrelated packages — see AUDIT_PLATFORM.md
section P).
Out of scope (left untouched in working tree):
- In-progress nomgap-on-Vercel migration: docker-compose.ecosystem.yml,
products/nomgap/product.json, services/platform-service/src/
modules/flags/seed.ts.
- pnpm-lock.yaml: my `pnpm install -r` regenerated it (+2.9k/-8.5k
lines) — not part of the audit, owner should commit deliberately.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three coordinated fixes so 'docker compose up cosmos-emulator platform-service
cowork-service --wait' completes end-to-end (pre-existing blocker surfaced by
W1 post-push review).
1. Remove harmful prepare:tsc from @bytelyst/react-native-platform-sdk
package.json. The hook fires during pnpm install --frozen-lockfile against
an empty src/ tree (because Dockerfiles COPY package.jsons before
sources), tsc aborts, install fails. Canonical monorepo build flow is
pnpm -r build using the existing build:tsc script; prepare only runs for
git+ URL installs (which this published package doesn't use), so removing
it is lossless.
2. Add --ignore-scripts to platform-service + mcp-server Dockerfile install
steps. Mirrors the pattern already used by extraction-service/Dockerfile,
dashboards/admin-web/Dockerfile, dashboards/tracker-web/Dockerfile.
Belt-and-braces against future prepare-hook regressions in any workspace
package.
3. Expand .dockerignore node_modules/dist/.next/coverage to **/ globs.
Docker's .dockerignore with bare 'node_modules' only matches root-level;
nested packages/*/node_modules/ were being COPY'd into images, poisoning
them with host-absolute-path .bin shims (e.g. @bytelyst/storage's tsc
shim resolved to /learning_voice_ai_agent/node_modules/.pnpm/... which
doesn't exist in the container → MODULE_NOT_FOUND). The glob fix makes
COPY packages/ packages/ deliver source only.
Gap: INFRA-gap-02
Verified:
pnpm install --frozen-lockfile ✅
pnpm --filter @bytelyst/react-native-platform-sdk build ✅
pnpm --filter @bytelyst/react-native-platform-sdk typecheck ✅
docker compose build platform-service ✅ (previously failed)
docker compose build mcp-server ✅
docker compose build extraction-service ✅
Hot-reload the orchestrator's on-disk plugin registry without a
restart. Routes to the reload_plugins Rust IPC method, gated by the
same authz the orchestrator enforces (admin role OR platform-signed
JWT) so a forbidden caller gets a canonical ForbiddenError envelope
instead of a raw IPC error passthrough. The response body is a
ReloadStats { loaded, added, removed, updated, errors } summary,
validated against ReloadResponseSchema before being returned to the
caller.
Tests cover: admin success (200 + envelope), user-without-platform
(403 before IPC), bridge unavailable (400), orchestrator -32003 →
ForbiddenError, other IPC errors → BadRequestError, malformed
orchestrator payloads → BadRequestError.
Phase: 3.1
Verified: pnpm -r typecheck, pnpm --filter @lysnrai/cowork-service {lint,build,test}
(140 passed, 6 new reload tests)
Baseline pnpm-lock.yaml on origin/main was missing entries for
packages/billing-client and packages/webhook-dispatch (their
package.json files list typescript + vitest devDependencies that the
lockfile didn't reflect). Any pnpm install --frozen-lockfile — in CI,
in services/platform-service/Dockerfile, in services/mcp-server/Dockerfile,
in services/extraction-service/Dockerfile — therefore failed with
ERR_PNPM_OUTDATED_LOCKFILE.
Ran pnpm install which regenerated the lockfile deterministically; the
net diff cleans up a large amount of stale phantom entries while adding
the two missing package entries. After the refresh,
pnpm install --frozen-lockfile succeeds.
This is W1 baseline-repair scope (similar to commit a954f434 for lint).
It does NOT fully restore the full-stack docker compose smoke because
services/platform-service/Dockerfile also has a separate pre-existing
bug: @bytelyst/react-native-platform-sdk runs `tsc` in its prepare
script, but pnpm install runs prepare scripts before the Dockerfile
COPY packages/ step brings in source — so tsc has nothing to compile
and fails. That Dockerfile is outside W1's Files-You-Own and needs
a separate fix (either remove/no-op the prepare script, use pnpm
install --ignore-scripts, or COPY source before install).
Gap: none (baseline repair supporting INFRA-gap-01)
Verified: pnpm install --frozen-lockfile (clean), pnpm -r typecheck /
lint / build / test (all green), docker compose build
cowork-service + docker compose up -d cowork-service --wait
(still Healthy), curl localhost:4009/health (200 OK).
Adds cowork-service (port 4009) to docker-compose.yml with healthcheck,
depends_on gates for cosmos-emulator and platform-service, env_file
integration, and Traefik labels. Unblocks Phase 3 ecosystem wiring of
the ByteLyst roadmap.
Also adds the services/cowork-service/Dockerfile that compose builds
from. Pattern mirrors services/mcp-server/Dockerfile but copies the
full workspace in one step rather than enumerating every package.json,
to stay resilient to workspace membership changes. Production stage
runs `node dist/server.js` on :4009 with BusyBox-wget healthcheck
(bundled with node:22-alpine — no apk install required).
.env.example gains a Cowork-Service section documenting:
- ANTHROPIC_API_KEY, RUST_RUNTIME_BIN, RUST_RUNTIME_TIMEOUT_MS
- OLLAMA_URL, OLLAMA_MODELS
- FEATURE_FLAGS_ENABLED
The 13th clawcowork flag telemetry_enabled already ships via COMMON_FLAGS
in services/platform-service/src/modules/flags/seed.ts so seed.ts was not
touched.
Gap: INFRA-gap-01
Verified: docker compose config (YAML validity + env substitution),
pnpm -r typecheck / lint / build / test (all green),
docker compose build cowork-service (image built),
docker compose up -d cowork-service --no-deps --wait (Healthy),
curl -fsS localhost:4009/health → {"status":"ok","service":"cowork-service",...}.
Note: full-stack `docker compose up cosmos-emulator platform-service
cowork-service --wait` is blocked by a pre-existing issue in
services/platform-service/Dockerfile (react-native-platform-sdk prepare
script fails during pnpm install --frozen-lockfile in the image build).
That is outside W1 scope; cowork-service starts clean on its own and
becomes Healthy when platform-service is available out-of-band.
Baseline origin/main pnpm -r lint failed with 90+ errors across
platform-service, extraction-service, and tracker-web. These block the
shared W1 quality gates (prompts/README.md §4) which require all of
typecheck + lint + build + test to be green before committing W1 infra
work. Fixes are strictly scoped to unblock gates:
- eslint.config.js: extend @typescript-eslint/no-unused-vars with
varsIgnorePattern / caughtErrorsIgnorePattern / destructuredArrayIgnorePattern
all honouring the existing `^_` convention already used for args.
- platform-service: add file-level eslint-disable for
@typescript-eslint/no-unused-vars, no-redeclare, no-useless-escape on
the 33 legacy files failing lint (ab-testing, ai-diagnostics,
diagnostics, predictive-analytics, broadcasts/types, surveys/types,
lib/push-notifications).
- extraction-service tests: drop unused vitest imports (beforeEach,
afterEach, HealthCheck).
- tracker-web tracker-proxy.test.ts: prefix unused url with _.
- Applied eslint --fix on platform-service which normalised a handful
of `let` → `const` and removed one redundant disable comment.
Scope creep vs W1 "Files You Own" is acknowledged — user explicitly
approved this path when baseline rot was surfaced.
Verified: pnpm -r typecheck, lint, build, test all green.
Never edit .npmrc directly in product repos — managed by
canonical template in learning_ai_common_plat/scripts/npmrc.template.
Use sync-npmrc.sh to propagate. Prevents gitea.bytelyst.com hardcoding.
Browser/React Native-safe typed client for platform-service billing
endpoints: plans, subscriptions, payments, and usage.
Follows the same factory pattern as broadcast-client and survey-client.
Any ByteLyst product can add billing with 5 lines of wiring code.
12 tests covering all methods, auth headers, error handling, and
404 null-return for missing subscriptions.
Published 60 @bytelyst/* packages to local Gitea npm registry.
create-app skipped (private: true — internal scaffolding tool).
Token regenerated with full write:package scope to fix E401.
Root causes found:
1. publishConfig.registry in each package.json overrides --registry CLI
flag, causing npm to hit gitea.bytelyst.com through corp proxy.
2. Global ~/.npmrc proxy settings (NPM_CONFIG_PROXY env vars) route
localhost:3300 through the corporate proxy.
3. No .npmrc with auth token was created for npm publish to use.
Fix: generate a proper .npmrc in WORK_DIR with:
- _authToken for registry auth
- @bytelyst:registry scoped override (bypasses publishConfig)
- proxy=false + https-proxy=false on corp network
- Unified corp/home publish path (both use same .npmrc)
Token scope issue still open: current GITEA_NPM_TOKEN has read:package
but not write:package — needs regeneration in Gitea UI.
- Use shared ~/.npmrc via --userconfig for all npm view + publish calls
(inline --// flags are unreliable on npm v10+ for writes)
- Verify registry credentials upfront before any work begins
- Log each package status inline as scan runs (✓/⊘/→/✗) grouped by workspace
- Suppress noisy npm notice / pnpm progress output; surface only errors
- Move FAILED to its own tracked array; exit non-zero if any publish fails
- Restrict release commits to package.json / pnpm-lock.yaml / .changeset
(prevents node-compile-cache and other generated dirs being committed)
- Fix pagination bug in registry comparison (was only checking 50 packages)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- packages/llm: add FallbackLLMProvider (providers/fallback.ts) that
tries each provider in order, skipping unconfigured or erroring ones;
wire 'fallback' as a first-class LLMProviderType in factory + types
- packages/llm: improve auto-detection in factory — PERPLEXITY_API_KEY
and GEMINI_API_KEY trigger auto-selection when no explicit provider set
- scripts/release.sh: new pipeline — rebase from origin/main, build,
apply changesets, publish outdated packages to Gitea registry, push
- scripts/run-registry-tests.sh: fix Gitea URL health-check to use a
real package endpoint with auth header instead of bare registry root
- docs: mark Vercel track-B prompts B1–B3 as complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BUG 1: Azure locale derivation produced 'en-EN' (invalid) for 2-letter codes.
→ Added toAzureLocale() with 28-language mapping table (en→en-US, pt→pt-BR, etc.)
→ Exported for testing; falls back to code-CODE for unmapped languages.
BUG 2: model field from request schema was silently dropped after provider refactor.
→ Added optional model field to TranscriptionInput interface.
→ OpenAI provider now uses input.model override (falls back to config.model).
→ Route passes model through to provider.transcribe().
GAP 4: SUPPORTED_AUDIO_TYPES was defined but never validated against.
→ Route now rejects unsupported content-types with a clear error message.
→ Allows application/octet-stream (Azure Blob SAS URLs often return this).
GAP 5: Client JSDoc still said 'via OpenAI Whisper API' — now 'via configured STT provider'.
GAP 8: Azure WAV content-type hardcoded samplerate=16000 — now generic audio/wav.
Tests: 42 transcription tests (was 35), 178 total passing.
→ toAzureLocale: 4 tests (locale mapping, passthrough, fallback, case-insensitive)
→ setSTT: 1 test (singleton override)
→ model passthrough: 2 tests (mock ignores, input accepts)