09e9f3545f
CodeQL / Analyze (push) Waiting to run
dependency-audit / pip-audit (push) Waiting to run
Test / Code Quality (push) Has been cancelled
Test / Test (macos-latest, Python 3.10) (push) Has been cancelled
Test / Test (macos-latest, Python 3.11) (push) Has been cancelled
Test / Test (macos-latest, Python 3.12) (push) Has been cancelled
Test / Test (macos-latest, Python 3.13) (push) Has been cancelled
Test / Test (macos-latest, Python 3.14) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.10) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.11) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.12) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.13) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.14) (push) Has been cancelled
Test / Test (windows-latest, Python 3.10) (push) Has been cancelled
Test / Test (windows-latest, Python 3.11) (push) Has been cancelled
Test / Test (windows-latest, Python 3.12) (push) Has been cancelled
Test / Test (windows-latest, Python 3.13) (push) Has been cancelled
Test / Test (windows-latest, Python 3.14) (push) Has been cancelled
410 lines
16 KiB
Python
410 lines
16 KiB
Python
#!/usr/bin/env python3
|
|
"""Strip internal audit-tracker references from comments, docstrings, and markdown.
|
|
|
|
Conservative bulk pass: only drops *parenthetical* ID references that ride
|
|
alongside prose and a small number of whole-sentence meta-commentary lines
|
|
that introduce the now-removed ID convention. Inline noun-form refs (e.g.
|
|
``T7.F2:`` at the start of a comment, ``audit §27 failure #1`` mid-sentence,
|
|
``Pre-T7.F4``) are intentionally left for targeted hand edits because the
|
|
surrounding sentence needs rewriting.
|
|
|
|
Whitespace is preserved outside the deleted-token regions; the script never
|
|
collapses runs of whitespace or reformats multi-line constructs.
|
|
|
|
The script is run repeatedly across the cleanup phases (Phase 1: src/, docs/,
|
|
CHANGELOG, pyproject, CLAUDE.md; Phase 2: tests/).
|
|
Each invocation is restricted to a phase-specific allow-list of file paths so
|
|
that one phase's run cannot accidentally edit another phase's files.
|
|
|
|
Usage::
|
|
|
|
python scripts/_strip_audit_refs.py phase1
|
|
python scripts/_strip_audit_refs.py phase2
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Pattern definitions
|
|
# ---------------------------------------------------------------------------
|
|
|
|
T_ID = r"T\d+\.[A-Z][0-9a-z]*"
|
|
PR_T_ID = r"PR-" + T_ID
|
|
PHASE_T_ID = r"P\d+\.T\d+"
|
|
AUDIT_SEC = r"audit §\d+[a-z]?"
|
|
AUDIT_ROW = r"audit row [A-Z]?\d+[A-Za-z0-9]*"
|
|
AUDIT_SECTION = r"audit section \d+"
|
|
# CLI UX audit row IDs (``cli-ux-audit.md``): C1, C2, I1..I16, M1..M5.
|
|
# Match in parentheticals only; the bare letters are too common to strip
|
|
# unconditionally.
|
|
CLI_UX_ROW_ID = r"(?:[ICM]\d+(?:,\s*[ICM]\d+)*)"
|
|
# Phase markers (e.g. ``F8.T4``) used to coordinate landed-in-arc work.
|
|
PHASE_F_ID = r"F\d+\.T\d+"
|
|
|
|
|
|
# Parenthetical patterns — order matters: longest/most-specific first.
|
|
PAREN_PATTERNS: list[tuple[str, str]] = [
|
|
# Combined inside one parens, with / or , separators
|
|
(rf" \({T_ID}\s*[/,]\s*{AUDIT_SEC}\)", ""),
|
|
(rf" \({AUDIT_SEC}\s*[/,]\s*{T_ID}\)", ""),
|
|
(rf" \({T_ID}\s*[/,]\s*{AUDIT_SECTION}\)", ""),
|
|
(rf" \({AUDIT_SECTION}\s*[/,]\s*{T_ID}\)", ""),
|
|
# T + audit-section with extra tail text inside parens
|
|
(rf" \({T_ID}\s+{AUDIT_SEC}(?:[^()]*)?\)", ""),
|
|
(rf" \({AUDIT_SEC}\s+{T_ID}(?:[^()]*)?\)", ""),
|
|
# Audit-section failure-numbered variant: (audit §27 failure #1)
|
|
(rf" \({AUDIT_SEC}\s+failure\s+#\d+\)", ""),
|
|
# Standalone audit-row, audit-section, audit-§
|
|
(rf" \({AUDIT_ROW}(?:[^()]*)?\)", ""),
|
|
(rf" \({AUDIT_SECTION}\)", ""),
|
|
(rf" \({AUDIT_SEC}\)", ""),
|
|
# Standalone T-tier and PR-T (must come last to avoid stealing combined matches)
|
|
(rf" \({T_ID}\)", ""),
|
|
(rf" \({PR_T_ID}\)", ""),
|
|
(rf" \({PHASE_T_ID}\)", ""),
|
|
(rf" \({PHASE_F_ID}\)", ""),
|
|
# CLI UX audit row IDs in parentheticals (cli-ux-audit.md):
|
|
# ``(I1)``, ``(I3, I4)``, ``(C1)``, ``(M2)``, etc.
|
|
(rf" \({CLI_UX_ROW_ID}\)", ""),
|
|
# Phase task ID paired with a CLI-UX row ID, with or without leading
|
|
# ``-`` and with a ``/`` separator: ``(P5.T2 / I7)``, ``(M2 / P5.T3)``.
|
|
(rf" \({PHASE_T_ID}\s*/\s*{CLI_UX_ROW_ID}\)", ""),
|
|
(rf" \({CLI_UX_ROW_ID}\s*/\s*{PHASE_T_ID}\)", ""),
|
|
# Multi-section audit references: ``(audit §§13, 15, 16, 21)``.
|
|
(r" \(audit §§\d+(?:,\s*\d+)*\)", ""),
|
|
]
|
|
|
|
|
|
# Whole-sentence patterns that read as meta-commentary about the audit tags.
|
|
SENTENCE_PATTERNS: list[tuple[str, str]] = [
|
|
(
|
|
r"\s*Per-arc audit IDs \([^)]*\) are noted in parentheses on each non-cli-ux entry\.",
|
|
"",
|
|
),
|
|
(
|
|
r"\s*Audit-row IDs from `\.sisyphus/plans/cli-ux-audit\.md` \([^)]*\) are noted in parentheses on each entry\.",
|
|
"",
|
|
),
|
|
]
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Phase scopes
|
|
# ---------------------------------------------------------------------------
|
|
|
|
PHASE_1_FILES: list[str] = [
|
|
# src/notebooklm/**/*.py
|
|
"src/notebooklm/__init__.py",
|
|
"src/notebooklm/_artifacts.py",
|
|
"src/notebooklm/_auth/cookie_policy.py",
|
|
"src/notebooklm/_auth/storage.py",
|
|
"src/notebooklm/_idempotency.py",
|
|
"src/notebooklm/_logging.py",
|
|
"src/notebooklm/_mind_map.py",
|
|
"src/notebooklm/_notebooks.py",
|
|
"src/notebooklm/_research.py",
|
|
"src/notebooklm/_sources.py",
|
|
"src/notebooklm/auth.py",
|
|
"src/notebooklm/cli/artifact_cmd.py",
|
|
"src/notebooklm/cli/chat_cmd.py",
|
|
"src/notebooklm/cli/download_cmd.py",
|
|
"src/notebooklm/cli/error_handler.py",
|
|
"src/notebooklm/cli/generate_cmd.py",
|
|
"src/notebooklm/cli/helpers.py",
|
|
"src/notebooklm/cli/note_cmd.py",
|
|
"src/notebooklm/cli/notebook_cmd.py",
|
|
"src/notebooklm/cli/options.py",
|
|
"src/notebooklm/cli/research_cmd.py",
|
|
"src/notebooklm/cli/session_cmd.py",
|
|
"src/notebooklm/cli/source_cmd.py",
|
|
"src/notebooklm/notebooklm_cli.py",
|
|
"src/notebooklm/client.py",
|
|
"src/notebooklm/exceptions.py",
|
|
"src/notebooklm/types.py",
|
|
# docs (user-facing).
|
|
"docs/python-api.md",
|
|
"docs/development.md",
|
|
"docs/auth-cookie-lifecycle.md",
|
|
"docs/cli-exit-codes.md",
|
|
"docs/cli-reference.md",
|
|
# root
|
|
"CHANGELOG.md",
|
|
"pyproject.toml",
|
|
"CLAUDE.md",
|
|
]
|
|
|
|
|
|
PHASE_2_FILES: list[str] = [
|
|
# Top-level test helpers.
|
|
"tests/cassette_patterns.py",
|
|
"tests/conftest.py",
|
|
"tests/vcr_config.py",
|
|
# Integration top-level.
|
|
"tests/integration/conftest.py",
|
|
"tests/integration/README.md",
|
|
"tests/integration/test_artifacts_integration.py",
|
|
"tests/integration/test_auth_refresh_vcr.py",
|
|
"tests/integration/test_auto_refresh.py",
|
|
"tests/integration/test_chat_multi_source_vcr.py",
|
|
"tests/integration/test_empty_results_vcr.py",
|
|
"tests/integration/test_error_paths_vcr.py",
|
|
"tests/integration/test_mind_map_chain_vcr.py",
|
|
"tests/integration/test_notebooks_integration.py",
|
|
"tests/integration/test_notes_integration.py",
|
|
"tests/integration/test_polling_vcr.py",
|
|
"tests/integration/test_research_deep_poll_vcr.py",
|
|
"tests/integration/test_save_chat_as_note_integration.py",
|
|
"tests/integration/test_settings_integration.py",
|
|
"tests/integration/test_sharing_integration.py",
|
|
"tests/integration/test_sources_integration.py",
|
|
"tests/integration/test_vcr_comprehensive.py",
|
|
"tests/integration/test_vcr_example.py",
|
|
"tests/integration/test_vcr_real_api.py",
|
|
"tests/integration/test_workflow_tracer_vcr.py",
|
|
# CLI VCR.
|
|
"tests/integration/cli_vcr/conftest.py",
|
|
"tests/integration/cli_vcr/test_artifacts.py",
|
|
"tests/integration/cli_vcr/test_chat.py",
|
|
"tests/integration/cli_vcr/test_doctor.py",
|
|
"tests/integration/cli_vcr/test_downloads.py",
|
|
"tests/integration/cli_vcr/test_generate.py",
|
|
"tests/integration/cli_vcr/test_login_browser_cookies.py",
|
|
"tests/integration/cli_vcr/test_notebooks.py",
|
|
"tests/integration/cli_vcr/test_notes.py",
|
|
"tests/integration/cli_vcr/test_profile.py",
|
|
"tests/integration/cli_vcr/test_settings.py",
|
|
"tests/integration/cli_vcr/test_sources.py",
|
|
# Concurrency integration.
|
|
"tests/integration/concurrency/conftest.py",
|
|
"tests/integration/concurrency/helpers.py",
|
|
"tests/integration/concurrency/README.md",
|
|
"tests/integration/concurrency/test_add_file_toctou.py",
|
|
"tests/integration/concurrency/test_aexit_exception_masking.py",
|
|
"tests/integration/concurrency/test_artifact_poll_dedupe.py",
|
|
"tests/integration/concurrency/test_auth_snapshot_torn_read.py",
|
|
"tests/integration/concurrency/test_chat_history_race.py",
|
|
"tests/integration/concurrency/test_cross_loop_affinity.py",
|
|
"tests/integration/concurrency/test_download_blocks_loop.py",
|
|
"tests/integration/concurrency/test_harness_smoke.py",
|
|
"tests/integration/concurrency/test_helpers.py",
|
|
"tests/integration/concurrency/test_idempotency_create.py",
|
|
"tests/integration/concurrency/test_keepalive_path_canonicalize.py",
|
|
"tests/integration/concurrency/test_max_concurrent_rpcs.py",
|
|
"tests/integration/concurrency/test_note_create_cancel.py",
|
|
"tests/integration/concurrency/test_pool_tuning.py",
|
|
"tests/integration/concurrency/test_rate_limit_default.py",
|
|
"tests/integration/concurrency/test_refresh_cancellation_propagation.py",
|
|
"tests/integration/concurrency/test_refresh_cmd_race.py",
|
|
"tests/integration/concurrency/test_research_task_crosswire.py",
|
|
"tests/integration/concurrency/test_upload_blocks_loop.py",
|
|
"tests/integration/concurrency/test_upload_cancel_dangling_session.py",
|
|
"tests/integration/concurrency/test_upload_timeout_config.py",
|
|
"tests/integration/concurrency/test_wait_for_sources_leak.py",
|
|
# tests/scripts (test-adjacent helpers).
|
|
"tests/scripts/check_cassettes_clean.py",
|
|
"tests/scripts/check_method_coverage.py",
|
|
"tests/scripts/compress_polling_cassette.py",
|
|
"tests/scripts/setup-generation-notebook.py",
|
|
# Unit conftest.
|
|
"tests/unit/conftest.py",
|
|
# Unit CLI tests.
|
|
"tests/unit/cli/conftest.py",
|
|
"tests/unit/cli/test_agent.py",
|
|
"tests/unit/cli/test_artifact.py",
|
|
"tests/unit/cli/test_chat.py",
|
|
"tests/unit/cli/test_cli_contract.py",
|
|
"tests/unit/cli/test_completion.py",
|
|
"tests/unit/cli/test_doctor.py",
|
|
"tests/unit/cli/test_download.py",
|
|
"tests/unit/cli/test_encoding.py",
|
|
"tests/unit/cli/test_error_handler.py",
|
|
"tests/unit/cli/test_generate.py",
|
|
"tests/unit/cli/test_grouped.py",
|
|
"tests/unit/cli/test_help_text.py",
|
|
"tests/unit/cli/test_helpers.py",
|
|
"tests/unit/cli/test_language.py",
|
|
"tests/unit/cli/test_note.py",
|
|
"tests/unit/cli/test_notebook.py",
|
|
"tests/unit/cli/test_profile.py",
|
|
"tests/unit/cli/test_prompt_file.py",
|
|
"tests/unit/cli/test_research.py",
|
|
"tests/unit/cli/test_resolve.py",
|
|
"tests/unit/cli/test_root_group.py",
|
|
"tests/unit/cli/test_share.py",
|
|
"tests/unit/cli/test_skill.py",
|
|
"tests/unit/cli/test_source.py",
|
|
"tests/unit/cli/test_storage_context_isolation.py",
|
|
"tests/unit/cli/test_use_fails_closed.py",
|
|
# Unit concurrency tests.
|
|
"tests/unit/concurrency/test_auth_load_blocks_loop.py",
|
|
"tests/unit/concurrency/test_close_cancellation_leak.py",
|
|
"tests/unit/concurrency/test_download_collision.py",
|
|
# Unit tests (top-level).
|
|
"tests/unit/test_api_coverage.py",
|
|
"tests/unit/test_artifact_downloads.py",
|
|
"tests/unit/test_artifact_type_code_consistency.py",
|
|
"tests/unit/test_artifacts_coverage.py",
|
|
"tests/unit/test_artifacts_helpers.py",
|
|
"tests/unit/test_artifacts_mind_map_injection.py",
|
|
"tests/unit/test_artifacts_polling_retries.py",
|
|
"tests/unit/test_atomic_io.py",
|
|
"tests/unit/test_atomic_update_json.py",
|
|
"tests/unit/test_auth_cookie_save_race.py",
|
|
"tests/unit/test_auth_session.py",
|
|
"tests/unit/test_backoff.py",
|
|
"tests/unit/test_cassette_patterns.py",
|
|
"tests/unit/test_cassette_sanitizer.py",
|
|
"tests/unit/test_chat.py",
|
|
"tests/unit/test_chat_ask_invariants.py",
|
|
"tests/unit/test_chat_characterization.py",
|
|
"tests/unit/test_chat_error_payload.py",
|
|
"tests/unit/test_chat_helpers.py",
|
|
"tests/unit/test_chat_history.py",
|
|
"tests/unit/test_chat_references.py",
|
|
"tests/unit/test_check_coverage_thresholds.py",
|
|
"tests/unit/test_check_rpc_health.py",
|
|
"tests/unit/test_chromium_profiles.py",
|
|
"tests/unit/test_ci_audit_scripts.py",
|
|
"tests/unit/test_ci_install_parity.py",
|
|
"tests/unit/test_claude_md_freshness.py",
|
|
"tests/unit/test_cli_source_delete.py",
|
|
"tests/unit/test_client.py",
|
|
"tests/unit/test_client_keepalive.py",
|
|
"tests/unit/test_concurrency_cache_race.py",
|
|
"tests/unit/test_concurrency_refresh_race.py",
|
|
"tests/unit/test_conversation.py",
|
|
"tests/unit/test_cookie_domain_split.py",
|
|
"tests/unit/test_cookie_redaction.py",
|
|
"tests/unit/test_decoder.py",
|
|
"tests/unit/test_docstrings.py",
|
|
"tests/unit/test_download_helpers.py",
|
|
"tests/unit/test_download_result.py",
|
|
"tests/unit/test_download_url.py",
|
|
"tests/unit/test_e2e_conftest_options.py",
|
|
"tests/unit/test_encoder.py",
|
|
"tests/unit/test_env.py",
|
|
"tests/unit/test_env_base_url.py",
|
|
"tests/unit/test_exceptions.py",
|
|
"tests/unit/test_firefox_containers.py",
|
|
"tests/unit/test_init_order.py",
|
|
"tests/unit/test_json_error_exit.py",
|
|
"tests/unit/test_json_stdout_purity.py",
|
|
"tests/unit/test_logging.py",
|
|
"tests/unit/test_logging_correlation.py",
|
|
"tests/unit/test_migration.py",
|
|
"tests/unit/test_migration_lock.py",
|
|
"tests/unit/test_notebook_api.py",
|
|
"tests/unit/test_notebook_metadata.py",
|
|
"tests/unit/test_notebooks_extractors.py",
|
|
"tests/unit/test_notes_unit.py",
|
|
"tests/unit/test_observability.py",
|
|
"tests/unit/test_paths.py",
|
|
"tests/unit/test_public_shims.py",
|
|
"tests/unit/test_quota_failure_detection.py",
|
|
"tests/unit/test_rate_limit_retry.py",
|
|
"tests/unit/test_refresh_cmd_shlex.py",
|
|
"tests/unit/test_refresh_lock_lazy_init.py",
|
|
"tests/unit/test_refresh_lock_registry.py",
|
|
"tests/unit/test_refresh_state_machine.py",
|
|
"tests/unit/test_research.py",
|
|
"tests/unit/test_research_api.py",
|
|
"tests/unit/test_rescrub_cassettes_script.py",
|
|
"tests/unit/test_response_preview.py",
|
|
"tests/unit/test_retry_after.py",
|
|
"tests/unit/test_rpc_health_coverage.py",
|
|
"tests/unit/test_rpc_overrides.py",
|
|
"tests/unit/test_rpc_types.py",
|
|
"tests/unit/test_safe_index.py",
|
|
"tests/unit/test_save_chat_as_note_encoder.py",
|
|
"tests/unit/test_save_lock_contract.py",
|
|
"tests/unit/test_select_artifact.py",
|
|
"tests/unit/test_sharing_manager.py",
|
|
"tests/unit/test_sharing_types.py",
|
|
"tests/unit/test_source_add_service.py",
|
|
"tests/unit/test_source_content_renderer.py",
|
|
"tests/unit/test_source_listing_service.py",
|
|
"tests/unit/test_source_polling_service.py",
|
|
"tests/unit/test_source_selection.py",
|
|
"tests/unit/test_source_status.py",
|
|
"tests/unit/test_source_symlink.py",
|
|
"tests/unit/test_source_upload_pipeline.py",
|
|
"tests/unit/test_sources_upload.py",
|
|
"tests/unit/test_streaming_chat_wire.py",
|
|
"tests/unit/test_swallow_observability.py",
|
|
"tests/unit/test_tier_enforcement_hook.py",
|
|
"tests/unit/test_token_regex.py",
|
|
"tests/unit/test_types.py",
|
|
"tests/unit/test_url_utils.py",
|
|
"tests/unit/test_user_settings_api.py",
|
|
"tests/unit/test_vcr_config.py",
|
|
"tests/unit/test_version_check.py",
|
|
"tests/unit/test_version_gate.py",
|
|
"tests/unit/test_warning_dedupe.py",
|
|
"tests/unit/test_windows_compatibility.py",
|
|
"tests/unit/test_with_client_handle_errors.py",
|
|
"tests/unit/test_youtube_extraction.py",
|
|
]
|
|
|
|
|
|
PHASE_SCOPES: dict[str, list[str]] = {
|
|
"phase1": PHASE_1_FILES,
|
|
"phase2": PHASE_2_FILES,
|
|
}
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Driver
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def transform_text(text: str) -> str:
|
|
out = text
|
|
for pat, repl in PAREN_PATTERNS:
|
|
out = re.sub(pat, repl, out)
|
|
for pat, repl in SENTENCE_PATTERNS:
|
|
out = re.sub(pat, repl, out)
|
|
return out
|
|
|
|
|
|
def main(argv: list[str]) -> int:
|
|
if len(argv) != 2 or argv[1] not in PHASE_SCOPES:
|
|
valid_phases = "|".join(sorted(PHASE_SCOPES.keys()))
|
|
print(f"usage: {argv[0]} {{{valid_phases}}}", file=sys.stderr)
|
|
return 2
|
|
|
|
phase = argv[1]
|
|
targets = PHASE_SCOPES[phase]
|
|
|
|
changed: list[Path] = []
|
|
missing: list[str] = []
|
|
for rel in targets:
|
|
path = REPO_ROOT / rel
|
|
if not path.exists():
|
|
missing.append(rel)
|
|
continue
|
|
text = path.read_text(encoding="utf-8")
|
|
new = transform_text(text)
|
|
if new != text:
|
|
path.write_text(new, encoding="utf-8")
|
|
changed.append(path)
|
|
|
|
if missing:
|
|
print(f"WARNING: {len(missing)} target paths missing (skipped):")
|
|
for m in missing:
|
|
print(f" {m}")
|
|
|
|
print(f"Edited {len(changed)} files:")
|
|
for p in sorted(changed):
|
|
print(f" {p.relative_to(REPO_ROOT)}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main(sys.argv))
|