Skip to main content

Backlog

In progress​

(nothing — pick from Todo)

Blocked​

(nothing)

Todo​

Produce docs/run·test·structure/release + AGENTS router from the existing gitignored AGENTS body, verified against the code. Largest repo pass — commands must actually run. Conventions from the old body land here (they are repo-owned). TESTS-NOTES residue (dissection 2026-10-06): §1 runtime-verification mandate → AGENTS.md inviolable + docs/test.md; §3 prerequisites (local PG/Redis, CI=true pnpm install, 10 billing boot vars) + seed → docs/run.md; §3 local test DB (.env.test delta-only rule) → docs/test.md; §7 residue → dev-DB recovery notes for docs/run.md (stale-.env repoint: overlay DATABASE_URL/REDIS_URL from .env.test + delete a stale .seed-ids.json; stale PAYG rows failing 20260915150000_drop_billing_account_cycle: DELETE rows → migrate resolve --rolled-back → re-deploy. Slice 4 (2026-10-06): §8 unit-test patterns + §9 e2e guard-override pattern → docs/test.md; §11 backend residue → docs/test.md/run.md (rawBody on, RATE_LIMIT_DISABLED escape hatch + Redis-down symptom, psql/Prisma raw-SQL gotchas, AuditLog immutable trigger named ln, P2025→404 convention, quota-exception import path, EADDRINUSE stale dist/, Windows EPERM, remote-DB latency); seed note: Demo Org is seeded plan='starter' directly — exercising null-plan needs a genuinely fresh signup (procedure homed in internal testing/procedures). Slice 5 (2026-10-06): §12 residue → docs/run.md — remote-DB local snapshot (pg_dump -F c → drop/create/restore, then swap DATABASE_URL in .env) + the brew install libpq prunes /usr/local/bin/{node,npm,npx} symlinks gotcha. Left MAP-tagged in the legacy file.

Same shape as B-003; portal AGENTS body + docs/billing-endpoints.md get folded into the skeleton. Form conventions page in repo docs from the portal AGENTS body. TESTS-NOTES §1 residue: runtime-verification mandate → AGENTS.md inviolable + docs/test.md. Slice 4 (2026-10-06): §10 frontend unit-test patterns → docs/test.md (global Clerk mock — re-diff vs the live src/test/setup.tsx first, per-test useAuth/useHasFeature overrides, 402 inline-error + deterministic-quota mutation mock, jsdom/base-ui gotchas); §11 portal residue → docs/test.md (playwright chromium-headless-shell install, recharts SVG-tspan assertions, react-refresh route-export lint). Slice 5 (2026-10-06): portal transcripts died — /ref-page pointer → internal product/design-system.md; orgless choose-organization behavior → internal testing/test-accounts.md; auth-flow facts (Clerk path routing, safeRedirectPath intent restore, clerk-appearance.ts theming) and the FLOW-012/013/015 fetch-wrapper/error-state techniques died with the transcripts (durable record: repo code + FLOW audit docs). Nothing repo-bound left MAPped for this row.

Skeleton + router; fold in the t005–t009 gate runbooks from the legacy TESTS-NOTES tail (verify still true against the current toolchain first). TESTS-NOTES §1 residue: runtime-verification mandate → AGENTS.md inviolable + docs/test.md. Slice 4 (2026-10-06): §11 flutter residue → docs/test.md — fvm-managed flutter is not on agent shells' PATH; use ~/fvm/versions/3.35.7/bin/flutter explicitly. Slice 5 (2026-10-06) MAP residue in the legacy file — harvest + verify against the current toolchain on this pass: t005 toolchain (fvm paths, mocked-channel EventChannel/MethodChannel test idioms) → docs/test.md; t006 Android gate (emulator 10.0.2.2 IPv4 IP-bucket rule, crafted-click recipe, clipboard/UL/cold-start/delivery gotchas) → docs/test.md; t007 iOS plugin+SPM (path-less PBXFileReference neutralization, lipo patch, workspace requirement, deploy-target 15) → docs/test.md + docs/structure.md; t008 consolidated T1 checklist → docs/test.md; t009 T2 device gate (egress-alignment probe, scoped Redis drains, frozen-UA traps, LinkMatch ground truth) → docs/test.md; t010 dual iOS packaging (committed xcframework + prepare_command never runs, 3.38 floor rationale, podspec privacy bundle, lane toggle) + t010 addendum (plugin module declares org.jetbrains.kotlin.android) → docs/structure.md; pub.dev pre-flight (pana via fvm, README consumer-surface grep, decided report notes) → docs/release.md.

Skeleton + router; fold in the iOS device-gate runbooks (t008–t013 legacy notes), verified against Xcode/toolchain reality. TESTS-NOTES §1 residue: runtime-verification mandate → AGENTS.md inviolable + docs/test.md. Slice 5 (2026-10-06) MAP residue in the legacy file — harvest + verify on this pass: t003 live fixtures (iOS exact recipe = OMIT timezone; plaintext redis no --tls; key-mint shortcut; requestId on error bodies) → docs/test.md; t008 backend prerequisites (trust-proxy regression sequence — the backend facts landed in internal systems/links-resolution/device-identity-match.md; redirect-page clipboard payload verify) → docs/test.md; ticket 01 package gate (SPM repo rules, Bundle.module, JSONEncoder nil-drops, no public message) → docs/test.md; ticket 08 facade conventions → docs/test.md; ticket 09 gated live e2e runbook (IP-bucket discipline, scored-tier delta, pinned-UA, backend-reboot rule) → docs/test.md; ticket 10 Example-app simctl runbook → docs/test.md; ticket 11 release prep (PUBLISHING.md, mirror rsync paths) → docs/release.md; t013 prep + device pass (entitlements swap, -allowProvisioningUpdates, Apple CDN lag, onOpenURL-everything, NONE rows) → docs/test.md; t001 iOS half (INFO-trail assertion, drain-before-return) → docs/test.md.

Skeleton + router produced; README trimmed to the registry (Maven Central) template; PUBLISHING.md folded into docs/release.md — stale claims fixed against Gradle reality (the license block ships since 0.1.0, 0.1.1 is live on Central, release-time device checks validated via the Flutter-consumption path); live-e2e recipe + runbook gotchas into docs/test.md, version pins into docs/structure.md. → optolink-android/docs/ + AGENTS.md. Residue from the TESTS-NOTES dissection (2026-10-06): §1 runtime-verification mandate is still missing from AGENTS.md inviolables + docs/test.md — add on next touch; §7 residue for docs/test.md — the first-click timezone-header simulation note (sec-ch-timezone bare IANA id + Accept-Language + Robolectric-Build UA so the P2 hash lines up on all five components). Slice 5 (2026-10-06) MAP residue in the legacy file — harvest/dedupe on next touch (much is already homod in docs/): t003 SDK-surface fixtures (rotation grace = regenerate CLIENT twice; match legs engineerable via headers; 429 body has NO retryAfterSeconds field; xargs -I substitution trap) → docs/test.md (+ wire facts → internal systems/sdk-contracts/android.md, B-018); ticket 01 machine setup (aarch64 cmdline-tools build, aapt2 qemu-user fix, env exports) → docs/run.md; ticket 02 net-core conventions (test-scope org.json dep, mockwebserver3 5.x idioms, QueueDispatcher enqueue-first, KDoc /sdk/* nesting) → docs/test.md; ticket 04 collector conventions (installreferrer nested response class, clipboard shadows, collector seams) → docs/test.md; ticket 07 facade conventions (companion dispose reset, session-race drain, myapp:/// empty-authority form, internal 4-arg overload seam) → docs/test.md; t002 publish residue (consumer needs google()+mavenCentral for installreferrer — not a publish defect; Dokka retry) → docs/release.md; t001 Android half (Gradle distribution download stall workaround) → docs/run.md.

B-008 — Repo docs pass: optolinkWeb​

Minimal skeleton for the landing page repo (run/build/deploy). TESTS-NOTES §1 residue: runtime-verification mandate → AGENTS.md inviolable + docs/test.md.

This repo gets the same skeleton (run/test/structure/release) — build, IA rules, deploy-exclusion checks. TESTS-NOTES §1 residue: runtime-verification mandate → AGENTS.md inviolable + docs/test.md.

All four pages re-checked against backend @ 29f8589 / portal @ 7d31d45 (both HEAD). Killed: none. Fixed: link-management.md missed the API-path create gates added by #33 (659ce07) — POST /links now mirrors the portal's 428-before-402 order — plus drifted line refs (update-link DTO Transform, recordUsage early-return, template-controller create range). link-creation.md and link-templates.md: claims confirmed, line refs re-pinned, plans.config range corrected. device-identity-match.md: already at HEAD SHA, every claim confirmed as-is. Added the missing page-contract maintenance comment to the three drafted link pages (device-identity already had scope + maintenance). Verification lines refreshed to 2026-10-07.

B-015 — systems/click-analytics: verify drafted pages vs HEAD (2026-10-07)​

analytics.md re-checked against backend @ 29f8589 / portal @ 7d31d45 (both HEAD). Killed: none. src/analytics/ + the controller are byte-unchanged since the FLOW-005 harvest SHA, portal unchanged — every behavioral claim confirmed (endpoints/DTO bounds, overview composition, bucketing SQL, delta mechanism, rate preset, test counts). Fixed: the seed gotcha's claim that the org template "Summer Campaign" has 2 attached links (the links attach to the sys-email-to-app system starter; Summer Campaign has zero — seed.ts:792–816) and the constants.ts orphan-comment line ref (12-13 → 7-9); match count softened to the random-derived ≈76. Added the missing page-contract scope + maintenance comment. Verification line refreshed to 2026-10-07.

B-016 — systems/custom-domains: verify drafted pages vs HEAD (2026-10-07)​

custom-domains.md re-checked against backend @ 29f8589 / portal @ 7d31d45 (both HEAD). Killed: one claim — resolveExplicitDomain "400/409s otherwise" is wrong at HEAD: it 404s unknown ids and 400s non-VERIFIED (no 409 exists in link.service.ts). Fixed: the previous-pass hint confirmed — repair migration 20260924090000_fix_scheme_poisoned_domain_rows (commit f3cdc55, 2026-09-24) deletes a bogus scheme-prefixed platform row and repoints poisoned org cnameTargets; noted under Platform default row. Line refs re-pinned (DomainService header 13–31, create() 45–94, sslCertificate :345, PLANS 75–206, link.service 119–147 + :395, seed 645–662). Everything else confirmed (state machine, gate order :72/:75, cron, queue shapes, portal data layer, copy-bug gotcha still live). Added the missing page-contract scope + maintenance comment. Verification line refreshed to 2026-10-07.

B-017 — systems/portal-app: verify drafted pages vs HEAD (2026-10-07)​

All three pages re-checked against portal @ 7d31d45 / backend @ 29f8589 (both HEAD; portal unchanged since the FLOW-002/003/004 harvests). Killed: none. Fixed: drifted line refs only (team.controller listMembers L53→L58, portal-analytics overview :139→:131, portal-domain :81→:82, portal- entitlements :66→:56, click-aggregation + plans.config ranges) — every behavioral claim (route tree, guard nesting, shell reads, upgrade pill, wizard state gate + step write paths, fail-independent sections, attention derivation) confirmed. Added the missing page-contract maintenance comment to all three pages. Verification lines refreshed to 2026-10-07.

B-018 — systems/sdk-contracts: four contract pages (2026-10-07)​

Turn the four spec documents into verified contract pages (endpoints, auth tier, error envelope, pagination, compat lines). Done. All four stubs are real contract pages (status draft, 107–132 lines each), source-checked against optolink-backend @ 29f8589 (code-read only, no live pass — noted on each page): node.md (the /links CRUD+QR surface; spec-vs-code deltas written: POST /links now runs the 428→402 portal gates, duplicate shortCode is a clean 409 Conflict whose envelope still renders error: "Error" — 409 missing from the filter's name table; /links rate presets 100/s–1000/s per key added), android.md (bulk POST /match shape incl. lowercase matchConfidence, /data 410s the specs omitted, 500/s /data limit, CLIENT-key 24h grace verified in api-key.service.ts, assetlinks.json contract), ios.md (same tables, the two deliberate deltas — omit-timezone + no installReferrer — AASA/teamId skip rule, spec's "requestId on all error bodies" claim corrected to echo-only), flutter.md (channel contract, pub.dev 2.0.1 reality vs the spec's git-dependency 2.0.0, delivery rule, wire mapping). Cross-linked device-identity-match / entitlements / custom-domains instead of repeating. npm run build green; committed locally.

B-019 — product/: fill (PRD, pricing, feature registry, design system) (2026-10-07)​

Migrate + verify from the legacy PRD, pricing research, feature registry, DESIGN.md. Done. All four stubs are real pages (status draft, 77–103 lines each): prd.md (durable digest of PRD v2 — stages, resolved decision table, NFRs, locked seat decision, deferrals; full historical text left for B-021), pricing-and-plans.md (shipped ladder source-checked against plans.config.ts + seed PLAN_CONFIG_ROWS @ 29f8589 — code wins: Scale is $150/7,500 EGP not the doc's $149; overage is per click $0.06/$0.05/$0.04 USD, not per-1K; tier meter is clicks/mo, the research's MAU quotas never shipped → B-026; seats 1/2/5/15), feature-registry.md (4 FeatureKeys + 5 QuotaKeys mapped, shipped- ungated list, never-built deferral list; enforcement linked not repeated), design-system.md (DESIGN.md trimmed to contributor essentials — posture, tokens, One Orange/Data-is-Mono/Two Shadows rules, logo+favicon; ref-page pointer kept). npm run build green; committed locally.

B-028 — systems/entitlements: verify enforcement page vs HEAD​

Domain created by dissection slice 3 (2026-10-06) with enforcement.md source-checked @ 29f8589 (code-read only — no live 402/403/428 pass). 2026-10-07 re-verification pass (B-028): every claim re-checked against 29f8589 (still HEAD) — killed two: the plan-matrix footnote "every other plan is block" (paid tiers run clicks_per_month as overage) and "limit is null for unlimited" (controller passes the raw MAX_SAFE_INTEGER sentinel through; only the DTO doc comment claims null). Added: API-key POST /links mirrors the portal 428→402 gates, real 428 body, countUsage line pin, paid-clicks gotcha. Plan matrix numbers confirmed against plans.config.ts

  • the 5×2 plan_config seed rows. Still open (needs execution, not reading): run the gated-endpoint probes live, then promote to stable.

B-020 — operations/: fill (release policy, env-var registry) (2026-10-07)​

release-policy.md (semver clocks, compat lines, what syncs at publish) + env-vars.md (cross-repo matrix, Clerk-instance pairing rules). Done. release-policy.md: universal rules, per-package clock table (npm/Maven Central/SPM-mirror/pub.dev versions verified at current SHAs; backend+portal are deploy-per-commit, no registry), publish-sync checklist (changelog↔docs-site, README compat line, version mirrors; flutter's missing docs-site changelog page flagged as a gap). B-018 open question resolved on the page: the "Compatible with OptoLink backend v2.1.0+" line refers to the product release train, stays hand-maintained in each SDK README, with this page as the register of its meaning — marked recommended, pending owner sign-off (backend package.json says 1.0.0; no machine-readable anchor exists). env-vars.md: backend 6 boot-required + 10 billing boot-required + optional lists, portal VITE_* set, SDK e2e vars per suite (tier-shaped: opl_api_ for node, opl_sdk_ for android/ios), and the three pairing rules (Clerk instance backend↔portal incl. ops-org id, BACKEND/CLIENT/VITE base URLs, key tiers). No values in docs. npm run build green; committed locally.

SKILL.md pack(s) so coding agents consume the SDKs efficiently: install → init → method surface → errors/quota handling → deferred linking. Home + per-SDK split decided when started.

B-025 — Continue the UX/UI audit (portal Settings flows)​

Resume where it paused (FLOW-015): billing & subscription flows, organisation configuration/settings, team members. Audit scaffolding lives with the portal repo, not here; internal/history gets milestone entries.

B-026 — MAU (monthly active users) flow​

New capability: MAU table, analytics surface, likely a per-plan quota. Needs a small spec pass before backend work.

B-021 — Archive sweep + history entries; legacy triage​

Frozen records into archive/; misc/ + screenshots die; .scratch maps move to their repos. Before deleting misc/: rehome the audit scripts referenced by internal pages (quota-fillers.mjs, quota-cleanup.mjs, matrix-.mjs, seed-visual-test/) — they are cited from testing/procedures/test-stack.md and testing/infrastructure/deployed-stack.md.

B-022 — Cutover: monorepo root dies​

Root AGENTS/DESIGN/PRODUCT/docs deleted after their content is placed; every repo's router verified to resolve standalone; build:public asserted internal-free.

Done​

B-010 — Promote intro + decisions to stable (2026-10-07)​

Repo/section/boundary claims confirmed against the 2026-10-07 systems passes; fixed: page-contract frontmatter list (sidebar_position), the inert-geo gateway sentence (FLOW-012 D1 — browser defaults EGP → Paymob, USD/Stripe only via manual localStorage override), and the plans→mechanics pointers (entitlements vs billing). Verification lines added; both pages now stable. npm run build green; committed locally.

B-012 — systems/auth-clerk: verify drafted pages vs HEAD (2026-10-07)​

Every code-referencing claim in authentication.md + team-management.md re-checked against backend @ 29f8589 / portal @ 7d31d45 (both HEAD). Killed: the phantom ops api-keys minting endpoint. Fixed: admin-bearer surface routes (/admin/organizations…, not /api/*), plan writers (plan selection also writes it), enterprise seat ladder onExhausted, two legacy docs/FLOW-001.md path pointers. Added the missing page-contract elements (scope + maintenance comment) to authentication.md. Verification lines refreshed to 2026-10-07.

B-013 — systems/billing: write architecture + checkout gate (2026-10-07)​

Mechanism depth landed source-checked (backend @ 29f8589 — HEAD unchanged since the slice-3/4 pass — portal @ 7d31d45): architecture.md (currency routing incl. the inert-geo correction — the browser defaults to EGP/Paymob, geo-IP detection never runs; checkout internals; the shared action union; first-party plan lifecycle; invoice-keyed webhook idempotency; config fail-fast) + renewals-and-overage.md (cron trio, MOTO renewal engine, overage sweep) + rest-surface.md (absorbs the old billing-architecture.md surface/gotchas; stub retired, references swept). checkout-gate.md re-verified against the same backend commit, extended with the plan-lifecycle curls + admin-route activation and a beyond-the-local-gate note (no live run — recorded bodies keep their re-verify markers). The legacy progress record itself stays unmigrated for B-021 archive.

B-023 — Update the public docs site (2026-10-06)​

All stub pages across the six public sections filled (user-driven harvest pass); stubs removed. Outcome lives in the public build — verified by CI on push.

B-001 — Internal restructure to section IA (2026-10-06)​

internal/ reorganized; FLOW harvest pages moved into systems/; templates/ created. → internal/, templates/

Full skeleton + router + README decision; gates run green; review fixes applied (role-only identity, final-path refs, rule/fact split, tagging). The worked example for all repo passes. → optolink-node/docs/

B-011 — The dissection — legacy TESTS-NOTES dissolved (2026-10-06)​

Five slices took the legacy file from 2,950 to 1,703 lines; what remains is repo-bound MAP material only. Systems discovered on the way: entitlements (B-028), auth-clerk/team-management, links-resolution/device-identity-match, billing/checkout-gate. Landing maps for every homed piece are recorded on the repo rows (B-003–B-007).