doc3gpp 0.2.1__tar.gz → 0.3.2__tar.gz
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.
- doc3gpp-0.3.2/.superpowers/sdd/.gitignore +2 -0
- doc3gpp-0.3.2/.superpowers/sdd/2026-09-24-spec-doc-metadata-and-portal-fix/final-fix-report.md +179 -0
- doc3gpp-0.3.2/.superpowers/sdd/2026-09-24-spec-doc-metadata-and-portal-fix/task-2-report.md +129 -0
- doc3gpp-0.3.2/.superpowers/sdd/2026-09-24-spec-doc-web-portal/final-fix-report.md +255 -0
- doc3gpp-0.3.2/.superpowers/sdd/2026-09-24-spec-doc-web-portal/task-2-report.md +62 -0
- doc3gpp-0.3.2/.superpowers/sdd/2026-09-25-spec-parsed-output/final-fix-report.md +129 -0
- doc3gpp-0.3.2/.superpowers/sdd/2026-09-25-spec-parsed-output/task-3-report.md +73 -0
- doc3gpp-0.3.2/.superpowers/sdd/2026-09-25-spec-parsed-output/task-4-report.md +90 -0
- doc3gpp-0.3.2/.superpowers/sdd/2026-09-25-spec-parsed-output/task-7-report.md +174 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/AGENTS.md +49 -48
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/PKG-INFO +153 -141
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/README.md +151 -138
- doc3gpp-0.3.2/docs/TODO.md +42 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/architecture.md +303 -67
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/cli.md +285 -115
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/code-map.md +67 -26
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/conventions.md +11 -3
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-22-remote-embedding-api.md +675 -0
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-23-spec-doc-parse.md +1553 -0
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-24-spec-doc-fetch-command-removal.md +380 -0
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-24-spec-doc-metadata-and-portal-fix.md +911 -0
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-24-tdoc-search-namespace.md +422 -0
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-25-spec-doc-chunk-context.md +305 -0
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-25-spec-doc-pagination.md +527 -0
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-25-spec-parsed-output.md +772 -0
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-26-unified-search-index.md +734 -0
- doc3gpp-0.3.2/docs/superpowers/plans/2026-09-27-mcp-stdio.md +923 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-22-remote-embedding-api-design.md +163 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-23-spec-doc-parse-design.md +296 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-24-spec-doc-fetch-command-removal-design.md +130 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-24-spec-doc-metadata-and-portal-fix-design.md +185 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-24-spec-doc-web-portal-design.md +338 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-24-tdoc-search-namespace-design.md +153 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-25-spec-doc-chunk-context-design.md +136 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-25-spec-doc-pagination-design.md +234 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-25-spec-parsed-output-design.md +125 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-26-unified-search-index-design.md +417 -0
- doc3gpp-0.3.2/docs/superpowers/specs/2026-09-27-mcp-stdio-design.md +209 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/web-server.md +137 -53
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/pyproject.toml +4 -3
- doc3gpp-0.3.2/scripts/dev_run.sh +12 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/__init__.py +1 -1
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/cli.py +920 -624
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/cli_server.py +88 -23
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/data/doc3gpp.toml.example +107 -49
- doc3gpp-0.3.2/src/doc3gpp/data/skills/doc3gpp/SKILL.md +64 -0
- doc3gpp-0.3.2/src/doc3gpp/models/index.py +101 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/jobs.py +4 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/schema_info.py +43 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/search.py +16 -5
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/semantic_search.py +2 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/spec.py +16 -0
- doc3gpp-0.3.2/src/doc3gpp/models/spec_doc.py +125 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/tdoc.py +2 -1
- doc3gpp-0.3.2/src/doc3gpp/models/unified_search.py +98 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/docx_converter.py +127 -1
- doc3gpp-0.3.2/src/doc3gpp/parsers/spec_doc.py +141 -0
- doc3gpp-0.3.2/src/doc3gpp/parsers/spec_doc_chunker.py +295 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/repository/protocols.py +285 -28
- doc3gpp-0.3.2/src/doc3gpp/scraping/spec_doc_source.py +73 -0
- doc3gpp-0.3.2/src/doc3gpp/services/embedding/__init__.py +11 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/embedding/chunker.py +2 -2
- doc3gpp-0.3.2/src/doc3gpp/services/embedding/remote_embedder.py +97 -0
- doc3gpp-0.3.2/src/doc3gpp/services/factory.py +820 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/search_service.py +18 -14
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/semantic_reranker.py +9 -7
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/semantic_search_service.py +31 -12
- doc3gpp-0.3.2/src/doc3gpp/services/spec_doc_index_service.py +167 -0
- doc3gpp-0.3.2/src/doc3gpp/services/spec_doc_search_facade.py +197 -0
- doc3gpp-0.3.2/src/doc3gpp/services/spec_doc_search_service.py +136 -0
- doc3gpp-0.3.2/src/doc3gpp/services/spec_doc_semantic_service.py +298 -0
- doc3gpp-0.3.2/src/doc3gpp/services/spec_doc_service.py +407 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/spec_service.py +45 -6
- doc3gpp-0.3.2/src/doc3gpp/services/tdoc_index_service.py +159 -0
- doc3gpp-0.3.2/src/doc3gpp/services/tdoc_search_facade.py +179 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/settings/config_writer.py +13 -1
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/settings/schema.py +178 -45
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/backends/sqlite.py +15 -7
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/db/migrate.py +150 -24
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/db/models.py +58 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/db/session.py +54 -3
- doc3gpp-0.3.2/src/doc3gpp/storage/db/specdata_base.py +13 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/jobs_sql.py +7 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/search_sql.py +5 -2
- doc3gpp-0.3.2/src/doc3gpp/storage/repositories/spec_doc_search_sql.py +508 -0
- doc3gpp-0.3.2/src/doc3gpp/storage/repositories/spec_doc_sql.py +416 -0
- doc3gpp-0.3.2/src/doc3gpp/storage/repositories/spec_doc_vector_sql.py +654 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/spec_sql.py +8 -10
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/tdoc_sql.py +59 -3
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/vector_sql.py +138 -30
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/app.py +74 -12
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/deps.py +44 -3
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/errors.py +81 -13
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/mcp_server.py +277 -79
- doc3gpp-0.3.2/src/doc3gpp/web/mcp_stdio.py +71 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/render.py +99 -5
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/__init__.py +4 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/jobs.py +71 -11
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/landing.py +7 -2
- doc3gpp-0.3.2/src/doc3gpp/web/routes/search.py +230 -0
- doc3gpp-0.3.2/src/doc3gpp/web/routes/spec_docs.py +465 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/specs.py +6 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/state.py +45 -16
- doc3gpp-0.3.2/src/doc3gpp/web/static/js/spec_doc_parse.js +32 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/js/sync_hub.js +15 -6
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/style.css +41 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/base.html +2 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/search_form.html +7 -21
- doc3gpp-0.3.2/src/doc3gpp/web/templates/partials/search_resource_tabs.html +4 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/search_results.html +4 -7
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/search_results_table.html +8 -14
- doc3gpp-0.3.2/src/doc3gpp/web/templates/partials/spec_doc_chunks.html +56 -0
- doc3gpp-0.3.2/src/doc3gpp/web/templates/partials/spec_doc_search_form.html +36 -0
- doc3gpp-0.3.2/src/doc3gpp/web/templates/partials/spec_doc_search_results.html +22 -0
- doc3gpp-0.3.2/src/doc3gpp/web/templates/partials/spec_doc_search_results_table.html +60 -0
- doc3gpp-0.3.2/src/doc3gpp/web/templates/partials/spec_doc_show_results.html +78 -0
- doc3gpp-0.3.2/src/doc3gpp/web/templates/partials/spec_doc_toc_results.html +41 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/spec_filters.html +7 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/spec_results.html +2 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/search_results.html +8 -17
- doc3gpp-0.3.2/src/doc3gpp/web/templates/spec_doc_show.html +51 -0
- doc3gpp-0.3.2/src/doc3gpp/web/templates/spec_doc_toc.html +10 -0
- doc3gpp-0.3.2/src/doc3gpp/web/templates/spec_docs_search.html +24 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/spec_show.html +6 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/sync.html +29 -8
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/workers/handlers.py +154 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/workers/job_worker.py +15 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/conftest.py +12 -3
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/semantic_search_corpus.py +2 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_cli_server.py +54 -6
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_config_init_cli_sqlite.py +18 -6
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_mcp_end_to_end.py +737 -88
- doc3gpp-0.3.2/tests/integration/test_online_spec_doc_sync.py +103 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_filters.py +33 -5
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_previews_per_column.py +32 -4
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_query_sem_rerank.py +62 -86
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_sem_end_to_end.py +9 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_spec_cli.py +103 -0
- doc3gpp-0.3.2/tests/integration/test_spec_doc_cli.py +61 -0
- doc3gpp-0.3.2/tests/integration/test_spec_doc_repo.py +178 -0
- doc3gpp-0.3.2/tests/integration/test_spec_doc_search_repo.py +479 -0
- doc3gpp-0.3.2/tests/integration/test_spec_doc_search_service.py +395 -0
- doc3gpp-0.3.2/tests/integration/test_spec_doc_service.py +299 -0
- doc3gpp-0.3.2/tests/integration/test_spec_doc_web.py +43 -0
- doc3gpp-0.3.2/tests/integration/test_spec_parsed_output.py +134 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_spec_sql.py +10 -0
- doc3gpp-0.3.2/tests/integration/test_sqlite_backend.py +67 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_sync_hub_end_to_end.py +21 -6
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdoc_sqlite.py +71 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_vector_index_lifecycle.py +158 -1
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_vector_repo_get_min_distance.py +3 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_web_search_end_to_end.py +27 -21
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_cache_cli.py +4 -4
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_chunker.py +2 -2
- doc3gpp-0.3.2/tests/unit/test_cli_search.py +739 -0
- doc3gpp-0.3.2/tests/unit/test_cli_search_sem.py +89 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_cli_server_start.py +25 -16
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_cli_server_stubs.py +9 -17
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_cr_parser.py +17 -11
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_db_reset_cli.py +15 -2
- doc3gpp-0.3.2/tests/unit/test_factory_semantic.py +179 -0
- doc3gpp-0.3.2/tests/unit/test_index_services.py +293 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_job_worker.py +152 -16
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_jobs_sql.py +18 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_meeting_sync_tsg_validation.py +3 -7
- doc3gpp-0.3.2/tests/unit/test_packaging_semantic.py +117 -0
- doc3gpp-0.3.2/tests/unit/test_remote_embedder.py +109 -0
- doc3gpp-0.3.2/tests/unit/test_remote_embedding_settings.py +65 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_schema_info.py +31 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_search_service.py +69 -9
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_semantic_search_service.py +12 -2
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_semantic_settings.py +3 -3
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_server_settings.py +3 -3
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_services_factory.py +32 -1
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_settings.py +1 -1
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_settings_config_file.py +23 -9
- doc3gpp-0.3.2/tests/unit/test_spec_doc_blocks.py +97 -0
- doc3gpp-0.3.2/tests/unit/test_spec_doc_chunker.py +315 -0
- doc3gpp-0.3.2/tests/unit/test_spec_doc_models.py +82 -0
- doc3gpp-0.3.2/tests/unit/test_spec_doc_parser.py +124 -0
- doc3gpp-0.3.2/tests/unit/test_spec_doc_search_facade.py +324 -0
- doc3gpp-0.3.2/tests/unit/test_spec_doc_service_reads.py +135 -0
- doc3gpp-0.3.2/tests/unit/test_spec_doc_settings.py +75 -0
- doc3gpp-0.3.2/tests/unit/test_spec_doc_source.py +95 -0
- doc3gpp-0.3.2/tests/unit/test_spec_doc_vector_metadata.py +216 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_spec_model.py +12 -1
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_spec_service.py +94 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_sync_hub_page.py +8 -2
- doc3gpp-0.3.2/tests/unit/test_tdoc_search_facade.py +259 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_testcase_db_url.py +8 -0
- doc3gpp-0.3.2/tests/unit/test_unified_search_models.py +249 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_web_app.py +25 -9
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_web_errors.py +29 -5
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_web_jobs_routes.py +29 -5
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_web_routes.py +1570 -258
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/web/test_landing_version.py +13 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/web/test_mcp_server.py +89 -0
- doc3gpp-0.3.2/tests/unit/web/test_mcp_stdio.py +224 -0
- doc3gpp-0.2.1/scripts/dev_run.sh +0 -12
- doc3gpp-0.2.1/src/doc3gpp/services/embedding/__init__.py +0 -10
- doc3gpp-0.2.1/src/doc3gpp/services/embedding/embedder.py +0 -76
- doc3gpp-0.2.1/src/doc3gpp/services/factory.py +0 -376
- doc3gpp-0.2.1/src/doc3gpp/web/routes/search.py +0 -272
- doc3gpp-0.2.1/tests/integration/test_sqlite_backend.py +0 -32
- doc3gpp-0.2.1/tests/unit/test_cli_search.py +0 -509
- doc3gpp-0.2.1/tests/unit/test_cli_search_sem.py +0 -82
- doc3gpp-0.2.1/tests/unit/test_embedder.py +0 -104
- doc3gpp-0.2.1/tests/unit/test_factory_semantic.py +0 -44
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/.env.example +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/.github/workflows/publish.yml +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/.gitignore +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/LICENSE +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/doc3gpp.toml.example +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/3gpp-knowledge.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/known-constraints.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-07-28-compact-output.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-07-28-tdoc-size-limit.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-07-29-fts5-search.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-07-29-tdoc-cr-body-changes.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-07-30-fts5-perf.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-07-31-embedding-search.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-01-fts5-hit-rename.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-01-fts5-semantic-rerank.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-01-semantic-search-revision.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-02-all-extra.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-02-remove-mysql-postgres.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-02-web-and-mcp-server.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-03-meeting-sync-display.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-03-meetings-tdoc-filter.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-04-web-ui-enhancements.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-05-tdoc-columns-dropdown.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-05-web-parse-and-search.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-07-mcp-sse-transport.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-10-spec-sync-list-show.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-11-spec-rapporteurs-comment.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-11-spec-rapporteurs-filter.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-12-mcp-spec-sync.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-12-single-spec-sync.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-12-spec-show-version-limit.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-12-spec-sync-dynareport-fetch.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-13-idempotent-cancel.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-13-mcp-parse-tdoc-url.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-13-per-spec-skip-rule.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-13-spec-per-version-details-flag.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-13-web-job-detail-params.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-13-web-mcp-meeting-name-filter.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-14-cover-page-summary-of-change.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-14-job-progress.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-14-sync-hub-page.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-14-version-display.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-14-web-tdoc-extracted-changes.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-19-tdocs-xlsx-metadata.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-08-19-web-mcp-tdoc-show-by-url.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-09-11-ran5-testcases.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-09-12-testcase-nested-statuses.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-09-12-testcase-separate-db.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/plans/2026-09-13-resource-schema.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-07-28-compact-output-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-07-28-tdoc-size-limit-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-07-29-fts5-search-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-07-29-tdoc-cr-body-changes-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-07-30-fts5-perf.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-07-31-embedding-search-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-01-fts5-hit-rename-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-01-fts5-semantic-rerank-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-01-semantic-search-revision-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-02-all-extra-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-02-remove-mysql-postgres-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-02-web-and-mcp-server-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-03-meeting-sync-display-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-03-meetings-tdoc-filter-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-04-web-ui-enhancements-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-05-tdoc-columns-dropdown-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-05-web-parse-and-search-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-10-spec-sync-list-show-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-11-spec-rapporteurs-comment-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-11-spec-rapporteurs-filter-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-12-mcp-spec-sync-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-12-single-spec-sync-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-12-spec-show-version-limit-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-12-spec-sync-dynareport-fetch-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-13-docs-review-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-13-idempotent-cancel-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-13-mcp-parse-tdoc-url-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-13-spec-per-version-details-flag-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-13-web-job-detail-params-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-13-web-mcp-meeting-name-filter-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-14-cover-page-summary-of-change-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-14-sync-hub-page-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-14-version-display-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-14-web-jobs-cancel-button-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-14-web-tdoc-extracted-changes-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-19-tdocs-xlsx-metadata-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-08-19-web-mcp-tdoc-show-by-url-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-09-11-ran5-testcases-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-09-12-testcase-nested-statuses-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-09-12-testcase-separate-db-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/docs/superpowers/specs/2026-09-13-resource-schema-design.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/scripts/test_sqlite.sh +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/cli_auto_sync.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/cli_filters.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/cli_url_helpers.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/config.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/meeting.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/sync.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/tdoc_cr.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/tdoc_cr_change_details.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/tdoc_file.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/tdoc_show.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/testcase.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/tsg.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/models/wi.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/calendar_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/cr/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/cr/body_changes.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/cr/cover_page.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/cr/cr_parsers.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/cr/header.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/cr/helpers.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/cr/ttcn_functions.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/cr/ttcn_sections.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/cr_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/direct_extractor.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/html_parsers.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/normalizers.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/spec_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/spec_release.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/tdoc_file_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/tdoc_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/tdoc_parsers.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/testcase_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/parsers/wi_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/repository/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/cache.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/cache_keys.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/calendar_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/client.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/ftp_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/portal_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/spec_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/tdoc_zip_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/testcase_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/scraping/wi_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/_duration.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/meetings_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/tdoc_cr_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/tdoc_file_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/tdoc_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/tdoc_sync_coordinator.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/testcase_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/tsg_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/services/wi_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/settings/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/settings/config_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/settings/loader.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/backends/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/cache.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/compression.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/db/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/db/base.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/db/fts5_query.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/db/migrations/README.md +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/db/testcase_base.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/export.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/meeting_sql.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/rich_filters.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/tdoc_cr_change_details_sql.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/tdoc_cr_sql.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/tdoc_cr_ttcn_sql.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/tdoc_file_sql.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/testcase_sql.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/tsg_sql.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/storage/repositories/wi_sql.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/filters.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/install.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/meetings.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/sync.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/tdocs.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/testcases.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/tsgs.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/routes/wis.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/htmx.min.js +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/js/job_poller.js +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/js/meeting_sync.js +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/js/search.js +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/js/spec_clipboard.js +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/js/spec_sync.js +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/js/tdoc_columns.js +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/static/js/tdoc_parse.js +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/job_status.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/landing.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/meeting_list.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/meeting_show.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/_job_row.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/job_status.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/meeting_filters.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/meeting_results.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/pagination.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/schema_results.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/sync_recent_jobs.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/tdoc_filters.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/tdoc_results.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/testcase_filters.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/testcase_results.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/wi_filters.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/partials/wi_results.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/schema.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/spec_list.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/tdoc_content.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/tdoc_list.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/tdoc_show.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/testcase_list.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/testcase_show.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/tsg_list.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/tsg_show.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates/wi_list.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/templates_setup.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/src/doc3gpp/web/workers/__init__.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/sample_pages/3GPP-meeting-R5.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/search_corpus.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/spec_pages/R5_crs.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/spec_pages/R5_detail.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/spec_pages/R5_detail_portal.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/spec_pages/R5_etsi.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/spec_pages/R5_list.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/tdoc_cr_doc/C6-250028.zip +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/tdoc_cr_doc/R5-227476.zip +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/tdoc_cr_doc/R5-253079.zip +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/tdoc_cr_doc/R5s260009.zip +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/tdoc_cr_doc/R5s260051.zip +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/tdoc_cr_doc/R5s260135.zip +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/tdoc_cr_doc/R5s260176.zip +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/tdoc_xlsx/TDoc_List_Meeting_85434_portal.xlsx +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/tdoc_xlsx/TDoc_List_Meeting_RAN5#111.xlsx +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/fixtures/wi_pages/R5.html +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_auto_sync_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_cli_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_config_set_cli_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_db_reset_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_embed_after_parse.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_meeting_service_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_migrate_tsg_spec_last_sync_drop.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_online_3gpp_calendar.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_online_spec_sync.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_online_tdoc_fetch_r5.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_online_tdoc_parse.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_online_testcase_sync.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_parse_tdoc_url_job_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_schema_parity.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_sdk_integration.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_after_parse.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_extras_disabled.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_index_lifecycle.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_indexes.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_schema.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_snippet_column.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_search_weighted_bm25.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_semantic_extras_disabled.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_spec_migration.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdoc_cr_change_details_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdoc_cr_rename_migration.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdoc_cr_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdoc_cr_ttcn_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdoc_file_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdoc_parse_direct_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdoc_parse_ftp_batch_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdoc_parse_local_batch_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdocs_xlsx_metadata_migration_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tdocs_xlsx_metadata_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_testcase_cli.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_testcase_sql.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_tsg_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_vector_schema_migration.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_web_end_to_end.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/integration/test_wi_sqlite.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/_job_polling_smoke.js +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_bind_job_polling_on_terminal.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_body_changes_extractor.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_cache_keys.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_calendar_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_calendar_parser_defensive.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_cli_auto_sync.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_cli_filters.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_cli_version.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_compact_helpers.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_config_init_cli.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_config_set_cli.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_config_writer.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_docx_converter.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_ftp_listing.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_fts5_query.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_job_row_partial.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_list_output_format.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_meeting_cli.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_meeting_cli_filters_combined.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_meeting_cli_invalid_fields.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_meeting_cli_location_filter.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_meeting_repository_combined_filters.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_meeting_repository_filters.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_meeting_repository_location_filter.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_meeting_repository_upsert.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_parse_tdoc_url_route.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_parsers_utils.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_portal_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_protocols_semantic.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_rrf.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_scraper_client.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_search_query_builder.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_search_settings.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_semantic_models.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_semantic_reranker.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_spec_orm.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_spec_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_spec_release.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_spec_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_storage_utils.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_cache.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_cli_fields.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_cr_change_details_model.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_cr_model.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_cr_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_cr_service_body_changes.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_cr_service_ftp_batch.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_file_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_file_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_file_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_parse_cli.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_parse_direct.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_parse_settings.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_parse_url_batch.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_repository_crud.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_repository_filters.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_service_sync.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_show_record.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_sync_cli.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_sync_coordinator.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_url_not_found.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tdoc_zip_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_testcase_model.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_testcase_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_testcase_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_testcase_source.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tsg_cli.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tsg_repository.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tsg_service.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_tsg_url_pattern.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_ttcn_functions.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_web_filters.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_web_install.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_web_template_filters.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_wi_cli.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_wi_parser.py +0 -0
- {doc3gpp-0.2.1 → doc3gpp-0.3.2}/tests/unit/test_wi_repository_filters.py +0 -0
doc3gpp-0.3.2/.superpowers/sdd/2026-09-24-spec-doc-metadata-and-portal-fix/final-fix-report.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Final Review Fix Report
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Implemented and committed as `c37f292` (`fix(spec-doc): close final metadata review gaps`).
|
|
6
|
+
|
|
7
|
+
The approved untracked implementation plan,
|
|
8
|
+
`docs/superpowers/plans/2026-09-24-spec-doc-metadata-and-portal-fix.md`, was not
|
|
9
|
+
modified or staged. Pre-existing worktree changes outside this final fix wave
|
|
10
|
+
were also left untouched.
|
|
11
|
+
|
|
12
|
+
## Findings Addressed
|
|
13
|
+
|
|
14
|
+
### FTS5 nullable metadata
|
|
15
|
+
|
|
16
|
+
`SQLAlchemySpecDocSearchRepository.upsert_for_version()` now preserves
|
|
17
|
+
`None` for nullable `sections` and `tables` instead of converting them to empty
|
|
18
|
+
strings. FTS5 `null` and `not-null` predicates therefore match the relational
|
|
19
|
+
chunk contract.
|
|
20
|
+
|
|
21
|
+
Added explicit integration coverage for both fields and all related rich-filter
|
|
22
|
+
branches:
|
|
23
|
+
|
|
24
|
+
- `null`
|
|
25
|
+
- `not-null`
|
|
26
|
+
- positive LIKE
|
|
27
|
+
- negated `!pattern`
|
|
28
|
+
- simultaneous `sections` and `tables` filters with AND semantics
|
|
29
|
+
|
|
30
|
+
### Overlap metadata scope
|
|
31
|
+
|
|
32
|
+
`chunk_blocks()` now tracks metadata at source-token granularity. When overlap
|
|
33
|
+
tokens are prepended, only metadata attached to the trailing token range is
|
|
34
|
+
merged into the following chunk. Ordered deduplication and current-chunk
|
|
35
|
+
metadata remain unchanged.
|
|
36
|
+
|
|
37
|
+
Regression coverage includes:
|
|
38
|
+
|
|
39
|
+
- a previous chunk with earlier and later section metadata where only the later
|
|
40
|
+
section overlaps;
|
|
41
|
+
- the equivalent table-overlap case;
|
|
42
|
+
- repeated section/table metadata deduplication.
|
|
43
|
+
|
|
44
|
+
Existing atomic-table, chunk-boundary, character-ceiling, file-tag, and empty
|
|
45
|
+
metadata behavior remains covered.
|
|
46
|
+
|
|
47
|
+
### Stable stale-only rebuild cutoff
|
|
48
|
+
|
|
49
|
+
`rebuild_batch(stale_only=True)` captures `last_indexed_parsed_at` once before
|
|
50
|
+
iterating batches and binds that stable cutoff for every page. Per-version
|
|
51
|
+
`upsert_for_version()` watermark updates can no longer remove older stale rows
|
|
52
|
+
from later pages.
|
|
53
|
+
|
|
54
|
+
The regression seeds two stale versions and rebuilds with `batch_size=1`; both
|
|
55
|
+
versions must be indexed.
|
|
56
|
+
|
|
57
|
+
### Configured cache path expansion
|
|
58
|
+
|
|
59
|
+
`SpecDocSettings.cache_dir` now applies `Path.expanduser()` after Pydantic
|
|
60
|
+
validation. TOML-style `~/.cache/doc3gpp/specs` values resolve under the user
|
|
61
|
+
home, while absolute explicit paths and the absolute default remain unchanged.
|
|
62
|
+
|
|
63
|
+
### Contract coverage
|
|
64
|
+
|
|
65
|
+
The final wave pins:
|
|
66
|
+
|
|
67
|
+
- exact `_SPEC_DOC_SNIPPET_COLUMNS` ordering;
|
|
68
|
+
- removal of all split chunk/hit/filter DTO fields;
|
|
69
|
+
- nullable FTS metadata behavior;
|
|
70
|
+
- complete rich-filter semantics for both combined metadata fields;
|
|
71
|
+
- overlap deduplication and table overlap;
|
|
72
|
+
- configured cache path behavior.
|
|
73
|
+
|
|
74
|
+
### Vector-side `release` semantics
|
|
75
|
+
|
|
76
|
+
The existing semantic implementation intentionally uses exact equality for
|
|
77
|
+
vector-side `spec_id`, `version`, and `release`, while vector-side `sections`
|
|
78
|
+
and `tables` use plain LIKE. The FTS side remains the rich-filter path.
|
|
79
|
+
|
|
80
|
+
This is now explicit and consistent in:
|
|
81
|
+
|
|
82
|
+
- `src/doc3gpp/storage/repositories/spec_doc_vector_sql.py`;
|
|
83
|
+
- `src/doc3gpp/services/spec_doc_semantic_service.py`;
|
|
84
|
+
- `docs/architecture.md`;
|
|
85
|
+
- `docs/cli.md`;
|
|
86
|
+
- `AGENTS.md`.
|
|
87
|
+
|
|
88
|
+
An optional sqlite-vec regression asserts that `release="Rel-18"` matches and
|
|
89
|
+
`release="Rel-1%"` does not, preserving the intentional exact contract.
|
|
90
|
+
|
|
91
|
+
## TDD Evidence
|
|
92
|
+
|
|
93
|
+
The new regression tests were written before production changes.
|
|
94
|
+
|
|
95
|
+
Initial red run:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
rtk pytest tests/unit/test_spec_doc_models.py tests/unit/test_spec_doc_settings.py tests/unit/test_spec_doc_chunker.py tests/integration/test_spec_doc_search_repo.py -q
|
|
99
|
+
Pytest: 33 passed, 7 failed
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The failures were the expected reviewer defects:
|
|
103
|
+
|
|
104
|
+
- configured `~` cache path stayed literal;
|
|
105
|
+
- section overlap copied the earlier metadata;
|
|
106
|
+
- table overlap copied the earlier metadata;
|
|
107
|
+
- nullable FTS filters returned no matching rows;
|
|
108
|
+
- stale-only batch size 1 indexed only one of two stale versions.
|
|
109
|
+
|
|
110
|
+
Green focused run after the minimal fixes:
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
rtk pytest tests/unit/test_spec_doc_models.py tests/unit/test_spec_doc_settings.py tests/unit/test_spec_doc_chunker.py tests/integration/test_spec_doc_search_repo.py -q
|
|
114
|
+
40 passed
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The covering spec-document/web/MCP run then passed:
|
|
118
|
+
|
|
119
|
+
```text
|
|
120
|
+
rtk pytest tests/unit/test_spec_doc_*.py tests/integration/test_spec_doc_*.py tests/unit/test_web_routes.py tests/integration/test_mcp_end_to_end.py -q
|
|
121
|
+
330 passed
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Verification
|
|
125
|
+
|
|
126
|
+
Full offline SQLite suite:
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
rtk ./scripts/test_sqlite.sh
|
|
130
|
+
2405 passed, 1 skipped, 109 warnings in 103.45s
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The skip is the existing optional-dependency skip. Existing collection and
|
|
134
|
+
datetime deprecation warnings remain; the stale-rebuild path also exercises the
|
|
135
|
+
project's existing `datetime.utcnow()` warning in
|
|
136
|
+
`spec_doc_search_service.py`.
|
|
137
|
+
|
|
138
|
+
Lint:
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
rtk ruff check .
|
|
142
|
+
clean, exit 0
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Whitespace:
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
rtk git diff --check
|
|
149
|
+
clean, exit 0
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The focused fix files also passed their targeted Ruff check before the full
|
|
153
|
+
gate.
|
|
154
|
+
|
|
155
|
+
## Files In Commit
|
|
156
|
+
|
|
157
|
+
- `AGENTS.md`
|
|
158
|
+
- `docs/architecture.md`
|
|
159
|
+
- `docs/cli.md`
|
|
160
|
+
- `src/doc3gpp/parsers/spec_doc_chunker.py`
|
|
161
|
+
- `src/doc3gpp/settings/schema.py`
|
|
162
|
+
- `src/doc3gpp/storage/repositories/spec_doc_search_sql.py`
|
|
163
|
+
- `tests/integration/test_spec_doc_search_repo.py`
|
|
164
|
+
- `tests/unit/test_spec_doc_chunker.py`
|
|
165
|
+
- `tests/unit/test_spec_doc_models.py`
|
|
166
|
+
- `tests/unit/test_spec_doc_settings.py`
|
|
167
|
+
|
|
168
|
+
No migration, public repair command, unrelated TDoc behavior, or generated
|
|
169
|
+
artifact was added.
|
|
170
|
+
|
|
171
|
+
## Concerns
|
|
172
|
+
|
|
173
|
+
- Vector-side semantic behavior was not changed from exact `release` matching;
|
|
174
|
+
the docs now state that contract instead of claiming release LIKE behavior.
|
|
175
|
+
- sqlite-vec-specific assertions are skipped when the optional extension is not
|
|
176
|
+
installed; the core FTS, chunker, cache, and stale-rebuild coverage is
|
|
177
|
+
extension-independent.
|
|
178
|
+
- The repository retains its pre-existing warning set, including UTC datetime
|
|
179
|
+
deprecations.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Task 2 Report
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
DONE_WITH_CONCERNS
|
|
6
|
+
|
|
7
|
+
## Files Changed
|
|
8
|
+
|
|
9
|
+
- `src/doc3gpp/parsers/docx_converter.py`
|
|
10
|
+
- Recognizes alphanumeric section identifiers such as `7.2A.3` and `7.2A.3A`.
|
|
11
|
+
- Recognizes table captions with 3GPP identifiers and colon, dash, or whitespace separators.
|
|
12
|
+
- Collapses caption whitespace while retaining caption paragraphs in the block stream.
|
|
13
|
+
- `src/doc3gpp/parsers/spec_doc.py`
|
|
14
|
+
- Adds a natural section sort key that compares numeric tokens numerically and alphabetic tokens case-insensitively.
|
|
15
|
+
- Preserves front-matter and unnumbered-file ordering rules.
|
|
16
|
+
- `tests/unit/test_spec_doc_blocks.py`
|
|
17
|
+
- Adds real in-memory `python-docx` tests for alphanumeric headings and table captions.
|
|
18
|
+
- `tests/unit/test_spec_doc_parser.py`
|
|
19
|
+
- Adds alphanumeric file-ordering and TOC preservation tests.
|
|
20
|
+
|
|
21
|
+
No chunker, ORM, search, web, or unrelated files were modified. `HeadingBlock.section_no`, `TableBlock.table_no/table_title`, and TOC split fields remain unchanged.
|
|
22
|
+
|
|
23
|
+
## TDD Verification
|
|
24
|
+
|
|
25
|
+
### Red
|
|
26
|
+
|
|
27
|
+
Command:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
rtk pytest tests/unit/test_spec_doc_blocks.py tests/unit/test_spec_doc_parser.py -v
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Result: `10 passed, 3 failed`.
|
|
34
|
+
|
|
35
|
+
The three expected failures were:
|
|
36
|
+
|
|
37
|
+
- `test_heading_accepts_alphanumeric_section_suffixes`: the numeric-only section regex returned `None`.
|
|
38
|
+
- `test_table_caption_accepts_3gpp_identifier_and_separator`: the numeric-only caption regex returned no table number.
|
|
39
|
+
- `test_order_numbered_files_handles_alphanumeric_sections`: the numeric-only `_first_section` path could not order the alphanumeric section.
|
|
40
|
+
|
|
41
|
+
### Green
|
|
42
|
+
|
|
43
|
+
Command:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
rtk pytest tests/unit/test_spec_doc_blocks.py tests/unit/test_spec_doc_parser.py -v
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Result: `13 passed`.
|
|
50
|
+
|
|
51
|
+
Additional checks:
|
|
52
|
+
|
|
53
|
+
- `rtk ruff check src/doc3gpp/parsers/docx_converter.py src/doc3gpp/parsers/spec_doc.py tests/unit/test_spec_doc_blocks.py tests/unit/test_spec_doc_parser.py`: no findings.
|
|
54
|
+
- `rtk git diff HEAD^ HEAD --check`: clean.
|
|
55
|
+
|
|
56
|
+
The broader command `rtk pytest tests/unit/test_spec_doc_*.py -v` reports `34 passed, 5 failed`. The five failures are existing Task 3 chunker failures caused by the Task 1 `ChunkDraft` contract change before the chunker has been updated; they are outside this task and were not changed.
|
|
57
|
+
|
|
58
|
+
## Commit
|
|
59
|
+
|
|
60
|
+
- Hash: `b00a2eb`
|
|
61
|
+
- Message: `fix(spec-doc): recognize alphanumeric sections and tables`
|
|
62
|
+
|
|
63
|
+
## Self-Review Findings
|
|
64
|
+
|
|
65
|
+
- No Task 2 defects found in the focused review.
|
|
66
|
+
- The heading regex requires an identifier to start with a digit, permits alphanumeric dotted components, and still requires following whitespace.
|
|
67
|
+
- Caption parsing supports the requested identifier and separator forms, normalizes whitespace, and leaves caption paragraphs as `ParagraphBlock` entries.
|
|
68
|
+
- Natural sorting uses token types that are safe to compare in Python tuple ordering and keeps numeric section ordering natural (`7.2` before `7.10`).
|
|
69
|
+
- Existing numeric-section, front-matter, unnumbered-file, and TOC tests remain green.
|
|
70
|
+
- The commit contains only the four files specified by the Task 2 brief.
|
|
71
|
+
|
|
72
|
+
## Concerns
|
|
73
|
+
|
|
74
|
+
- The full spec-document unit-test glob is not green until the planned Task 3 chunker implementation updates its constructors and metadata handling for the Task 1 DTO contract. This was intentionally left untouched to preserve Task 2 scope.
|
|
75
|
+
- The approved plan file `docs/superpowers/plans/2026-09-24-spec-doc-metadata-and-portal-fix.md` remains pre-existing and untracked; it was not added to the Task 2 commit.
|
|
76
|
+
|
|
77
|
+
## Fix Round: Alphanumeric Hyphenated Table Suffixes
|
|
78
|
+
|
|
79
|
+
### Finding Addressed
|
|
80
|
+
|
|
81
|
+
The table-caption identifier grammar previously allowed only numeric suffixes after
|
|
82
|
+
the hyphen. It split identifiers such as `4.4.2-1A` and `4.6.1-4.0A` before the
|
|
83
|
+
suffix. The grammar now permits alphanumeric and dotted components after the
|
|
84
|
+
hyphen, while retaining the existing base identifier rules.
|
|
85
|
+
|
|
86
|
+
The real in-memory DOCX regression coverage now parameterizes colon, dash, and
|
|
87
|
+
whitespace separators for table captions, covers both reviewed identifiers, and
|
|
88
|
+
asserts that the caption remains a `ParagraphBlock` in the block stream.
|
|
89
|
+
|
|
90
|
+
### TDD Verification
|
|
91
|
+
|
|
92
|
+
Red command:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
rtk pytest tests/unit/test_spec_doc_blocks.py tests/unit/test_spec_doc_parser.py -v
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Result: `13 passed, 2 failed`. The two new hyphenated-suffix cases failed with
|
|
99
|
+
the old numeric-only suffix grammar; for example, `4.4.2-1A` was parsed as
|
|
100
|
+
`4.4.2`.
|
|
101
|
+
|
|
102
|
+
Green command:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
rtk pytest tests/unit/test_spec_doc_blocks.py tests/unit/test_spec_doc_parser.py -v
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Result: `15 passed`.
|
|
109
|
+
|
|
110
|
+
Targeted lint:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
rtk ruff check src/doc3gpp/parsers/docx_converter.py src/doc3gpp/parsers/spec_doc.py tests/unit/test_spec_doc_blocks.py tests/unit/test_spec_doc_parser.py
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Result: no findings.
|
|
117
|
+
|
|
118
|
+
### Fix Commit
|
|
119
|
+
|
|
120
|
+
- Hash: `1836c50`
|
|
121
|
+
- Message: `fix(spec-doc): accept alphanumeric table suffixes`
|
|
122
|
+
|
|
123
|
+
### Remaining Concerns
|
|
124
|
+
|
|
125
|
+
- The broader `rtk pytest tests/unit/test_spec_doc_*.py -v` scope still has the
|
|
126
|
+
previously recorded five Task 3 chunker failures caused by the Task 1 DTO
|
|
127
|
+
contract; no unrelated chunker changes were made in this fix round.
|
|
128
|
+
- The pre-existing untracked plan file remains untracked and was not included in
|
|
129
|
+
either fix commit.
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# Final Review Fix Report
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
This fix wave addresses the final review findings for the spec-document web
|
|
6
|
+
portal branch at `9e44230`. The pre-existing untracked approved plan,
|
|
7
|
+
`docs/superpowers/plans/2026-09-24-spec-doc-web-portal.md`, was not modified or
|
|
8
|
+
staged.
|
|
9
|
+
|
|
10
|
+
## Files Changed
|
|
11
|
+
|
|
12
|
+
- `src/doc3gpp/storage/repositories/spec_doc_sql.py`
|
|
13
|
+
- Removed the `parsed_at` and `chunk_count` success-state mutation from
|
|
14
|
+
`replace_chunks()`.
|
|
15
|
+
- `record_parsed()` is now the only repository operation that marks a source
|
|
16
|
+
parsed or records its final chunk count.
|
|
17
|
+
- `tests/integration/test_spec_doc_service.py`
|
|
18
|
+
- Added a regression test that fails the markdown-cache write after chunks
|
|
19
|
+
are stored, verifies `parsed_at` remains unset, and verifies a subsequent
|
|
20
|
+
non-force parse succeeds rather than being skipped.
|
|
21
|
+
- `tests/integration/test_spec_doc_repo.py`
|
|
22
|
+
- Updated the repository round-trip to assert that chunk replacement alone
|
|
23
|
+
leaves the source unparsed, then explicitly records the successful parse.
|
|
24
|
+
- Added coverage that direct chunk replacement still creates an explicitly
|
|
25
|
+
unparsed source row when no source row exists.
|
|
26
|
+
- `src/doc3gpp/web/templates/spec_doc_show.html`
|
|
27
|
+
- Hides the force checkbox unless the source is parsed.
|
|
28
|
+
- Adds an explicit parsed-state data attribute for defensive client logic.
|
|
29
|
+
- `src/doc3gpp/web/static/js/spec_doc_parse.js`
|
|
30
|
+
- Forces the submitted `force` value to `false` unless the form declares a
|
|
31
|
+
parsed source, even if a stale or injected checkbox is present.
|
|
32
|
+
- `src/doc3gpp/web/templates/partials/spec_doc_show_results.html`
|
|
33
|
+
- Renders the stored TOC file summary, including source filename, file order,
|
|
34
|
+
and first section.
|
|
35
|
+
- `src/doc3gpp/web/templates/partials/spec_doc_chunks.html`
|
|
36
|
+
- Distinguishes a parsed zero-chunk source from a non-matching section
|
|
37
|
+
filter.
|
|
38
|
+
- `tests/unit/test_web_routes.py`
|
|
39
|
+
- Covers force-control availability for unparsed and parsed states, the TOC
|
|
40
|
+
file summary, the zero-chunk message, and the JS parsed-state guard.
|
|
41
|
+
- `docs/web-server.md`
|
|
42
|
+
- Clarifies that the endpoint accepts optional `release`, while the version
|
|
43
|
+
page form submits `spec_ids`, the selected exact `version`, and `force`
|
|
44
|
+
without a release selector.
|
|
45
|
+
|
|
46
|
+
## Tests And Commands
|
|
47
|
+
|
|
48
|
+
- `rtk pytest tests/integration/test_spec_doc_service.py -k post_chunk_cache_failure -q`
|
|
49
|
+
- Initial TDD red run: failed because `replace_chunks()` had already set
|
|
50
|
+
`parsed_at`; this confirmed the regression exercised the reported bug.
|
|
51
|
+
- `rtk pytest tests/integration/test_spec_doc_service.py tests/integration/test_spec_doc_repo.py -q`
|
|
52
|
+
- `10 passed`.
|
|
53
|
+
- `rtk pytest tests/unit/test_web_routes.py -k 'spec_doc_show or spec_doc_parse_js' -q`
|
|
54
|
+
- `8 passed`.
|
|
55
|
+
- `rtk pytest tests/unit/test_spec_doc_service_reads.py tests/unit/test_spec_doc_source.py tests/integration/test_spec_doc_service.py tests/integration/test_spec_doc_repo.py tests/integration/test_spec_doc_search_repo.py tests/integration/test_spec_doc_search_service.py tests/integration/test_spec_doc_web.py tests/unit/test_web_routes.py tests/unit/web/test_landing_version.py -q`
|
|
56
|
+
- `225 passed`.
|
|
57
|
+
- `rtk pytest tests/integration/test_spec_doc_cli.py tests/unit/test_spec_doc_settings.py tests/unit/test_spec_doc_models.py tests/unit/test_spec_doc_parser.py tests/unit/test_spec_doc_chunker.py -q`
|
|
58
|
+
- `23 passed`.
|
|
59
|
+
- `rtk ./scripts/test_sqlite.sh`
|
|
60
|
+
- `2356 passed, 1 skipped, 108 warnings`.
|
|
61
|
+
- Warnings are the repository's existing pytest collection and deprecation
|
|
62
|
+
warnings; no test failures occurred.
|
|
63
|
+
- `rtk ruff check .`
|
|
64
|
+
- Clean.
|
|
65
|
+
- `rtk git diff --check`
|
|
66
|
+
- Clean.
|
|
67
|
+
|
|
68
|
+
## Self-Review
|
|
69
|
+
|
|
70
|
+
- A failed parse after chunk replacement and before markdown-cache completion
|
|
71
|
+
no longer creates a false successful parse marker. The retry path uses the
|
|
72
|
+
existing ZIP cache and reaches `record_parsed()` normally.
|
|
73
|
+
- Existing force re-parse behavior remains available for parsed sources. The
|
|
74
|
+
browser checkbox is absent for unparsed/downloaded sources, and the client
|
|
75
|
+
independently clamps `force` to `false` in that state.
|
|
76
|
+
- The version page's TOC now includes the complete stored file summary using
|
|
77
|
+
the same fields as the existing standalone TOC page.
|
|
78
|
+
- A parsed source with `chunk_count == 0` gets an incomplete/corrupt/zero-chunk
|
|
79
|
+
message. A parsed source with chunks but no rows after filtering retains the
|
|
80
|
+
filter-empty message.
|
|
81
|
+
- The documentation now separates endpoint query support from the form's
|
|
82
|
+
exact-version job payload.
|
|
83
|
+
- No CLI, MCP, JSON, schema, or job contract was changed.
|
|
84
|
+
- No direct semantic nested-hit route test was added; this remains the
|
|
85
|
+
explicitly accepted test-only residual from the prior review.
|
|
86
|
+
|
|
87
|
+
## Concerns
|
|
88
|
+
|
|
89
|
+
- TOC persistence, chunk replacement, filesystem cache writes, and the parsed
|
|
90
|
+
ledger remain separate operations because the existing repository architecture
|
|
91
|
+
does not provide one cross-storage transaction. A failed attempt can leave
|
|
92
|
+
intermediate TOC/chunk/cache data, but `parsed_at` remains unset and the
|
|
93
|
+
next parse replaces those intermediates before recording success.
|
|
94
|
+
- The full suite retains the existing 108 warnings noted above; they are not
|
|
95
|
+
introduced by this fix wave.
|
|
96
|
+
|
|
97
|
+
## Fix Round 2
|
|
98
|
+
|
|
99
|
+
### Finding Addressed
|
|
100
|
+
|
|
101
|
+
A forced re-parse of an already parsed version could leave the old non-null
|
|
102
|
+
`parsed_at` marker in place when post-chunk/cache work failed. A later
|
|
103
|
+
non-force parse then treated the failed re-parse as an immutable success and
|
|
104
|
+
skipped it.
|
|
105
|
+
|
|
106
|
+
### Files Changed
|
|
107
|
+
|
|
108
|
+
- `src/doc3gpp/storage/repositories/spec_doc_sql.py`
|
|
109
|
+
- `record_download()` now clears `parsed_at` and resets `chunk_count` when
|
|
110
|
+
refreshing an existing source row. This invalidates the previous success
|
|
111
|
+
marker at the force-download boundary while preserving the existing method
|
|
112
|
+
signature and repository flow.
|
|
113
|
+
- `tests/integration/test_spec_doc_service.py`
|
|
114
|
+
- Added coverage that parses a version successfully, forces a re-parse that
|
|
115
|
+
fails during markdown-cache writing, verifies the old marker is cleared,
|
|
116
|
+
and verifies a subsequent non-force parse succeeds.
|
|
117
|
+
- `.superpowers/sdd/2026-09-24-spec-doc-web-portal/final-fix-report.md`
|
|
118
|
+
- Appended this fix-round record. The approved untracked plan remains
|
|
119
|
+
untouched and unstaged.
|
|
120
|
+
|
|
121
|
+
### Tests And Commands
|
|
122
|
+
|
|
123
|
+
- `rtk pytest tests/integration/test_spec_doc_service.py -k 'failed_force_reparse_invalidates_old_marker_for_retry or post_chunk_cache_failure or force_reparses' -q`
|
|
124
|
+
- `3 passed`.
|
|
125
|
+
- `rtk pytest tests/integration/test_spec_doc_repo.py -q`
|
|
126
|
+
- `2 passed`.
|
|
127
|
+
- `rtk pytest tests/integration/test_spec_doc_service.py tests/integration/test_spec_doc_repo.py tests/integration/test_spec_doc_search_repo.py tests/integration/test_spec_doc_search_service.py tests/integration/test_spec_doc_web.py tests/unit/test_spec_doc_service_reads.py tests/unit/test_web_routes.py tests/unit/web/test_landing_version.py -q`
|
|
128
|
+
- `220 passed`.
|
|
129
|
+
- `rtk ./scripts/test_sqlite.sh`
|
|
130
|
+
- `2357 passed, 1 skipped, 108 warnings`.
|
|
131
|
+
- `rtk ruff check .`
|
|
132
|
+
- Clean.
|
|
133
|
+
- `rtk git diff --check`
|
|
134
|
+
- Clean.
|
|
135
|
+
|
|
136
|
+
### Self-Review
|
|
137
|
+
|
|
138
|
+
- A successful force re-parse still reaches `record_parsed()` and restores a
|
|
139
|
+
non-null marker with the new chunk count.
|
|
140
|
+
- A non-force immutable skip does not call `record_download()` when the ZIP
|
|
141
|
+
cache and parsed source already exist, so existing skip behavior is
|
|
142
|
+
unchanged.
|
|
143
|
+
- If a forced download or a cache-miss download replaces an existing source,
|
|
144
|
+
its previous success marker is invalidated before parse work begins; any
|
|
145
|
+
later failure therefore remains retryable.
|
|
146
|
+
- `record_parsed()` remains the only operation that marks a source as
|
|
147
|
+
successfully parsed.
|
|
148
|
+
- The fix changes no schema, service signature, CLI, HTTP, MCP, or job
|
|
149
|
+
contract.
|
|
150
|
+
|
|
151
|
+
### Concerns
|
|
152
|
+
|
|
153
|
+
- As in the first fix round, TOC/chunk/cache writes and the source ledger use
|
|
154
|
+
separate repository/filesystem transactions. A failed force re-parse may
|
|
155
|
+
leave intermediate replacement data, but the source remains unparsed and a
|
|
156
|
+
subsequent retry replaces those intermediates before recording success.
|
|
157
|
+
- The full suite retains the existing 108 warnings; no new warning category
|
|
158
|
+
was introduced by this round.
|
|
159
|
+
|
|
160
|
+
## Fix Round 3
|
|
161
|
+
|
|
162
|
+
### Finding Addressed
|
|
163
|
+
|
|
164
|
+
The round-2 placement was still too late for a forced network failure:
|
|
165
|
+
`SpecDocService.fetch(force=True)` called `_fetcher()` before
|
|
166
|
+
`record_download()`, so a failed download left an already parsed source's old
|
|
167
|
+
`parsed_at` marker intact. The final fix invalidates parse state before the
|
|
168
|
+
forced fetch, without recording a download that did not succeed.
|
|
169
|
+
|
|
170
|
+
### TDD Failing-Test Evidence
|
|
171
|
+
|
|
172
|
+
Added `test_failed_force_download_invalidates_old_marker_for_retry` to
|
|
173
|
+
`tests/integration/test_spec_doc_service.py`. The first focused run was:
|
|
174
|
+
|
|
175
|
+
```text
|
|
176
|
+
rtk pytest tests/integration/test_spec_doc_service.py -k failed_force_download_invalidates_old_marker_for_retry -q
|
|
177
|
+
Pytest: 0 passed, 1 failed
|
|
178
|
+
AssertionError: source.parsed_at is None
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The failure reproduced the confirmed root cause: the source remained parsed
|
|
182
|
+
after the forced `_fetcher()` raised `OSError("upstream unavailable")`.
|
|
183
|
+
|
|
184
|
+
### Files Changed
|
|
185
|
+
|
|
186
|
+
- `src/doc3gpp/repository/protocols.py`
|
|
187
|
+
- Added the clearly named `SpecDocRepository.invalidate_parse_state()`
|
|
188
|
+
operation.
|
|
189
|
+
- `src/doc3gpp/storage/repositories/spec_doc_sql.py`
|
|
190
|
+
- Implemented `invalidate_parse_state()` as a committed update of only
|
|
191
|
+
`parsed_at` and `chunk_count` for an existing source row.
|
|
192
|
+
- Kept `record_download()` responsible for successful-download metadata;
|
|
193
|
+
it no longer doubles as parse-state invalidation.
|
|
194
|
+
- `src/doc3gpp/services/spec_doc_service.py`
|
|
195
|
+
- On `force=True`, resolves the existing source and invalidates its parse
|
|
196
|
+
state before invoking `_fetcher()`.
|
|
197
|
+
- Does nothing for a missing source, preserving the first-download path.
|
|
198
|
+
- `tests/integration/test_spec_doc_service.py`
|
|
199
|
+
- Added the required already-parsed, forced-network-failure, then
|
|
200
|
+
non-force-retry regression.
|
|
201
|
+
- `tests/integration/test_spec_doc_repo.py`
|
|
202
|
+
- Verifies explicit invalidation clears only parse state while preserving
|
|
203
|
+
release, FTP URL, download timestamp, and DOCX count.
|
|
204
|
+
- `.superpowers/sdd/2026-09-24-spec-doc-web-portal/final-fix-report.md`
|
|
205
|
+
- Appended this round-3 record. The approved untracked plan remains
|
|
206
|
+
untouched and unstaged.
|
|
207
|
+
|
|
208
|
+
### Tests And Commands
|
|
209
|
+
|
|
210
|
+
- `rtk pytest tests/integration/test_spec_doc_service.py -k failed_force_download_invalidates_old_marker_for_retry -q`
|
|
211
|
+
- Initial TDD red run: `0 passed, 1 failed`, with the expected stale
|
|
212
|
+
`parsed_at` assertion failure.
|
|
213
|
+
- `rtk pytest tests/integration/test_spec_doc_service.py -k 'failed_force_download_invalidates_old_marker_for_retry or failed_force_reparse_invalidates_old_marker_for_retry or post_chunk_cache_failure or force_reparses' -q`
|
|
214
|
+
- `4 passed` after the fix.
|
|
215
|
+
- `rtk pytest tests/integration/test_spec_doc_repo.py -q`
|
|
216
|
+
- `2 passed`.
|
|
217
|
+
- `rtk pytest tests/integration/test_spec_doc_service.py tests/integration/test_spec_doc_repo.py tests/integration/test_spec_doc_search_repo.py tests/integration/test_spec_doc_search_service.py tests/integration/test_spec_doc_web.py tests/unit/test_spec_doc_service_reads.py tests/unit/test_web_routes.py tests/unit/web/test_landing_version.py -q`
|
|
218
|
+
- `221 passed`.
|
|
219
|
+
- `rtk ./scripts/test_sqlite.sh`
|
|
220
|
+
- `2358 passed, 1 skipped, 108 warnings`.
|
|
221
|
+
- `rtk ruff check .`
|
|
222
|
+
- Clean.
|
|
223
|
+
- `rtk git diff --check`
|
|
224
|
+
- Clean.
|
|
225
|
+
|
|
226
|
+
### Self-Review
|
|
227
|
+
|
|
228
|
+
- A forced re-parse with an existing source clears the success marker before
|
|
229
|
+
any network, ZIP-size, cache-write, or parse operation can fail.
|
|
230
|
+
- The invalidation operation preserves truthful download metadata and does not
|
|
231
|
+
create a source row or claim that a forced download succeeded.
|
|
232
|
+
- Successful force re-parse still runs `record_download()` after bytes arrive,
|
|
233
|
+
then `record_parsed()` after all required parse/cache work completes.
|
|
234
|
+
- A non-force immutable skip does not call the invalidation operation because
|
|
235
|
+
it returns through the existing cache/parsed check without entering the
|
|
236
|
+
forced path.
|
|
237
|
+
- First-parse failures and the prior post-chunk/cache failure regression remain
|
|
238
|
+
covered and retryable.
|
|
239
|
+
- The round-2 reset inside `record_download()` was removed; round 3 replaces
|
|
240
|
+
that late invalidation with the explicit pre-fetch operation requested by the
|
|
241
|
+
review.
|
|
242
|
+
- No web portal behavior, schema, job payload, CLI contract, or public service
|
|
243
|
+
signature changed.
|
|
244
|
+
|
|
245
|
+
### Concerns
|
|
246
|
+
|
|
247
|
+
- Parse-state invalidation and the later network/cache/parse work remain
|
|
248
|
+
separate transactions under the existing repository architecture. After a
|
|
249
|
+
forced network failure, prior download metadata and cached bytes remain, but
|
|
250
|
+
`parsed_at` is intentionally null so the source is not treated as a
|
|
251
|
+
successful parse and the next non-force run retries.
|
|
252
|
+
- A failure after TOC/chunk replacement can still leave intermediate data; the
|
|
253
|
+
existing retry path replaces it before `record_parsed()` marks success.
|
|
254
|
+
- The full suite retains the existing 108 warnings; no new warning category
|
|
255
|
+
was introduced by this round.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Task 2 Report: Add Spec Document Version Read Page
|
|
2
|
+
|
|
3
|
+
## Files Changed
|
|
4
|
+
|
|
5
|
+
- `src/doc3gpp/web/routes/spec_docs.py`
|
|
6
|
+
- Added `GET /specs/{spec_id}/docs` before the existing TOC route.
|
|
7
|
+
- Resolves the parent spec and exact requested version through the injected `SpecService`.
|
|
8
|
+
- Reads source, TOC, and chunks only through `SpecDocService.get_source`, `get_toc`, and `list_chunks`.
|
|
9
|
+
- Supports release/section filters, bounded chunk pagination, one-row probe fetching, and HTMX `#results` fragments.
|
|
10
|
+
- Preserves the existing error mapping for missing specs, missing versions, disabled spec-doc services, and invalid query values.
|
|
11
|
+
- `src/doc3gpp/web/templates/spec_doc_show.html`
|
|
12
|
+
- Added the full version document page with spec/version identity, parent-spec link, source links, and metadata.
|
|
13
|
+
- `src/doc3gpp/web/templates/partials/spec_doc_show_results.html`
|
|
14
|
+
- Added the `#results` fragment with source state, parsed metadata, TOC, and chunk composition.
|
|
15
|
+
- `src/doc3gpp/web/templates/partials/spec_doc_chunks.html`
|
|
16
|
+
- Added chunk cards, section/table metadata, source filenames, preformatted text, and filter-preserving pagination.
|
|
17
|
+
- `src/doc3gpp/web/static/style.css`
|
|
18
|
+
- Added responsive source/chunk page styles while reusing existing portal primitives.
|
|
19
|
+
- `tests/unit/test_web_routes.py`
|
|
20
|
+
- Added fake public spec-document service data and focused tests for unparsed state, parsed TOC/chunks, probe pagination, HTMX fragments, and unknown versions.
|
|
21
|
+
- `.superpowers/sdd/2026-09-24-spec-doc-web-portal/task-2-report.md`
|
|
22
|
+
- Added this report.
|
|
23
|
+
|
|
24
|
+
The pre-existing untracked `docs/superpowers/plans/2026-09-24-spec-doc-web-portal.md` was not modified or staged.
|
|
25
|
+
|
|
26
|
+
## Tests And Commands
|
|
27
|
+
|
|
28
|
+
- `rtk pytest tests/unit/test_web_routes.py -k "spec_doc_show" -q`
|
|
29
|
+
- Initial TDD red run: `0 passed, 5 failed`; the expected failure was HTTP 404 because the new route did not yet exist.
|
|
30
|
+
- `rtk pytest tests/unit/test_web_routes.py -k "spec_doc_show" -q`
|
|
31
|
+
- Final result: `5 passed`.
|
|
32
|
+
- `rtk pytest tests/integration/test_spec_doc_web.py -q`
|
|
33
|
+
- Final result: `3 passed`.
|
|
34
|
+
- `rtk pytest tests/unit/test_web_routes.py -q`
|
|
35
|
+
- Final result: `178 passed`.
|
|
36
|
+
- `rtk ruff check src/doc3gpp/web/routes/spec_docs.py tests/unit/test_web_routes.py`
|
|
37
|
+
- Final result: clean (`[]`).
|
|
38
|
+
- `rtk git diff --check`
|
|
39
|
+
- Final result: clean.
|
|
40
|
+
- `rtk pytest`
|
|
41
|
+
- Collection did not start because three existing integration/unit modules import `tests.integration.test_web_end_to_end` and the plain executable entry point did not expose the repository root as the `tests` package (`3 ModuleNotFoundError` collection errors).
|
|
42
|
+
- `rtk python -m pytest -q`
|
|
43
|
+
- Final result: `2346 passed, 1 skipped, 10 deselected, 18 warnings` in `401.75s`.
|
|
44
|
+
- `rtk grep '_doc_repo|fetch|parse form|spec-doc-parse-form|jobs/parse' src/doc3gpp/web/routes/spec_docs.py`
|
|
45
|
+
- Final result: no route/private-repository/fetch/parse-control matches.
|
|
46
|
+
|
|
47
|
+
## Self-Review
|
|
48
|
+
|
|
49
|
+
- The route is registered before `/specs/{spec_id}/docs/toc`, so the static TOC path remains reachable.
|
|
50
|
+
- Exact version identity is verified after `SpecService.list_versions(..., version=version)`; unknown versions include available version strings in the normal 404 envelope.
|
|
51
|
+
- `parsed_at` is the authoritative gate: unparsed or missing source rows do not trigger TOC/chunk reads.
|
|
52
|
+
- A missing TOC for an otherwise parsed source is treated as absent while chunks continue to render, as required.
|
|
53
|
+
- Pagination requests `limit + 1`, renders only `limit`, and preserves `version`, `release`, and `section` in next/previous links.
|
|
54
|
+
- HTMX responses render only `partials/spec_doc_show_results.html` with the required outer `#results` element.
|
|
55
|
+
- No JSON contract, storage schema, CLI, MCP, fetch route, version-table link, or synchronous parse behavior was added or changed.
|
|
56
|
+
- The direct task instruction defers parse controls to Task 3, so the page intentionally renders read/source state without a parse form or parse JavaScript despite the broader plan's future parse-form design.
|
|
57
|
+
- Tests use the public `SpecDocService` surface and do not access `_doc_repo`.
|
|
58
|
+
|
|
59
|
+
## Concerns
|
|
60
|
+
|
|
61
|
+
- The page currently has no parse action by design; Task 3 must add the parse form/job poller integration.
|
|
62
|
+
- The pre-existing untracked plan file remains in the worktree and was intentionally left untouched.
|