Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
274 changes: 53 additions & 221 deletions .dev-loop/INGEST_REPORT.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ follow the cross-pointers in their index or take the next matching seeded domain
| [backend](wiki/backend/index.md) | **seeded** | Server-side application code — language-agnostic (`common/`: API contracts, call-site enumeration before a contract change, idempotency, JWT, timeouts/retries, caching, jobs, transactions in app code, shared state/pools, errors, consuming LLM APIs (completion validation, context budgeting), authoring agent-facing artifacts (binding instruction text, agent tool-surface granularity/parity), MAPE-aligned point-prediction calibration, consuming external-API responses, externally-owned defaults, object-storage references, sync-vs-async integration choice, WebSocket/SSE connection lifecycle) plus stack subtrees: `java/` (JPA, Spring proxies, JVM threads/memory), `node/` (event loop, promises, runtime validation, shutdown), `python/` (GIL/asyncio, pydantic, WSGI/ASGI workers, language traps, packaging data files with `importlib.resources`) |
| [frontend](wiki/frontend/index.md) | **seeded** | Web UI code: state placement, rendering performance, in-UI data fetching (races, infinite scroll), auth token handling, forms, XSS-safe output, accessibility, agent-facing tool surfaces (WebMCP) |
| [infrastructure](wiki/infrastructure/index.md) | **seeded** | CI/CD pipelines, secrets in build/deploy, container image builds, rollout/rollback strategy, observability (logs/metrics/alerting), per-environment/path-valued config, multi-agent orchestration (worker liveness signals, shared run state, tmux pane delivery, completion gates, worktree-isolated workers, autonomous ask-vs-rule decisions, session context/token budgeting, a pre-built code knowledge graph as a freshness-gated orientation layer for planning) |
| [testing](wiki/testing/index.md) | **seeded** | Writing or structuring automated tests: level choice, test-before-code ordering, cases/assertions, cross-layer effect scoping, test data, mock decisions, flaky tests (release-process quality → qa) |
| [qa](wiki/qa/index.md) | **seeded** | Release-quality process: release gates, regression scoping, bug reports, severity/priority triage, evidence for completion claims, acting on code-review feedback, adversarial review of high-risk diffs, exploratory testing (guarded-path coverage, override matrices), scope-purity gates, sourcing deliverable documents from generated artifacts, verifying the quantitative claims in a document before publishing it, automated verification of document deliverables (spec/RFC gates) (writing automated test code → testing) |
| [testing](wiki/testing/index.md) | **seeded** | Writing or structuring automated tests: level choice, test-before-code ordering, cases/assertions, cross-layer effect scoping, test data, mock decisions, flaky tests, test-infrastructure containers (Testcontainers) failing on the dev host, testing a SwiftPM executable target (release-process quality → qa) |
| [qa](wiki/qa/index.md) | **seeded** | Release-quality process: release gates, regression scoping, bug reports, severity/priority triage, evidence for completion claims, acting on code-review feedback, adversarial review of high-risk diffs, exploratory testing (guarded-path coverage, override matrices), scope-purity gates, sourcing deliverable documents from generated artifacts, verifying the quantitative claims in a document before publishing it, automated verification of document deliverables (spec/RFC gates), an aging detector for model-coupled agent guidance, capturing an app's own screen content without Screen Recording permission (writing automated test code → testing) |
| [debugging](wiki/debugging/index.md) | **seeded** | Diagnosing a failure — finding what is wrong and why: reproducing, bisection, hypothesis testing, traces/logs, intermittent failures (fixing the diagnosed fault → its owning domain) |
| [security](wiki/security/index.md) | **seeded** | Trust-boundary decisions: input validation, session-vs-token auth choice, per-resource authorization (IDOR), secrets hygiene, dependency trust, PII handling, in-session agent tool exposure (prompt-injection blast radius), the author identity a commit publishes to a public repository, host-compromise triage / incident response (verifying assumed security agents, identifying masquerading processes) (XSS rendering → frontend; CI secrets → infrastructure; JWT implementation → backend/frontend auth) |
| [security](wiki/security/index.md) | **seeded** | Trust-boundary decisions: input validation, session-vs-token auth choice, per-resource authorization (IDOR), secrets hygiene (including ciphertext orphaned by a regenerated encryption key), dependency trust, PII handling, in-session agent tool exposure (prompt-injection blast radius), the author identity a commit publishes to a public repository, host-compromise triage / incident response (verifying assumed security agents, identifying masquerading processes) (XSS rendering → frontend; CI secrets → infrastructure; JWT implementation → backend/frontend auth) |
| [platforms](wiki/platforms/index.md) | **seeded** | OS-level differences breaking code across macOS/Linux/Windows: shell portability, BSD-vs-GNU CLI, filesystem case/line endings, Unicode normalization in text/file-name matching, commands inspected before execution, background services/cron, invoking prompt-capable CLIs non-interactively, toolchain version pinning |
| [mobile](wiki/mobile/index.md) | **seeded** | App-side iOS/Android/cross-platform: process death/state survival, offline-first sync, mobile-network calls, store rollout/hotfix strategy, startup time |

