@tyroneross/build-loop 0.36.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +2 -2
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/rules/build-loop-surface.mdc +12 -11
- package/.cursor/rules/skill-index.mdc +33 -0
- package/AGENTS.md +213 -34
- package/README.md +99 -31
- package/agents/advisor.md +4 -4
- package/agents/alignment-checker.md +2 -2
- package/agents/architecture-scout.md +4 -4
- package/agents/build-orchestrator.md +38 -36
- package/agents/database-assessor.md +11 -5
- package/agents/design-contract-specialist.md +8 -8
- package/agents/fact-checker.md +13 -3
- package/agents/fix-critique.md +2 -2
- package/agents/independent-auditor.md +60 -7
- package/agents/leak-scanner.md +82 -0
- package/agents/overfitting-reviewer.md +2 -2
- package/agents/plan-critic.md +1 -1
- package/agents/promotion-reviewer.md +5 -5
- package/agents/retrospective-synthesizer.md +138 -35
- package/agents/scope-auditor.md +82 -11
- package/agents/security-reviewer.md +56 -2
- package/agents/self-improvement-architect.md +17 -3
- package/agents/transcript-pattern-miner.md +5 -5
- package/agents/ui-validator.md +1 -1
- package/bin/build-loop-debugger.js +143 -0
- package/bin/build-loop-install.js +1 -4
- package/bin/build-loop-load-probe.js +345 -0
- package/codex-skills/build-loop/SKILL.md +28 -6
- package/commands/feedback.md +37 -0
- package/dist/src/interactive-verifier.d.ts +1 -14
- package/dist/src/interactive-verifier.d.ts.map +1 -1
- package/dist/src/interactive-verifier.js +6 -113
- package/dist/src/interactive-verifier.js.map +1 -1
- package/dist/src/quality.d.ts +5 -0
- package/dist/src/quality.d.ts.map +1 -0
- package/dist/src/quality.js +81 -0
- package/dist/src/quality.js.map +1 -0
- package/dist/src/storage.d.ts.map +1 -1
- package/dist/src/storage.js +37 -3
- package/dist/src/storage.js.map +1 -1
- package/docs/agent-surface-policy.md +35 -31
- package/docs/memory-setup.md +19 -0
- package/hooks/git/pre-push +65 -4
- package/hooks/hooks.json +95 -38
- package/hooks/pre-commit +20 -1
- package/hooks/pre-edit-rally-point.sh +10 -3
- package/hooks/session-start-codex-hook-trust.sh +30 -0
- package/hooks/session-start-git-hooks.sh +3 -1
- package/hooks/session-start-rally-point.sh +52 -4
- package/hooks/session-start-worktree-gc.sh +47 -94
- package/hooks/stop-transcript-sweep.sh +173 -0
- package/hooks/test_closeout.sh +14 -2
- package/package.json +8 -7
- package/scripts/README.md +1 -1
- package/scripts/_paths.py +65 -0
- package/scripts/groundwork_exchange.py +1012 -0
- package/scripts/install_memory.py +33 -1
- package/scripts/lessons_index/ingest.py +13 -2
- package/scripts/lessons_index/query.py +36 -13
- package/scripts/memory_context/__init__.py +108 -14
- package/scripts/memory_graph/__init__.py +5 -1
- package/scripts/project_resolver.py +42 -36
- package/scripts/sync_plugin_cache.py +37 -2
- package/skills/agent-rally-point/SKILL.md +46 -0
- package/skills/api-registry-bridge/SKILL.md +1 -1
- package/skills/architecture/dead/SKILL.md +1 -1
- package/skills/architecture/impact/SKILL.md +1 -1
- package/skills/architecture/review/SKILL.md +1 -1
- package/skills/architecture/rules/SKILL.md +3 -3
- package/skills/architecture/scan/SKILL.md +1 -1
- package/skills/architecture/trace/SKILL.md +1 -1
- package/skills/attribution-standard/SKILL.md +6 -6
- package/skills/auto-decision-capture/SKILL.md +31 -2
- package/skills/auto-finding-capture/SKILL.md +28 -1
- package/skills/build-loop/SKILL.md +131 -23
- package/skills/build-loop/fallbacks.md +16 -21
- package/skills/build-loop/phases/ui-validation.md +2 -2
- package/skills/build-loop/references/advisor-dispatch-ladder.md +1 -1
- package/skills/build-loop/references/apple-native-planning.md +1 -1
- package/skills/build-loop/references/autonomous-and-per-commit-modes.md +11 -5
- package/skills/build-loop/references/autonomy-dashboard.md +115 -0
- package/skills/build-loop/references/capability-routing.md +24 -2
- package/skills/build-loop/references/coordination.md +24 -6
- package/skills/build-loop/references/experiment-results-template.md +15 -3
- package/skills/build-loop/references/leadership.md +1 -1
- package/skills/build-loop/references/memory.md +14 -3
- package/skills/build-loop/references/modular-systems-pack.md +8 -0
- package/skills/build-loop/references/output-style.md +86 -0
- package/skills/build-loop/references/phase-1-assess.md +102 -2
- package/skills/build-loop/references/phase-2-plan.md +9 -1
- package/skills/build-loop/references/phase-3-execute.md +5 -2
- package/skills/build-loop/references/phase-4-review.md +85 -8
- package/skills/build-loop/references/phase-5-iterate.md +76 -8
- package/skills/build-loop/references/phase-6-learn.md +10 -17
- package/skills/build-loop/references/privileged-request-broker.md +254 -0
- package/skills/build-loop/references/resource-aware-execution.md +183 -0
- package/skills/build-loop/references/self-recursive-dev.md +2 -2
- package/skills/build-loop/references/status-output-format.md +207 -0
- package/skills/build-loop/references/verify-dispatch.md +56 -2
- package/skills/building-with-deepagents/SKILL.md +1 -1
- package/skills/claim-scope/SKILL.md +185 -0
- package/skills/color-engine/SKILL.md +103 -0
- package/skills/color-engine/_core.py +464 -0
- package/skills/color-engine/color_engine.py +175 -0
- package/skills/cost-rca/SKILL.md +61 -0
- package/skills/data-plane-worktrees/SKILL.md +139 -0
- package/skills/data-plane-worktrees/agents/openai.yaml +4 -0
- package/skills/database-practice/SKILL.md +200 -0
- package/skills/database-practice/references/diagnostic-queries.sql +126 -0
- package/skills/database-practice/references/vector-and-graph-tuning.md +208 -0
- package/skills/database-practice/scripts/db_table_map.py +1244 -0
- package/skills/database-practice/scripts/test_db_table_map.py +514 -0
- package/skills/debug-loop/SKILL.md +36 -6
- package/skills/debugging-memory/SKILL.md +32 -430
- package/skills/debugging-memory/references/pattern-extraction.md +4 -4
- package/skills/debugging-memory/references/search.md +32 -120
- package/skills/debugging-memory/references/store.md +32 -126
- package/skills/debugging-memory/references/subagent-integration.md +1 -1
- package/skills/decision-queue/SKILL.md +251 -0
- package/skills/decision-queue/assets/template.html +1242 -0
- package/skills/decision-queue/references/example-large-queue-batching.md +164 -0
- package/skills/decision-queue/scripts/regen_template_constants.py +160 -0
- package/skills/defenseclaw-bridge/SKILL.md +2 -2
- package/skills/defenseclaw-bridge/references/dc-config-mapping.md +2 -9
- package/skills/drain-proposals/SKILL.md +53 -0
- package/skills/focused-loop-builder/SKILL.md +31 -0
- package/skills/focused-loop-builder/references/spec-format.md +27 -0
- package/skills/handoff/SKILL.md +169 -8
- package/skills/ibr-bridge/SKILL.md +4 -1
- package/skills/knowledge/SKILL.md +26 -14
- package/skills/knowledge/references/review-mode.md +2 -3
- package/skills/knowledge/templates/madr-minimal.md +1 -1
- package/skills/mcp-builder/SKILL.md +1 -1
- package/skills/model-bakeoff/SKILL.md +48 -10
- package/skills/model-tiering/SKILL.md +92 -31
- package/skills/native-ax-driver/SKILL.md +38 -5
- package/skills/native-ax-driver/scripts/native_driver.py +278 -22
- package/skills/native-ax-driver/scripts/test_native_driver.py +227 -0
- package/skills/optimize/SKILL.md +1 -1
- package/skills/plugin-builder/SKILL.md +48 -1
- package/skills/plugin-builder/references/build-loop-phase-guidance.md +3 -4
- package/skills/plugin-builder/references/distribution.md +13 -2
- package/skills/plugin-builder/references/plugin-hygiene-lessons.md +2 -2
- package/skills/plugin-tests/SKILL.md +2 -2
- package/skills/recursive-retrospective/SKILL.md +1 -1
- package/skills/repo-closeout/SKILL.md +17 -0
- package/skills/repo-closeout/agents/openai.yaml +4 -0
- package/skills/repo-maintenance/SKILL.md +179 -0
- package/skills/repo-maintenance/agents/openai.yaml +4 -0
- package/skills/repo-maintenance/references/pre-public-hygiene.md +134 -0
- package/skills/repo-maintenance/references/repository-taxonomy.md +161 -0
- package/skills/repo-maintenance/references/safety-protocol.md +106 -0
- package/skills/repo-maintenance/references/stack-profiles.md +138 -0
- package/skills/repo-maintenance/scripts/audit_repo_maintenance.py +1198 -0
- package/skills/repo-maintenance/scripts/test_audit_repo_maintenance.py +506 -0
- package/skills/repository-intelligence/SKILL.md +189 -0
- package/skills/repository-intelligence/agents/openai.yaml +4 -0
- package/skills/repository-intelligence/references/assessment-rubric.md +88 -0
- package/skills/repository-intelligence/scripts/repository_inventory.py +347 -0
- package/skills/research/SKILL.md +12 -2
- package/skills/root-cause-analysis/SKILL.md +1 -1
- package/skills/runtime-parity-verification/SKILL.md +36 -1
- package/skills/security-methodology/SKILL.md +23 -10
- package/skills/security-methodology/references/agentic-handoff-templates.md +220 -0
- package/skills/security-methodology/references/cross-source-matrix.md +1 -1
- package/skills/security-methodology/references/owasp-agentic-top-10.md +1 -1
- package/skills/security-scan/SKILL.md +55 -15
- package/skills/self-improve/SKILL.md +70 -50
- package/skills/silent-assumptions/SKILL.md +341 -0
- package/skills/silent-assumptions/references/elicitation-detectors.md +342 -0
- package/skills/spec-writing/SKILL.md +128 -24
- package/skills/spec-writing/scripts/check_checklist.py +114 -15
- package/skills/ui-design/SKILL.md +6 -4
- package/skills/ui-design/references/color-engine.md +132 -0
- package/skills/ui-design/references/design-preferences-from-owned-apps.md +8 -8
- package/skills/ui-design/references/ui-guidance-sources.md +1 -1
- package/skills/ui-design/references/universal-design-principles.alt.md +2 -2
- package/plugin-artifacts/codex/.codex-plugin/plugin.json +0 -41
- package/plugin-artifacts/codex/AGENTS.md +0 -560
- package/plugin-artifacts/codex/BUILD-ARTIFACT.md +0 -5
- package/plugin-artifacts/codex/LICENSE +0 -202
- package/plugin-artifacts/codex/README.md +0 -313
- package/plugin-artifacts/codex/assets/build-loop-plugin-icon.png +0 -0
- package/plugin-artifacts/codex/docs/agent-surface-policy.md +0 -63
- package/plugin-artifacts/codex/references/advisor-dispatch-ladder.md +0 -62
- package/plugin-artifacts/codex/references/agent-role-taxonomy.md +0 -135
- package/plugin-artifacts/codex/references/autonomous-and-per-commit-modes.md +0 -161
- package/plugin-artifacts/codex/references/autonomy-config.md +0 -231
- package/plugin-artifacts/codex/references/backlog-system.md +0 -285
- package/plugin-artifacts/codex/references/capability-routing.md +0 -231
- package/plugin-artifacts/codex/references/codex-subagents.md +0 -106
- package/plugin-artifacts/codex/references/coordination-file-template.md +0 -181
- package/plugin-artifacts/codex/references/coordination-rules.md +0 -552
- package/plugin-artifacts/codex/references/dogfood-reload-checkpoint.md +0 -112
- package/plugin-artifacts/codex/references/halt-and-ask-protocol.md +0 -102
- package/plugin-artifacts/codex/references/implementer-envelope-schema.md +0 -302
- package/plugin-artifacts/codex/references/intent-capability-pack.md +0 -257
- package/plugin-artifacts/codex/references/intent-exploration-prompts.md +0 -96
- package/plugin-artifacts/codex/references/leadership.md +0 -72
- package/plugin-artifacts/codex/references/memory-systems.md +0 -261
- package/plugin-artifacts/codex/references/memory.md +0 -313
- package/plugin-artifacts/codex/references/model-tier-mapping.md +0 -296
- package/plugin-artifacts/codex/references/modular-systems-pack.md +0 -96
- package/plugin-artifacts/codex/references/phase-1-assess.md +0 -249
- package/plugin-artifacts/codex/references/phase-2-plan.md +0 -86
- package/plugin-artifacts/codex/references/phase-3-execute.md +0 -49
- package/plugin-artifacts/codex/references/phase-4-review.md +0 -341
- package/plugin-artifacts/codex/references/phase-5-iterate.md +0 -72
- package/plugin-artifacts/codex/references/phase-6-learn.md +0 -58
- package/plugin-artifacts/codex/references/recent-design-structures.md +0 -274
- package/plugin-artifacts/codex/references/research-trigger-policy.md +0 -140
- package/plugin-artifacts/codex/references/runtime-smoke-triggers.md +0 -42
- package/plugin-artifacts/codex/references/self-review.md +0 -234
- package/plugin-artifacts/codex/references/single-writer-commit-protocol.md +0 -90
- package/plugin-artifacts/codex/references/task-capture-policy.md +0 -68
- package/plugin-artifacts/codex/references/ui-io-contract.md +0 -116
- package/plugin-artifacts/codex/references/ui-spotcheck-protocol.md +0 -65
- package/plugin-artifacts/codex/references/verify-dispatch.md +0 -85
- package/plugin-artifacts/codex/skills/build-loop/SKILL.md +0 -381
- package/plugin-artifacts/codex/skills/build-loop/detect-plugins.mjs +0 -82
- package/plugin-artifacts/codex/skills/build-loop/eval-guide.md +0 -65
- package/plugin-artifacts/codex/skills/build-loop/fallbacks.md +0 -549
- package/plugin-artifacts/codex/skills/build-loop/phases/fact-check.md +0 -42
- package/plugin-artifacts/codex/skills/build-loop/phases/ui-validation.md +0 -267
- package/plugin-artifacts/codex/skills/build-loop/references/advisor-dispatch-ladder.md +0 -62
- package/plugin-artifacts/codex/skills/build-loop/references/apple-native-planning.md +0 -439
- package/plugin-artifacts/codex/skills/build-loop/references/autonomous-and-per-commit-modes.md +0 -161
- package/plugin-artifacts/codex/skills/build-loop/references/capability-routing.md +0 -231
- package/plugin-artifacts/codex/skills/build-loop/references/codex-subagents.md +0 -106
- package/plugin-artifacts/codex/skills/build-loop/references/coordination.md +0 -161
- package/plugin-artifacts/codex/skills/build-loop/references/correction-aware-capture.md +0 -177
- package/plugin-artifacts/codex/skills/build-loop/references/experiment-results-template.md +0 -101
- package/plugin-artifacts/codex/skills/build-loop/references/independent-auditor.md +0 -72
- package/plugin-artifacts/codex/skills/build-loop/references/intent-capability-pack.md +0 -257
- package/plugin-artifacts/codex/skills/build-loop/references/intent-exploration-prompts.md +0 -96
- package/plugin-artifacts/codex/skills/build-loop/references/leadership.md +0 -72
- package/plugin-artifacts/codex/skills/build-loop/references/memory.md +0 -313
- package/plugin-artifacts/codex/skills/build-loop/references/modular-systems-pack.md +0 -96
- package/plugin-artifacts/codex/skills/build-loop/references/output-style.md +0 -222
- package/plugin-artifacts/codex/skills/build-loop/references/pay-it-forward-arch.md +0 -98
- package/plugin-artifacts/codex/skills/build-loop/references/phase-1-assess.md +0 -249
- package/plugin-artifacts/codex/skills/build-loop/references/phase-2-plan.md +0 -86
- package/plugin-artifacts/codex/skills/build-loop/references/phase-3-execute.md +0 -49
- package/plugin-artifacts/codex/skills/build-loop/references/phase-4-review.md +0 -341
- package/plugin-artifacts/codex/skills/build-loop/references/phase-5-iterate.md +0 -72
- package/plugin-artifacts/codex/skills/build-loop/references/phase-6-learn.md +0 -58
- package/plugin-artifacts/codex/skills/build-loop/references/recent-design-structures.md +0 -274
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/ASSESSMENT.md +0 -85
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +0 -149
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +0 -32
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +0 -48
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +0 -60
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +0 -51
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +0 -71
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +0 -52
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/trace-comparison.md +0 -202
- package/plugin-artifacts/codex/skills/build-loop/references/self-recursive-dev.md +0 -77
- package/plugin-artifacts/codex/skills/build-loop/references/self-review.md +0 -234
- package/plugin-artifacts/codex/skills/build-loop/references/ui-io-contract.md +0 -116
- package/plugin-artifacts/codex/skills/build-loop/references/verify-dispatch.md +0 -85
- package/plugin-artifacts/codex/skills/build-loop/scanners/audit-design-rules.mjs +0 -476
- package/plugin-artifacts/codex/skills/build-loop/scanners/require-visual-evidence.mjs +0 -239
- package/plugin-artifacts/codex/skills/build-loop/templates/backlog-item.md +0 -35
- package/plugin-artifacts/codex/skills/build-loop/templates/codex-worker-prompt.md +0 -100
- package/plugin-artifacts/codex/skills/build-loop/templates/ui-subagent-prompt.md +0 -179
- package/plugin-artifacts/codex/skills/build-loop/templates/ux-fix-plan.md +0 -40
- package/scripts/build_codex_plugin_artifact.py +0 -321
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Vector And Graph Tuning
|
|
2
|
+
|
|
3
|
+
Two shapes the base skill only sketches: a pgvector index, and a knowledge graph
|
|
4
|
+
stored in ordinary SQL tables. Every rule below carries the fingerprint you can
|
|
5
|
+
see in `db_table_map.py` output and the fix that follows from it. Numbers marked
|
|
6
|
+
*(observed)* come from one production instance — PostgreSQL 17.4 on Supabase,
|
|
7
|
+
12 GB, counters over a 215-day window — and are illustrative, not thresholds.
|
|
8
|
+
|
|
9
|
+
## pgvector And HNSW
|
|
10
|
+
|
|
11
|
+
### 1. `hnsw.ef_search` is the recall knob, and its default is 40
|
|
12
|
+
|
|
13
|
+
**Fingerprint.** A similarity query returns plausible but incomplete results,
|
|
14
|
+
and nobody can say what recall it achieves. No `ef_search` appears anywhere in
|
|
15
|
+
the function definition or the session setup.
|
|
16
|
+
|
|
17
|
+
**Fix.** Raise `ef_search` for the specific query path and measure recall against
|
|
18
|
+
an exact `ORDER BY embedding <=> $1` scan on a sample. `ef_search` sets how many
|
|
19
|
+
candidates the search keeps per layer: higher is slower and more accurate. It
|
|
20
|
+
must be at least the `LIMIT`. Treat it as a per-query setting, not a global one.
|
|
21
|
+
|
|
22
|
+
### 2. A filtered query under-returns unless the scan can iterate
|
|
23
|
+
|
|
24
|
+
**Fingerprint.** `LIMIT 20` returns 6 rows. The query pairs a vector distance
|
|
25
|
+
with a `WHERE` clause on a normal column. Nothing errors; the result is just
|
|
26
|
+
short, and the application treats the short list as "all there is".
|
|
27
|
+
|
|
28
|
+
Why: the index search runs first and returns `ef_search` candidates, then the
|
|
29
|
+
filter deletes most of them. With the default `ef_search` of 40 and a predicate
|
|
30
|
+
that keeps 10% of rows, roughly 4 rows survive.
|
|
31
|
+
|
|
32
|
+
**Fix.** pgvector 0.8.0 added `hnsw.iterative_scan`, which keeps scanning until
|
|
33
|
+
enough rows survive the filter. `strict_order` guarantees exact distance order;
|
|
34
|
+
`relaxed_order` allows slightly out-of-order results and recovers more of them.
|
|
35
|
+
`hnsw.max_scan_tuples` bounds how far the iterative scan will go before it gives
|
|
36
|
+
up and returns fewer than `LIMIT` rows. In the observed instance, switching a
|
|
37
|
+
filtered chunk search to `relaxed_order` moved it from 6 of 20 rows (recall 0.30)
|
|
38
|
+
to 20 of 20 (recall 1.00) for about +2 ms *(observed)*.
|
|
39
|
+
|
|
40
|
+
Prefer `relaxed_order` when the caller reranks anyway; `strict_order` when the
|
|
41
|
+
returned order is the answer.
|
|
42
|
+
|
|
43
|
+
### 3. `m` and `ef_construction` are build-time trade-offs you pay for forever
|
|
44
|
+
|
|
45
|
+
**Fingerprint.** An HNSW index built at the defaults (`m=16`,
|
|
46
|
+
`ef_construction=64`) on a table whose insert path is the top cost in
|
|
47
|
+
`pg_stat_statements`.
|
|
48
|
+
|
|
49
|
+
**Fix.** `m` sets edges per node: raising it raises recall, index size, build
|
|
50
|
+
time, and per-insert maintenance. `ef_construction` raises build quality and
|
|
51
|
+
build time only. Because index size is the thing that decides whether the graph
|
|
52
|
+
fits cache (rule 4), treat `m` as a size decision, not just a recall decision.
|
|
53
|
+
Halving dimensions with `halfvec` or a smaller model is usually a bigger win than
|
|
54
|
+
tuning `m`. Rehearse any rebuild against a copy — a rebuild locks writes.
|
|
55
|
+
|
|
56
|
+
### 4. The graph must fit `shared_buffers` or the page cache
|
|
57
|
+
|
|
58
|
+
**Fingerprint.** `shared_buffers` 256 MB, HNSW index 2.2 GB, database 12 GB
|
|
59
|
+
*(observed)*. Insert `mean_exec_time` around 1,000 ms that barely moves with row
|
|
60
|
+
count. `db_table_map.py` reports this as the `vector-insert-above-cache` shape.
|
|
61
|
+
|
|
62
|
+
**Fix.** Size the graph to the cache or the cache to the graph — there is no
|
|
63
|
+
third option. Every insert into a graph that cannot be cached is random I/O
|
|
64
|
+
against storage, and no batch size makes disk seeks free. Shrinking the vector
|
|
65
|
+
(dimensions, `halfvec`) shrinks the graph; raising `shared_buffers` costs money
|
|
66
|
+
on a managed instance but is one setting.
|
|
67
|
+
|
|
68
|
+
### 5. Set GUCs on the function, never on the session
|
|
69
|
+
|
|
70
|
+
**Fingerprint.** The repository's SQL file sets `hnsw.iterative_scan` and
|
|
71
|
+
`ef_search`; production `proconfig` carries only `enable_seqscan=off` *(observed)*.
|
|
72
|
+
The settings were lost somewhere between the file and the database, and nothing
|
|
73
|
+
noticed.
|
|
74
|
+
|
|
75
|
+
**Fix.** `ALTER FUNCTION similarity_search(...) SET hnsw.ef_search = 100` binds
|
|
76
|
+
the setting to the call. A session-level `SET` does not survive a transaction-mode
|
|
77
|
+
pooler, which hands the next statement a different backend; under PgBouncer in
|
|
78
|
+
transaction mode a session `SET` is silently ineffective. Function-scoped
|
|
79
|
+
settings are also self-documenting: they show up in `pg_proc.proconfig`, so they
|
|
80
|
+
are auditable.
|
|
81
|
+
|
|
82
|
+
### 6. Detect `proconfig` drift, do not trust the migration
|
|
83
|
+
|
|
84
|
+
**Fingerprint.** `db_table_map.py` lists a function that uses a vector distance
|
|
85
|
+
operator (`<=>`, `<->`, `<#>`, `<+>`) or takes/returns a `vector` type, with no
|
|
86
|
+
`hnsw.ef_search` and no `hnsw.iterative_scan` in `proconfig`.
|
|
87
|
+
|
|
88
|
+
**Fix.** Re-apply the `ALTER FUNCTION` and commit the map that proves it. Compare
|
|
89
|
+
the "Function GUCs" section against the repository's SQL on every map run; a
|
|
90
|
+
setting that lives only in a migration file is a setting nobody is enforcing.
|
|
91
|
+
|
|
92
|
+
### 7. Write amplification: the index is maintained on every insert
|
|
93
|
+
|
|
94
|
+
**Fingerprint.** An HNSW index of 2.2 GB with 33 lifetime scans against 402,158
|
|
95
|
+
table inserts; a second at 338 MB with 5 scans *(observed)*. Both are maintained
|
|
96
|
+
on every write. `db_table_map.py` calls this `index-maintenance-on-writes`.
|
|
97
|
+
|
|
98
|
+
**Fix.** An index whose read benefit is 33 scans and whose write cost is 402,158
|
|
99
|
+
maintenance operations is a liability with a positive-sounding name. Drop it, or
|
|
100
|
+
write down why the cost is accepted. Check `idx_scan` on the *other* HNSW index
|
|
101
|
+
over the same data before dropping: two graphs over one column usually means one
|
|
102
|
+
is the live read path and the other is a leftover.
|
|
103
|
+
|
|
104
|
+
### 8. Split fixed from marginal cost before you "batch harder"
|
|
105
|
+
|
|
106
|
+
**Fingerprint.** `rows / calls = 1.00` on a high-call `INSERT`.
|
|
107
|
+
|
|
108
|
+
**Fix.** Regress `mean_exec_time` against `rows / calls` across the normalized
|
|
109
|
+
statement variants `pg_stat_statements` already separates. In the observed
|
|
110
|
+
instance the call-weighted fit was 957 ms fixed + 47 ms per row — 95% fixed at
|
|
111
|
+
one row per statement *(observed)*. A high marginal term means batch. A high
|
|
112
|
+
fixed term means the batch is too small for the per-statement overhead, or the
|
|
113
|
+
graph does not fit cache. Choosing without the split optimizes the wrong term.
|
|
114
|
+
|
|
115
|
+
### 9. Batch sizing follows the split, and is rehearsed
|
|
116
|
+
|
|
117
|
+
Raise the batch only after the split says the fixed term dominates, and only as
|
|
118
|
+
far as the write path's memory and lock-hold time allow. Larger batches hold row
|
|
119
|
+
locks longer and raise the cost of a retry. The projection from an observational
|
|
120
|
+
fit is a hypothesis; rehearse the new size against a copy before shipping it.
|
|
121
|
+
|
|
122
|
+
### 10. Partial indexes for low-cardinality filters
|
|
123
|
+
|
|
124
|
+
**Fingerprint.** Every vector query carries the same narrow predicate —
|
|
125
|
+
`WHERE tenant_id = $1`, `WHERE status = 'published'` — and the filter deletes
|
|
126
|
+
most candidates after the search.
|
|
127
|
+
|
|
128
|
+
**Fix.** Build a partial HNSW index per value:
|
|
129
|
+
`CREATE INDEX ... ON t USING hnsw (embedding vector_cosine_ops) WHERE status = 'published'`.
|
|
130
|
+
The planner searches a graph that contains only matching rows, so `ef_search`
|
|
131
|
+
candidates are all usable and iterative scan is unnecessary. This works when the
|
|
132
|
+
filter column has few values and they are stable; it does not scale to a
|
|
133
|
+
per-user predicate, where the right answer is iterative scan.
|
|
134
|
+
|
|
135
|
+
## Graph In SQL
|
|
136
|
+
|
|
137
|
+
A knowledge graph stored in relational tables — entities, mentions, pairs,
|
|
138
|
+
evidence, trends, snapshots — is a normal schema with unusual access patterns.
|
|
139
|
+
No extension makes these rules unnecessary.
|
|
140
|
+
|
|
141
|
+
### 11. Adjacency tables need both directions indexed
|
|
142
|
+
|
|
143
|
+
**Fingerprint.** An edge table with a composite index on `(src_id, dst_id)` and
|
|
144
|
+
nothing on `(dst_id, ...)`. Forward traversal is fast; the reverse traversal
|
|
145
|
+
sequentially scans, and the map shows `seq_scan` climbing on the edge table.
|
|
146
|
+
|
|
147
|
+
**Fix.** Index both `(src_id, dst_id)` and `(dst_id, src_id)`, and include the
|
|
148
|
+
columns the traversal reads so the lookup stays index-only. Both directions get
|
|
149
|
+
used the moment anyone asks "what points at this".
|
|
150
|
+
|
|
151
|
+
### 12. Bound every recursive CTE by depth and rows
|
|
152
|
+
|
|
153
|
+
**Fingerprint.** A `WITH RECURSIVE` traversal with no depth column and no
|
|
154
|
+
`LIMIT`. It is fine until one hub entity connects to 50,000 others, then it
|
|
155
|
+
spills — visible as `temp_files` and `temp_bytes` in the map's spill section.
|
|
156
|
+
|
|
157
|
+
**Fix.** Carry a `depth` column, stop at an explicit maximum, and cap total rows.
|
|
158
|
+
Cycle-guard with a visited array or a `UNION` (not `UNION ALL`) when the data can
|
|
159
|
+
contain loops. Return a truncation flag rather than a silently partial answer.
|
|
160
|
+
|
|
161
|
+
### 13. Materialize hot neighborhoods, with explicit staleness
|
|
162
|
+
|
|
163
|
+
**Fingerprint.** The same neighborhood is re-traversed on every request, and the
|
|
164
|
+
table holding the precomputed answer takes 3.0 million updates against 6,321 rows
|
|
165
|
+
*(observed)*.
|
|
166
|
+
|
|
167
|
+
**Fix.** Materializing a context pack per entity is the right shape; rewriting
|
|
168
|
+
the same rows hundreds of times each is not. Store `built_at`, the source
|
|
169
|
+
version, and the inputs' versions on the pack, serve it while it is fresh, and
|
|
170
|
+
rebuild on a schedule or on an explicit invalidation — not on every write that
|
|
171
|
+
touches any input. A cache without a staleness field is a second source of truth.
|
|
172
|
+
|
|
173
|
+
### 14. Evidence rows are append-only, pruned by policy
|
|
174
|
+
|
|
175
|
+
**Fingerprint.** An evidence or mention table updated in place, so the record of
|
|
176
|
+
why a relationship was asserted changes under the reader's feet.
|
|
177
|
+
|
|
178
|
+
**Fix.** Append evidence with a timestamp and a source pointer; supersede rather
|
|
179
|
+
than mutate. Prune on a written retention policy, not opportunistically. This is
|
|
180
|
+
the constitution's governance requirement — lineage and evidence must survive.
|
|
181
|
+
|
|
182
|
+
### 15. Update-heavy hot rows bloat
|
|
183
|
+
|
|
184
|
+
**Fingerprint.** 1.1 million updates against 252,720 rows *(observed)*, with
|
|
185
|
+
`n_dead_tup` climbing and `last_autovacuum` old. Each update writes a new row
|
|
186
|
+
version; when the updated column is indexed, HOT pruning cannot apply and every
|
|
187
|
+
index on the table is maintained too.
|
|
188
|
+
|
|
189
|
+
**Fix.** Check `n_dead_tup` and `last_autovacuum` in the map before proposing
|
|
190
|
+
anything. Move high-churn counters (`last_seen_at`, `mention_count`) into a
|
|
191
|
+
narrow side table with no indexes on the churning columns, lower `fillfactor` on
|
|
192
|
+
the hot table so HOT updates can stay on-page, or tune per-table autovacuum
|
|
193
|
+
thresholds. Do not run `VACUUM FULL` on a live large table — it takes an
|
|
194
|
+
`ACCESS EXCLUSIVE` lock.
|
|
195
|
+
|
|
196
|
+
## Sources
|
|
197
|
+
|
|
198
|
+
- [pgvector README](https://github.com/pgvector/pgvector) — index options, GUC
|
|
199
|
+
names and defaults, iterative scan (0.8.0), filtering guidance.
|
|
200
|
+
- [Crunchy Data: hybrid vector search with Postgres and pgvector](https://www.crunchydata.com/blog/hybrid-vector-search)
|
|
201
|
+
— HNSW behaviour under filters and the recall consequence of `ef_search`.
|
|
202
|
+
- [dbi-services: pgvector, a guide for DBA — part 2, indexes (March 2026)](https://www.dbi-services.com/blog/pgvector-a-guide-for-dba-part-2-indexes-update-march-2026/)
|
|
203
|
+
— build parameters, index size, and maintenance cost from a DBA view.
|
|
204
|
+
|
|
205
|
+
Verified against the pgvector docs on 2026-09-05: `hnsw.iterative_scan` accepts
|
|
206
|
+
`off`, `strict_order`, `relaxed_order` and shipped in 0.8.0; `hnsw.ef_search`
|
|
207
|
+
defaults to 40. Build defaults `m=16` / `ef_construction=64` are the pgvector
|
|
208
|
+
README's stated defaults.
|