Backlog
In progress
(nothing — pick from Todo)
Blocked
(nothing)
Todo
B-003 — Repo docs pass: optolink-backend
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.
B-004 — Repo docs pass: optolink-portal
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.
B-005 — Repo docs pass: optolink-flutter
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.
B-006 — Repo docs pass: optolink-ios
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.
B-007 — Repo docs pass: optolink-android (2026-10-06)
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.
B-009 — Repo docs pass: optolink-docs itself
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.
B-014 — systems/links-resolution: verify drafted pages vs HEAD (2026-10-07)
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_configseed 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.
B-024 — AI-agent skill set for the OptoLink SDKs
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)
stableRepo/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/
B-002 — Pilot: optolink-node (2026-10-06)
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).