Expand Down
10 changes: 10 additions & 0 deletions log.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,13 @@ Append-only. Format: `## [YYYY-MM-DD] <ingest|revise|lint|gap|contradiction|drif
## [2026-08-30] revise | frontend/design/design-canvas-workflow — agent-gate Check 3 remediation (PR #164). The gate's fact finding was half right: its "no skill named `design` exists" conclusion is refuted by ground truth (the skill is listed in the authoring session's available-skills roster as `design: Create a design canvas…` and its bundled payload exists on the authoring machine's disk; the reviewer's CI environment lacks the preview, and it conflated the skill with the unrelated `/design-sync` component-upload tool) — but the verifiability objection stands: the skill is an early research preview absent from public docs, so a single un-fetchable in-session source cannot carry `confidence: verified`. Fixed per AGENTS.md: confidence downgraded to field-tested with the experience context stated in the body; two live-fetched public sources added (anthropic.com/news/claude-design-anthropic-labs — official Claude Design product announcement, research preview, Claude Code handoff; explainx.ai 2026 post — /design ships in Claude Code as a research-preview command producing editable artboards via the Artifacts runtime); the mandatory-routing directive and the frontend/index.md load-when line conditioned on the skill appearing in the session's available-skills list, with the existing no-skill edge case as the explicit fallback; the unverifiable "design-review skill" name-drop in the audit edge case generalized to session-provided audit tooling.
## [2026-09-03] ingest | databases/selection — new category: datastore selection by workload (4 pages: choosing-a-datastore-by-workload, relational-jsonb-vs-document-store, vector-search-engine-selection, graph-workloads-relational-vs-graph-db); brave-search research, sources cited per page
## [2026-09-04] ingest | infrastructure/agent-orchestration/code-graph-as-orientation-layer (field-tested — 1 new page). A locally built code knowledge graph (graphify) is a freshness-gated, lead-not-evidence orientation layer for planning and parallel task decomposition: gate on graph mtime vs git log, symbol-anchored explain/path only, CLI delivery with bounded output, graph-derived assumptions named in reports. Sources: Developers Digest, AQ Score, Autonoma, Tiare Balbi, graphify README + measurements on graphifyy 0.4.23.
## [2026-09-06] ingest | testing/strategy/executable-target-tests-in-swiftpm (verified — 1 new page). A SwiftPM test target can depend on an `.executableTarget` directly and `@testable import` it since tools-version 5.5 (SwiftPM CHANGELOG #3316); `swift test` enables testability for debug builds; Windows `@main` duplicate-symbol caveat (swift-package-manager#6367); library split only for reuse. Field: desk-bat 49/49.
## [2026-09-06] ingest | qa/environments/offscreen-render-capture-without-screen-recording (verified — 1 new page). Screenshots/GIF reels of a macOS app's own content via `SKView.texture(from:)` / `NSView.cacheDisplay` + ImageIO `CGImageDestination` when the Screen Recording (TCC) grant is unavailable; GIF delay clamped to 100 ms (Apple doc) so capture at 10 fps; screen-of-other-apps still needs the grant + ScreenCaptureKit. Field: desk-bat d0da30d.
## [2026-09-06] ingest | testing/data/testcontainers-reaper-on-docker-desktop-macos (verified — 1 new page). Ryuk's socket bind-mount fails on Docker Desktop's per-user socket; fix order: Desktop "Allow the default Docker socket" setting → `TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock` → `TESTCONTAINERS_RYUK_DISABLED=true` on the dev host only. Candidate's directive (disable Ryuk first) demoted to the last row per testcontainers/Rancher/Colima docs. Field: linkly 0 tests → 27/27.
## [2026-09-06] ingest | security/secrets/ciphertext-orphaned-by-a-regenerated-key (verified — 1 new page). Separate "key loaded" from "row encrypted under this key": sentinel round-trip, read-only recoverable/total scan before any delete, recover previous key from secret-store history, key id/version with ciphertext (OWASP, Rails `previous:`, Tink key-id prefix), idempotent bootstrap. Field: linkly-calendar 124/124 unrecoverable.
## [2026-09-06] ingest | qa/document-verification/model-coupled-guidance-aging-detector (verified — 1 new page). Aging detector for agent-facing docs: subject keywords in prose (27/271) not quirk phrases (3/271), scan outside frontmatter/Sources/URLs/index files (32 vs 21 pages), `verified_model` field, overridable current-generation list, report-only exit code outside the blocking CI step. Sources: Anthropic prompting best practices, dev-loop scripts/wiki-lint-model-era.js, PR #178; reproduced 276/21/21.
## [2026-09-06] ingest | backend/common/api-design/cors-and-preflight — merge: an injected probe POSTing JSON to a hand-rolled local collector gets nothing through because the collector 404s the `OPTIONS` preflight; `curl -i -X OPTIONS` probe row + Instead-of row; related links to probe-path-vs-operation-path and browser-console-capture-gaps. Field: linkly-crew collector.mjs 0 → 6 reports.
## [2026-09-06] ingest | infrastructure/agent-orchestration/control-signals-vs-primary-artifacts — merge: a queued candidate's `pending` row is a control signal about the destination store; grep the store for the candidate's phrase before processing and retire already-landed rows with the landing PR id. Body-only edit (frontmatter `related:` is rewritten by open PR #179). Field: dev-loop flush row f1ba9bf617fbd101 / PR #184.
## [2026-09-06] ingest | testing/quality/tests-that-cannot-fail — merge: never-fails row for a test that re-asserts the literal a layout constant is declared as; declare the constant from its components and assert relations between production values. Body-only edit (frontmatter rewritten by open PRs #179/#180). Field: linkly-calendar LinklyTabBar 96 vs 80 pt, fix 4e584cc.
## [2026-09-06] fold | infrastructure/agent-orchestration/checkable-claims-in-an-adopted-plan (on open PR #181) — author-side rows: grep both ends of a threaded value / id-keyed lookup and confirm the call path; enumerate every (role, surface) contrast pair the contract tests enforce. frontend/design/responsive-layout (on open PR #181) — CJK label + pill row wraps after padding change: `nowrap; flex-shrink: 0` / `flex: 1; min-width: 0`, browser measurement with real strings.
## [2026-09-06] drop | queue candidate 11c6ad7b2166e611 (Prisma `CREATE INDEX CONCURRENTLY` in a multi-statement migration) — pending duplicate of open PR #185's online-schema-changes rows (same field evidence, 2026-08-31 linkly-calendar); retired without a wiki change.
11 changes: 8 additions & 3 deletions wiki/backend/common/api-design/cors-and-preflight.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ confidence: verified
sources:
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS
- https://fetch.spec.whatwg.org/#http-cors-protocol
last_verified: 2026-08-17
related: [security-api-exposure-exposing-an-origin-http-api]
last_verified: 2026-09-06
related: [security-api-exposure-exposing-an-origin-http-api, debugging-methodology-probe-path-vs-operation-path, qa-environments-browser-console-capture-gaps]
---

# Handling Browser CORS Requests and Preflight
Expand All @@ -21,7 +21,9 @@ console with a CORS error even though a direct `curl` to the same endpoint
succeeds — CORS is enforced by the browser, not the server, so server-side
tools never reproduce it. Also applies when designing which endpoints need
`Access-Control-*` headers and whether the browser will send an OPTIONS
preflight before the real request.
preflight before the real request. Also when an instrumentation probe injected
into a page (a WKWebView/Tauri app, a browser under test) `fetch`-POSTs JSON to a
local collector you wrote and the collector logs nothing.

## Do this

Expand All @@ -41,15 +43,18 @@ preflight before the real request.
| Preflight succeeds (200) but the real request still fails CORS | The preflight and the real response are checked independently — the real response also needs `Access-Control-Allow-Origin`; a proxy/CDN that strips CORS headers only from the real response is a common cause |
| A reverse proxy or API gateway sits in front of the origin | Confirm CORS headers are added at the layer that actually terminates OPTIONS — if the origin app never sees the preflight (the gateway auto-answers it), the origin's response headers still need to match or the real response is blocked |
| Non-browser client (server-to-server, mobile app, curl) reports a "CORS error" | It cannot — CORS is a browser-enforced restriction; the real failure is elsewhere (auth, network) and the report is misattributed |
| An injected probe POSTs JSON to a hand-rolled local collector (`http.createServer` branching on `POST` only) and nothing arrives, while a direct `curl -X POST` succeeds | `Content-Type: application/json` makes the browser send `OPTIONS` first; a server that answers only `POST` returns 404 to the preflight and the real POST is never sent — the page's `fetch(...).catch()` swallows it, so the probe looks unreachable rather than rejected. Run `curl -i -X OPTIONS <url>` and require a 2xx carrying `Access-Control-Allow-Origin`, `-Methods`, `-Headers`; then answer `OPTIONS` with 204 plus those headers and put `Access-Control-Allow-Origin` on the `POST` response as well |

## Instead of

| If you are about to | Do this instead | Why |
|---------------------|-----------------|-----|
| Set `Access-Control-Allow-Origin: *` on an endpoint that also sets `Access-Control-Allow-Credentials: true` | Echo back the validated request `Origin` as a single explicit value | The Fetch spec's CORS protocol forbids the wildcard on a credentialed response, and browsers enforce this by blocking the response even if the server sends it |
| Conclude "the page never loads the probe" because the collector logged zero requests | Send one `curl -i -X OPTIONS` to the collector and one deliberate `fetch` from the page's console | A collector that 404s the preflight and a probe that never ran produce the same empty log; the OPTIONS probe separates them ([debugging-methodology-probe-path-vs-operation-path]) |
| Debug a CORS failure by relaxing the server to allow every origin | Read the exact console error (it names the missing/mismatched header) and add only that header for the specific origins that need it | A blanket allow-all reopens the endpoint to any site's browser-side JS, including credentialed requests if cookies are involved |

## Sources

- https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS — simple vs preflighted requests, response headers, wildcard-with-credentials prohibition
- https://fetch.spec.whatwg.org/#http-cors-protocol — CORS-safelisted methods/headers, preflight algorithm, non-wildcard credentialed response requirement
- Field reproduction 2026-09-02 (linkly-crew t2-live-visual-verify, Tauri/WKWebView app with a Node `collector.mjs`): the collector handled only `POST`; a full app rebuild and launch produced zero reports and `curl -X OPTIONS /report` returned 404. After adding an `OPTIONS` branch (204 with `access-control-allow-origin/methods/headers`) and the same headers on POST responses, the unchanged probe delivered 6 reports within 10 s
2 changes: 1 addition & 1 deletion wiki/backend/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Match your situation to a "load when" line; load only matching pages.
| [idempotency](common/api-design/idempotency.md) | An endpoint with side effects (create, charge, send) can receive the same request twice — client retry after timeout, user double-submit, gateway retry; designing idempotency-key storage; deciding which operations are safe to retry |
| [pagination-contract](common/api-design/pagination-contract.md) | Designing a list endpoint's request/response contract — cursor vs page-number, limit caps, total counts, expired-cursor behavior (the backing SQL/index → databases/query-optimization/keyset-pagination) |
| [unenforced-declarations](common/api-design/unenforced-declarations.md) | Your system accepts declarative input (config file, DSL/manifest, policy block, schema annotation) and part of what a caller may write is unimplemented — an unknown key, a verb outside your vocabulary, or a knob recorded but never acted on; a user reports "I declared X and nothing happened"; choosing between reject/warn/ignore and where that strictness is selected |
| [cors-and-preflight](common/api-design/cors-and-preflight.md) | A browser-based caller on a different origin fails with a CORS error in the console (a direct curl to the same endpoint works); deciding whether a change to an endpoint's method/headers/content-type will trigger an OPTIONS preflight; designing `Access-Control-*` headers for a credentialed vs public endpoint; allowlisting more than one origin |
| [cors-and-preflight](common/api-design/cors-and-preflight.md) | A browser-based caller on a different origin fails with a CORS error in the console (a direct curl to the same endpoint works); deciding whether a change to an endpoint's method/headers/content-type will trigger an OPTIONS preflight; designing `Access-Control-*` headers for a credentialed vs public endpoint; allowlisting more than one origin; an injected probe POSTs JSON to a hand-rolled local collector and nothing arrives |
| [api-versioning-and-breaking-changes](common/api-design/api-versioning-and-breaking-changes.md) | An API has external callers you cannot enumerate or force-upgrade and you need to add/remove/rename/retype a field or endpoint; classifying a change as backward-compatible vs breaking; choosing a versioning mechanism (header vs URL); deprecating an old version (internal-only contract changes → [backend-common-change-impact-call-site-enumeration]) |
| [agent-tool-granularity](common/api-design/agent-tool-granularity.md) | Adding agent capabilities to an app (MCP server, function-calling tools, plugin tools); choosing between exposing a workflow function and exposing primitives; an agent cannot perform an action the UI offers; reviewing a tool list for CRUD completeness, completion signaling, or UI/agent parity |

Expand Down
Loading
Loading