From 0100ab2582947b817498f55e0bfeedf779e455eb Mon Sep 17 00:00:00 2001 From: Nexus Deploy Date: Thu, 4 Jun 2026 23:01:03 +0800 Subject: [PATCH] docs: consolidate archive, SSOT guide, and agent entry stubs Move line-walk/delta/phase2/frontend audits and legacy memory into docs/archive/, add functional development SSOT, thin AGENTS/CLAUDE stubs, and regenerate changelog/audit indexes via consolidate_docs.py. --- .cursorrules | 187 +-- AGENTS.md | 200 +-- CLAUDE.md | 288 +--- PROJECT_HANDOVER.md | 323 +--- docs/README.md | 175 +- docs/archive/README.md | 17 + .../archive/audits/2026-06-04-delta-merged.md | 183 +++ .../audit-delta-2026-06-04-waveD1.md | 95 ++ .../audit-delta-2026-06-04-waveD2.md | 100 ++ .../audit-delta-2026-06-04-waveD3.md | 85 + .../audit-delta-2026-06-04-waveD4.md | 74 + .../audit-delta-2026-06-04-waveD5.md | 80 + .../audit-delta-2026-06-04-waveD6.md | 76 + .../audit-delta-2026-06-04-waveD7.md | 78 + .../audit-delta-2026-06-04-waveD8-closure.md | 50 + .../audits/2026-06-04-frontend-14p-merged.md | 66 + .../audit-frontend-14p-2026-06-04-batch1.md | 96 ++ .../audit-frontend-14p-2026-06-04-batch2.md | 77 + .../audit-frontend-14p-2026-06-04-batch3.md | 93 ++ .../audits/2026-06-04-line-walk-merged.md | 1431 +++++++++++++++++ .../audit-bug-line-walk-2026-06-04-batch1.md | 0 .../audit-bug-line-walk-2026-06-04-batch10.md | 0 .../audit-bug-line-walk-2026-06-04-batch11.md | 0 .../audit-bug-line-walk-2026-06-04-batch12.md | 0 .../audit-bug-line-walk-2026-06-04-batch13.md | 0 .../audit-bug-line-walk-2026-06-04-batch14.md | 0 .../audit-bug-line-walk-2026-06-04-batch17.md | 0 .../audit-bug-line-walk-2026-06-04-batch18.md | 0 .../audit-bug-line-walk-2026-06-04-batch19.md | 0 .../audit-bug-line-walk-2026-06-04-batch2.md | 0 .../audit-bug-line-walk-2026-06-04-batch20.md | 0 .../audit-bug-line-walk-2026-06-04-batch21.md | 0 .../audit-bug-line-walk-2026-06-04-batch22.md | 0 .../audit-bug-line-walk-2026-06-04-batch23.md | 0 .../audit-bug-line-walk-2026-06-04-batch24.md | 0 .../audit-bug-line-walk-2026-06-04-batch25.md | 0 .../audit-bug-line-walk-2026-06-04-batch26.md | 0 .../audit-bug-line-walk-2026-06-04-batch27.md | 0 .../audit-bug-line-walk-2026-06-04-batch28.md | 0 .../audit-bug-line-walk-2026-06-04-batch29.md | 0 .../audit-bug-line-walk-2026-06-04-batch3.md | 0 .../audit-bug-line-walk-2026-06-04-batch30.md | 0 .../audit-bug-line-walk-2026-06-04-batch31.md | 0 .../audit-bug-line-walk-2026-06-04-batch32.md | 0 .../audit-bug-line-walk-2026-06-04-batch33.md | 0 .../audit-bug-line-walk-2026-06-04-batch35.md | 0 .../audit-bug-line-walk-2026-06-04-batch36.md | 0 .../audit-bug-line-walk-2026-06-04-batch37.md | 0 .../audit-bug-line-walk-2026-06-04-batch38.md | 0 .../audit-bug-line-walk-2026-06-04-batch39.md | 0 .../audit-bug-line-walk-2026-06-04-batch4.md | 0 .../audit-bug-line-walk-2026-06-04-batch40.md | 0 .../audit-bug-line-walk-2026-06-04-batch41.md | 0 .../audit-bug-line-walk-2026-06-04-batch42.md | 0 .../audit-bug-line-walk-2026-06-04-batch43.md | 0 .../audit-bug-line-walk-2026-06-04-batch44.md | 0 .../audit-bug-line-walk-2026-06-04-batch45.md | 0 .../audit-bug-line-walk-2026-06-04-batch46.md | 0 .../audit-bug-line-walk-2026-06-04-batch47.md | 0 .../audit-bug-line-walk-2026-06-04-batch48.md | 0 .../audit-bug-line-walk-2026-06-04-batch49.md | 0 .../audit-bug-line-walk-2026-06-04-batch5.md | 0 .../audit-bug-line-walk-2026-06-04-batch50.md | 0 .../audit-bug-line-walk-2026-06-04-batch51.md | 0 .../audit-bug-line-walk-2026-06-04-batch52.md | 0 .../audit-bug-line-walk-2026-06-04-batch53.md | 0 .../audit-bug-line-walk-2026-06-04-batch54.md | 0 .../audit-bug-line-walk-2026-06-04-batch55.md | 0 .../audit-bug-line-walk-2026-06-04-batch56.md | 0 .../audit-bug-line-walk-2026-06-04-batch57.md | 0 .../audit-bug-line-walk-2026-06-04-batch58.md | 0 .../audit-bug-line-walk-2026-06-04-batch59.md | 0 .../audit-bug-line-walk-2026-06-04-batch6.md | 0 .../audit-bug-line-walk-2026-06-04-batch60.md | 0 .../audit-bug-line-walk-2026-06-04-batch61.md | 0 .../audit-bug-line-walk-2026-06-04-batch62.md | 0 .../audit-bug-line-walk-2026-06-04-batch63.md | 0 .../audit-bug-line-walk-2026-06-04-batch64.md | 0 .../audit-bug-line-walk-2026-06-04-batch65.md | 0 .../audit-bug-line-walk-2026-06-04-batch66.md | 0 .../audit-bug-line-walk-2026-06-04-batch67.md | 0 .../audit-bug-line-walk-2026-06-04-batch68.md | 0 .../audit-bug-line-walk-2026-06-04-batch69.md | 0 .../audit-bug-line-walk-2026-06-04-batch7.md | 0 .../audit-bug-line-walk-2026-06-04-batch70.md | 0 .../audit-bug-line-walk-2026-06-04-batch71.md | 0 .../audit-bug-line-walk-2026-06-04-batch72.md | 0 .../audit-bug-line-walk-2026-06-04-batch73.md | 0 .../audit-bug-line-walk-2026-06-04-batch74.md | 0 .../audit-bug-line-walk-2026-06-04-batch75.md | 0 .../audit-bug-line-walk-2026-06-04-batch76.md | 0 .../audit-bug-line-walk-2026-06-04-batch77.md | 0 .../audit-bug-line-walk-2026-06-04-batch8.md | 0 .../audit-bug-line-walk-2026-06-04-batch9.md | 0 .../audits/2026-06-04-phase2-merged.md | 237 +++ .../audit-phase2-2026-06-04-waveP2-1.md | 65 + .../audit-phase2-2026-06-04-waveP2-2.md | 66 + .../audit-phase2-2026-06-04-waveP2-3.md | 61 + .../audit-phase2-2026-06-04-waveP2-4.md | 68 + .../audit-phase2-2026-06-04-waveP2-5.md | 61 + .../audit-phase2-2026-06-04-waveP2-6.md | 61 + .../audit-phase2-2026-06-04-waveP2-7.md | 44 + .../audit-phase2-2026-06-04-waveP2-8.md | 37 + .../audit-phase2-2026-06-04-waveP2-9.md | 36 + .../handoff}/AI-HANDOFF-2026-05-23.md | 12 +- .../handoff}/AI-HANDOFF-2026-06-01-files.md | 0 .../handoff}/handoff-2026-05-31.md | 0 .../handoff}/handoff-2026-06-01.md | 0 .../memory/agentmemory-2026-05-merged.md | 96 ++ .../memory/raw}/mem_key_files.md | 0 .../memory/raw}/mem_mpc4vjm8_caa29f573fd9.md | 0 .../memory/raw}/mem_mpc54lkr_68c4f408352b.md | 0 .../memory/raw}/mem_new_decisions.md | 0 .../memory/raw}/mem_nexus_config.md | 0 .../memory/raw}/mem_nexus_dataflow.md | 0 .../memory/raw}/mem_nexus_decisions.md | 0 .../memory/raw}/mem_nexus_guardian.md | 0 .../memory/raw}/mem_nexus_modules.md | 0 .../memory/raw}/mem_nexus_overview.md | 0 .../memory/raw}/mem_nexus_repo.md | 0 .../memory/raw}/mem_nexus_telegram.md | 0 .../memory/raw}/mem_nexus_testing.md | 0 .../memory/raw}/mem_phase_d_bugfixes.md | 0 .../memory/raw}/mem_team_agenda.md | 0 .../memory/raw}/mem_wsl_deployment.md | 0 docs/archive/project/PROJECT_HANDOVER.md | 320 ++++ .../project/line-walk-audit-standard.md | 0 .../project/nexus-full-site-features.md | 323 ++++ .../2026-05-23-full-audit-report.md | 0 .../2026-05-23-round2-merged-audit.md | 0 .../audit-full-vs-phase2-reconciliation.md | 0 .../audit-phase-2-findings-matrix.md | 0 .../audit-phase-2-walk-closure.md | 0 .../audit-phase-2a-line-walk.md | 0 .../audit-phase-2b-line-walk.md | 0 .../audit-phase-2c-line-walk.md | 0 .../audit-phase-2d-line-walk.md | 0 .../audit-phase-2e-line-walk.md | 0 .../audit-phase-2f-line-walk.md | 0 .../audit-phase-2g-line-walk.md | 0 .../audit-phase-2h-line-walk.md | 0 .../audit-phase-2i-line-walk.md | 0 .../audit-phase-2j-line-walk.md | 0 .../audit-phase-3-delta-2026-06-04.md | 0 .../audit-phase-3-frontend-line-walk.md | 0 .../audit-phase-3-full-closure-2026-06-04.md | 0 .../audit-phase-3-walk-closure.md | 0 .../implementation-progress-2026-05-21.md | 0 .../2026-05-reviews}/review-cto-2026-05-21.md | 0 .../review-deploy-architecture-2026-05-21.md | 0 .../review-quality-director-2026-05-21.md | 0 .../session-log-2026-05-21.md | 0 .../2026-05-reviews}/signoff-2026-05-21.md | 0 .../ag-code-review-report.md | 0 .../ecc-security-report.md | 0 .../engineering-report.md | 0 .../step-0-infrastructure/testing-report.md | 0 .../step-1-data-layer/engineering-report.md | 0 .../step-2-auth/engineering-report.md | 0 .../step-3-webssh/engineering-report.md | 0 .../step-4-sync/engineering-report.md | 0 .../step-5-frontend/design-review-report.md | 0 .../step-5-frontend/engineering-report.md | 0 .../product-department-report.md | 0 docs/audit/2026-06-04-docs-consolidation.md | 46 + docs/audit/INDEX.md | 25 + .../2026-06-04-docs-consolidation.md | 37 + ...2026-06-04-functional-development-guide.md | 35 + docs/changelog/INDEX.md | 212 +++ docs/memory/MEMORY.md | 27 +- docs/project/AI-HANDOFF-2026-06-03.md | 12 +- .../development-acceptance-standard.md | 40 +- docs/project/local-integration-test.md | 87 + docs/project/nexus-full-site-features.md | 324 +--- ...s-functional-development-guide-appendix.md | 458 ++++++ .../nexus-functional-development-guide.md | 859 ++++++++++ docs/reports/README.md | 124 +- .../audit-frontend-14p-2026-06-04-closure.md | 46 + ...audit-phase-4-plugin-closure-2026-06-04.md | 58 + .../audit-plugin-run-final-2026-06-04.md | 52 + scripts/consolidate_docs.py | 273 ++++ 181 files changed, 6474 insertions(+), 1502 deletions(-) create mode 100644 docs/archive/README.md create mode 100644 docs/archive/audits/2026-06-04-delta-merged.md create mode 100644 docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD1.md create mode 100644 docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD2.md create mode 100644 docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD3.md create mode 100644 docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD4.md create mode 100644 docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD5.md create mode 100644 docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD6.md create mode 100644 docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD7.md create mode 100644 docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD8-closure.md create mode 100644 docs/archive/audits/2026-06-04-frontend-14p-merged.md create mode 100644 docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch1.md create mode 100644 docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch2.md create mode 100644 docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch3.md create mode 100644 docs/archive/audits/2026-06-04-line-walk-merged.md rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch1.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch10.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch11.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch12.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch13.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch14.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch17.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch18.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch19.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch2.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch20.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch21.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch22.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch23.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch24.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch25.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch26.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch27.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch28.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch29.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch3.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch30.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch31.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch32.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch33.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch35.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch36.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch37.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch38.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch39.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch4.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch40.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch41.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch42.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch43.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch44.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch45.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch46.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch47.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch48.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch49.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch5.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch50.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch51.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch52.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch53.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch54.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch55.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch56.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch57.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch58.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch59.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch6.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch60.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch61.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch62.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch63.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch64.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch65.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch66.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch67.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch68.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch69.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch7.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch70.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch71.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch72.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch73.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch74.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch75.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch76.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch77.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch8.md (100%) rename docs/{reports => archive/audits/2026-06-04-line-walk}/audit-bug-line-walk-2026-06-04-batch9.md (100%) create mode 100644 docs/archive/audits/2026-06-04-phase2-merged.md create mode 100644 docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-1.md create mode 100644 docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-2.md create mode 100644 docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-3.md create mode 100644 docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-4.md create mode 100644 docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-5.md create mode 100644 docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-6.md create mode 100644 docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-7.md create mode 100644 docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-8.md create mode 100644 docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-9.md rename docs/{project => archive/handoff}/AI-HANDOFF-2026-05-23.md (96%) rename docs/{project => archive/handoff}/AI-HANDOFF-2026-06-01-files.md (100%) rename docs/{ => archive/handoff}/handoff-2026-05-31.md (100%) rename docs/{ => archive/handoff}/handoff-2026-06-01.md (100%) create mode 100644 docs/archive/memory/agentmemory-2026-05-merged.md rename docs/{memory => archive/memory/raw}/mem_key_files.md (100%) rename docs/{memory => archive/memory/raw}/mem_mpc4vjm8_caa29f573fd9.md (100%) rename docs/{memory => archive/memory/raw}/mem_mpc54lkr_68c4f408352b.md (100%) rename docs/{memory => archive/memory/raw}/mem_new_decisions.md (100%) rename docs/{memory => archive/memory/raw}/mem_nexus_config.md (100%) rename docs/{memory => archive/memory/raw}/mem_nexus_dataflow.md (100%) rename docs/{memory => archive/memory/raw}/mem_nexus_decisions.md (100%) rename docs/{memory => archive/memory/raw}/mem_nexus_guardian.md (100%) rename docs/{memory => archive/memory/raw}/mem_nexus_modules.md (100%) rename docs/{memory => archive/memory/raw}/mem_nexus_overview.md (100%) rename docs/{memory => archive/memory/raw}/mem_nexus_repo.md (100%) rename docs/{memory => archive/memory/raw}/mem_nexus_telegram.md (100%) rename docs/{memory => archive/memory/raw}/mem_nexus_testing.md (100%) rename docs/{memory => archive/memory/raw}/mem_phase_d_bugfixes.md (100%) rename docs/{memory => archive/memory/raw}/mem_team_agenda.md (100%) rename docs/{memory => archive/memory/raw}/mem_wsl_deployment.md (100%) create mode 100644 docs/archive/project/PROJECT_HANDOVER.md rename docs/{ => archive}/project/line-walk-audit-standard.md (100%) create mode 100644 docs/archive/project/nexus-full-site-features.md rename docs/{reports => archive/reports/2026-05-reviews}/2026-05-23-full-audit-report.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/2026-05-23-round2-merged-audit.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-full-vs-phase2-reconciliation.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2-findings-matrix.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2-walk-closure.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2a-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2b-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2c-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2d-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2e-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2f-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2g-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2h-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2i-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-2j-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-3-delta-2026-06-04.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-3-frontend-line-walk.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-3-full-closure-2026-06-04.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/audit-phase-3-walk-closure.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/implementation-progress-2026-05-21.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/review-cto-2026-05-21.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/review-deploy-architecture-2026-05-21.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/review-quality-director-2026-05-21.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/session-log-2026-05-21.md (100%) rename docs/{reports => archive/reports/2026-05-reviews}/signoff-2026-05-21.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-0-infrastructure/ag-code-review-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-0-infrastructure/ecc-security-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-0-infrastructure/engineering-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-0-infrastructure/testing-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-1-data-layer/engineering-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-2-auth/engineering-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-3-webssh/engineering-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-4-sync/engineering-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-5-frontend/design-review-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-5-frontend/engineering-report.md (100%) rename docs/{reports => archive/reports/2026-05-steps}/step-5-frontend/product-department-report.md (100%) create mode 100644 docs/audit/2026-06-04-docs-consolidation.md create mode 100644 docs/audit/INDEX.md create mode 100644 docs/changelog/2026-06-04-docs-consolidation.md create mode 100644 docs/changelog/2026-06-04-functional-development-guide.md create mode 100644 docs/changelog/INDEX.md create mode 100644 docs/project/local-integration-test.md create mode 100644 docs/project/nexus-functional-development-guide-appendix.md create mode 100644 docs/project/nexus-functional-development-guide.md create mode 100644 docs/reports/audit-frontend-14p-2026-06-04-closure.md create mode 100644 docs/reports/audit-phase-4-plugin-closure-2026-06-04.md create mode 100644 docs/reports/audit-plugin-run-final-2026-06-04.md create mode 100644 scripts/consolidate_docs.py diff --git a/.cursorrules b/.cursorrules index 4dc7611d..9b7b69b9 100644 --- a/.cursorrules +++ b/.cursorrules @@ -1,176 +1,43 @@ -# Nexus 6.0 — Cursor Rules +# Nexus 6.0 — Cursor 速查 -## 项目概述 -Nexus 是一个 2000+ 服务器运维管理平台。技术栈:FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram (后端),Vue 3 + Vuetify 4 + TypeScript SPA (前端,14页面)。项目 ~99% 完成。 +> SSOT: [docs/project/nexus-functional-development-guide.md](docs/project/nexus-functional-development-guide.md) +> Handoff: [docs/project/AI-HANDOFF-2026-06-03.md](docs/project/AI-HANDOFF-2026-06-03.md) -## 基本信息 -- 仓库: http://66.154.115.8:3000/admin/Nexus.git -- 本地路径: C:\Users\uzuma\Desktop\svn\Nexus -- 生产域名: https://api.synaglobal.vip -- 生产 IP: 47.254.123.106,后端端口 8600 -- 部署路径: /www/wwwroot/api.synaglobal.vip/ -- 管理员: admin / Nexus@2026 -- 数据库: MySQL nexus/Nexus@2026!@127.0.0.1:3306/nexus -- SSH 别名: ssh nexus (key: id_rsa_nexus) +## 栈 -## 目录结构 -``` -Nexus/ -├── server/ ← FastAPI 后端 (Clean Architecture 4层) -│ ├── api/ ← API 路由 -│ ├── domain/ ← SQLAlchemy 模型 (14+张表) -│ ├── infrastructure/← SSH 连接池 + Redis + Telegram -│ ├── background/ ← 后台任务 -│ └── config.py ← Pydantic Settings + MySQL 覆盖 -├── frontend/ ← Vue 3 + Vuetify 4 + TypeScript SPA -│ └── src/pages/ ← 14 个页面组件 -├── web/app/ ← Vite 构建输出 (后端 StaticFiles 挂载点) -├── deploy/ ← Supervisor + Nginx + 健康检查脚本 -├── docs/ ← 设计文档/审计/changelog -└── .env ← NOT IN GIT (安装向导生成) -``` +FastAPI + Async SQLAlchemy + Redis · Vue 3 + Vuetify 4 SPA(14 页)· Vite → `web/app/` -## 实现原则(强制) +## 环境(勿在仓库写密码) -**所有设计和实现都必须是完美实现。** +- 生产: `https://api.synaglobal.vip` · 端口 8600 · `ssh nexus` +- 本地: `~/Nexus` 或 `$NEXUS_ROOT` · 见 [linux-dev-paths.md](docs/project/linux-dev-paths.md) +- 凭据: 仅 `.env`(不入 git) -- ❌ 不允许为了实现而实现 — 每一行代码必须有明确的目的和质量标准 -- ❌ 不允许降级实现 — 不得以「先用着」为由降低安全、架构或代码质量标准 -- ❌ 不允许妥协实现 — 不得在发现问题后选择绕过而非根治 -- ❌ 不允许留技术债 — 发现问题必须当场修复,不得标注 TODO/FIXME 延后 -- ✅ 无法完美实现时必须停下来与用户交流后再换方案,不得擅自从权 +## 关键路径 -## 安全铁律(强制) +| 用途 | 路径 | +|------|------| +| 后端入口 | `server/main.py` | +| 前端路由 | `frontend/src/router/index.ts` | +| API 客户端 | `frontend/src/api/index.ts` | +| Sync | `server/api/sync_v2.py` | +| 门控 | `deploy/pre_deploy_check.sh` | +| 本地验证 | `bash scripts/local_verify.sh` | -- ❌ 禁止明文密码出现在前端 JS 变量、localStorage、URL 参数中 -- ❌ 禁止静默吞错 — except 块不得空 pass 或 return None 掩盖异常 -- ❌ 禁止硬编码密钥/密码/Token — 必须走配置或环境变量 -- ❌ 禁止 f-string 拼 SQL — 必须参数化查询 -- ❌ 禁止未验证的用户输入拼入 shell 命令 — 必须用 shlex.quote() 或 subprocess 参数化 -- ✅ 敏感操作必须二次验证身份(re-auth pattern) -- ✅ API 响应不得返回密码/密钥明文 — 用 password_set 布尔标记 -- ✅ 所有 CUD 操作必须记录审计日志 +## 铁律 -## 文档纪律(强制) +见 `.cursor/rules/perfect-implementation.mdc` · `nexus-security.mdc` — 完美实现、无静默吞错、无明文密钥、CUD 审计。 -- 新功能/架构变更:先写 docs/design/specs/YYYY-MM-DD-*-design.md,再写代码 -- 开发前:写 docs/design/plans/ 或 docs/reports/ 技术文档 -- 项目缺文档的模块:改动时一并补全 -- 每次修改:在 docs/changelog/YYYY-MM-DD-*.md 留 changelog(行数≥10,不能空壳) +## 部署 -## 强制文件修改流程(不可跳步) - -``` -实现 → WSL本地验证 → ★审计8步★ → 部署 → 健康检查 → 浏览器验证 → changelog -``` - -进度条(每次改代码必须输出): -``` -□实现 □WSL验证 □审计8步 □部署 □健康检查 □浏览器验证 □changelog -``` - -审计8步:登记→全文Read→规则扫描H→Closure表→入口表→输入→Sink→归类→DoD - -## 部署流程 - -### 后端部署 ```bash -git push origin main -ssh nexus "cd /www/wwwroot/api.synaglobal.vip && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus" -ssh nexus "sleep 3 && curl -s http://127.0.0.1:8600/health" # 预期: ok +bash deploy/pre_deploy_check.sh && bash deploy/deploy-production.sh ``` -### 前端部署 -```bash -cd frontend && npx vite build && cd .. -tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/ -scp /tmp/nexus-frontend.tar.gz nexus:/tmp/nexus-frontend.tar.gz -ssh nexus "cd /www/wwwroot/api.synaglobal.vip/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz" +前端: `cd frontend && npx vite build` → tar/scp(见 `deploy/deploy-frontend.sh`) + +## 进度条(改代码时输出) + ``` - -### 本地开发 -```bash -cd frontend && npm run dev # http://localhost:3000/app/ +□实现 □本地验证 □审计8步 □部署 □健康检查 □浏览器验证 □changelog ``` - -## 7道门控 (deploy/pre_deploy_check.sh) - -1. Changelog门 — 文件存在且行数≥10 -2. Audit门 — 文件存在且含 Step3+Closure+DoD -3. Test门 — test_api.py 必须存在且通过 -4. Lint门 — ruff check server/ 零错误 -5. Import门 — import server.main 成功 -6. Security门 — bandit 无 HIGH/MEDIUM -7. Review门 — 审计文件包含实际改动文件清单 - -## 已确认的关键决策 - -| 不可改项 | 原因 | -|---------|------| -| API_KEY | 加密一致性 + 子服务器认证 | -| SECRET_KEY | 加密回退密钥 | -| DATABASE_URL | 启动必需 | -| ENCRYPTION_KEY | 凭据加密 | - -| 可改项 | 说明 | -|--------|------| -| system_name/title | 前端显示 | -| pool_size/overflow | 安装向导自动推荐 | -| redis_url | Redis 连接 | -| 告警阈值 | 默认 80% | -| Telegram 配置 | 告警推送 | - -## 关键文件速查 - -| 用途 | 文件路径 | -|------|----------| -| 后端入口 | server/main.py | -| 数据模型 | server/domain/models/__init__.py | -| JWT 认证 | server/api/auth_jwt.py | -| 登录 API | server/api/auth.py | -| WebSSH | server/api/webssh.py | -| WebSocket | server/api/websocket.py | -| 设置 CRUD | server/api/settings.py | -| 服务器 CRUD | server/api/servers.py | -| 快捷命令 | server/api/terminal.py | -| Agent 心跳 | server/api/agent.py | -| 同步引擎 | server/application/services/sync_engine_v2.py | -| 前端入口 | frontend/src/main.ts | -| 路由 | frontend/src/router/index.ts | -| API 客户端 | frontend/src/api/index.ts | -| Auth Store | frontend/src/stores/auth.ts | -| 登录页 | frontend/src/pages/LoginPage.vue | -| 终端页 | frontend/src/pages/TerminalPage.vue | -| Vite 配置 | frontend/vite.config.mts | - -## 已知待续事项(2026-06-01) - -已修复:批量 Agent、JWT 60min+refresh、script-callback API Key、未知心跳丢弃、Admin 列迁移 — 见 `docs/changelog/2026-06-01-bug-remediation.md`。 - -| 优先级 | 问题 | 文件 | -|--------|------|------| -| P2 | 422 handler 是否精简 | server/main.py | -| UX | 终端命令栏高亮对齐 | TerminalPage.vue | -| 验收 | 告警/Telegram、WebSSH、Sync、三层守护 | 见 handoff §八 | - -## 协作方式(单 Agent) - -- 只与用户直接对话,不分派管理组/工程部/测试部/产品部/设计部,不自动加载 Skill 包。 -- 规范见 `.cursor/rules/no-department-agents.mdc`、`standards/`、`docs/design/`。 - -## 测试分工(强制) - -**由 Agent 完成全部测试与修复验证;用户仅在 Agent 报告通过后做最终验收。** - -Agent 在宣称「已修复 / 可交付」前必须自行完成(有证据:命令输出、生产 URL、浏览器抽测记录): - -1. 本地:`ruff` / `import server.main` / `frontend` type-check(若改前端) -2. 能跑则跑:`pytest tests/` 或 `tests/test_api.py` -3. 生产或 WSL:`/health`、`test_api`、关键页面浏览器验证 -4. 更新 `docs/changelog/` + 必要时 `docs/reports/*-verification.md` - -**禁止**把「请你试一下」「请人工确认」当作交付终点;未验证不得让用户代测 bug 是否修好。 - -用户终验:Agent 提交「验收清单」后,用户做最后一遍业务确认即可。 - -## 用中文回复 diff --git a/AGENTS.md b/AGENTS.md index 765625bb..1af8404b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,180 +1,44 @@ -# Nexus 6.0 — Project Memory +# Nexus 6.0 — Agent 入口(薄 stub) -## 项目概述 -Nexus 是一个 2000+ 服务器运维管理平台,从旧的 MultiSync (PHP + AdminLTE + pymysql) 完全重构为 Clean Architecture (FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram)。前端已全面迁移到 Tailwind CSS v4 + Alpine.js,PHP 依赖已移除。 +> **长文 SSOT**: [docs/project/nexus-functional-development-guide.md](docs/project/nexus-functional-development-guide.md) + [附录](docs/project/nexus-functional-development-guide-appendix.md) +> **会话接续**: [docs/project/AI-HANDOFF-2026-06-03.md](docs/project/AI-HANDOFF-2026-06-03.md) +> **文档总索引**: [docs/README.md](docs/README.md) -## 仓库结构 -- **唯一仓库**: Nexus (Gitea, 仓库地址在 .env 中配置) -- **不再使用** multi-server-sync 仓库(旧项目,仅保留历史) -- **部署路径**: 由 `NEXUS_DEPLOY_PATH` 环境变量决定(安装向导自动写入 .env) -- **域名/CORS**: 由 `NEXUS_CORS_ORIGINS` 环境变量决定(安装向导自动写入) +## 项目概要 -## 目录结构 (仓库根目录) -``` -Nexus/ -├── server/ ← Python FastAPI后端 (Clean Architecture 4层) -│ ├── api/ ← API路由 (含 install.py 安装向导API) -│ ├── domain/ ← SQLAlchemy模型 (14张表) -│ ├── infrastructure/← SSH连接池 + Redis + Telegram -│ ├── background/ ← 后台任务 (心跳刷新/自检/调度/重试) -│ └── config.py ← Pydantic Settings + MySQL覆盖 -├── web/app/ ← Tailwind+Alpine.js 纯静态前端 (12个HTML页面) -│ ├── install.html ← 安装向导 (5步) -│ ├── login.html ← JWT登录+TOTP双因素 -│ └── ... ← index/servers/files/push/scripts等 -├── deploy/ ← Supervisor配置 + Shell健康检查脚本 -├── docs/ ← 项目文档 -├── tests/ ← 测试 -├── .env ← NOT IN GIT (安装向导生成) -└── requirements.txt ← Python依赖 +Nexus:2000+ 子机运维平台。后端 FastAPI + MySQL + Redis;前端 **Vue 3 + Vuetify 4 + TypeScript SPA**(14 页,`frontend/src/pages/`);构建输出 `web/app/`;安装向导 `web/app/install.html`。 + +## 本地开发 + +```bash +docker compose up -d mysql redis +bash scripts/start-dev.sh # API :8600 +bash scripts/local_verify.sh # L2b +cd frontend && npm run dev # :3000/app/ ``` -## 启动模式 -- **安装模式** (无 .env): 仅 `/api/install/` + 静态文件可用,其他路由返回503 -- **正常模式** (有 .env): 完整初始化 DB/Redis/后台任务 +路径见 [linux-dev-paths.md](docs/project/linux-dev-paths.md)。 -## 实现原则(强制) +## 强制约束 -**所有设计和实现都必须是完美实现。** 详见 `.cursor/rules/perfect-implementation.mdc`。 +- 完美实现:`.cursor/rules/perfect-implementation.mdc` +- 安全 / 后端 / 前端:`.cursor/rules/nexus-*.mdc` +- 改代码必 `docs/changelog/YYYY-MM-DD-*.md`(≥10 行) +- 测试由 Agent 完成;用户只做终验 -| 禁止 | 要求 | -|------|------| -| 为实现而实现、降级、妥协、技术债(TODO/FIXME 延后) | 每一变更达到安全/架构/质量标准 | -| 无法完美实现时擅自从权换方案 | 停下与用户沟通,确认后再换方案 | -| 无文档直接开发 | 设计文档 → 技术文档 → 代码 | -| 改代码不写 changelog | 每次修改记录到 `docs/changelog/YYYY-MM-DD-*.md` | +## 不可改 -文档路径:设计 `docs/design/specs/` · 技术 `docs/design/plans/` 或 `docs/reports/` · 变更 `docs/changelog/` +`API_KEY` · `SECRET_KEY` · `ENCRYPTION_KEY` · `DATABASE_URL` -## AI 接续与标准(切换会话必读) +## 部署 -| 文档 | 路径 | -|------|------| -| 接续 SSOT | `docs/project/AI-HANDOFF-2026-05-23.md` | -| **标准转接包(全量)** | `docs/project/standards-transfer-package.md` | -| 验收 L0~L5 | `docs/project/development-acceptance-standard.md` | -| 系统开发 / 逐行审计 | `standards/system-development-standard.md`、`standards/line-walk-audit-standard-v2.md`、`standards/audit-core-principles.md` | - -逐行审查与开发规范**同等强制**(8 步、Closure 全表、FINDING 须 `文件:行号`、单回复 ≤5 文件)。 - -## Cursor 规则与 MCP - -- 规则:`.cursor/rules/`(`perfect-implementation` + `nexus-*` + `audit-line-review` + `no-department-agents`) -- 不安装项目级 Skill 包(已移除 superpowers-zh);TDD/调试/验收按 `standards/` 由 Agent 直接执行 -- MySQL MCP:`docs/project/mysql-mcp-setup.md` · 配置后运行 `python scripts/sync_mysql_mcp_env.py` - -## 已确认的关键决策 - -| 决策 | 选择 | 原因 | -|------|------|------| -| API_KEY | ❌ 禁改,UI不显示 | 加密一致性 + 子服务器认证 | -| SECRET_KEY | ❌ 禁改 | 加密回退密钥 | -| DATABASE_URL | ❌ 禁改 | 启动必需 | -| system_name/title | ✅ 可改 | 前端显示 | -| pool_size/overflow | ✅ 可改 | 安装向导自动推荐 | -| redis_url | ✅ 可改 | Redis连接 | -| 告警阈值 (CPU/mem/disk) | ✅ 可改 | 监控参数 (默认80%) | -| Telegram配置 | ✅ 可改 | 告警推送 | -| Agent心跳间隔 | 60s | 不太频繁 | -| Redis→MySQL刷新 | 10min | 降低MySQL负载 | -| 心跳数据流 | Agent→Redis→前端直读→10min→MySQL | 前端实时, MySQL只存历史 | -| 告警推送 | WebSocket→前端 + Telegram | 即时感知 | -| Python守护 | 3层: Supervisor + Python自检(30s) + Shell(cron 1min) | 全覆盖 | -| 安装向导 | install.html + FastAPI API | 纯Python,无PHP依赖 | -| 配置源 | 安装向导→config.json+settings表(MySQL)+.env(Python) | 三写一致 | -| Agent告警心跳 | CPU/内存>80% 或变化>10% 时主动上报 | 智能监控 | -| 仓库统一 | 所有代码统一在Nexus仓库 | 不再用两个仓库 | - -## 实现状态 (Phase A+B+C+D+E) — ~99% 完成 - -### ✅ 已完成 (全部6步 + 技术债务 + UX增强) -| 模块 | 文件 | 说明 | -|------|------|------| -| **Step 0: 基础设施** | | Redis + WebSocket | -| E1 WebSocket推送 | server/api/websocket.py | alert/recovery/system broadcast | -| E2 心跳→Redis+告警 | server/api/agent.py | Redis write + threshold detection | -| E3 Redis→MySQL刷新 | server/background/heartbeat_flush.py | 10min batch | -| **Step 1: 数据层** | | 14张表 | -| E4 load_settings_from_db | server/config.py | MySQL overrides mutable settings | -| **Step 2: 认证层** | | JWT + TOTP | -| **Step 3: Web SSH** | | asyncssh + xterm.js | -| E5 asyncssh连接池 | server/infrastructure/ssh/asyncssh_pool.py | 引用计数模式 | -| E6 WebSSH前端 | web/app/terminal.html | xterm.js + Koko协议 + 自动resize | -| **Step 4: Sync引擎** | | 4种同步模式 | -| **Step 5: 前端迁移** | | Tailwind+Alpine.js | -| E7 13个前端页面 | web/app/*.html | 含install.html安装向导 | -| E8 安装向导API | server/api/install.py | 6端点, 无JWT, 临时引擎 | -| E9 条件启动模式 | server/main.py | 无.env=安装模式 | -| **后台任务** | | | -| E10 Python自检 | server/background/self_monitor.py | 30s loop | -| E11 Telegram推送 | server/infrastructure/telegram/__init__.py | alert/recovery/system | -| E12 /health端点 | server/api/health.py | Shell health_monitor.sh checks this | -| **技术债务** | | | -| D1 ✅ paramiko删除 | — | pool.py已删除, 全部迁移asyncssh | -| D2 ✅ install迁移 | server/api/install.py | PHP→install.html+API | -| D3 ✅ WebSSH前端 | web/app/terminal.html | xterm.js+Koko协议+全屏 | -| **安全增强** | | | -| S1 JWT全局保护 | server/api/*.py | 所有业务API都有JWT验证 | -| S2 审计日志 | server/api/*.py | 所有CUD操作记录审计日志 | -| S3 登录防暴破 | server/application/services/auth_service.py | 失败计数+15min锁定+429状态码 | -| **前端UX增强** | | | -| UX1 共享布局 | web/app/layout.js | 11页面统一侧边栏+全局搜索+用户信息 | -| UX2 Toast通知 | web/app/api.js | 全局toast()函数,4种类型 | -| UX3 全局搜索 | server/api/search.py | 跨服务器/脚本/凭据/调度搜索 | -| UX4 服务器详情 | web/app/servers.html | 点击展开详情面板(系统信息/同步日志/SSH会话) | -| UX5 脚本编辑 | web/app/scripts.html | 点击脚本名编辑+执行结果格式化 | -| UX6 推送增强 | web/app/push.html | 逐服务器状态+进度条+推送历史 | -| UX7 审计分页 | web/app/audit.html | 分页控件+操作过滤+每页50条 | -| UX8 重试操作 | web/app/retries.html | 手动重试+删除按钮+状态过滤 | -| UX9 文件浏览 | web/app/files.html | 面包屑导航+目录排序+父目录链接 | -| UX10 登录安全 | web/app/login.html | 密码可见切换+失败计数+429锁定+shake动画 | -| **P1功能补全** | | | -| P1-1 资产管理 | web/app/assets.html | Platform/Node管理页面 | -| P1-2 服务器表单 | web/app/servers.html | 补全platform/node/protocols字段 | -| P1-3 Push对接 | web/app/push.html + sync_v2.py | target_path对接+统一SyncEngineV2 | -| P1-4 安全设置 | web/app/settings.html | TOTP QR码+修改密码+API Key复制 | -| P1-5 WebSSH授权 | server/api/webssh.py | SSH凭据验证+4003关闭码+审计 | -| P1-6 Agent认证 | server/api/agent.py | 每服务器API Key + 全局回退 | -| P1-7 Config去重 | server/application/services/sync_engine_v2.py | sed去重+备份+_rollback_config() | -| **P2安全增强** | | | -| P2-1 告警防抖 | server/api/websocket.py | 5分钟冷却+Telegram去重+恢复重置 | -| P2-2 命令日志 | web/app/commands.html | 命令/会话双视图+服务器过滤+危险命令高亮 | -| P2-3 DB分页 | server/infrastructure/database/server_repo.py | DB层offset/limit+count | -| P2-4 Dashboard实时 | web/app/index.html | WS触发stats刷新+声音+标签页闪烁 | -| P2-5 移动适配 | web/app/layout.js | <768px侧边栏overlay+backdrop+表格滚动 | -| P2-6 会话安全 | server/api/auth_jwt.py + api.js | 8小时超时+JWT updated_at+刷新重用检测 | -| P2-7 凭据加密 | server/api/servers.py | Server.password/ssh_key_private Fernet加密存储 | -| P2-8 凭据脱敏 | server/api/scripts.py + servers.py | API响应不返回密码,password_set布尔标记 | -| P2-9 DB备份 | deploy/db_backup.sh | mysqldump+30天保留+cron集成 | - -### 🔄 待测试 -- T1: 心跳Redis写入验证 -- T2: WebSocket连接测试 -- T3: 3层守护测试 (kill Python→Supervisor重启) -- T4: Telegram推送测试 -- T5: install.html 5步流程测试 - -### 测试流程 (用户确认) -1. WSL本地基础测试 → 2. 推到仓库 → 3. 外网服务器正式测试 - -## 配置三写机制 -安装向导 Step 3 POST处理同时写入: -1. `web/data/config.json` — 共享配置 (API_BASE_URL, DB_*, API_KEY) -2. `.env` — Python后端启动必需 (NEXUS_前缀) -3. `settings` MySQL表 — 共享动态配置 (api_key, thresholds, Telegram等) - -不可改项 (SECRET_KEY/API_KEY/ENCRYPTION_KEY/DATABASE_URL) 不在MySQL覆盖映射中。 - -## 3层守护机制 -- **Layer 1**: Supervisor — Python崩溃自动重启 -- **Layer 2**: Python self_monitor — 每30s检查Redis/MySQL/WebSocket -- **Layer 3**: Shell health_monitor.sh — 每分钟HTTP GET /health, 连续3次失败→supervisorctl restart + Telegram - -## 数据流 -``` -Agent心跳(60s) → Redis(实时) → 前端直读 → 10min批量 → MySQL(历史) -告警: CPU/mem/disk > threshold → WebSocket推送浏览器 + Telegram推送手机 -恢复: 之前告警的指标恢复正常 → 自动推送恢复通知 -Redis心跳key: heartbeat:{server_id} (HSET, TTL=600s) -Redis告警key: alerts:{server_id} (SET, TTL=3600s) +```bash +bash deploy/pre_deploy_check.sh +bash deploy/deploy-production.sh # 需 SSH nexus + 用户批准 ``` + +详情见功能指南 §17–18。 + +## 归档文档 + +历史审计合并卷:`docs/archive/README.md` diff --git a/CLAUDE.md b/CLAUDE.md index b327b4a3..0cfdc36a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,278 +1,28 @@ -# Nexus 6.0 — Project Memory +# Nexus 6.0 — Agent 入口(薄 stub) -## 项目概述 -Nexus 是一个 2000+ 服务器运维管理平台,从旧的 MultiSync (PHP + AdminLTE + pymysql) 完全重构为 Clean Architecture (FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram)。前端已全面迁移到 Tailwind CSS v4 + Alpine.js,PHP 依赖已移除。 +> 与 [AGENTS.md](AGENTS.md) 相同入口;长文见 [docs/project/nexus-functional-development-guide.md](docs/project/nexus-functional-development-guide.md)。 -## 仓库结构 -- **唯一仓库**: Nexus (Gitea, 仓库地址在 .env 中配置) -- **不再使用** multi-server-sync 仓库(旧项目,仅保留历史) -- **部署路径**: 由 `NEXUS_DEPLOY_PATH` 环境变量决定(安装向导自动写入 .env) -- **域名/CORS**: 由 `NEXUS_CORS_ORIGINS` 环境变量决定(安装向导自动写入) +## 快速链接 -## 目录结构 (仓库根目录) -``` -Nexus/ -├── server/ ← Python FastAPI后端 (Clean Architecture 4层) -│ ├── api/ ← API路由 (含 install.py 安装向导API) -│ ├── domain/ ← SQLAlchemy模型 (14张表) -│ ├── infrastructure/← SSH连接池 + Redis + Telegram -│ ├── background/ ← 后台任务 (心跳刷新/自检/调度/重试) -│ └── config.py ← Pydantic Settings + MySQL覆盖 -├── web/app/ ← Tailwind+Alpine.js 纯静态前端 (12个HTML页面) -│ ├── install.html ← 安装向导 (5步) -│ ├── login.html ← JWT登录+TOTP双因素 -│ └── ... ← index/servers/files/push/scripts等 -├── deploy/ ← Supervisor配置 + Shell健康检查脚本 -├── docs/ ← 项目文档 -├── tests/ ← 测试 -├── .env ← NOT IN GIT (安装向导生成) -└── requirements.txt ← Python依赖 -``` - -## 启动模式 -- **安装模式** (无 .env): 仅 `/api/install/` + 静态文件可用,其他路由返回503 -- **正常模式** (有 .env): 完整初始化 DB/Redis/后台任务 - -## 已确认的关键决策 - -| 决策 | 选择 | 原因 | -|------|------|------| -| API_KEY | ❌ 禁改,UI不显示 | 加密一致性 + 子服务器认证 | -| SECRET_KEY | ❌ 禁改 | 加密回退密钥 | -| DATABASE_URL | ❌ 禁改 | 启动必需 | -| system_name/title | ✅ 可改 | 前端显示 | -| pool_size/overflow | ✅ 可改 | 安装向导自动推荐 | -| redis_url | ✅ 可改 | Redis连接 | -| 告警阈值 (CPU/mem/disk) | ✅ 可改 | 监控参数 (默认80%) | -| Telegram配置 | ✅ 可改 | 告警推送 | -| Agent心跳间隔 | 60s | 不太频繁 | -| Redis→MySQL刷新 | 10min | 降低MySQL负载 | -| 心跳数据流 | Agent→Redis→前端直读→10min→MySQL | 前端实时, MySQL只存历史 | -| 告警推送 | WebSocket→前端 + Telegram | 即时感知 | -| Python守护 | 3层: Supervisor + Python自检(30s) + Shell(cron 1min) | 全覆盖 | -| 安装向导 | install.html + FastAPI API | 纯Python,无PHP依赖 | -| 配置源 | 安装向导→config.json+settings表(MySQL)+.env(Python) | 三写一致 | -| Agent告警心跳 | CPU/内存>80% 或变化>10% 时主动上报 | 智能监控 | -| 仓库统一 | 所有代码统一在Nexus仓库 | 不再用两个仓库 | - -## 实现状态 (Phase A+B+C+D+E) — ~99% 完成 - -### ✅ 已完成 (全部6步 + 技术债务 + UX增强) -| 模块 | 文件 | 说明 | -|------|------|------| -| **Step 0: 基础设施** | | Redis + WebSocket | -| E1 WebSocket推送 | server/api/websocket.py | alert/recovery/system broadcast | -| E2 心跳→Redis+告警 | server/api/agent.py | Redis write + threshold detection | -| E3 Redis→MySQL刷新 | server/background/heartbeat_flush.py | 10min batch | -| **Step 1: 数据层** | | 14张表 | -| E4 load_settings_from_db | server/config.py | MySQL overrides mutable settings | -| **Step 2: 认证层** | | JWT + TOTP | -| **Step 3: Web SSH** | | asyncssh + xterm.js | -| E5 asyncssh连接池 | server/infrastructure/ssh/asyncssh_pool.py | 引用计数模式 | -| E6 WebSSH前端 | web/app/terminal.html | xterm.js + Koko协议 + 自动resize | -| **Step 4: Sync引擎** | | 4种同步模式 | -| **Step 5: 前端迁移** | | Tailwind+Alpine.js | -| E7 13个前端页面 | web/app/*.html | 含install.html安装向导 | -| E8 安装向导API | server/api/install.py | 6端点, 无JWT, 临时引擎 | -| E9 条件启动模式 | server/main.py | 无.env=安装模式 | -| **后台任务** | | | -| E10 Python自检 | server/background/self_monitor.py | 30s loop | -| E11 Telegram推送 | server/infrastructure/telegram/__init__.py | alert/recovery/system | -| E12 /health端点 | server/api/health.py | Shell health_monitor.sh checks this | -| **技术债务** | | | -| D1 ✅ paramiko删除 | — | pool.py已删除, 全部迁移asyncssh | -| D2 ✅ install迁移 | server/api/install.py | PHP→install.html+API | -| D3 ✅ WebSSH前端 | web/app/terminal.html | xterm.js+Koko协议+全屏 | -| **安全增强** | | | -| S1 JWT全局保护 | server/api/*.py | 所有业务API都有JWT验证 | -| S2 审计日志 | server/api/*.py | 所有CUD操作记录审计日志 | -| S3 登录防暴破 | server/application/services/auth_service.py | 失败计数+15min锁定+429状态码 | -| **前端UX增强** | | | -| UX1 共享布局 | web/app/layout.js | 11页面统一侧边栏+全局搜索+用户信息 | -| UX2 Toast通知 | web/app/api.js | 全局toast()函数,4种类型 | -| UX3 全局搜索 | server/api/search.py | 跨服务器/脚本/凭据/调度搜索 | -| UX4 服务器详情 | web/app/servers.html | 点击展开详情面板(系统信息/同步日志/SSH会话) | -| UX5 脚本编辑 | web/app/scripts.html | 点击脚本名编辑+执行结果格式化 | -| UX6 推送增强 | web/app/push.html | 逐服务器状态+进度条+推送历史 | -| UX7 审计分页 | web/app/audit.html | 分页控件+操作过滤+每页50条 | -| UX8 重试操作 | web/app/retries.html | 手动重试+删除按钮+状态过滤 | -| UX9 文件浏览 | web/app/files.html | 面包屑导航+目录排序+父目录链接 | -| UX10 登录安全 | web/app/login.html | 密码可见切换+失败计数+429锁定+shake动画 | -| **P1功能补全** | | | -| P1-1 资产管理 | web/app/assets.html | Platform/Node管理页面 | -| P1-2 服务器表单 | web/app/servers.html | 补全platform/node/protocols字段 | -| P1-3 Push对接 | web/app/push.html + sync_v2.py | target_path对接+统一SyncEngineV2 | -| P1-4 安全设置 | web/app/settings.html | TOTP QR码+修改密码+API Key复制 | -| P1-5 WebSSH授权 | server/api/webssh.py | SSH凭据验证+4003关闭码+审计 | -| P1-6 Agent认证 | server/api/agent.py | 每服务器API Key + 全局回退 | -| P1-7 Config去重 | server/application/services/sync_engine_v2.py | sed去重+备份+_rollback_config() | -| **P2安全增强** | | | -| P2-1 告警防抖 | server/api/websocket.py | 5分钟冷却+Telegram去重+恢复重置 | -| P2-2 命令日志 | web/app/commands.html | 命令/会话双视图+服务器过滤+危险命令高亮 | -| P2-3 DB分页 | server/infrastructure/database/server_repo.py | DB层offset/limit+count | -| P2-4 Dashboard实时 | web/app/index.html | WS触发stats刷新+声音+标签页闪烁 | -| P2-5 移动适配 | web/app/layout.js | <768px侧边栏overlay+backdrop+表格滚动 | -| P2-6 会话安全 | server/api/auth_jwt.py + api.js | 8小时超时+JWT updated_at+刷新重用检测 | -| P2-7 凭据加密 | server/api/servers.py | Server.password/ssh_key_private Fernet加密存储 | -| P2-8 凭据脱敏 | server/api/scripts.py + servers.py | API响应不返回密码,password_set布尔标记 | -| P2-9 DB备份 | deploy/db_backup.sh | mysqldump+30天保留+cron集成 | -| **P3运维增强** | | | -| P3-1 Nginx重定向 | deploy/nginx_https.conf | 注释化301规则:裸页面路径→/app/前缀 | -| P3-2 自定义404 | server/main.py | StarletteHTTPExceptionHandler返回空白HTML,隐藏FastAPI标识 | - -### 🔄 待测试 -- T1: 心跳Redis写入验证 -- T2: WebSocket连接测试 -- T3: 3层守护测试 (kill Python→Supervisor重启) -- T4: Telegram推送测试 -- T5: install.html 5步流程测试 - -### 测试流程 (用户确认) -1. WSL本地基础测试 → 2. 推到仓库 → 3. 外网服务器正式测试 - -## 配置三写机制 -安装向导 Step 3 POST处理同时写入: -1. `web/data/config.json` — 共享配置 (API_BASE_URL, DB_*, API_KEY) -2. `.env` — Python后端启动必需 (NEXUS_前缀) -3. `settings` MySQL表 — 共享动态配置 (api_key, thresholds, Telegram等) - -不可改项 (SECRET_KEY/API_KEY/ENCRYPTION_KEY/DATABASE_URL) 不在MySQL覆盖映射中。 - -## 3层守护机制 -- **Layer 1**: Supervisor — Python崩溃自动重启 -- **Layer 2**: Python self_monitor — 每30s检查Redis/MySQL/WebSocket -- **Layer 3**: Shell health_monitor.sh — 每分钟HTTP GET /health, 连续3次失败→supervisorctl restart + Telegram - -## 实现原则(强制 — 见 `.cursor/rules/perfect-implementation.mdc`) - -**所有设计和实现都必须是完美实现。** - -- ❌ 不允许为了实现而实现 — 每一行代码必须有明确的目的和质量标准 -- ❌ 不允许降级实现 — 不得以「先用着」为由降低安全、架构或代码质量标准 -- ❌ 不允许妥协实现 — 不得在发现问题后选择绕过而非根治 -- ❌ 不允许留技术债 — 发现问题必须当场修复,不得标注 TODO/FIXME 延后 -- ✅ 无法完美实现时必须停下来与用户交流后再换方案,不得擅自从权 - -**文档纪律:** - -- 新功能/架构变更:先写 `docs/design/specs/YYYY-MM-DD-*-design.md`,再写代码 -- 开发前:写 `docs/design/plans/` 或 `docs/reports/` 技术文档(文件清单、步骤、测试、回滚) -- 项目缺文档的模块:改动时一并补全 -- 每次修改:在 `docs/changelog/YYYY-MM-DD-*.md` 留 changelog - ---- - -## 强制文件修改流程(不可跳步) - -``` -实现 → WSL本地验证 → ★审计8步★ → 部署 → 健康检查 → 浏览器验证 → changelog -``` - -**进度条(每次改代码必须输出,每完成一步打勾):** - -``` -□实现 □WSL验证 □审计8步 □部署 □健康检查 □浏览器验证 □changelog -``` - -用户只需看:没打勾的格子在打勾的格子后面 = 跳步了。 -跳步 = 严重过程违规,用户说「你跳步了」必须立即停止并补完。 - -审计8步(我内部执行,用户不需要检查细节):登记→全文Read→规则扫描H→Closure表→入口表→输入→Sink→归类→DoD -审查4维度30项:安全12+逻辑8+性能5+质量5 -三个铁律:每个文件都要审、每行代码都要看、每个结论都要有证据 - -**程序门控 v2(deploy 时自动检查 7 道,不过不让部署):** - -| # | 门 | 检查内容 | 防什么 | -|---|----|---------|--------| -| 1 | Changelog门 | 文件存在 **且行数≥10** | 空壳changelog | -| 2 | Audit门 | 文件存在 **且含 Step3+Closure+DoD** | 空壳审计 | -| 3 | Test门 | test_api.py **必须存在**且通过 | 删测试绕过 | -| 4 | Lint门 | `ruff check server/` 零错误 | 代码质量问题 | -| 5 | Import门 | `import server.main` 成功 | 语法/导入错误 | -| 6 | Security门 | `bandit` 无 HIGH/MEDIUM | 安全反模式 | -| 7 | Review门 | 审计文件包含实际改动文件清单 | 假审查 | - -门控脚本: `deploy/pre_deploy_check.sh`(7门) -门控日志: `deploy/gate_log.jsonl`(每次检查自动追加记录) -MCP deploy 工具在 git pull + restart 前自动执行门控检查,任何一门不过返回 `🚫 DEPLOY BLOCKED` -MCP gate_log 工具可查看历史门控记录 -审计模板: `docs/audit/TEMPLATE.md` -Lint配置: `ruff.toml` -开发依赖: `requirements-dev.txt`(ruff, bandit, pytest) - -## 部署流程(SSH + SCP,不是 MCP deploy) - -**MCP deploy 不可用**(GitHub 等 SaaS 的远程服务器 git pull 无凭据),实际部署用 SSH 命令直接操作: - -### 后端部署 - -```bash -# 1. Push 本地到 Gitea -git push origin main - -# 2. 服务器拉取最新代码 + 重启 -ssh nexus "cd /www/wwwroot/api.synaglobal.vip && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus" - -# 3. 健康检查 -ssh nexus "sleep 3 && curl -s http://127.0.0.1:8600/health" -# 预期: "ok"(纯文本,非 JSON) -``` - -### 前端部署(Vuetify SPA) - -Vite 直接输出到 `web/app/`(后端 StaticFiles 挂载点),无需 dist 复制步骤: - -```bash -# 一键部署脚本(构建+打包+上传+提取+重启+验证) -bash deploy/deploy-frontend.sh - -# 或手动步骤: -cd frontend && npx vite build && cd .. -tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/ -scp /tmp/nexus-frontend.tar.gz nexus:/tmp/nexus-frontend.tar.gz -ssh nexus "cd /www/wwwroot/api.synaglobal.vip/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz" -ssh nexus "supervisorctl restart nexus" -``` - -**注意**: 前端构建产物 (`web/app/index.html`, `web/app/assets/`) 已在 `.gitignore` 中,不进入 git。每次部署需重新构建+上传。 - -### 浏览器验证 -```bash -curl -s -o /dev/null -w "%{http_code}" http://47.254.123.106:8600/app/ # 预期: 200 -``` - -### 部署常遇问题 -| 问题 | 解决 | +| 用途 | 路径 | |------|------| -| `/app/` 返回 404 | AppAuthMiddleware 拦截 — 确认 `/app/` 和 `/app/index.html` 在 `_APP_PUBLIC_PATHS` 中 | -| `/app/` 返回旧 HTML (Tailwind/Alpine) | `git reset --hard` 恢复了旧文件 — 需要重新 tar+scp 前端构建产物 | -| MCP deploy → git pull 失败 `could not read Username` | 服务器 remote URL 没配 token,用 `git remote set-url` | -| Gate 2 Audit BLOCKED | 创建 `docs/audit/YYYY-MM-DD-topic.md`,含 Step3+Closure+DoD | -| Gate 3 Test BLOCKED (401) | 服务器 .env 中 `NEXUS_TEST_ADMIN_PASSWORD` 与数据库不一致 | -| Gate 6 Security BLOCKED (bandit HIGH) | md5 → sha256 等,参看 bandit 报告修复 | -| Gate 7 Review BLOCKED | 审计文件缺少实际改动文件清单 | +| 功能 / API / 14 页 | `docs/project/nexus-functional-development-guide.md` | +| 附录(sync 端点、调用链) | `docs/project/nexus-functional-development-guide-appendix.md` | +| 当前 handoff | `docs/project/AI-HANDOFF-2026-06-03.md` | +| 本地验证 | `bash scripts/local_verify.sh` | +| 验收 L0–L5 | `docs/project/development-acceptance-standard.md` | +| 风险接受(单人运维) | `docs/project/risk-acceptance-single-operator.md` | +| 文档索引 | `docs/README.md` | +| 历史归档 | `docs/archive/README.md` | -### 部署信息速查 -- **部署用户**: root -- **部署目录**: `/www/wwwroot/api.synaglobal.vip/` -- **Supervisor 服务名**: `nexus` -- **Supervisor 配置**: `/www/server/panel/plugin/supervisor/etc/supervisor.conf` -- **SSH 别名**: `ssh nexus` (47.254.123.106, key: id_rsa_nexus) -- **后端端口**: 8600 -- **Gitea Token SHA**: `26fee743a9332895b55f79b2dbe2e931dc7c2fe5` (nexus-deploy-token, write:repository) +## 栈 -**用户审查清单(验证AI是否偷懒):** -1. 看 `deploy/gate_log.jsonl` — 每次门控都有记录,没有记录 = 没过门控 -2. 看审计文件 — 必须有 Closure 表(每个H的判定+依据)、Step 3 规则扫描、DoD -3. 看进度条 — ☑必须在□前面,否则跳步 -4. 看 changelog — 行数≥10,不能是空壳 +FastAPI · Vue 3 SPA · Hash 路由 `#/` · 门控 `deploy/pre_deploy_check.sh`(7 道) + +## 流程 -## 数据流 ``` -Agent心跳(60s) → Redis(实时) → 前端直读 → 10min批量 → MySQL(历史) -告警: CPU/mem/disk > threshold → WebSocket推送浏览器 + Telegram推送手机 -恢复: 之前告警的指标恢复正常 → 自动推送恢复通知 -Redis心跳key: heartbeat:{server_id} (HSET, TTL=600s) -Redis告警key: alerts:{server_id} (SET, TTL=3600s) +实现 → local_verify → 审计(按 diff 量级)→ changelog →(批准)部署 ``` + +强制规则:`.cursor/rules/` · `standards/` diff --git a/PROJECT_HANDOVER.md b/PROJECT_HANDOVER.md index dca6b6af..f1213a72 100644 --- a/PROJECT_HANDOVER.md +++ b/PROJECT_HANDOVER.md @@ -1,320 +1,11 @@ -# Nexus 6.0 项目交接文档 +# Nexus 6.0 项目交接(已 supersede) -> **⚠️ 2026-05-23 起请以 SSOT 为准**: [`AI-HANDOFF`](docs/project/AI-HANDOFF-2026-05-23.md) · **全量标准** [`standards-transfer-package`](docs/project/standards-transfer-package.md) · 验收 [`development-acceptance-standard`](docs/project/development-acceptance-standard.md) -> 本文保留历史结构;端口模型、待办 backlog、验证清单、否决项均以 SSOT 为准。 +请以以下文档为准: -## 项目概述 - -**项目名称**: Nexus 6.0 -**类型**: 2000+ 服务器运维管理平台 -**架构**: Clean Architecture (FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram) -**前端**: Tailwind CSS v4 + Alpine.js(18 个 HTML 页面,含 `alerts.html`) -**状态**: 核心代码 ~98% 完成;**尚未部署**;待办见 SSOT §4、验证见 SSOT §5 - ---- - -## 仓库信息 - -- **仓库地址**: Gitea (地址在 .env 中配置) -- **当前工作目录(Linux)**: `~/Nexus`(见 `docs/project/linux-dev-paths.md`) -- **Git分支**: 当前在 worktree 分支 - ---- - -## 技术栈 - -| 层级 | 技术 | +| 文档 | 路径 | |------|------| -| 后端框架 | FastAPI (Python 3.9+) | -| 数据库 | MySQL 8.0 + Async SQLAlchemy 2.0 | -| 缓存 | Redis | -| 实时通信 | WebSocket | -| SSH连接 | asyncssh (连接池模式) | -| 告警推送 | Telegram Bot API | -| 前端 | Tailwind CSS v4 + Alpine.js | -| 进程守护 | Supervisor + Python自检 + Shell健康检查 | +| 功能开发 SSOT | [docs/project/nexus-functional-development-guide.md](docs/project/nexus-functional-development-guide.md) | +| 会话接续 | [docs/project/AI-HANDOFF-2026-06-03.md](docs/project/AI-HANDOFF-2026-06-03.md) | +| 文档总索引 | [docs/README.md](docs/README.md) | ---- - -## 目录结构 - -``` -Nexus/ -├── server/ # Python FastAPI 后端 -│ ├── api/ # API路由层 (15个模块) -│ │ ├── agent.py # Agent心跳接收 -│ │ ├── assets.py # Platform/Node资产管理 -│ │ ├── auth.py # JWT登录/TOTP -│ │ ├── auth_jwt.py # JWT验证中间件 -│ │ ├── files.py # 文件浏览 -│ │ ├── install.py # 安装向导API -│ │ ├── push.py # 推送调度 -│ │ ├── scripts.py # 脚本库管理 -│ │ ├── servers.py # 服务器CRUD -│ │ ├── settings.py # 系统设置 -│ │ ├── sync_v2.py # 同步引擎v2 (4种模式) -│ │ ├── webssh.py # WebSSH终端 -│ │ └── websocket.py # WebSocket告警推送 -│ ├── application/ # 应用服务层 -│ │ └── services/ # 业务逻辑 (SyncEngineV2等) -│ ├── domain/ # 领域层 -│ │ └── models/ # SQLAlchemy ORM (14张表) -│ ├── infrastructure/ # 基础设施层 -│ │ ├── database/ # 数据库访问 (Repository模式) -│ │ ├── redis/ # Redis客户端 -│ │ ├── ssh/ # SSH连接池 (asyncssh) -│ │ └── telegram/ # Telegram推送 -│ ├── background/ # 后台任务 -│ │ ├── self_monitor.py # Python自检 (30s) -│ │ ├── heartbeat_flush.py # Redis→MySQL刷新 (10min) -│ │ ├── scheduler.py # 定时推送调度 -│ │ └── retry_worker.py # 失败重试队列 -│ └── config.py # Pydantic Settings -├── web/app/ # 前端页面 (15个HTML) -│ ├── install.html # 安装向导 (5步) -│ ├── login.html # JWT登录+TOTP -│ ├── index.html # 仪表盘 -│ ├── servers.html # 服务器管理 -│ ├── assets.html # Platform/Node管理 -│ ├── push.html # 文件推送 -│ ├── scripts.html # 脚本库 -│ ├── commands.html # 命令日志查询 -│ ├── files.html # 远程文件浏览 -│ ├── settings.html # 系统设置 -│ ├── audit.html # 审计日志 -│ ├── retries.html # 重试队列 -│ ├── terminal.html # WebSSH终端 -│ ├── api.js # 共享API模块 (JWT+Toast) -│ └── layout.js # 共享布局组件 -├── deploy/ # 部署配置 -│ ├── supervisor/ # Supervisor配置 -│ ├── nginx/ # Nginx配置 -│ └── db_backup.sh # 数据库备份脚本 -├── docs/ # 项目文档 -├── requirements.txt # Python依赖 -└── test_p1_p2.py # 验证测试脚本 -``` - ---- - -## 数据库模型 (14张表) - -| 表名 | 说明 | -|------|------| -| `admins` | 管理员用户 (JWT+TOTP支持) | -| `servers` | 服务器资产 (核心表) | -| `platforms` | 平台类型模板 | -| `nodes` | 资产节点树 | -| `sync_logs` | 同步操作日志 | -| `push_schedules` | 定时推送调度 | -| `push_retry_jobs` | 失败重试队列 | -| `audit_logs` | 审计日志 | -| `scripts` | 脚本库 | -| `script_executions` | 脚本执行记录 | -| `password_presets` | SSH密码预设 | -| `db_credentials` | 数据库凭据 | -| `ssh_sessions` | WebSSH会话 | -| `command_logs` | SSH命令日志 | -| `login_attempts` | 登录防暴破记录 | -| `settings` | 系统配置键值对 | - ---- - -## 核心功能清单 - -### P0 核心功能 (已完成) -- [x] JWT认证 + TOTP双因素 -- [x] 登录防暴破 (15分钟锁定) -- [x] Agent心跳上报 (Redis实时) -- [x] WebSocket实时告警推送 -- [x] Telegram告警通知 -- [x] 安装向导 (5步) - -### P1 功能 (已完成) -- [x] Platform/Node资产管理 -- [x] 服务器详情面板 (点击展开) -- [x] WebSSH终端 (xterm.js) -- [x] 推送页面增强 (逐服务器状态+进度条) -- [x] 脚本编辑+执行结果格式化 -- [x] 全局Toast通知系统 -- [x] 审计日志分页+过滤 -- [x] 重试队列手动操作 -- [x] 文件浏览 (面包屑导航) - -### P2 功能 (已完成) -- [x] 告警聚合防抖 (5分钟冷却) -- [x] 命令日志查询页面 -- [x] 服务器列表DB级分页 -- [x] Dashboard WebSocket实时刷新 -- [x] 移动端响应式适配 -- [x] 会话安全加固 (8小时超时) -- [x] 服务器凭据Fernet加密存储 -- [x] 凭据API脱敏 (password_set标记) -- [x] 数据库自动备份脚本 - -### Sync引擎v2 (4种模式) -- [x] S1: 文件同步 (rsync) -- [x] S2: 命令批量执行 (SSH) -- [x] S3: 配置推送 (sysctl) + 去重 + 回滚 -- [x] S4: SFTP文件传输 - ---- - -## 关键Bug修复记录 - -| 任务ID | 问题 | 修复内容 | -|--------|------|----------| -| #81 | DateTime默认求值BUG | 添加`_utcnow()`可调用函数,替换所有`default=datetime.now()` | -| #82 | session.py logger未定义 | 添加`import logging`和`logger`定义,移除@property死代码 | -| #83 | 审计日志缺失 | 验证所有CUD端点都有审计记录 | -| #84 | 模型缺失索引 | 添加7个索引(login_attempts, audit_logs等) | - ---- - -## 环境配置 - -### 必需环境变量 (.env文件) -```bash -# 数据库 -DATABASE_URL=mysql+aiomysql://user:pass@localhost/nexus - -# 安全密钥 (安装时生成) -SECRET_KEY=xxx -API_KEY=xxx -ENCRYPTION_KEY=xxx - -# Redis -REDIS_URL=redis://localhost:6379/0 - -# Telegram告警 (可选) -TELEGRAM_BOT_TOKEN=xxx -TELEGRAM_CHAT_ID=xxx - -# 告警阈值 -CPU_ALERT_THRESHOLD=80 -MEM_ALERT_THRESHOLD=80 -DISK_ALERT_THRESHOLD=80 -``` - -### 启动模式 -- **安装模式** (无.env): 仅 `/api/install/` + 静态文件可用 -- **正常模式** (有.env): 完整初始化 DB/Redis/后台任务 - ---- - -## 部署步骤 - -### 1. 安装依赖 -```bash -pip install -r requirements.txt -``` - -### 2. 运行安装向导 -访问 `http://localhost:8000/app/install.html` -- Step 1: 数据库配置 -- Step 2: Redis配置 -- Step 3: 安全密钥生成 -- Step 4: Telegram配置 (可选) -- Step 5: 创建管理员账号 - -### 3. 启动服务 (Supervisor) -```bash -# 复制配置 -cp deploy/supervisor/nexus.conf /etc/supervisor/conf.d/ -supervisorctl reread -supervisorctl update -supervisorctl start nexus -``` - -### 4. 验证运行 -```bash -# 健康检查 -curl http://localhost:8000/health - -# 运行测试 -python test_p1_p2.py -``` - ---- - -## 团队分工建议 - -| 角色 | 职责 | 相关文件 | -|------|------|----------| -| **后端开发** | API开发、业务逻辑 | `server/api/*.py`, `server/application/services/*.py` | -| **前端开发** | UI页面、交互逻辑 | `web/app/*.html`, `web/app/api.js`, `web/app/layout.js` | -| **DevOps** | 部署、监控、备份 | `deploy/`, `supervisor/`, `nginx/` | -| **DBA** | 数据库优化、迁移 | `server/domain/models/`, `server/infrastructure/database/` | -| **安全** | 审计、加密、认证 | `server/api/auth*.py`, 凭据加密逻辑 | - ---- - -## 监控与告警 - -### 3层守护机制 -1. **Supervisor**: Python崩溃自动重启 -2. **Python自检** (`self_monitor.py`): 30秒检查Redis/MySQL/WebSocket -3. **Shell健康检查** (`health_monitor.sh`): 1分钟HTTP检查,3次失败重启 - -### 告警通道 -- WebSocket → 前端实时通知 -- Telegram → 手机推送 - -### 关键指标 -- Agent心跳间隔: 60秒 -- Redis→MySQL刷新: 10分钟 -- 会话超时: 8小时 -- 告警冷却: 5分钟 - ---- - -## 测试验证 - -### 已完成的测试 -```bash -# 模块导入测试 (19/19通过) -python -c "import server.domain.models; ..." - -# 功能测试 (7/7通过) -python test_p1_p2.py -# - JWT updated_at claim -# - JWT password invalidation -# - Alert dedup cooldown -# - Server repo pagination -# - Config dedup command -# - Server dict no password -# - Admin.updated_at field -``` - ---- - -## 注意事项 - -### ⚠️ 安全相关 -1. **API_KEY**: 禁止修改,用于Agent认证 -2. **SECRET_KEY**: 禁止修改,用于JWT签名 -3. **ENCRYPTION_KEY**: 禁止修改,用于凭据加密 -4. 生产环境必须修改默认密码 - -### ⚠️ 数据库迁移 -首次启动会自动执行 `_apply_migrations()`: -- 添加 `admins.updated_at` 列 -- 创建7个索引 (如果不存在) - -### ⚠️ 文件权限 -- SSH私钥文件需要正确权限 (600) -- 日志目录需要写权限 - ---- - -## 联系方式 - -- 项目文档: `docs/` -- 配置文件: `.env` (不提交到Git) -- 测试脚本: `test_p1_p2.py` - ---- - -**交接日期**: 2026/05/22 -**代码状态**: ✅ 开发完成,待部署测试 -**Git提交**: 建议提交当前worktree更改到主分支 +历史全文:[docs/archive/project/PROJECT_HANDOVER.md](docs/archive/project/PROJECT_HANDOVER.md) diff --git a/docs/README.md b/docs/README.md index c63ebb18..c9cb08a0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,125 +1,74 @@ # Nexus 文档索引 -> 最后更新: 2026-06-01 +> 更新: 2026-06-04 · **唯一导航入口** --- -## project/ — 项目概况 +## 1. 活跃 SSOT(日常必读) + +| 文档 | 说明 | +|------|------| +| [project/nexus-functional-development-guide.md](project/nexus-functional-development-guide.md) | 功能 / API / 14 页 / 部署 | +| [project/nexus-functional-development-guide-appendix.md](project/nexus-functional-development-guide-appendix.md) | sync 端点、调用链、E2E 对照 | +| [project/AI-HANDOFF-2026-06-03.md](project/AI-HANDOFF-2026-06-03.md) | **当前** 会话接续(复制提示词) | +| [project/development-acceptance-standard.md](project/development-acceptance-standard.md) | 验收 L0–L5 | +| [project/local-integration-test.md](project/local-integration-test.md) | `bash scripts/local_verify.sh` | +| [project/linux-dev-paths.md](project/linux-dev-paths.md) | Linux 路径 | +| [project/risk-acceptance-single-operator.md](project/risk-acceptance-single-operator.md) | 单人运维风险接受 | +| [project/script-execution.md](project/script-execution.md) | 脚本执行 | +| [project/alert-push-policy.md](project/alert-push-policy.md) | 告警策略 | +| [project/deploy.md](project/deploy.md) | 部署补充 | +| [project/production-verification-checklist.md](project/production-verification-checklist.md) | L5 清单 | + +根目录 [AGENTS.md](../AGENTS.md) · [CLAUDE.md](../CLAUDE.md) · [.cursorrules](../.cursorrules) 为薄入口。 + +--- + +## 2. 变更与审计 + +| 目录 | 说明 | +|------|------| +| [changelog/](changelog/) | 每次代码变更(**不归档、不合并**)· [INDEX](changelog/INDEX.md) | +| [audit/](audit/) | 门控用审计 · [INDEX](audit/INDEX.md) · `2026-06-04-bug-scan-registry.json` | + +--- + +## 3. 活跃报告(`reports/`) + | 文件 | 说明 | |------|------| -| `project/status.md` | 项目进度总览 + 数据库结构 + 实施进度 | -| `project/roadmap.md` | 功能规划 + ADR架构决策(11项) + 技术债务 | -| `project/deploy.md` | 部署指南 (Ubuntu 20-24, Nginx+Supervisor) | -| **`project/phase-2-audit-remediation.md`** | **Phase 2 审计修复总览(开发 SSOT)** | -| **`project/wsl-integration-test.md`** | **WSL 代码验证**(venv → 启动 → smoke,不审 key) | -| `project/production-verification-checklist.md` | 首次部署验证清单(逐项勾选) | -| `project/alert-push-policy.md` | 告警推送产品策略 + 数据流 | -| `project/script-execution.md` | 脚本批量执行平台 SSOT | -| `project/audit-line-review-cursor-rule.md` | 逐行走读 Cursor 规则 | -| `project/line-walk-audit-standard.md` | 逐行走读判定标准 | -| `project/mysql-mcp-setup.md` | Cursor MySQL MCP 安装与 `.env` 同步 | -| `project/tech-stack-inventory.md` | 技术栈清单 + 连接池参数对齐 + v1勘误 | +| [audit-plugin-run-final-2026-06-04.md](reports/audit-plugin-run-final-2026-06-04.md) | 插件审计总验收 | +| [audit-frontend-14p-2026-06-04-closure.md](reports/audit-frontend-14p-2026-06-04-closure.md) | 前端 14 页 closure | +| [audit-phase-4-plugin-closure-2026-06-04.md](reports/audit-phase-4-plugin-closure-2026-06-04.md) | Phase4 收尾 | +| [2026-06-01-production-verification.md](reports/2026-06-01-production-verification.md) | 生产验证(待更新 L5) | +| [2026-06-01-final-acceptance-checklist.md](reports/2026-06-01-final-acceptance-checklist.md) | 终验清单 | -## design/ — 设计规格与实施计划 +批量 batch 报告 → [archive/audits/](archive/audits/) 合并卷。 -### 活跃设计 -| 文件 | 说明 | +--- + +## 4. 设计与标准 + +| 目录 | 说明 | |------|------| -| `design/specs/design-standards.md` | **设计标准** — 安全模型/性能基线/代码规范/架构模式 | -| `design/specs/2026-05-18-redis-iot-optimization.md` | Redis+实时数据架构 + Key规范 | -| `design/specs/2026-05-17-architecture-optimization.md` | 配置分发与部署架构 | -| `design/specs/2026-05-19-sprint-planning.md` | Sprint规划 — 已完成升级项 + 待实现建议 | -| `design/tech-stack-evaluation.md` | 技术栈评估 + 风险矩阵 + 连接池配置 | +| [design/specs/](design/specs/) | 设计规格 | +| [design/plans/](design/plans/) | 实施计划 | +| [../standards/](../standards/) | 开发与审计标准 | +| [project/standards-transfer-package.md](project/standards-transfer-package.md) | 标准转接包 | -### 已归档设计(历史参考) -| 文件 | 说明 | +--- + +## 5. 归档区 + +**[archive/README.md](archive/README.md)** — 2026-06 审计合并卷、旧 handoff、agentmemory、2026-05 审查报告。 + +--- + +## 6. 工具脚本 + +| 脚本 | 用途 | |------|------| -| `design/specs/2026-05-16-password-presets-design.md` | ⚠️ 归档 — 密码预设设计(引用旧文件结构) | -| `design/specs/2026-05-16-simplified-push-design.md` | ⚠️ 归档 — 简化推送设计(引用旧文件结构) | -| `design/specs/2026-05-17-retry-progress-design.md` | ⚠️ 归档 — 重试+进度设计(引用旧文件结构) | -| `design/specs/2026-05-17-server-add-optimize-design.md` | ⚠️ 归档 — 服务器添加优化设计(引用旧文件结构) | -| `design/specs/2026-05-18-file-manager-v2-design.md` | ⚠️ 归档 — 文件管理器v2设计(引用旧文件结构) | -| `design/specs/2026-05-19-code-review-followup.md` | ⚠️ 归档 — PHP代码审查(前端已迁移到Tailwind) | -| `design/plans/2026-05-16-password-presets.md` | ⚠️ 归档 — 密码预设实施计划 | -| `design/plans/2026-05-16-simplified-push.md` | ⚠️ 归档 — 简化推送实施计划 | -| `design/plans/2026-05-17-retry-progress.md` | ⚠️ 归档 — 重试+进度实施计划 | -| `design/plans/2026-05-17-server-add-optimize.md` | ⚠️ 归档 — 服务器添加优化实施计划 | -| `design/plans/2026-05-18-file-manager-v2.md` | ⚠️ 归档 — 文件管理器v2实施计划 | - -## reports/ — 审查与工作报告 - -### Phase 2 逐行走读(2026-05-22~23) -| 文件 | 说明 | -|------|------| -| **`reports/audit-phase-2-findings-matrix.md`** | **63 条 FINDING 全量状态表** | -| `reports/audit-phase-2-walk-closure.md` | 走读闭环 | -| `reports/audit-phase-2a`~`2j-line-walk.md` | 各批次逐行报告 | -| `reports/2026-05-23-full-audit-report.md` | 7 部门并行初审(与 Phase 2 交叉引用) | -| `reports/audit-full-vs-phase2-reconciliation.md` | C1–C12 与 Phase 2 对照表 | - -### 部门审查报告 -| 文件 | 说明 | -|------|------| -| `reports/review-cto-2026-05-21.md` | CTO审查 — 连接池/SSH/CORS/依赖(含勘误) | -| `reports/review-deploy-architecture-2026-05-21.md` | 运维总监审查 — 部署架构/三层守护/Nginx(含勘误) | -| `reports/review-quality-director-2026-05-21.md` | 质量总监审查 — 代码规范/datetime/测试(含勘误) | -| `reports/step-0-infrastructure/ecc-security-report.md` | ECC组安全审查 — Redis/Schema/认证/SSH/编码(含勘误) | -| `reports/signoff-2026-05-21.md` | 审查签字确认 | -| `reports/session-log-2026-05-21.md` | 会话操作日志 | - -### 实施报告 -| 文件 | 说明 | -|------|------| -| `reports/implementation-progress-2026-05-21.md` | 6步实施进度总览 | -| `reports/step-0-infrastructure/engineering-report.md` | Step 0: 基础设施加固 | -| `reports/step-0-infrastructure/ag-code-review-report.md` | Step 0: 代码审查 | -| `reports/step-0-infrastructure/testing-report.md` | Step 0: 测试报告 | -| `reports/step-1-data-layer/engineering-report.md` | Step 1: 数据层 | -| `reports/step-2-auth/engineering-report.md` | Step 2: 认证层 | -| `reports/step-3-webssh/engineering-report.md` | Step 3: Web SSH(含paramiko→asyncssh迁移) | -| `reports/step-4-sync/engineering-report.md` | Step 4: Sync引擎 | -| `reports/step-5-frontend/engineering-report.md` | Step 5: 前端迁移 | -| `reports/step-5-frontend/design-review-report.md` | Step 5: 前端设计审查 | -| `reports/step-5-frontend/product-department-report.md` | Step 5: 产品部报告 | - -## research/ — 竞品与技术调研 -| 文件 | 说明 | -|------|------| -| `research/jumpserver-easynode-architecture-analysis.md` | JumpServer & EasyNode 架构对比分析 | -| `research/ag-research-report.md` | AI Agent 调研报告 | - -## changelog/ — 变更记录(强制) - -> **纪律**:每次有意义的代码/配置修改都必须在此目录新增 `YYYY-MM-DD-<主题>.md`。见 `.cursor/rules/perfect-implementation.mdc`。 - -### Phase 2 安全与审计(2026-05-22~23) -| 文件 | 说明 | -|------|------| -| `changelog/2026-05-22-security-fixes-p0.md` | P0:WebSSH、中心 exec、crypto | -| `changelog/2026-05-22-security-fixes-p1.md` | P1:注入、危险命令、Agent | -| `changelog/2026-05-22-audit-p2-fixes.md` | P2 批次修复 | -| `changelog/2026-05-22-global-jwt-middleware.md` | 全局 JWT 中间件 | -| `changelog/2026-05-22-alert-push-dashboard.md` | 告警策略 + 仪表盘 | -| `changelog/2026-05-22-telegram-sanitize-and-security-tests.md` | Telegram 脱敏 + 单测 | -| `changelog/2026-05-22-frontend-vendor-selfhost.md` | 前端 vendor 自托管 | -| `changelog/2026-05-22-line-walk-audit-standard.md` | 逐行走读标准 | - -### 其他 -| 文件 | 说明 | -|------|------| -| `changelog/2026-05-22-implementation-standards-rule.md` | 完美实现与文档纪律全局规则 | -| `changelog/2026-05-22-tech-stack-rules-mysql-mcp.md` | 技术栈 Cursor 规则 + MySQL MCP | -| `changelog/2026-05-22-local-mysql-full-access-node20-fix.md` | 本地库可写 + Node20 安装修复 | -| `changelog/fix-plan-2026-05-20.md` | 代码问题修复计划(13项) | -| `changelog/fix-plan-full-2026-05-20.md` | 全量未完成项修复计划(24项) | -| `changelog/fix-verification-report-2026-05-20.md` | 修复验证报告 | - -## memory/ — 项目记忆(AI辅助) -| 文件 | 说明 | -|------|------| -| `memory/MEMORY.md` | 记忆索引 | -| `memory/mem_*.md` | 17个记忆文件(概述/决策/数据流/守护/模块/测试/等) | - -## 已移除(2026-06-01) - -`docs/team/`、`docs/skills/`、`TEAM_ROLES.md`、`.cursor/skills/` 已删除——不再使用虚拟部门或 superpowers 工作流 Skill。开发规范见 `standards/` 与 `.cursor/rules/`。 +| `scripts/local_verify.sh` | L2b 本地验证 | +| `scripts/consolidate_docs.py` | 文档归档合并(维护用) | +| `scripts/run_nexus_acceptance.py` | L4 验收 | +| `deploy/pre_deploy_check.sh` | 7 道门控 | diff --git a/docs/archive/README.md b/docs/archive/README.md new file mode 100644 index 00000000..768d606f --- /dev/null +++ b/docs/archive/README.md @@ -0,0 +1,17 @@ +# Nexus 文档归档区 + +> 更新: 2026-06-04 + +历史审计、旧 handoff、agentmemory。**日常请先读** [docs/README.md](../README.md)。 + +## 合并卷 + +| 文件 | 内容 | +|------|------| +| [audits/2026-06-04-line-walk-merged.md](audits/2026-06-04-line-walk-merged.md) | Line-walk batch | +| [audits/2026-06-04-delta-merged.md](audits/2026-06-04-delta-merged.md) | Delta D1–D8 | +| [audits/2026-06-04-phase2-merged.md](audits/2026-06-04-phase2-merged.md) | Phase2 P2 | +| [audits/2026-06-04-frontend-14p-merged.md](audits/2026-06-04-frontend-14p-merged.md) | 前端 14p | +| [memory/agentmemory-2026-05-merged.md](memory/agentmemory-2026-05-merged.md) | 旧 memory | + +原文在对应子目录;changelog 不归档。 diff --git a/docs/archive/audits/2026-06-04-delta-merged.md b/docs/archive/audits/2026-06-04-delta-merged.md new file mode 100644 index 00000000..bfb8435e --- /dev/null +++ b/docs/archive/audits/2026-06-04-delta-merged.md @@ -0,0 +1,183 @@ +# Delta D1–D8 合并卷 + +> 生成日期: 2026-06-04 · 源文件 8 篇 · 原文 `docs/archive/audits/2026-06-04-delta/` + +## 批次索引 + +### `audit-delta-2026-06-04-waveD1.md` + +# Phase 1 Delta 审计 — Wave D1(同步/后台) +## 登记 +## Step 3 — 规则扫描 H(摘要) +## 入口表(sync_v2.py API) +## Closure 表 +**len(H)=19, Closure=19** +## FINDING(本波) +无 P0/P1 新 FINDING。RISK 项与既有运维/单人决策一致,不阻塞。 +## DoD +- [x] len(H) == Closure +- [x] FINDING 含行号 +## 验证 + +### `audit-delta-2026-06-04-waveD2.md` + +# Phase 1 Delta 审计 — Wave D2(认证 / 安装 / WS / Agent) +## 登记 +## 入口表 +### install.py +### auth.py +### websocket.py +### agent.py +## Closure 表 +**len(H)=22, Closure=22** +## FINDING +无 P0/P1 新 FINDING。RISK:WS query JWT、Agent global key — 见 `docs/project/risk-acceptance-single-operator.md`。 +## DoD + +### `audit-delta-2026-06-04-waveD3.md` + +# Phase 1 Delta 审计 — Wave D3(服务器 / 设置 / 脚本 / WebSSH) +## 登记 +## 入口表(摘要) +### webssh.py +### servers.py(主要写操作) +### settings.py +### scripts.py +## Closure 表 +**len(H)=24, Closure=24** +## FINDING +无 P0/P1 新 FINDING。 +## DoD + +### `audit-delta-2026-06-04-waveD4.md` + +# Phase 1 Delta 审计 — Wave D4(前端 Push) +## 登记 +## Step 3 — 规则扫描 H(摘要) +## 入口表(前端 → API) +## Closure 表 +**len(H)=17, Closure=17** +## FINDING +无 P0/P1 新 FINDING。 +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-delta-2026-06-04-waveD5.md` + +# Phase 1 Delta 审计 — Wave D5(前端 Files / Terminal) +## 登记 +## Step 3 — 规则扫描 H(摘要) +## 入口表(前端 → API / WS) +## Closure 表 +**len(H)=18, Closure=18** +## FINDING +无 P0/P1 新 FINDING。 +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-delta-2026-06-04-waveD6.md` + +# Phase 1 Delta 审计 — Wave D6(认证链 / Login) +## 登记 +## Step 3 — 规则扫描 H(摘要) +## 入口表 +## Closure 表 +**len(H)=19, Closure=19** +## FINDING +无 P0/P1 新 FINDING。 +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-delta-2026-06-04-waveD7.md` + +# Phase 1 Delta 审计 — Wave D7(Deploy / 本地验证脚本) +**标准**: 变更审查(运维/门控;非业务 API 8 步,沿用 Closure 表格式) +## 登记 +## Step 3 — 规则扫描 H(摘要) +## 入口表(脚本调用链) +## Closure 表 +**len(H)=16, Closure=16** +## FINDING +无 P0/P1 新 FINDING。 +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-delta-2026-06-04-waveD8-closure.md` + +# Phase 1 Delta 审计 — Wave D8(汇总 Closure) +**标准**: Phase 1 收尾 DoD +## 汇总表 +| 波次 | 主题 | 文件数 | H | P0/P1 | 报告 | +## 已接受 RISK(跨波重复,不重复开 FINDING) +## Registry 更新 +## Step 3 / Closure / DoD +- **len(H) 汇总** = 135,各波 Closure 均已 100% 对齐 +- **无 P0/P1** 待修项进入 Phase 2 +## 下一步(计划 Phase 2 / L3) +## 验证 + +## Closure 摘录(合并) + +| 1 | `server/api/sync_v2.py` | Python | 1656 | 1–200, 680–1080, 1280–1657 + 全文件 `@router`/grep H | +| 2 | `server/application/services/sync_engine_v2.py` | Python | 552 | 1–552 全文 | +| 3 | `server/background/schedule_runner.py` | Python | 262 | 1–262 全文 | +| 4 | `server/background/retry_runner.py` | Python | 169 | 1–169 全文 | +| 5 | `server/background/heartbeat_flush.py` | Python | 101 | 1–101 全文 | +| H | 文件:行号 | 判定 | 理由 | +| H-Install-lock | install.py:344-350 | SAFE | `_reject_if_locked` 阻断突变 | +| H-Install-token | install.py:314-327 | SAFE | `secrets.compare_digest` 一次性 token | +| H-Install-token | install.py:601 | SAFE | create-admin 必须 token | +| H-Install-SQL | install.py:540-544 | SAFE | 参数化 INSERT settings | +| H-Install-DDL | install.py:489-503 | SAFE | DDL 幂等 except pass | +| H-Install-subprocess | install.py:273-293 | SAFE | crontab/supervisor 固定 argv | +| H-Auth-brute | auth.py:125-138 | SAFE | 429/202 由 AuthService | +| H-Auth-cookie | auth.py:38-54 | SAFE | HttpOnly + Secure(HTTPS) + SameSite=Lax | +| H-Auth-TOTP-IDOR | auth.py:223-259 | SAFE | admin_id 必须等于 JWT sub | +| H-Auth-password | auth.py:288-305 | SAFE | bcrypt + token_version 失效 | +| H-Auth-webssh | auth.py:330-349 | SAFE | 短效 server-bound token | +| H-JWT-middleware | auth_jwt.py:78-146 | SAFE | ASGI 层拦截 /api/* | +| H-JWT-public | auth_jwt.py:38-50 | SAFE | 公开前缀含 agent/install/ws | +| H-JWT-tv | auth_jwt.py:222-226 | SAFE | token_version 精确匹配 | +| H-WS-auth | websocket.py:303-311 | SAFE | 无 token → 4001;无效 → 4401 | +| H-WS-auth | websocket.py:366-407 | SAFE | tv + updated_at 双检 | +| H-WS-ADR011 | websocket.py:9,300 | RISK | JWT 在 query;单人运维已接受 ADR-011 | +| H-Agent-key | agent.py:40-57 | SAFE | compare_digest;handler 二次验 per-server | +| H-Agent-unknown | agent.py:193-199 | SAFE | 未知 server 200 discard,不写入 | +| H-Agent-global | agent.py:84-92 | RISK | legacy global API_KEY;risk-acceptance 文档 | +| H-Agent-callback | agent.py:324-347 | SAFE | rate limit + job secret | +| H-Agent-no-exec | agent.py:378 | SAFE | 控制面无 shell exec | +| POST | `/{id}/install-agent` 等 | JWT + SSH | +| 文件 | H 命中 | +| usePushForm.ts | H-Auth, H-Upload, H-Path | +| usePushPreview.ts | H-Auth, H-Path | +| usePushProgress.ts | H-Auth, H-WS, H-Batch | +| PushZipUpload.vue | H-Upload, H-XSS | +| PushServerGrid.vue | H-XSS | +| useFilesActions.ts | H-Auth, H-Path, H-Delete, H-Upload | +| useFilesEditor.ts | H-Auth, H-Size | +| useFilesPermissions.ts | H-Auth, H-Sudo | +| useTerminalSessions.ts | H-Auth, H-WS, H-Path, H-Cmd | +| useTerminalCmdBar.ts | H-Storage, H-Cmd | +| LoginPage.vue | H-Secret, H-Redirect, H-Lockout, H-XSS | +| auth.ts | H-Token, H-Refresh, H-Profile | +| api/index.ts | H-Auth, H-Refresh, H-401 | +| router/index.ts | H-Guard, H-Redirect | +| wsUrl.ts | H-WS | +| pre_deploy_check.sh | H-Gate, H-Secret, H-Git | +| local_verify.sh | H-Chain | +| local_integration_smoke.sh | H-Health, H-Auth | +| start-dev.sh | H-DevBind, H-Env | +| docker-compose.yml | H-Port, H-DefaultCreds | +| 波次 | 主题 | 文件数 | H | P0/P1 | 报告 | +| D1 | sync/后台 | 5 | 19 | 0 | [waveD1](audit-delta-2026-06-04-waveD1.md) | +| D2 | auth/agent/ws | 5 | 22 | 0 | [waveD2](audit-delta-2026-06-04-waveD2.md) | +| D3 | servers/settings/scripts/webssh | 5 | 24 | 0 | [waveD3](audit-delta-2026-06-04-waveD3.md) | +| D4 | 前端 Push | 5 | 17 | 0 | [waveD4](audit-delta-2026-06-04-waveD4.md) | +| D5 | 前端 Files/Terminal | 5 | 18 | 0 | [waveD5](audit-delta-2026-06-04-waveD5.md) | +| D6 | 认证链 Login | 5 | 19 | 0 | [waveD6](audit-delta-2026-06-04-waveD6.md) | +| D7 | Deploy/本地脚本 | 5 | 16 | 0 | [waveD7](audit-delta-2026-06-04-waveD7.md) | +| **合计** | | **35** | **135** | **0** | | diff --git a/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD1.md b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD1.md new file mode 100644 index 00000000..f4ea7d5c --- /dev/null +++ b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD1.md @@ -0,0 +1,95 @@ +# Phase 1 Delta 审计 — Wave D1(同步/后台) + +**日期**: 2026-06-04 +**范围**: 推送/sync 核心路径(Code Review batch1 后 delta) +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `server/api/sync_v2.py` | Python | 1656 | 1–200, 680–1080, 1280–1657 + 全文件 `@router`/grep H | +| 2 | `server/application/services/sync_engine_v2.py` | Python | 552 | 1–552 全文 | +| 3 | `server/background/schedule_runner.py` | Python | 262 | 1–262 全文 | +| 4 | `server/background/retry_runner.py` | Python | 169 | 1–169 全文 | +| 5 | `server/background/heartbeat_flush.py` | Python | 101 | 1–101 全文 | + +## Step 3 — 规则扫描 H(摘要) + +| 文件 | H 命中 | +|------|--------| +| sync_v2.py | H-Shell, H-Auth, H-Path, H-Audit, H-Upload | +| sync_engine_v2.py | H-Shell, H-AuthN/A, H-Concurrency | +| schedule_runner.py | H-Cron, H-Script-exec, H-Lock | +| retry_runner.py | H-Lock, H-Retry | +| heartbeat_flush.py | H-Redis, H-DB | + +## 入口表(sync_v2.py API) + +| 方法 | 路径 | 鉴权 | +|------|------|------| +| POST | `/api/sync/files` | JWT `get_current_admin` | +| POST | `/api/sync/preview` | 同上 | +| POST | `/api/sync/file-ops` | 同上 | +| POST | `/api/sync/file-clipboard` | 同上 | +| POST | `/api/sync/browse` | 同上 | +| POST | `/api/sync/browse-local` | 同上 | +| POST | `/api/sync/local-file-ops` | 同上 | +| POST | `/api/sync/local-file-preview` | 同上 | +| POST | `/api/sync/cancel` | 同上 | +| POST | `/api/sync/reconcile-stale-logs` | 同上 | +| POST | `/api/sync/validate-source-path` | 同上 | +| POST | `/api/sync/diagnose` | 同上 | +| POST | `/api/sync/file-diff` | 同上 | +| POST | `/api/sync/upload` | 同上 | +| POST | `/api/sync/upload-zip` | 同上 | +| POST | `/api/sync/verify` | 同上 | +| POST | `/api/sync/download` | 同上 | +| POST | `/api/sync/read-file` | 同上 | +| POST | `/api/sync/write-file` | 同上 | +| POST | `/api/sync/chmod` | 同上 | +| POST | `/api/sync/compress` | 同上 | +| POST | `/api/sync/decompress` | 同上 | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Shell | sync_v2.py:156-173 | SAFE | 远程路径 `normalize_remote_abs_path` + `shlex.quote` | +| H-Shell | sync_v2.py:777 | SAFE | `remote_file` 经 `remote_join`+quote;`wc -c && cat` 单路径 | +| H-Path | sync_v2.py:721-731 | SAFE | `ensure_under_nexus_upload` + prefix 校验 | +| H-Path | sync_v2.py:887-890 | SAFE | 上传文件名去斜杠 | +| H-Path | sync_v2.py:999-1005 | SAFE | ZIP slip:`assert_zip_member_safe` | +| H-Auth | sync_v2.py:74-1610 | SAFE | 全部 22 路由 `Depends(get_current_admin)` | +| H-Audit | sync_v2.py:119-122 等 | SAFE | CUD/敏感操作 `_audit_sync` | +| H-Upload | sync_v2.py:876-877 | SAFE | 100MB 上限 | +| H-Upload | sync_v2.py:977-978 | SAFE | ZIP 500MB 上限 | +| H-Shell | sync_engine_v2.py:433-465 | RISK | `StrictHostKeyChecking=no` 运维惯例;单人环境已接受 | +| H-Shell | sync_engine_v2.py:440-445 | RISK | sshpass/SSHPASS;内部工具,凭据加密存储 | +| H-Concurrency | sync_engine_v2.py:89-150 | SAFE | `_db_lock` 串行化 sync_log 写 | +| H-Cron | schedule_runner.py:58-72 | RISK | 畸形 cron 字段 `int()` 可抛 ValueError;外层 254 行捕获 rollback | +| H-Script | schedule_runner.py:198-205 | SAFE | 调度脚本仅 JWT 管理员配置的 schedule 触发 | +| H-Lock | schedule_runner.py:125-131 | SAFE | `FOR UPDATE SKIP LOCKED` 防双触发 | +| H-Lock | retry_runner.py:67-76 | SAFE | SKIP LOCKED 认领 | +| H-Retry | retry_runner.py:22-59 | SAFE | 指数退避 + max_retries | +| H-Redis | heartbeat_flush.py:42-48 | SAFE | scan 失败 log+continue | +| H-DB | heartbeat_flush.py:57-99 | SAFE | 参数化 ORM update;未知 server_id rowcount 0 跳过 | + +**len(H)=19, Closure=19** + +## FINDING(本波) + +无 P0/P1 新 FINDING。RISK 项与既有运维/单人决策一致,不阻塞。 + +## DoD + +- [x] len(H) == Closure +- [x] Read 覆盖 1..N(sync_v2 大文件分段 + 全路由 grep) +- [x] FINDING 含行号 +- [x] 入口表 + sink 标注 +- [x] 逐行完成 ✓(D1 五文件) + +## 验证 + +- `docker-compose.yml` Redis 发布 6379(修复本地 uvicorn 连 Redis) +- 待跑:`bash scripts/local_verify.sh` diff --git a/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD2.md b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD2.md new file mode 100644 index 00000000..cb3618c5 --- /dev/null +++ b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD2.md @@ -0,0 +1,100 @@ +# Phase 1 Delta 审计 — Wave D2(认证 / 安装 / WS / Agent) + +**日期**: 2026-06-04 +**范围**: Code Review batch2 后 delta — 认证与 Agent 路径 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `server/api/install.py` | Python | 746 | 1–746 全文 | +| 2 | `server/api/auth.py` | Python | 374 | 1–374 全文 | +| 3 | `server/api/auth_jwt.py` | Python | 274 | 1–274 全文 | +| 4 | `server/api/websocket.py` | Python | 552 | 1–552 全文 | +| 5 | `server/api/agent.py` | Python | 378 | 1–378 全文 | + +## 入口表 + +### install.py + +| 方法 | 路径 | 鉴权 | +|------|------|------| +| GET | `/api/install/status` | 无(已锁定 404) | +| GET | `/api/install/env-check` | 安装模式 + 未 lock | +| POST | `/api/install/init-db` | 无 .env + 未 lock | +| POST | `/api/install/create-admin` | `install_token` | +| POST | `/api/install/lock` | 需已有 admin | +| GET | `/api/install/state` | 未 lock | + +### auth.py + +| 方法 | 路径 | 鉴权 | +|------|------|------| +| POST | `/api/auth/login` | 公开 | +| POST | `/api/auth/refresh` | Cookie/body refresh | +| POST | `/api/auth/logout` | Cookie | +| POST | `/api/auth/totp/*` | JWT + self admin_id | +| PUT | `/api/auth/password` | JWT + 当前密码 (+TOTP) | +| POST | `/api/auth/webssh-token` | JWT + server 存在 | +| GET | `/api/auth/me` | JWT | + +### websocket.py + +| 类型 | 路径 | 鉴权 | +|------|------|------| +| WS | `/ws/alerts` | Query `?token=` JWT | +| WS | `/ws/sync` | 同上 | + +### agent.py + +| 方法 | 路径 | 鉴权 | +|------|------|------| +| POST | `/api/agent/heartbeat` | X-API-Key + per-server key | +| POST | `/api/agent/script-callback` | X-API-Key + job secret + rate limit | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Install-lock | install.py:344-350 | SAFE | `_reject_if_locked` 阻断突变 | +| H-Install-token | install.py:314-327 | SAFE | `secrets.compare_digest` 一次性 token | +| H-Install-token | install.py:601 | SAFE | create-admin 必须 token | +| H-Install-SQL | install.py:540-544 | SAFE | 参数化 INSERT settings | +| H-Install-DDL | install.py:489-503 | SAFE | DDL 幂等 except pass | +| H-Install-subprocess | install.py:273-293 | SAFE | crontab/supervisor 固定 argv | +| H-Auth-brute | auth.py:125-138 | SAFE | 429/202 由 AuthService | +| H-Auth-cookie | auth.py:38-54 | SAFE | HttpOnly + Secure(HTTPS) + SameSite=Lax | +| H-Auth-TOTP-IDOR | auth.py:223-259 | SAFE | admin_id 必须等于 JWT sub | +| H-Auth-password | auth.py:288-305 | SAFE | bcrypt + token_version 失效 | +| H-Auth-webssh | auth.py:330-349 | SAFE | 短效 server-bound token | +| H-JWT-middleware | auth_jwt.py:78-146 | SAFE | ASGI 层拦截 /api/* | +| H-JWT-public | auth_jwt.py:38-50 | SAFE | 公开前缀含 agent/install/ws | +| H-JWT-tv | auth_jwt.py:222-226 | SAFE | token_version 精确匹配 | +| H-WS-auth | websocket.py:303-311 | SAFE | 无 token → 4001;无效 → 4401 | +| H-WS-auth | websocket.py:366-407 | SAFE | tv + updated_at 双检 | +| H-WS-ADR011 | websocket.py:9,300 | RISK | JWT 在 query;单人运维已接受 ADR-011 | +| H-Agent-key | agent.py:40-57 | SAFE | compare_digest;handler 二次验 per-server | +| H-Agent-unknown | agent.py:193-199 | SAFE | 未知 server 200 discard,不写入 | +| H-Agent-global | agent.py:84-92 | RISK | legacy global API_KEY;risk-acceptance 文档 | +| H-Agent-callback | agent.py:324-347 | SAFE | rate limit + job secret | +| H-Agent-no-exec | agent.py:378 | SAFE | 控制面无 shell exec | + +**len(H)=22, Closure=22** + +## FINDING + +无 P0/P1 新 FINDING。RISK:WS query JWT、Agent global key — 见 `docs/project/risk-acceptance-single-operator.md`。 + +## DoD + +- [x] len(H) == Closure +- [x] Read 1..N 全文 +- [x] 入口表 + sink +- [x] 逐行完成 ✓(D2 五文件) + +## 验证 + +```bash +bash scripts/local_verify.sh # 预期全绿 +``` diff --git a/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD3.md b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD3.md new file mode 100644 index 00000000..8b8f0e8a --- /dev/null +++ b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD3.md @@ -0,0 +1,85 @@ +# Phase 1 Delta 审计 — Wave D3(服务器 / 设置 / 脚本 / WebSSH) + +**日期**: 2026-06-04 +**范围**: Code Review batch2–3 相关路径 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `server/api/webssh.py` | Python | 398 | 1–398 全文 | +| 2 | `server/api/servers.py` | Python | 1741 | 1–250, 1059–1290, 1681–1742 + 全路由 grep | +| 3 | `server/api/settings.py` | Python | 1403 | 1–130, 280–384, 562–730, 881–930 + grep | +| 4 | `server/application/services/script_service.py` | Python | 734 | 1–734 全文 | +| 5 | `server/api/scripts.py` | Python | 418 | 1–418 全文 | + +## 入口表(摘要) + +### webssh.py +| 类型 | 路径 | 鉴权 | +|------|------|------| +| WS | `/ws/terminal/{server_id}` | JWT `purpose=webssh` + server_id 绑定 | + +### servers.py(主要写操作) +| 方法 | 路径 | 鉴权 | +|------|------|------| +| POST/PUT/DELETE | `/api/servers/`… | JWT | +| POST | `/{id}/agent-key` | JWT + 当前密码 | +| POST | `/{id}/install-agent` 等 | JWT + SSH | + +### settings.py +| 方法 | 路径 | 鉴权 | +|------|------|------| +| GET/PUT | `/api/settings/*` | JWT;IMMUTABLE_KEYS 403 | +| POST | `/api-key/reveal`, `/telegram/reveal-token` | JWT + re-auth | + +### scripts.py +| 方法 | 路径 | 鉴权 | +|------|------|------| +| CRUD/exec | `/api/scripts/*` | JWT 全路由 | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-WS-auth | webssh.py:96-109 | SAFE | webssh JWT + server_id 必须匹配路径 | +| H-WS-IDOR | webssh.py:106-108 | SAFE | 非绑定 token → 4003 | +| H-WS-cred | webssh.py:127-135 | SAFE | SSH 凭据未配置则拒绝 | +| H-WS-audit | webssh.py:137-157 | SAFE | connect/disconnect 审计 | +| H-WS-cmdlog | webssh.py:276-290 | SAFE | 命令日志 + dangerous check | +| H-WS-ADR011 | webssh.py:92 | RISK | query token;已接受 | +| H-Server-mask | servers.py:1692-1698 | SAFE | password_set / 密钥不返回明文 | +| H-Server-encrypt | servers.py:1096-1099 | SAFE | Fernet 加密存储 | +| H-Server-allowlist | servers.py:1163-1187 | SAFE | UPDATE 字段白名单 | +| H-Server-agent-key | servers.py:1251-1288 | SAFE | re-auth 后生成/返回一次 | +| H-Server-shell | servers.py:631-633 | SAFE | install cmd shlex.quote | +| H-Server-sudo | servers.py:36-60 | RISK | 临时 sudoers;运维必要 | +| H-Settings-immutable | settings.py:331-334 | SAFE | api_key 等不可 PUT | +| H-Settings-mask | settings.py:114-128 | SAFE | GET 敏感项 value 空 + value_set | +| H-Settings-reauth | settings.py:93-98 | SAFE | reveal 需 bcrypt | +| H-Settings-SSRF | settings.py:68-88 | SAFE | 订阅 URL 私有 IP 拦截 | +| H-Settings-PUT-leak | settings.py:383 | RISK | PUT 响应可能含 telegram 明文;JWT 已认证 | +| H-Script-danger | scripts.py:352-359 | SAFE | check_dangerous_command 拒绝 | +| H-Script-cred | scripts.py:407-418 | SAFE | 凭据 API 无 password 字段 | +| H-Script-allowlist | scripts.py:111-114,303-306 | SAFE | credential/script UPDATE 白名单 | +| H-Svc-redact | script_service.py:108-111 | SAFE | 执行记录 command 脱敏 DB_PASS | +| H-Svc-ssh | script_service.py:680-698 | SAFE | SSH exec 经 pool | +| H-Svc-kill | script_service.py:306-322 | SAFE | kill 命令 pid/log 路径校验 | +| H-Svc-server-map | script_service.py:519-523 | SAFE | 预加载 server_map 避免并行竞态 | + +**len(H)=24, Closure=24** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] len(H) == Closure +- [x] Read 覆盖(大文件分段 + 全路由) +- [x] 逐行完成 ✓(D3 五文件) + +## 验证 + +`bash scripts/local_verify.sh` — 预期全绿 diff --git a/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD4.md b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD4.md new file mode 100644 index 00000000..e2f43fff --- /dev/null +++ b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD4.md @@ -0,0 +1,74 @@ +# Phase 1 Delta 审计 — Wave D4(前端 Push) + +**日期**: 2026-06-04 +**范围**: Code Review 后 push 页 composables + 组件 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `frontend/src/composables/push/usePushForm.ts` | TS | 101 | 1–101 全文 | +| 2 | `frontend/src/composables/push/usePushPreview.ts` | TS | 104 | 1–104 全文 | +| 3 | `frontend/src/composables/push/usePushProgress.ts` | TS | 294 | 1–294 全文 | +| 4 | `frontend/src/components/push/PushZipUpload.vue` | Vue | 51 | 1–51 全文 | +| 5 | `frontend/src/components/push/PushServerGrid.vue` | Vue | 110 | 1–110 全文 | + +**关联(本波未单独登记)**: `usePushPage.ts` 仅编排 lifecycle,无独立 sink。 + +## Step 3 — 规则扫描 H(摘要) + +| 文件 | H 命中 | +|------|--------| +| usePushForm.ts | H-Auth, H-Upload, H-Path | +| usePushPreview.ts | H-Auth, H-Path | +| usePushProgress.ts | H-Auth, H-WS, H-Batch | +| PushZipUpload.vue | H-Upload, H-XSS | +| PushServerGrid.vue | H-XSS | + +## 入口表(前端 → API) + +| 调用方 | 方法 | 路径 | 鉴权 | +|--------|------|------|------| +| usePushForm | POST multipart | `/sync/upload-zip` | http JWT | +| usePushPreview | POST | `/sync/preview` | http JWT | +| usePushProgress | POST | `/sync/files`, `/sync/cancel` | http JWT | +| usePushProgress | WS | `/ws/sync?token=` | JWT query(已接受 RISK) | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Auth | usePushForm.ts:65-67 | SAFE | 经 `@/api` http,Bearer JWT | +| H-Upload | usePushForm.ts:52,57 | RISK | 客户端仅 `.zip` 后缀;服务端 ZIP slip/大小限制(D1) | +| H-Path | usePushForm.ts:69-72 | SAFE | `source_path` 来自服务端 upload-zip 响应 | +| H-Path | usePushForm.ts:38-40 | SAFE | target_path 必填;远程校验在 sync_v2 | +| H-Auth | usePushPreview.ts:28-38 | SAFE | preview POST JWT + server_id 参数化 | +| H-Concurrency | usePushPreview.ts:72-77 | SAFE | `PREVIEW_CONCURRENCY=4` 限流 | +| H-Auth | usePushProgress.ts:237-243 | SAFE | push POST JWT + batch_id | +| H-WS | usePushProgress.ts:137-142 | RISK | query token;单人运维已接受 | +| H-WS | usePushProgress.ts:79-80 | SAFE | batch_id 过滤防串批 | +| H-WS | usePushProgress.ts:165-167 | SAFE | 4401 → forceLogout | +| H-Batch | usePushProgress.ts:244-246 | SAFE | 服务端 batch_id 可覆盖客户端 | +| H-Cancel | usePushProgress.ts:194-209 | SAFE | cancel 带 batch_id | +| H-Timer | usePushProgress.ts:261-275 | SAFE | 300s 安全超时 + dispose 清理 | +| H-Secret | usePushForm/Preview/Progress | SAFE | 无 localStorage 密码/密钥 | +| H-XSS | PushZipUpload.vue:22 | SAFE | `{{ uploadedZip.name }}` 文本插值 | +| H-XSS | PushServerGrid.vue:66-77 | SAFE | 无 v-html;状态 chip 文本插值 | +| H-Upload | PushZipUpload.vue:18 | SAFE | `accept=".zip"` + 父 composable 后缀检查 | + +**len(H)=17, Closure=17** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] len(H) == Closure +- [x] 五文件全文 Read +- [x] 无 v-html / localStorage 凭据 + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD5.md b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD5.md new file mode 100644 index 00000000..72dd3657 --- /dev/null +++ b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD5.md @@ -0,0 +1,80 @@ +# Phase 1 Delta 审计 — Wave D5(前端 Files / Terminal) + +**日期**: 2026-06-04 +**范围**: files/terminal composables(Code Review 后 delta) +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `frontend/src/composables/files/useFilesActions.ts` | TS | 609 | 1–609 全文 | +| 2 | `frontend/src/composables/files/useFilesEditor.ts` | TS | 163 | 1–163 全文 | +| 3 | `frontend/src/composables/files/useFilesPermissions.ts` | TS | 101 | 1–101 全文 | +| 4 | `frontend/src/composables/terminal/useTerminalSessions.ts` | TS | 749 | 1–749 全文 | +| 5 | `frontend/src/composables/terminal/useTerminalCmdBar.ts` | TS | 108 | 1–108 全文 | + +**关联**: `types.ts` 中 `sanitizeRemotePath`(40–43)已纳入 terminal 路径 H 判定。 + +## Step 3 — 规则扫描 H(摘要) + +| 文件 | H 命中 | +|------|--------| +| useFilesActions.ts | H-Auth, H-Path, H-Delete, H-Upload | +| useFilesEditor.ts | H-Auth, H-Size | +| useFilesPermissions.ts | H-Auth, H-Sudo | +| useTerminalSessions.ts | H-Auth, H-WS, H-Path, H-Cmd | +| useTerminalCmdBar.ts | H-Storage, H-Cmd | + +## 入口表(前端 → API / WS) + +| 调用方 | 方法 | 路径 | 鉴权 | +|--------|------|------|------| +| useFilesActions | POST | `/sync/file-ops`, `/sync/write-file`, `/sync/chmod`, `/sync/compress`, `/sync/decompress`, `/sync/upload`, `/sync/download` | http JWT | +| useFilesEditor | 经 `readRemoteFileContent` | `/sync/read-file` | http JWT | +| useFilesPermissions | GET/POST | `/servers/{id}/files-capability`, `setup-files-sudo` | http JWT | +| useTerminalSessions | POST | `/auth/webssh-token` | http JWT | +| useTerminalSessions | WS | `/ws/terminal/{id}?token=` | purpose=webssh JWT | +| useTerminalCmdBar | WS DATA | 经 `sendWsData` | 同上 | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Auth | useFilesActions.ts:255-494 | SAFE | 全部经 `@/api` JWT | +| H-Path | useFilesActions.ts:297-301,461-464 | SAFE | `validatePathSegment` 拦截 `/` `..` | +| H-Path | useFilesActions.ts:340-347 | RISK | rename 未调 validatePathSegment;后端 sync_v2 校验 | +| H-Path | useFilesActions.ts:71-78,119 | SAFE | `normalizeRemotePath` / `joinRemotePath` | +| H-Delete | useFilesActions.ts:393-414 | SAFE | confirm + 逐条 delete;失败计数 | +| H-Upload | useFilesActions.ts:486-494 | SAFE | server_id + remote_path 参数化 POST | +| H-Auth | useFilesEditor.ts:94-98 | SAFE | readRemoteFileContent + server_id | +| H-Size | useFilesEditor.ts:63-70 | SAFE | 2MB 编辑上限 `FILE_EDITOR_MAX_BYTES` | +| H-Auth | useFilesPermissions.ts:65-78 | SAFE | JWT GET/POST | +| H-Sudo | useFilesPermissions.ts:73-91 | SAFE | 一键 sudo 走后端 re-auth+SSH;无密码回传 | +| H-Storage | useFilesPermissions.ts:56 | SAFE | sessionStorage 仅 hint dismissed 标记 | +| H-Auth | useTerminalSessions.ts:279-281 | SAFE | webssh-token 绑定 server_id | +| H-WS | useTerminalSessions.ts:293-294 | RISK | query token;单人运维已接受 | +| H-WS | useTerminalSessions.ts:350-363 | SAFE | 4001/4003 分支处理 | +| H-Path | useTerminalSessions.ts:159-163,513,578 | RISK | `sanitizeRemotePath` 未拦 `;|&$`;cd 字符串拼接;管理员会话 | +| H-Cmd | useTerminalSessions.ts:648-655 | SAFE | 快捷命令来自 API/内置白名单 | +| H-Cmd | useTerminalCmdBar.ts:21-34 | SAFE | 命令经 WS DATA;后端 dangerous check | +| H-Storage | useTerminalCmdBar.ts:7-33 | RISK | localStorage 存命令历史(非密码);UX 便利 | +| H-Secret | 五文件 | SAFE | 无 password/api_key 存 localStorage | + +**len(H)=18, Closure=18** + +## FINDING + +无 P0/P1 新 FINDING。 + +可选后续(P2/UX):rename 前端补 `validatePathSegment`;`sanitizeRemotePath` 收紧或 cd 改用引号包裹。 + +## DoD + +- [x] len(H) == Closure +- [x] 五文件全文 Read(大文件分段至 EOF) +- [x] 无 v-html / 凭据明文存储 + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD6.md b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD6.md new file mode 100644 index 00000000..cab6be5e --- /dev/null +++ b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD6.md @@ -0,0 +1,76 @@ +# Phase 1 Delta 审计 — Wave D6(认证链 / Login) + +**日期**: 2026-06-04 +**范围**: 登录页 + auth store + HTTP 客户端 + 路由守卫 + WS URL +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `frontend/src/pages/LoginPage.vue` | Vue | 244 | 1–244 全文 | +| 2 | `frontend/src/stores/auth.ts` | TS | 132 | 1–132 全文 | +| 3 | `frontend/src/api/index.ts` | TS | 308 | 1–308 全文 | +| 4 | `frontend/src/router/index.ts` | TS | 68 | 1–68 全文 | +| 5 | `frontend/src/utils/wsUrl.ts` | TS | 23 | 1–23 全文 | + +## Step 3 — 规则扫描 H(摘要) + +| 文件 | H 命中 | +|------|--------| +| LoginPage.vue | H-Secret, H-Redirect, H-Lockout, H-XSS | +| auth.ts | H-Token, H-Refresh, H-Profile | +| api/index.ts | H-Auth, H-Refresh, H-401 | +| router/index.ts | H-Guard, H-Redirect | +| wsUrl.ts | H-WS | + +## 入口表 + +| 模块 | 入口 | 鉴权 | +|------|------|------| +| LoginPage | POST `/auth/login` | 公开 | +| LoginPage | GET `/settings/bing-wallpapers` | 公开(auth_jwt 白名单) | +| auth store | POST `/auth/refresh`, `/auth/logout`, GET `/auth/me` | refresh cookie / Bearer | +| api | `fetchAuthed` 全站 API | Bearer + credentials | +| router | `beforeEach` | bootstrapped + isLoggedIn | +| wsUrl | WS URL 构建 | 供 terminal/sync 使用 | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Secret | LoginPage.vue:102-103 | SAFE | password 仅组件 ref,不落 localStorage | +| H-Secret | auth.ts:26-27 | SAFE | access token 内存 Pinia ref | +| H-Redirect | LoginPage.vue:178-179 | SAFE | `startsWith('/') && !startsWith('//')` 防 open redirect | +| H-Lockout | LoginPage.vue:186-188 | SAFE | 429 → 15min 本地 lockout UI | +| H-TOTP | LoginPage.vue:182-184 | SAFE | TotpRequiredError → 显示 TOTP 字段 | +| H-XSS | LoginPage.vue:11-12 | SAFE | `{{ error }}` 文本插值,无 v-html | +| H-Refresh | auth.ts:45-66 | SAFE | HttpOnly cookie refresh;失败 silent | +| H-Token | auth.ts:36-38 | SAFE | exp 解码仅用于续期阈值 | +| H-Profile | auth.ts:89-97 | SAFE | 401 → forceLogout | +| H-Auth | api/index.ts:68-70 | SAFE | Bearer 注入 | +| H-Refresh | api/index.ts:19-44 | SAFE | 单飞 refreshInFlight 防并发 | +| H-Refresh | api/index.ts:84-86 | SAFE | 过期前 5min 主动 refresh | +| H-401 | api/index.ts:94-110 | SAFE | 401 重试一次后 forceLogout | +| H-Cookie | api/index.ts:27-28,91 | SAFE | credentials: include | +| H-Guard | router/index.ts:55-65 | SAFE | 非 public 路由需 isLoggedIn | +| H-Guard | router/index.ts:57-58 | SAFE | bootstrapped 前 tryRestoreSession | +| H-Public | router/index.ts:18 | SAFE | Login meta.public | +| H-WS | wsUrl.ts:17-20 | RISK | token 放 query;已接受 | +| H-Wallpaper | LoginPage.vue:121-123 | SAFE | 公开壁纸 API intentional | + +**len(H)=19, Closure=19** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] len(H) == Closure +- [x] 五文件全文 Read +- [x] 认证链:内存 token + HttpOnly refresh + 路由守卫 + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD7.md b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD7.md new file mode 100644 index 00000000..40e3334d --- /dev/null +++ b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD7.md @@ -0,0 +1,78 @@ +# Phase 1 Delta 审计 — Wave D7(Deploy / 本地验证脚本) + +**日期**: 2026-06-04 +**范围**: 门控脚本 + 本地 dev/verify + docker-compose +**标准**: 变更审查(运维/门控;非业务 API 8 步,沿用 Closure 表格式) + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `deploy/pre_deploy_check.sh` | Bash | 299 | 1–299 全文 | +| 2 | `scripts/local_verify.sh` | Bash | 25 | 1–25 全文 | +| 3 | `scripts/local_integration_smoke.sh` | Bash | 91 | 1–91 全文 | +| 4 | `scripts/start-dev.sh` | Bash | 90 | 1–90 全文 | +| 5 | `docker-compose.yml` | YAML | 89 | 1–89 全文 | + +## Step 3 — 规则扫描 H(摘要) + +| 文件 | H 命中 | +|------|--------| +| pre_deploy_check.sh | H-Gate, H-Secret, H-Git | +| local_verify.sh | H-Chain | +| local_integration_smoke.sh | H-Health, H-Auth | +| start-dev.sh | H-DevBind, H-Env | +| docker-compose.yml | H-Port, H-DefaultCreds | + +## 入口表(脚本调用链) + +``` +local_verify.sh + → start-dev.sh (docker mysql+redis, uvicorn :8600) + → local_integration_smoke.sh (/health, JWT 401, unit tests) + → tests/test_api.py + → ruff check server/ -F + +pre_deploy_check.sh (独立 L3 门控,7+2 pre-flight) +``` + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Gate | pre_deploy_check.sh:50-74 | SAFE | Changelog 日期+≥10 行 | +| H-Gate | pre_deploy_check.sh:76-105 | RISK | 审计路径 `docs/audit/`;delta 报告在 `docs/reports/` 不自动过 Gate2 | +| H-Gate | pre_deploy_check.sh:107-131 | SAFE | test_api 必须存在且通过 | +| H-Gate | pre_deploy_check.sh:134-160 | SAFE | ruff F;未装则 SKIP | +| H-Gate | pre_deploy_check.sh:194-218 | RISK | bandit `-ll` 仅 HIGH;文档写 HIGH/MEDIUM 有漂移 | +| H-Gate | pre_deploy_check.sh:221-258 | RISK | Gate7 用 `HEAD~1` diff;未 commit 改动可能漏检 | +| H-Gate | pre_deploy_check.sh:261-284 | SAFE | shell/text EOL pre-flight | +| H-Chain | local_verify.sh:10-22 | SAFE | 固定顺序 smoke→test_api→ruff | +| H-Health | local_integration_smoke.sh:67-70 | SAFE | /health 200 | +| H-Auth | local_integration_smoke.sh:72-75 | SAFE | /api/servers/ 无 JWT → 401 | +| H-DevBind | start-dev.sh:75-76 | RISK | uvicorn `--host 0.0.0.0` 仅本地 dev | +| H-Env | start-dev.sh:29-32 | SAFE | 无 .env 时 generate_env,不写 git | +| H-Port | docker-compose.yml:40-41 | SAFE | Redis publish 6379 修复本机 uvicorn 连 Redis | +| H-Port | docker-compose.yml:26-27 | RISK | MySQL 3306 暴露主机;dev 惯例 | +| H-DefaultCreds | docker-compose.yml:14-17 | RISK | 默认 dev 密码;非生产 compose | +| H-Secret | docker-compose.yml:68-70 | SAFE | SECRET/API/ENCRYPTION 从 env 注入,无硬编码 | + +**len(H)=16, Closure=16** + +## FINDING + +无 P0/P1 新 FINDING。 + +**运维备注(非阻塞)**: +- Phase1 delta 报告在 `docs/reports/audit-delta-*.md`;部署前若只跑 pre_deploy,需另备 `docs/audit/YYYY-MM-DD-*.md` 或调整 Gate2 路径。 +- 生产部署仍走 SSH + handoff,不依赖本 compose 默认密码。 + +## DoD + +- [x] len(H) == Closure +- [x] 五文件全文 Read +- [x] local_verify 链路可复现 + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD8-closure.md b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD8-closure.md new file mode 100644 index 00000000..ecf4de99 --- /dev/null +++ b/docs/archive/audits/2026-06-04-delta/audit-delta-2026-06-04-waveD8-closure.md @@ -0,0 +1,50 @@ +# Phase 1 Delta 审计 — Wave D8(汇总 Closure) + +**日期**: 2026-06-04 +**范围**: D1–D7 delta 波次汇总 + registry 更新 +**标准**: Phase 1 收尾 DoD + +## 汇总表 + +| 波次 | 主题 | 文件数 | H | P0/P1 | 报告 | +|------|------|--------|---|-------|------| +| D1 | sync/后台 | 5 | 19 | 0 | [waveD1](audit-delta-2026-06-04-waveD1.md) | +| D2 | auth/agent/ws | 5 | 22 | 0 | [waveD2](audit-delta-2026-06-04-waveD2.md) | +| D3 | servers/settings/scripts/webssh | 5 | 24 | 0 | [waveD3](audit-delta-2026-06-04-waveD3.md) | +| D4 | 前端 Push | 5 | 17 | 0 | [waveD4](audit-delta-2026-06-04-waveD4.md) | +| D5 | 前端 Files/Terminal | 5 | 18 | 0 | [waveD5](audit-delta-2026-06-04-waveD5.md) | +| D6 | 认证链 Login | 5 | 19 | 0 | [waveD6](audit-delta-2026-06-04-waveD6.md) | +| D7 | Deploy/本地脚本 | 5 | 16 | 0 | [waveD7](audit-delta-2026-06-04-waveD7.md) | +| **合计** | | **35** | **135** | **0** | | + +## 已接受 RISK(跨波重复,不重复开 FINDING) + +| 项 | 波次 | 依据 | +|----|------|------| +| WS query JWT (sync/terminal) | D2,D4,D5,D6 | `docs/project/risk-acceptance-single-operator.md` | +| Agent global API key 回退 | D2 | 同上 | +| dev compose 默认密码/端口暴露 | D7 | 仅本地 Docker | +| pre_deploy Gate2 路径 vs delta 报告 | D7 | 部署前需 `docs/audit/` 或调 Gate | + +## Registry 更新 + +`docs/audit/2026-06-04-bug-scan-registry.json` 新增 `delta_waves[]`(D1–D8 元数据)。 + +## Step 3 / Closure / DoD + +- **len(H) 汇总** = 135,各波 Closure 均已 100% 对齐 +- **每波** `bash scripts/local_verify.sh` 均通过 +- **无 P0/P1** 待修项进入 Phase 2 + +## 下一步(计划 Phase 2 / L3) + +1. `bash deploy/pre_deploy_check.sh`(L3 门控;需当日 `docs/audit/` 若走生产门控) +2. Phase 2 高险深审:`servers.py` / `sync_v2.py` / `files.py` 等节选全量 8 步 +3. L4 Playwright E2E:`frontend/e2e/full-acceptance.spec.mjs` + +## 验证 + +```bash +bash scripts/local_verify.sh # ✅ 2026-06-04 +pytest tests/ -q # 建议 Phase1 收尾跑一次全量 +``` diff --git a/docs/archive/audits/2026-06-04-frontend-14p-merged.md b/docs/archive/audits/2026-06-04-frontend-14p-merged.md new file mode 100644 index 00000000..0988de9d --- /dev/null +++ b/docs/archive/audits/2026-06-04-frontend-14p-merged.md @@ -0,0 +1,66 @@ +# 前端 14p batch 合并卷 + +> 生成日期: 2026-06-04 · 源文件 3 篇 · 原文 `docs/archive/audits/2026-06-04-frontend-14p/` + +## 批次索引 + +### `audit-frontend-14p-2026-06-04-batch1.md` + +# 前端 14 页深审 — Batch 1/3(Dashboard / Servers / Terminal / Files / Push) +## 登记 +## Step 3 — 逐文件 H 扫描 +### DashboardPage.vue (415) +### ServersPage.vue (477) +### TerminalPage.vue (408) +### FilesPage.vue (38) +### PushPage.vue (106) +## 入口表 +## Closure 表 +**len(H)=14, Closure=14** +## FINDING + +### `audit-frontend-14p-2026-06-04-batch2.md` + +# 前端 14 页深审 — Batch 2/3(Scripts / Credentials / Schedules / Retries / Commands) +## 登记 +## Step 3 — 逐文件 H +### ScriptsPage.vue (535) +### CredentialsPage.vue (400) +### SchedulesPage.vue (295) +### RetriesPage.vue (191) +### CommandsPage.vue (168) +## Closure 表 +**len(H)=15, Closure=15** +## FINDING +无 P0/P1 新 FINDING。 + +### `audit-frontend-14p-2026-06-04-batch3.md` + +# 前端 14 页深审 — Batch 3/3(Alerts / Audit / Settings / Login) +## 登记 +## Step 3 — 逐文件 H +### AlertsPage.vue (184) +### AuditPage.vue (154) +### SettingsPage.vue (497) +### LoginPage.vue (244) +## Closure 表 +**len(H)=14, Closure=14** +## 14 页汇总 +| 页面 | 行数 | 批次 | P0/P1 | +## FINDING + +## Closure 摘录(合并) + +| H | 行号 | 规则 | 命中 | +| H1 | 237,304-341 | API JWT | GET stats/alerts/audit/servers | +| H2 | 393-397 | WS | useWebSocket 刷新 stats | +| H3 | 383-387 | 路由 | server_id query 跳转 | +| H4 | 268-345 | 错误 | snackbar 非静默 | +| H5 | 405 | 副作用 | bing-wallpaper sync POST | +| H | 行号 | 规则 | +| H1 | 358-390 | CRUD /scripts JWT | +| H2 | 415-419 | exec script_id + server_ids | +| H3 | 463-467 | quick command exec | +| H4 | 527-528 | poll timer cleanup | +| H1 | 142-160 | GET /alert-history 分页+过滤 | +| H2 | 147 | loadStats 失败 snackbar | diff --git a/docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch1.md b/docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch1.md new file mode 100644 index 00000000..1eab19ee --- /dev/null +++ b/docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch1.md @@ -0,0 +1,96 @@ +# 前端 14 页深审 — Batch 1/3(Dashboard / Servers / Terminal / Files / Push) + +**日期**: 2026-06-04 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 +**说明**: 按路由顺序;每页 **1–N 全文 Read**;编排页含 composable 入口追踪 + +## 登记 + +| # | 文件 | 行数 N | Read 范围 | +|---|------|--------|-----------| +| 1 | `frontend/src/pages/DashboardPage.vue` | 415 | 1–415 全文 | +| 2 | `frontend/src/pages/ServersPage.vue` | 477 | 1–477 全文 | +| 3 | `frontend/src/pages/TerminalPage.vue` | 408 | 1–408 全文 | +| 4 | `frontend/src/pages/FilesPage.vue` | 38 | 1–38 全文 | +| 5 | `frontend/src/pages/PushPage.vue` | 106 | 1–106 全文 | + +**关联 composable(入口 Sink 追踪)**: + +| Composable | 行数 | 深审波次 | +|------------|------|----------| +| `useTerminalSessions.ts` | 749 | D5 + P2-5 webssh 链 | +| `useFilesPage.ts` + files/* | — | D5 + P2-1 | +| `usePushPage.ts` + push/* | — | D4 + P2-2 | + +## Step 3 — 逐文件 H 扫描 + +### DashboardPage.vue (415) + +| H | 行号 | 规则 | 命中 | +|---|------|------|------| +| H1 | 237,304-341 | API JWT | GET stats/alerts/audit/servers | +| H2 | 393-397 | WS | useWebSocket 刷新 stats | +| H3 | 383-387 | 路由 | server_id query 跳转 | +| H4 | 268-345 | 错误 | snackbar 非静默 | +| H5 | 405 | 副作用 | bing-wallpaper sync POST | + +### ServersPage.vue (477) + +| H | 行号 | 规则 | 命中 | +|---|------|------|------| +| H6 | 330-388 | 批量 | batch agent/check/delete JWT | +| H7 | 391-407 | 导出 | CSV 无 password 列 | +| H8 | 418-434 | 上传 | FormData CSV import | +| H9 | 162-176 | 表单 | ServerFormDialog 凭据 | + +### TerminalPage.vue (408) + +| H | 行号 | 规则 | 命中 | +|---|------|------|------| +| H10 | 132-166 | 编排 | useTerminalSessions 全部 WS/SSH | +| H11 | 233-246 | 剪贴板 | paste → xterm,非 URL | +| H12 | 276-278 | 生命周期 | disposeAllSessions onUnmount | + +### FilesPage.vue (38) + +| H | 行号 | 规则 | 命中 | +|---|------|------|------| +| H13 | 33-37 | 编排 | provideFilesPage + useFilesPage | + +### PushPage.vue (106) + +| H | 行号 | 规则 | 命中 | +|---|------|------|------| +| H14 | 105 | 编排 | usePushPage 解构 form/progress/preview | + +## 入口表 + +| 页面 | 用户输入 | API / WS | +|------|----------|----------| +| Dashboard | search | GET /servers/*, /alert-history/, /audit/ | +| Servers | search, CSV, form | CRUD /servers, batch/*, import | +| Terminal | cmd, quickCmd | POST /auth/webssh-token, WS /ws/terminal | +| Files | —(组件内) | GET /files/browse, sync/read-file | +| Push | path, servers | POST /sync/*, WS /ws/sync | + +## Closure 表 + +| H | 判定 | 依据 | +|---|------|------| +| H1-H5 | SAFE | JWT http;错误有 snackbar | +| H2 | RISK | WS query token(已接受 ADR-011) | +| H6-H9 | SAFE | 批量需 JWT;CSV 无凭据导出 | +| H10-H12 | SAFE | WebSSH token 短期;dispose 清理 | +| H13-H14 | SAFE | 逻辑在已审 composable,页壳无 sink | + +**len(H)=14, Closure=14** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] 5 页全文 Read(Terminal 408 行含 style) +- [x] composable 入口表完整 +- [x] len(H)==Closure diff --git a/docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch2.md b/docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch2.md new file mode 100644 index 00000000..90823d74 --- /dev/null +++ b/docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch2.md @@ -0,0 +1,77 @@ +# 前端 14 页深审 — Batch 2/3(Scripts / Credentials / Schedules / Retries / Commands) + +**日期**: 2026-06-04 +**标准**: 8 步逐行 + +## 登记 + +| # | 文件 | 行数 N | Read 范围 | +|---|------|--------|-----------| +| 1 | `frontend/src/pages/ScriptsPage.vue` | 535 | 1–535 全文 | +| 2 | `frontend/src/pages/CredentialsPage.vue` | 400 | 1–400 全文 | +| 3 | `frontend/src/pages/SchedulesPage.vue` | 295 | 1–295 全文 | +| 4 | `frontend/src/pages/RetriesPage.vue` | 191 | 1–191 全文 | +| 5 | `frontend/src/pages/CommandsPage.vue` | 168 | 1–168 全文 | + +## Step 3 — 逐文件 H + +### ScriptsPage.vue (535) + +| H | 行号 | 规则 | +|---|------|------| +| H1 | 358-390 | CRUD /scripts JWT | +| H2 | 415-419 | exec script_id + server_ids | +| H3 | 463-467 | quick command exec | +| H4 | 527-528 | poll timer cleanup | + +### CredentialsPage.vue (400) + +| H | 行号 | 规则 | +|---|------|------| +| H5 | 253-255 | GET 列表无密码 | +| H6 | 323-327 | encrypted_pw POST only | +| H7 | 306,340,357 | 编辑留空不改 | +| H8 | 346-347 | SSH 私钥提交时传输 | + +### SchedulesPage.vue (295) + +| H | 行号 | 规则 | +|---|------|------| +| H9 | 177 | cron 正则 `^[\d\s*/,\-]+$` | +| H10 | 173-189 | buildSchedulePayload 校验 | +| H11 | 263-267 | runNow → POST /sync/files | + +### RetriesPage.vue (191) + +| H | 行号 | 规则 | +|---|------|------| +| H12 | 129-134 | 客户端 filter(展示) | +| H13 | 146,160 | retry/delete JWT | + +### CommandsPage.vue (168) + +| H | 行号 | 规则 | +|---|------|------| +| H14 | 139-153 | 只读 command-logs / ssh-sessions | +| H15 | 50 | command 文本展示(后端已存) | + +## Closure 表 + +| H | 判定 | 依据 | +|---|------|------| +| H1-H4 | SAFE/RISK | exec 走后端;H3 RISK 临时命令(后端 dangerous check) | +| H5-H8 | SAFE | 无 localStorage;API 脱敏 | +| H9-H11 | SAFE | cron/路径校验;sync JWT | +| H12-H13 | SAFE | 只读+操作 JWT | +| H14-H15 | SAFE | 只读审计视图 | + +**len(H)=15, Closure=15** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] 5 页全文 Read +- [x] len(H)==Closure diff --git a/docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch3.md b/docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch3.md new file mode 100644 index 00000000..5afbf6e1 --- /dev/null +++ b/docs/archive/audits/2026-06-04-frontend-14p/audit-frontend-14p-2026-06-04-batch3.md @@ -0,0 +1,93 @@ +# 前端 14 页深审 — Batch 3/3(Alerts / Audit / Settings / Login) + +**日期**: 2026-06-04 +**标准**: 8 步逐行 + +## 登记 + +| # | 文件 | 行数 N | Read 范围 | +|---|------|--------|-----------| +| 1 | `frontend/src/pages/AlertsPage.vue` | 184 | 1–184 全文 | +| 2 | `frontend/src/pages/AuditPage.vue` | 154 | 1–154 全文 | +| 3 | `frontend/src/pages/SettingsPage.vue` | 497 | 1–497 全文 | +| 4 | `frontend/src/pages/LoginPage.vue` | 244 | 1–244 全文 | + +**合计 14 页**: Batch1(5) + Batch2(5) + Batch3(4) = 14 ✅ + +## Step 3 — 逐文件 H + +### AlertsPage.vue (184) + +| H | 行号 | 规则 | +|---|------|------| +| H1 | 142-160 | GET /alert-history 分页+过滤 | +| H2 | 147 | loadStats 失败 snackbar | + +### AuditPage.vue (154) + +| H | 行号 | 规则 | +|---|------|------| +| H3 | 131-137 | GET /audit 参数化 filter | +| H4 | 138 | normalizeAuditList | + +### SettingsPage.vue (497) + +| H | 行号 | 规则 | +|---|------|------| +| H5 | 272-275 | telegram value_set 不返明文 | +| H6 | 434-460 | reveal 需 current_password | +| H7 | 339-359 | 改密 PUT /auth/password | +| H8 | 362-404 | TOTP setup/enable/disable | +| H9 | 475-487 | IP allowlist POST | + +### LoginPage.vue (244) + +| H | 行号 | 规则 | +|---|------|------| +| H10 | 177 | auth.login 内存 token | +| H11 | 179 | redirect 防开放重定向 `//` | +| H12 | 186-188 | 429 lockout 15min | +| H13 | 102-103 | password ref 非 localStorage | +| H14 | 123 | bing wallpapers 公开 GET | + +## Closure 表 + +| H | 判定 | 依据 | +|---|------|------| +| H1-H2 | SAFE | 只读告警 | +| H3-H4 | SAFE | 只读审计+normalize | +| H5-H9 | SAFE | 敏感 reveal re-auth;TOTP 流程完整 | +| H10-H13 | SAFE | 无持久化密码;redirect 校验 | +| H14 | SAFE | 壁纸 URL 无凭据 | + +**len(H)=14, Closure=14** + +## 14 页汇总 + +| 页面 | 行数 | 批次 | P0/P1 | +|------|------|------|-------| +| DashboardPage | 415 | B1 | 0 | +| ServersPage | 477 | B1 | 0 | +| TerminalPage | 408 | B1 | 0 | +| FilesPage | 38 | B1 | 0 | +| PushPage | 106 | B1 | 0 | +| ScriptsPage | 535 | B2 | 0 | +| CredentialsPage | 400 | B2 | 0 | +| SchedulesPage | 295 | B2 | 0 | +| RetriesPage | 191 | B2 | 0 | +| CommandsPage | 168 | B2 | 0 | +| AlertsPage | 184 | B3 | 0 | +| AuditPage | 154 | B3 | 0 | +| SettingsPage | 497 | B3 | 0 | +| LoginPage | 244 | B3 | 0 | +| **合计** | **4112** | **3 批** | **0** | + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] 14/14 页全文 Read +- [x] 3 批 Closure 合计 43 H 全对齐 +- [x] 4112 行 frontend pages 覆盖完成 diff --git a/docs/archive/audits/2026-06-04-line-walk-merged.md b/docs/archive/audits/2026-06-04-line-walk-merged.md new file mode 100644 index 00000000..4e82b4a9 --- /dev/null +++ b/docs/archive/audits/2026-06-04-line-walk-merged.md @@ -0,0 +1,1431 @@ +# Bug Scan Line-Walk 合并卷 + +> 生成日期: 2026-06-04 · 源文件 74 篇 · 原文 `docs/archive/audits/2026-06-04-line-walk/` + +## 批次索引 + +### `audit-bug-line-walk-2026-06-04-batch1.md` + +# BUG 专项逐行走读 — Batch 1(2026-06-04) +## 范围(5 文件,全文 Read) +## Step 3 规则扫描(BUG 相关) +## Closure 表(BUG) +| install.html | 691-694 | **FINDING** | P1 | create-admin 成功后未检查 `/lock`;失败仍进 step5 | +| install.py | 648 | **FINDING** | P1 | create-admin 与 lock 非原子;锁定前 install API 仍可被未认证调用 | +| script_job_callback.py | 17-36 | **FINDING** | P2 | `server_ids==[]` 时直接 `return "completed"`,忽略 results 中 pending | +## FINDING 列表(8 字段) +### BUG-06-04-01 · P1 · install.html:691-694 +### BUG-06-04-02 · P1 · install.py:648 +### BUG-06-04-03 · P2 · script_job_callback.py:32-33 +## Step 7 统计 + +### `audit-bug-line-walk-2026-06-04-batch10.md` + +# BUG 专项逐行走读 — Batch 10(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch11.md` + +# BUG 专项逐行走读 — Batch 11(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch12.md` + +# BUG 专项逐行走读 — Batch 12(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch13.md` + +# BUG 专项逐行走读 — Batch 13(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch14.md` + +# BUG 专项逐行走读 — Batch 14(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch17.md` + +# BUG 专项逐行走读 — Batch 17(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch18.md` + +# BUG 专项逐行走读 — Batch 18(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch19.md` + +# BUG 专项逐行走读 — Batch 19(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch2.md` + +# BUG 专项逐行走读 — Batch 2(2026-06-04) +## 范围(5 文件,全文 Read) +## Step 3 规则扫描(BUG 相关) +## Closure 表(BUG) +| schedule_runner.py | 125-217 | **FINDING** | P1 | `run_mode=once` 执行前禁用;失败时仅 cron 回滚 `last_run_at`,once 永久失活 | +## FINDING 列表(8 字段) +### BUG-06-04-04 · P1 · schedule_runner.py:212-217 +## Step 7 统计 +schedule_runner.py 1 FINDING(已修) +## Step 8 DoD +- [x] Closure 全表 +- [x] FINDING 含 `文件:行号` + +### `audit-bug-line-walk-2026-06-04-batch20.md` + +# BUG 专项逐行走读 — Batch 20(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch21.md` + +# BUG 专项逐行走读 — Batch 21(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch22.md` + +# BUG 专项逐行走读 — Batch 22(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch23.md` + +# BUG 专项逐行走读 — Batch 23(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch24.md` + +# BUG 专项逐行走读 — Batch 24(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch25.md` + +# BUG 专项逐行走读 — Batch 25(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch26.md` + +# BUG 专项逐行走读 — Batch 26(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch27.md` + +# BUG 专项逐行走读 — Batch 27(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch28.md` + +# BUG 专项逐行走读 — Batch 28(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch29.md` + +# BUG 专项逐行走读 — Batch 29(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch3.md` + +# BUG 专项逐行走读 — Batch 3(2026-06-04) +## 范围(5 文件,全文 Read) +## Step 3 规则扫描(BUG 相关) +## Closure 表(BUG) +| retry_runner.py | 85-100 | **FINDING** | P2 | 仅 `failed==0 && completed>0` 成功;全 cancel 时 job 永久 pending | +| sync_engine_v2.py | 241-242 | **FINDING** | P2 | 任务异常时 `results` 缺项,`failed+completed` 可小于 `total` | +| servers.py | 276-279 | **FINDING** | P2 | Redis heartbeat 数可大于 DB `total`,在线率 >100% | +## FINDING 列表 +### BUG-06-04-05 · P2 · retry_runner.py +### BUG-06-04-06 · P2 · sync_engine_v2.py:241-242 +### BUG-06-04-07 · P2 · servers.py:276-279 +## Step 7 统计 + +### `audit-bug-line-walk-2026-06-04-batch30.md` + +# BUG 专项逐行走读 — Batch 30(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch31.md` + +# BUG 专项逐行走读 — Batch 31(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch32.md` + +# BUG 专项逐行走读 — Batch 32(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch33.md` + +# BUG 专项逐行走读 — Batch 33(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch35.md` + +# BUG 专项逐行走读 — Batch 35(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch36.md` + +# BUG 专项逐行走读 — Batch 36(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch37.md` + +# BUG 专项逐行走读 — Batch 37(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch38.md` + +# BUG 专项逐行走读 — Batch 38(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch39.md` + +# BUG 专项逐行走读 — Batch 39(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch4.md` + +# BUG 专项逐行走读 — Batch 4(2026-06-04) +## 范围(5 文件,全文 Read) +## Step 3 规则扫描(BUG 相关) +## Closure 表(BUG) +| usePushProgress.ts | 184-194 | **FINDING** | P1 | POST 阻塞至推送结束才连 WS,进度事件全部丢失 | +| sync_v2.py | 125-182 | **FINDING** | P2 | 远程 file-ops 后未 `invalidate_browse_cache`,304 陈旧目录 | +| heartbeat_flush.py | 57-89 | **FINDING** | P2 | 每服务器独立 session/commit;已删服务器仍计 flushed | +## FINDING 列表 +### BUG-06-04-08 · P1 · usePushProgress.ts +### BUG-06-04-09 · P2 · sync_v2 file-ops +### BUG-06-04-10 · P2 · heartbeat_flush.py +## Step 7 统计 + +### `audit-bug-line-walk-2026-06-04-batch40.md` + +# BUG 专项逐行走读 — Batch 40(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch41.md` + +# BUG 专项逐行走读 — Batch 41(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch42.md` + +# BUG 专项逐行走读 — Batch 42(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch43.md` + +# BUG 专项逐行走读 — Batch 43(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch44.md` + +# BUG 专项逐行走读 — Batch 44(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch45.md` + +# BUG 专项逐行走读 — Batch 45(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch46.md` + +# BUG 专项逐行走读 — Batch 46(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch47.md` + +# BUG 专项逐行走读 — Batch 47(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch48.md` + +# BUG 专项逐行走读 — Batch 48(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch49.md` + +# BUG 专项逐行走读 — Batch 49(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch5.md` + +# BUG 专项逐行走读 — Batch 5(2026-06-04) +## 范围(5 文件,全文 Read) +## Step 3 规则扫描(BUG 相关) +## Closure 表(BUG) +| agent.py | 34, 226-227 | **FINDING** | P2 | 注释写 TTL=1.5×flush,实际 600=600,停 Agent 后 key 可能在 flush 前过期 | +| sync_v2.py | 1474-1650 | **FINDING** | P2 | write/chmod/compress/decompress 未失效 browse ETag(Batch4 已覆盖 ops/upload) | +## FINDING 列表 +### BUG-06-04-11 · P2 · agent.py REDIS_KEY_EXPIRE +### BUG-06-04-12 · P2 · sync_v2 远程写路径 +## Step 7 统计 +agent.py 1 FINDING(已修) +sync_v2.py 1 FINDING(已修) + +### `audit-bug-line-walk-2026-06-04-batch50.md` + +# BUG 专项逐行走读 — Batch 50(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch51.md` + +# BUG 专项逐行走读 — Batch 51(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch52.md` + +# BUG 专项逐行走读 — Batch 52(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch53.md` + +# BUG 专项逐行走读 — Batch 53(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch54.md` + +# BUG 专项逐行走读 — Batch 54(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch55.md` + +# BUG 专项逐行走读 — Batch 55(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch56.md` + +# BUG 专项逐行走读 — Batch 56(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch57.md` + +# BUG 专项逐行走读 — Batch 57(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch58.md` + +# BUG 专项逐行走读 — Batch 58(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch59.md` + +# BUG 专项逐行走读 — Batch 59(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch6.md` + +# BUG 专项逐行走读 — Batch 6(2026-06-04) +## 范围(5 文件,全文 Read) +## Step 3 规则扫描(BUG 相关) +## Closure 表(BUG) +| auth_service.py | 239-246 | **FINDING** | P1 | 已轮换 refresh 不在 Redis 时仅 401,不升 `token_version`,被盗旧 token 与合法新会话可并存 | +| auth_service.py | 597-598 | **FINDING** | P2 | Redis 异常时 `_check_refresh_token` 曾返回 False,误拒合法刷新 | +| useFilesBrowse.ts | 187-195 | **FINDING** | P2 | 5s 内命中本地缓存直接 return,跳过后端 ETag,变更后仍显示旧列表 | +## FINDING 列表 +### BUG-06-04-13 · P1 · auth_service refresh 重用 +### BUG-06-04-14 · P2 · auth Redis 不可用 +### BUG-06-04-15 · P2 · useFilesBrowse 本地缓存短路 +## Step 7 统计 + +### `audit-bug-line-walk-2026-06-04-batch60.md` + +# BUG 专项逐行走读 — Batch 60(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch61.md` + +# BUG 专项逐行走读 — Batch 61(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch62.md` + +# BUG 专项逐行走读 — Batch 62(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch63.md` + +# BUG 专项逐行走读 — Batch 63(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch64.md` + +# BUG 专项逐行走读 — Batch 64(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch65.md` + +# BUG 专项逐行走读 — Batch 65(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch66.md` + +# BUG 专项逐行走读 — Batch 66(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch67.md` + +# BUG 专项逐行走读 — Batch 67(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch68.md` + +# BUG 专项逐行走读 — Batch 68(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch69.md` + +# BUG 专项逐行走读 — Batch 69(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch7.md` + +# BUG 专项逐行走读 — Batch 7(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch70.md` + +# BUG 专项逐行走读 — Batch 70(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch71.md` + +# BUG 专项逐行走读 — Batch 71(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch72.md` + +# BUG 专项逐行走读 — Batch 72(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch73.md` + +# BUG 专项逐行走读 — Batch 73(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch74.md` + +# BUG 专项逐行走读 — Batch 74(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch75.md` + +# BUG 专项逐行走读 — Batch 75(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch76.md` + +# BUG 专项逐行走读 — Batch 76(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch77.md` + +# BUG 专项逐行走读 — Batch 77(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch8.md` + +# BUG 专项逐行走读 — Batch 8(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +### `audit-bug-line-walk-2026-06-04-batch9.md` + +# BUG 专项逐行走读 — Batch 9(2026-06-04) +## 范围 +| 文件 | N | Read | H | FINDING | +## Step 3 规则扫描 +自动化规则表 §四(PY/FE/SH);每命中经 Closure。 +## Closure 表 +## Step 8 DoD +- [x] Closure 全表(含零命中说明) +- [x] FINDING: **0**(OPEN 须当批修或登记) +## 验证 +## FINDING 列表 +无(0 FINDING)。 + +## Closure 摘录(合并) + +| install.html | 691-694 | **FINDING** | P1 | create-admin 成功后未检查 `/lock`;失败仍进 step5 | +| install.py | 648 | **FINDING** | P1 | create-admin 与 lock 非原子;锁定前 install API 仍可被未认证调用 | +| script_job_callback.py | 17-36 | **FINDING** | P2 | `server_ids==[]` 时直接 `return "completed"`,忽略 results 中 pending | +| install.py | 509-526 | SAFE | — | state 不写 db_pass(有意);刷新 step4 需重填密码属 UX | +| agent.py | 154-180 | SAFE | — | 无 server_id / 未知 server 丢弃,设计如此 | +| agent.py | 86-94 | SAFE | — | 非数字指标跳过 | +| servers.py | 245-279 | RISK/BUG | P2 | `offline=total-online` 与列表 Redis 覆盖逻辑在「从未装 Agent」服务器上可能偏差;非回归 | +| servers.py | 205-212 | SAFE | — | is_online 过滤后重算 total | +| 文件 | N | Read | H | FINDING | +| `server/api/assets.py` | 358 | 1..358 | 19 | 0 | +| `server/api/files.py` | 77 | 1..77 | 3 | 0 | +| `server/api/health.py` | 67 | 1..67 | 8 | 0 | +| `server/api/scripts.py` | 418 | 1..418 | 18 | 0 | +| `server/api/search.py` | 119 | 1..119 | 7 | 0 | +| `server/api/__init__.py` | 1 | 1..1 | 0 | 0 | +| `server/api/dependencies.py` | 180 | 1..180 | 0 | 0 | +| `server/api/remote_path_validation.py` | 33 | 1..33 | 0 | 0 | +| `server/api/schema_path_validators.py` | 59 | 1..59 | 1 | 0 | +| `server/api/schemas.py` | 641 | 1..641 | 2 | 0 | +| `server/api/install.py` | 722 | 1..722 | 45 | 0 | +| `server/api/agent.py` | 362 | 1..362 | 16 | 0 | +| `server/api/auth_jwt.py` | 275 | 1..275 | 6 | 0 | +| `server/application/services/script_service.py` | 713 | 1..713 | 18 | 0 | +| `server/application/services/sync_engine_v2.py` | 540 | 1..540 | 16 | 0 | +| `server/application/services/auth_service.py` | 640 | 1..640 | 13 | 0 | +| `frontend/src/composables/terminal/useTerminalSessions.ts` | 750 | connect/reconnect/WebSSH | +| `server/application/services/files_browse_service.py` | 167 | 1..167 | 6 | 0 | +| `server/application/services/script_job_callback.py` | 110 | 1..110 | 2 | 0 | +| `server/application/services/script_jobs.py` | 125 | 1..125 | 1 | 0 | +| `server/application/services/server_service.py` | 68 | 1..68 | 0 | 0 | +| `server/application/services/sync_service.py` | 43 | 1..43 | 1 | 0 | +| `server/application/__init__.py` | 1 | 1..1 | 0 | 0 | +| `server/application/services/__init__.py` | 8 | 1..8 | 0 | 0 | +| `server/background/heartbeat_flush.py` | 102 | 1..102 | 3 | 0 | +| `server/background/retry_runner.py` | 148 | 1..148 | 7 | 0 | +| `server/background/schedule_runner.py` | 236 | 1..236 | 6 | 0 | +| `server/background/script_execution_flush.py` | 45 | 1..45 | 0 | 0 | +| `server/background/self_monitor.py` | 108 | 1..108 | 2 | 0 | +| `server/background/__init__.py` | 7 | 1..7 | 0 | 0 | +| `server/background/ip_allowlist_refresh.py` | 99 | 1..99 | 1 | 0 | +| `server/background/upload_staging_cleanup.py` | 60 | 1..60 | 0 | 0 | +| `server/__init__.py` | 5 | 1..5 | 0 | 0 | +| `server/config.py` | 217 | 1..217 | 3 | 0 | +| `server/main.py` | 669 | 1..669 | 21 | 0 | +| `server/infrastructure/database/__init__.py` | 1 | 1..1 | 0 | 0 | +| `server/infrastructure/database/admin_repo.py` | 62 | 1..62 | 4 | 0 | +| `server/infrastructure/database/audit_log_repo.py` | 86 | 1..86 | 5 | 0 | +| `server/infrastructure/database/crypto.py` | 54 | 1..54 | 0 | 0 | +| `server/infrastructure/database/db_credential_repo.py` | 38 | 1..38 | 2 | 0 | +| `server/infrastructure/database/engine_compat.py` | 23 | 1..23 | 0 | 0 | +| `server/infrastructure/database/migrations.py` | 180 | 1..180 | 6 | 0 | +| `server/infrastructure/database/password_preset_repo.py` | 38 | 1..38 | 2 | 0 | +| `server/infrastructure/database/platform_node_repo.py` | 83 | 1..83 | 7 | 0 | +| `server/infrastructure/database/push_schedule_repo.py` | 95 | 1..95 | 6 | 0 | +| `server/infrastructure/database/script_repo.py` | 90 | 1..90 | 8 | 0 | +| `server/infrastructure/database/server_repo.py` | 144 | 1..144 | 8 | 0 | +| `server/infrastructure/database/session.py` | 125 | 1..125 | 6 | 0 | +| `server/infrastructure/database/setting_repo.py` | 31 | 1..31 | 5 | 0 | +| `server/infrastructure/database/ssh_key_preset_repo.py` | 38 | 1..38 | 2 | 0 | +| `server/infrastructure/database/ssh_session_repo.py` | 83 | 1..83 | 6 | 0 | +| `server/infrastructure/database/sync_log_repo.py` | 120 | 1..120 | 6 | 0 | +| `server/infrastructure/ssh/__init__.py` | 1 | 1..1 | 0 | 0 | +| `server/infrastructure/ssh/asyncssh_pool.py` | 437 | 1..437 | 43 | 0 | +| `server/infrastructure/ssh/files_capability.py` | 62 | 1..62 | 3 | 0 | +| `server/infrastructure/ssh/remote_archive.py` | 128 | 1..128 | 2 | 0 | +| `server/infrastructure/ssh/remote_probe.py` | 85 | 1..85 | 5 | 0 | +| files_browse_service.py | 路径 `..`、SSH 命令引用 | +| servers.py | `offline = total - online`、Redis 脏 key | +| DashboardPage.vue | 是否混用 stats / 列表在线 | +| sync_engine_v2.py | `gather(return_exceptions=True)` | +| `server/infrastructure/ssh/remote_shell.py` | 63 | 1..63 | 5 | 0 | +| `server/infrastructure/__init__.py` | 15 | 1..15 | 0 | 0 | +| `server/infrastructure/agent_url.py` | 11 | 1..11 | 0 | 0 | +| `server/infrastructure/redis/__init__.py` | 1 | 1..1 | 0 | 0 | +| `server/infrastructure/redis/client.py` | 97 | 1..97 | 0 | 0 | +| `server/infrastructure/redis/script_callback_rate.py` | 44 | 1..44 | 1 | 0 | +| `server/infrastructure/redis/script_execution_store.py` | 422 | 1..422 | 10 | 0 | +| `server/infrastructure/subscription_parser.py` | 121 | 1..121 | 0 | 0 | +| `server/infrastructure/telegram/__init__.py` | 222 | 1..222 | 0 | 0 | +| `server/domain/__init__.py` | 3 | 1..3 | 0 | 0 | +| `server/domain/models/__init__.py` | 431 | 1..431 | 0 | 0 | +| `server/domain/repositories/__init__.py` | 125 | 1..125 | 0 | 0 | +| `server/utils/files_chmod_policy.py` | 29 | 1..29 | 0 | 0 | +| `server/utils/files_elevation.py` | 55 | 1..55 | 0 | 0 | +| `server/utils/posix_paths.py` | 122 | 1..122 | 2 | 0 | +| `server/utils/sync_error_message.py` | 72 | 1..72 | 0 | 0 | +| `server/utils/text_io.py` | 51 | 1..51 | 4 | 0 | +| `server/utils/unix_ls.py` | 115 | 1..115 | 1 | 0 | +| `frontend/src/pages/AlertsPage.vue` | 184 | 1..184 | 0 | 0 | +| `frontend/src/pages/AuditPage.vue` | 154 | 1..154 | 0 | 0 | +| `frontend/src/pages/CommandsPage.vue` | 164 | 1..164 | 0 | 0 | +| `frontend/src/pages/CredentialsPage.vue` | 390 | 1..390 | 0 | 0 | +| `frontend/src/pages/DashboardPage.vue` | 410 | 1..410 | 0 | 0 | +| `frontend/src/pages/FilesPage.vue` | 38 | 1..38 | 0 | 0 | +| `frontend/src/pages/LoginPage.vue` | 243 | 1..243 | 0 | 0 | +| `frontend/src/pages/PushPage.vue` | 106 | 1..106 | 0 | 0 | +| `frontend/src/pages/RetriesPage.vue` | 191 | 1..191 | 0 | 0 | +| `frontend/src/pages/SchedulesPage.vue` | 295 | 1..295 | 0 | 0 | +| `frontend/src/pages/ScriptsPage.vue` | 531 | 1..531 | 0 | 0 | +| `frontend/src/pages/ServersPage.vue` | 477 | 1..477 | 0 | 0 | +| `frontend/src/pages/SettingsPage.vue` | 434 | 1..434 | 0 | 0 | +| `frontend/src/pages/TerminalPage.vue` | 408 | 1..408 | 0 | 0 | +| `frontend/src/composables/terminal/useTerminalSessions.ts` | 749 | 1..749 | 0 | 0 | +| `frontend/src/composables/files/constants.ts` | 5 | 1..5 | 0 | 0 | +| `frontend/src/composables/files/filesPageContext.ts` | 21 | 1..21 | 0 | 0 | +| `frontend/src/composables/files/index.ts` | 9 | 1..9 | 0 | 0 | +| `frontend/src/composables/files/useFilesActions.ts` | 609 | 1..609 | 0 | 0 | +| `frontend/src/composables/files/useFilesBrowse.ts` | 267 | 1..267 | 0 | 0 | +| usePushProgress.ts | 184-194 | **FINDING** | P1 | POST 阻塞至推送结束才连 WS,进度事件全部丢失 | +| sync_v2.py | 125-182 | **FINDING** | P2 | 远程 file-ops 后未 `invalidate_browse_cache`,304 陈旧目录 | +| heartbeat_flush.py | 57-89 | **FINDING** | P2 | 每服务器独立 session/commit;已删服务器仍计 flushed | +| files.py | 39-77 | SAFE | — | 只读 browse;失效由 mutation 侧负责 | +| sync_v2.py | 73-90 | SAFE | — | 同步 API 本身无 ETag | +| `frontend/src/composables/files/useFilesEditor.ts` | 163 | 1..163 | 0 | 0 | +| `frontend/src/composables/files/useFilesNavigation.ts` | 210 | 1..210 | 0 | 0 | +| `frontend/src/composables/files/useFilesPage.ts` | 272 | 1..272 | 0 | 0 | +| `frontend/src/composables/files/useFilesPermissions.ts` | 101 | 1..101 | 0 | 0 | +| `frontend/src/composables/files/useFilesSelection.ts` | 28 | 1..28 | 0 | 0 | +| `frontend/src/composables/push/index.ts` | 3 | 1..3 | 0 | 0 | +| `frontend/src/composables/push/labels.ts` | 57 | 1..57 | 0 | 0 | +| `frontend/src/composables/push/types.ts` | 72 | 1..72 | 0 | 0 | +| `frontend/src/composables/push/usePushForm.ts` | 101 | 1..101 | 0 | 0 | +| `frontend/src/composables/push/usePushLogs.ts` | 146 | 1..146 | 0 | 0 | +| `frontend/src/composables/push/usePushPage.ts` | 40 | 1..40 | 0 | 0 | +| `frontend/src/composables/push/usePushPreview.ts` | 104 | 1..104 | 0 | 0 | +| `frontend/src/composables/push/usePushProgress.ts` | 288 | 1..288 | 0 | 0 | +| `frontend/src/composables/push/usePushServers.ts` | 115 | 1..115 | 0 | 0 | +| `frontend/src/composables/servers/useServerFormDialog.ts` | 255 | 1..255 | 0 | 0 | +| `frontend/src/composables/terminal/termNativeStore.ts` | 62 | 1..62 | 0 | 0 | +| `frontend/src/composables/terminal/types.ts` | 69 | 1..69 | 0 | 0 | +| `frontend/src/composables/terminal/useTerminalCmdBar.ts` | 108 | 1..108 | 0 | 0 | +| `frontend/src/composables/terminal/useTerminalSettings.ts` | 54 | 1..54 | 0 | 0 | +| `frontend/src/composables/useFilesClipboard.ts` | 91 | 1..91 | 0 | 0 | +| `frontend/src/composables/useFilesHotkeys.ts` | 79 | 1..79 | 0 | 0 | +| `frontend/src/composables/useFloatingPanel.ts` | 116 | 1..116 | 2 | 0 | +| `frontend/src/composables/useServerList.ts` | 38 | 1..38 | 0 | 0 | +| `frontend/src/composables/useServerPagination.ts` | 61 | 1..61 | 0 | 0 | +| `frontend/src/composables/useSnackbar.ts` | 13 | 1..13 | 0 | 0 | +| `frontend/src/composables/useTerminalQuickCommands.ts` | 73 | 1..73 | 0 | 0 | +| `frontend/src/composables/useWebSocket.ts` | 177 | 1..177 | 0 | 0 | +| `frontend/src/components/FileDirectoryTree.vue` | 316 | 1..316 | 0 | 0 | +| `frontend/src/components/FileEditorWorkbench.vue` | 1041 | 1..1041 | 0 | 0 | +| `frontend/src/components/FilePermissionDialog.vue` | 446 | 1..446 | 0 | 0 | +| `frontend/src/components/MonacoEditor.vue` | 254 | 1..254 | 0 | 0 | +| `frontend/src/components/ShellHighlightField.vue` | 200 | 1..200 | 1 | 0 | +| `frontend/src/components/StatCardsRow.vue` | 67 | 1..67 | 0 | 0 | +| `frontend/src/components/TerminalQuickCommandsSettings.vue` | 210 | 1..210 | 0 | 0 | +| `frontend/src/components/files/FilesBreadcrumb.vue` | 29 | 1..29 | 0 | 0 | +| `frontend/src/components/files/FilesDialogs.vue` | 180 | 1..180 | 0 | 0 | +| `frontend/src/components/files/FilesList.vue` | 279 | 1..279 | 0 | 0 | +| `frontend/src/components/files/FilesPermissionAlert.vue` | 35 | 1..35 | 0 | 0 | +| `frontend/src/components/files/FilesStatusBar.vue` | 24 | 1..24 | 0 | 0 | +| `frontend/src/components/files/FilesToolbar.vue` | 121 | 1..121 | 0 | 0 | +| `frontend/src/components/push/PushDiagnoseDialog.vue` | 71 | 1..71 | 0 | 0 | +| `frontend/src/components/push/PushHistoryTable.vue` | 139 | 1..139 | 0 | 0 | +| `frontend/src/components/push/PushPreviewDialog.vue` | 91 | 1..91 | 0 | 0 | +| `frontend/src/components/push/PushProgressList.vue` | 69 | 1..69 | 0 | 0 | +| `frontend/src/components/push/PushServerGrid.vue` | 110 | 1..110 | 0 | 0 | +| `frontend/src/components/push/PushSyncModeCard.vue` | 39 | 1..39 | 0 | 0 | +| `frontend/src/components/push/PushToolbar.vue` | 58 | 1..58 | 0 | 0 | +| agent.py | 34, 226-227 | **FINDING** | P2 | 注释写 TTL=1.5×flush,实际 600=600,停 Agent 后 key 可能在 flush 前过期 | +| sync_v2.py | 1474-1650 | **FINDING** | P2 | write/chmod/compress/decompress 未失效 browse ETag(Batch4 已覆盖 ops/upload) | +| heartbeat_flush.py | 18-20 | SAFE | — | 常量与 agent 对齐后由 agent 单一来源 | +| self_monitor.py | 102-107 | RISK | P3 | 原仅记录 alert WS;已补 sync WS 计数到 debug 日志 | +| files_browse_service.py | 65+ | SAFE | — | 新增 `invalidate_browse_parents` | +| `frontend/src/components/push/PushZipUpload.vue` | 51 | 1..51 | 0 | 0 | +| `frontend/src/components/servers/ServerFormDialog.vue` | 237 | 1..237 | 0 | 0 | +| `frontend/src/components/terminal/TerminalArea.vue` | 101 | 1..101 | 0 | 0 | +| `frontend/src/components/terminal/TerminalCmdBar.vue` | 109 | 1..109 | 0 | 0 | +| `frontend/src/components/terminal/TerminalQuickBar.vue` | 59 | 1..59 | 0 | 0 | +| `frontend/src/components/terminal/TerminalServerPicker.vue` | 86 | 1..86 | 0 | 0 | +| `frontend/src/components/terminal/TerminalTabBar.vue` | 66 | 1..66 | 0 | 0 | +| `frontend/src/components/terminal/TerminalToolbar.vue` | 108 | 1..108 | 0 | 0 | +| `frontend/src/App.vue` | 456 | 1..456 | 0 | 0 | +| `frontend/src/api/index.ts` | 308 | 1..308 | 2 | 0 | +| `frontend/src/router/index.ts` | 68 | 1..68 | 0 | 0 | +| `frontend/src/stores/auth.ts` | 132 | 1..132 | 0 | 0 | +| `frontend/src/stores/files.ts` | 129 | 1..129 | 0 | 0 | +| `frontend/src/monaco/initMonaco.ts` | 85 | 1..85 | 0 | 0 | +| `frontend/src/monaco/nexusThemes.ts` | 102 | 1..102 | 0 | 0 | +| `frontend/src/monaco/preloadMonaco.ts` | 30 | 1..30 | 0 | 0 | +| `frontend/src/monaco/setupMonacoEnv.ts` | 51 | 1..51 | 0 | 0 | +| `frontend/src/plugins/index.ts` | 19 | 1..19 | 0 | 0 | +| `frontend/src/plugins/vuetify.ts` | 20 | 1..20 | 0 | 0 | +| `frontend/src/styles/settings.scss` | 10 | 1..10 | 0 | 0 | +| `frontend/src/types/api.ts` | 256 | 1..256 | 0 | 0 | +| `frontend/src/types/global.d.ts` | 8 | 1..8 | 0 | 0 | +| `frontend/src/utils/apiError.ts` | 16 | 1..16 | 0 | 0 | +| `frontend/src/utils/auditLabels.ts` | 290 | 1..290 | 0 | 0 | +| `frontend/src/utils/auditNormalize.ts` | 23 | 1..23 | 0 | 0 | +| `frontend/src/utils/editorLanguage.ts` | 196 | 1..196 | 0 | 0 | +| `frontend/src/utils/fileBrowse.ts` | 61 | 1..61 | 0 | 0 | +| `frontend/src/utils/fileDownload.ts` | 12 | 1..12 | 0 | 0 | +| `frontend/src/utils/fileMode.ts` | 128 | 1..128 | 0 | 0 | +| `frontend/src/utils/filePreload.ts` | 141 | 1..141 | 0 | 0 | +| `frontend/src/utils/fileSort.ts` | 57 | 1..57 | 0 | 0 | +| `frontend/src/utils/pushErrorMessage.ts` | 65 | 1..65 | 0 | 0 | +| `frontend/src/utils/remotePath.ts` | 92 | 1..92 | 0 | 0 | +| `frontend/src/utils/serverSelection.ts` | 35 | 1..35 | 0 | 0 | +| `frontend/src/utils/shellHighlight.ts` | 196 | 1..196 | 0 | 0 | +| `frontend/src/utils/status.ts` | 35 | 1..35 | 0 | 0 | +| `frontend/src/utils/validation.ts` | 46 | 1..46 | 0 | 0 | +| `frontend/src/utils/wsUrl.ts` | 23 | 1..23 | 0 | 0 | +| `frontend/src/main.ts` | 28 | 1..28 | 0 | 0 | +| `web/app/api.js` | 214 | 1..214 | 11 | 0 | +| `web/app/index.html` | 14 | 1..14 | 0 | 0 | +| `web/app/install.html` | 730 | 1..730 | 6 | 0 | +| `web/app/layout.js` | 231 | 1..231 | 4 | 0 | +| `web/app/preview.html` | 183 | 1..183 | 0 | 0 | +| `web/agent/agent.py` | 434 | 1..434 | 26 | 0 | +| `web/agent/agent.sh` | 98 | 1..98 | 3 | 0 | +| `web/app/preview-v3.html` | 369 | 1..369 | 1 | 0 | +| `web/app/preview-v4.html` | 359 | 1..359 | 1 | 0 | +| `web/app/preview-v5.html` | 375 | 1..375 | 1 | 0 | +| auth_service.py | 239-246 | **FINDING** | P1 | 已轮换 refresh 不在 Redis 时仅 401,不升 `token_version`,被盗旧 token 与合法新会话可并存 | +| auth_service.py | 597-598 | **FINDING** | P2 | Redis 异常时 `_check_refresh_token` 曾返回 False,误拒合法刷新 | +| useFilesBrowse.ts | 187-195 | **FINDING** | P2 | 5s 内命中本地缓存直接 return,跳过后端 ETag,变更后仍显示旧列表 | +| auth_jwt.py | 217-226 | SAFE | — | `tv` 与 DB 严格比对 | +| script_execution_flush.py | 19-45 | SAFE | — | flush/stuck 分工清晰;`update_status` 内 commit | +| files.ts | 85-98 | SAFE | — | `invalidateCache` 与 mutation 联动 | +| `tests/__init__.py` | 0 | 1..0 | 0 | 0 | +| `tests/acceptance_catalog.py` | 64 | 1..64 | 0 | 0 | +| `tests/conftest.py` | 95 | 1..95 | 0 | 0 | +| `tests/load_test.py` | 201 | 1..201 | 20 | 0 | +| `tests/quick_load.py` | 86 | 1..86 | 9 | 0 | +| `web/agent/config.example.json` | 20 | 1..20 | 0 | 0 | +| `web/agent/install.sh` | 237 | 1..237 | 43 | 0 | +| `web/agent/uninstall.sh` | 115 | 1..115 | 20 | 0 | +| `tests/test_agent_heartbeat_ttl.py` | 9 | 1..9 | 1 | 0 | +| `tests/test_api.py` | 279 | 1..279 | 42 | 0 | +| `tests/test_auth_refresh_reuse.py` | 60 | 1..60 | 0 | 0 | +| `tests/test_editor_write_conflict.py` | 163 | 1..163 | 13 | 0 | +| `tests/test_file_permissions.py` | 75 | 1..75 | 0 | 0 | +| `tests/test_files_browse_etag.py` | 43 | 1..43 | 0 | 0 | +| `tests/test_files_elevation.py` | 109 | 1..109 | 10 | 0 | +| `tests/test_full_site_api.py` | 160 | 1..160 | 23 | 0 | +| `tests/test_nexus_v6.py` | 214 | 1..214 | 11 | 0 | +| `tests/test_posix_paths.py` | 62 | 1..62 | 0 | 0 | +| `tests/test_remote_path_validation.py` | 48 | 1..48 | 0 | 0 | +| `tests/test_retry_runner_outcome.py` | 58 | 1..58 | 0 | 0 | +| `tests/test_schedule_runner_once.py` | 21 | 1..21 | 0 | 0 | +| `tests/test_schema_path_validators.py` | 61 | 1..61 | 0 | 0 | +| `tests/test_security_unit.py` | 229 | 1..229 | 12 | 0 | +| `tests/test_step0_infrastructure.py` | 157 | 1..157 | 7 | 0 | +| `tests/test_step1to5_features.py` | 167 | 1..167 | 4 | 0 | +| `tests/test_sync_batch_id.py` | 24 | 1..24 | 0 | 0 | +| `tests/test_sync_error_message.py` | 39 | 1..39 | 0 | 0 | +| `tests/test_sync_websocket.py` | 44 | 1..44 | 1 | 0 | +| `tests/test_text_io.py` | 43 | 1..43 | 1 | 0 | +| `tests/test_unix_ls.py` | 21 | 1..21 | 0 | 0 | +| `tests/test_upload_staging_cleanup.py` | 64 | 1..64 | 1 | 0 | +| `deploy/check_shell_eol.sh` | 32 | 1..32 | 0 | 0 | +| `deploy/db_backup.sh` | 103 | 1..103 | 27 | 0 | +| `deploy/deploy-frontend.sh` | 60 | 1..60 | 3 | 0 | +| `deploy/gate_log.py` | 57 | 1..57 | 4 | 0 | +| `deploy/health_monitor.sh` | 70 | 1..70 | 14 | 0 | +| `deploy/install.sh` | 526 | 1..526 | 110 | 0 | +| `deploy/migrations/001_indexes.sql` | 24 | 1..24 | 0 | 0 | +| `deploy/nexus.conf` | 32 | 1..32 | 0 | 0 | +| `deploy/nginx_http.conf` | 79 | 1..79 | 0 | 0 | +| `deploy/nginx_https.conf` | 113 | 1..113 | 0 | 0 | +| `deploy/pre_deploy_check.sh` | 299 | 1..299 | 0 | 0 | +| `deploy/prune_frontend_assets.py` | 149 | 1..149 | 6 | 0 | +| `deploy/run_test_api_on_server.sh` | 6 | 1..6 | 0 | 0 | +| `deploy/uninstall.sh` | 145 | 1..145 | 23 | 0 | +| `deploy/upgrade.sh` | 130 | 1..130 | 22 | 0 | +| `deploy/verify_login.py` | 55 | 1..55 | 9 | 0 | +| `server/api/servers.py` | 1742 | 1..1742 | 68 | 0 | +| `scripts/_browse_test.py` | 37 | 1..37 | 8 | 0 | +| `scripts/bootstrap_database.py` | 118 | 1..118 | 13 | 0 | +| `scripts/cache-node20-windows.ps1` | 28 | 1..28 | 0 | 0 | +| `scripts/check_text_eol.py` | 111 | 1..111 | 11 | 0 | +| `scripts/check_worktree_eol.py` | 107 | 1..107 | 7 | 0 | +| `scripts/generate_bug_scan_registry.py` | 555 | 1..555 | 8 | 0 | +| `scripts/grant_nexus_local.sql` | 9 | 1..9 | 0 | 0 | +| `scripts/linux_mcp_mysql.sh` | 37 | 1..37 | 0 | 0 | +| `scripts/normalize_worktree_lf.sh` | 68 | 1..68 | 0 | 0 | +| `scripts/proxy-env.sh` | 16 | 1..16 | 0 | 0 | +| `scripts/proxychains-docker.conf` | 9 | 1..9 | 0 | 0 | +| `scripts/run_full_acceptance.sh` | 24 | 1..24 | 1 | 0 | +| `scripts/run_full_e2e.sh` | 13 | 1..13 | 1 | 0 | +| `scripts/run_nexus_acceptance.py` | 567 | 1..567 | 36 | 0 | +| `scripts/seed_local_admin.py` | 75 | 1..75 | 7 | 0 | +| `scripts/start-dev.sh` | 58 | 1..58 | 0 | 0 | +| `scripts/sync_frontend_vendor.py` | 180 | 1..180 | 18 | 0 | +| `scripts/sync_mysql_mcp_env.py` | 156 | 1..156 | 5 | 0 | +| `scripts/unlock_login_lockout.py` | 114 | 1..114 | 9 | 0 | +| `scripts/with-proxy.sh` | 9 | 1..9 | 0 | 0 | +| `scripts/wsl_check_mysql.py` | 66 | 1..66 | 13 | 0 | +| `scripts/wsl_ensure_venv.sh` | 19 | 1..19 | 7 | 0 | +| `scripts/wsl_install_node20.sh` | 117 | 1..117 | 1 | 0 | +| `scripts/wsl_integration_smoke.sh` | 76 | 1..76 | 7 | 0 | +| `scripts/wsl_mcp_mysql.sh` | 28 | 1..28 | 0 | 0 | +| `scripts/wsl_show_grants.py` | 45 | 1..45 | 6 | 0 | +| `scripts/wsl_start_dev.sh` | 21 | 1..21 | 2 | 0 | +| `.dockerignore` | 29 | 1..29 | 0 | 0 | +| `Dockerfile` | 29 | 1..29 | 0 | 0 | +| `docker/.env.example` | 18 | 1..18 | 0 | 0 | +| `docker/README.md` | 56 | 1..56 | 0 | 0 | +| `docker/entrypoint.sh` | 72 | 1..72 | 0 | 0 | +| `docker/generate_env.py` | 52 | 1..52 | 5 | 0 | +| `docker/sync_root_env.py` | 85 | 1..85 | 2 | 0 | +| `frontend/package.json` | 47 | 1..47 | 0 | 0 | +| `frontend/vite.config.mts` | 54 | 1..54 | 0 | 0 | +| `requirements-dev.txt` | 18 | 1..18 | 0 | 0 | +| `requirements.txt` | 18 | 1..18 | 0 | 0 | +| `ruff.toml` | 41 | 1..41 | 0 | 0 | +| `server/api/sync_v2.py` | 1666 | 1..1666 | 84 | 0 | +| `server/api/auth.py` | 375 | 1..375 | 14 | 0 | +| `server/api/settings.py` | 1396 | 1..1396 | 38 | 0 | +| `server/api/terminal.py` | 238 | 1..238 | 14 | 0 | +| `server/api/websocket.py` | 552 | 1..552 | 34 | 0 | +| `server/api/webssh.py` | 394 | 1..394 | 33 | 0 | diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch1.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch1.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch1.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch1.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch10.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch10.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch10.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch10.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch11.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch11.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch11.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch11.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch12.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch12.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch12.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch12.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch13.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch13.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch13.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch13.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch14.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch14.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch14.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch14.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch17.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch17.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch17.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch17.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch18.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch18.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch18.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch18.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch19.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch19.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch19.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch19.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch2.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch2.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch2.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch2.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch20.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch20.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch20.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch20.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch21.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch21.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch21.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch21.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch22.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch22.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch22.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch22.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch23.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch23.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch23.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch23.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch24.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch24.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch24.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch24.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch25.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch25.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch25.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch25.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch26.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch26.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch26.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch26.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch27.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch27.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch27.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch27.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch28.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch28.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch28.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch28.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch29.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch29.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch29.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch29.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch3.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch3.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch3.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch3.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch30.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch30.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch30.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch30.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch31.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch31.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch31.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch31.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch32.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch32.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch32.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch32.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch33.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch33.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch33.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch33.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch35.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch35.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch35.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch35.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch36.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch36.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch36.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch36.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch37.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch37.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch37.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch37.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch38.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch38.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch38.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch38.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch39.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch39.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch39.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch39.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch4.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch4.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch4.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch4.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch40.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch40.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch40.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch40.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch41.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch41.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch41.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch41.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch42.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch42.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch42.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch42.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch43.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch43.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch43.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch43.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch44.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch44.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch44.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch44.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch45.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch45.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch45.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch45.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch46.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch46.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch46.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch46.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch47.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch47.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch47.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch47.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch48.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch48.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch48.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch48.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch49.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch49.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch49.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch49.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch5.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch5.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch5.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch5.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch50.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch50.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch50.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch50.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch51.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch51.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch51.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch51.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch52.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch52.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch52.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch52.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch53.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch53.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch53.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch53.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch54.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch54.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch54.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch54.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch55.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch55.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch55.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch55.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch56.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch56.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch56.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch56.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch57.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch57.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch57.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch57.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch58.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch58.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch58.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch58.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch59.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch59.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch59.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch59.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch6.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch6.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch6.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch6.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch60.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch60.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch60.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch60.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch61.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch61.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch61.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch61.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch62.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch62.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch62.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch62.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch63.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch63.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch63.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch63.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch64.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch64.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch64.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch64.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch65.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch65.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch65.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch65.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch66.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch66.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch66.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch66.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch67.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch67.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch67.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch67.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch68.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch68.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch68.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch68.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch69.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch69.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch69.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch69.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch7.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch7.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch7.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch7.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch70.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch70.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch70.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch70.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch71.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch71.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch71.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch71.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch72.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch72.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch72.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch72.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch73.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch73.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch73.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch73.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch74.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch74.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch74.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch74.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch75.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch75.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch75.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch75.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch76.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch76.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch76.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch76.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch77.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch77.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch77.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch77.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch8.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch8.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch8.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch8.md diff --git a/docs/reports/audit-bug-line-walk-2026-06-04-batch9.md b/docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch9.md similarity index 100% rename from docs/reports/audit-bug-line-walk-2026-06-04-batch9.md rename to docs/archive/audits/2026-06-04-line-walk/audit-bug-line-walk-2026-06-04-batch9.md diff --git a/docs/archive/audits/2026-06-04-phase2-merged.md b/docs/archive/audits/2026-06-04-phase2-merged.md new file mode 100644 index 00000000..acf70017 --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2-merged.md @@ -0,0 +1,237 @@ +# Phase2 P2 合并卷 + +> 生成日期: 2026-06-04 · 源文件 9 篇 · 原文 `docs/archive/audits/2026-06-04-phase2/` + +## 批次索引 + +### `audit-phase2-2026-06-04-waveP2-1.md` + +# Phase 2 深审 — Wave P2-1(Files / SSH 基础设施) +## 登记 +## 入口表 +## Closure 表 +**len(H)=17, Closure=17** +## FINDING +无 P0/P1 新 FINDING。 +## L3 门控(同日记录) +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-phase2-2026-06-04-waveP2-2.md` + +# Phase 2 深审 — Wave P2-2(sync_v2 全文 + 路径/Shell 依赖) +## 登记 +## 入口表(sync_v2 全 22 路由) +## Closure 表 +**len(H)=20, Closure=20** +## FINDING +无 P0/P1 新 FINDING。 +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-phase2-2026-06-04-waveP2-3.md` + +# Phase 2 深审 — Wave P2-3(WebSocket / Dashboard 告警链) +## 登记 +## 入口表 +## Closure 表 +**len(H)=16, Closure=16** +## FINDING +无 P0/P1 新 FINDING。 +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-phase2-2026-06-04-waveP2-4.md` + +# Phase 2 深审 — Wave P2-4(servers.py 全文) +## 登记 +## 入口表(servers.py 26 路由) +## Closure 表 +**len(H)=20, Closure=20** +## FINDING +无 P0/P1 新 FINDING。 +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-phase2-2026-06-04-waveP2-5.md` + +# Phase 2 深审 — Wave P2-5(webssh.py 全文) +## 登记 +## 入口表 +## Closure 表 +**len(H)=17, Closure=17** +## FINDING +无 P0/P1 新 FINDING。 +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-phase2-2026-06-04-waveP2-6.md` + +# Phase 2 深审 — Wave P2-6(sync_engine_v2.py 全文) +## 登记 +## 入口表(服务层,经 sync_v2 API 调用) +## Closure 表 +**len(H)=17, Closure=17** +## FINDING +无 P0/P1 新 FINDING。 +## DoD +- [x] len(H) == Closure +## 验证 + +### `audit-phase2-2026-06-04-waveP2-7.md` + +# Phase 2 深审 — Wave P2-7(前端页 5/14) +## 登记 +## Closure 表 +**len(H)=13, Closure=13** +## FINDING +无 P0/P1 新 FINDING。 +## DoD + +### `audit-phase2-2026-06-04-waveP2-8.md` + +# Phase 2 深审 — Wave P2-8(前端页 5/14) +## 登记 +## Closure 表 +**len(H)=11, Closure=11** +## FINDING +无 P0/P1 新 FINDING。 + +### `audit-phase2-2026-06-04-waveP2-9.md` + +# Phase 2 深审 — Wave P2-9(前端页 4/14 + 编排层) +## 登记 +## Closure 表 +**len(H)=5, Closure=5** +## 交叉引用 +## FINDING +无 P0/P1 新 FINDING。 + +## Closure 摘录(合并) + +| SSH | `list_remote_directory` → `ls -la` | 经 pool + server 凭据 | +| H | 文件:行号 | 判定 | 理由 | +| H-Auth | sync_v2.py:74–1614 | SAFE | 22 路由均 `Depends(get_current_admin)` | +| H-Shell | sync_v2.py:156-168 | RISK | `rm -rf` 删目录;JWT+审计+前端 confirm | +| H-Shell | sync_v2.py:156,165,168,223-227 | SAFE | path shlex.quote | +| H-Path | sync_v2.py:149-165 | SAFE | normalize_remote_abs_path | +| H-Clipboard | sync_v2.py:207-208 | SAFE | assert_clipboard_transfer_safe | +| H-Sandbox | sync_v2.py:302,341,413,721 | SAFE | ensure_under_nexus_upload | +| H-Source | sync_v2.py:548,1096 | SAFE | FORBIDDEN prefixes + resolve | +| H-Audit | sync_v2.py:461-475 | SAFE | 失败 log warning+exc_info,非静默 pass | +| H-Upload | sync_v2.py:876-877,977-978 | SAFE | 100MB / 500MB 上限 | +| H-ZipSlip | sync_v2.py:1000-1005 | SAFE | assert_zip + is_path_under_prefix | +| H-Download | sync_v2.py:1244-1272 | SAFE | 100MB + filename sanitize | +| H-Read | sync_v2.py:1322-1326 | SAFE | max_size 来自 payload | +| H-Write | sync_v2.py:1394-1414 | SAFE | 5MB + etag 409 冲突 | +| H-Chmod | sync_v2.py:1507-1514 | SAFE | recursive policy + test -d | +| H-Verify | sync_v2.py:1145-1146 | SAFE | sha256sum 路径 shlex.quote | +| H-Path | posix_paths.py:46-59 | SAFE | 禁 `..` 与反斜杠 | +| H-Path | posix_paths.py:117-136 | SAFE | upload 前缀 + zip-slip | +| H-Sudo | remote_shell.py:35-53 | SAFE | bash -c + shlex.quote(command) | +| H-Clipboard | remote_path_validation.py:24-33 | SAFE | dest 非源子树 | +| H-Parse | unix_ls.py:70-71 | SAFE | 跳过 `.` `..` | +| H-WS-Auth | websocket.py:304-311,340-347 | SAFE | 无 token → 4001;无效 → 4401 | +| H-WS-Token | websocket.py:366-410 | SAFE | tv/updated_at 与 HTTP JWT 一致 | +| H-WS-ADR011 | websocket.py:9,296 | RISK | query JWT;单人运维已接受 | +| H-WS-Limit | websocket.py:49-52 | SAFE | MAX_CONNECTIONS=500 | +| H-WS-Heartbeat | websocket.py:139-165 | SAFE | 30s ping / 60s zombie | +| H-WS-Channel | websocket.py:246-249,531-551 | SAFE | alerts 与 sync 分 channel/manager | +| H-WS-Dedup | websocket.py:416-437 | SAFE | Telegram 5min 冷却;WS 仍实时 | +| H-WS-Recovery | websocket.py:512-513 | SAFE | recovery 清 cooldown | +| H-Frontend-Token | useWebSocket.ts:61 | RISK | URL query token;同 ADR-011 | +| H-Frontend-Auth | useWebSocket.ts:114-116 | SAFE | 4001/4401 → forceLogout | +| H-Frontend-XSS | useWebSocket.ts:99-102 | SAFE | snackbar 文本插值,无 v-html | +| H-Frontend-Singleton | useWebSocket.ts:17-18 | SAFE | 模块级单例;App 统一 connect | +| H-Dashboard-Refresh | DashboardPage.vue:393-397 | SAFE | WS alert → reload stats/alerts | +| H-Dashboard-API | DashboardPage.vue:302-337 | SAFE | http JWT 拉 stats/alert-history | +| H-App-Lifecycle | App.vue:257-259 | SAFE | login connect / logout disconnect | +| H-Alert-API | settings.py:768-828 | SAFE | alert-history JWT + 参数化 filter | +| H-Auth | servers.py:26×路由 | SAFE | 26 端点均 `get_current_admin` | +| H-Mask | servers.py:1692-1698 | SAFE | password_set / agent key 前缀截断 | +| H-Encrypt | servers.py:1096-1099,559-562 | SAFE | Fernet encrypt 入库 | +| H-Allowlist | servers.py:1163-1187 | SAFE | UPDATE 字段白名单;agent_api_key 排除 | +| H-Reauth | servers.py:1256-1260,1479-1483 | SAFE | agent-key/install-cmd 需当前密码 | +| H-Reveal | servers.py:1492-1502 | SAFE | install-cmd 不用全局 API_KEY | +| H-AgentKey | servers.py:1282-1288 | SAFE | 生成后 display_once 响应 | +| H-Fallback | servers.py:626,1321 | RISK | batch/single install 可回退 settings.API_KEY | +| H-Shell | servers.py:631-633,1330-1332 | SAFE | install shlex.quote url/key/port | +| H-Sudo | servers.py:36-60 | RISK | 临时 sudoers 白名单;运维必要 | +| H-SudoPwd | servers.py:1025-1027 | SAFE | sudo -S 密码走 stdin 非 argv | +| H-CSV | servers.py:376-388,445-446 | SAFE | formula injection 防御 + 1MB 上限 | +| H-CSV | servers.py:499-501 | SAFE | MAX_IMPORT_ROWS=500 | +| H-Batch | servers.py:615,686,772,850 | SAFE | Semaphore(5) 并发上限 | +| H-Redis | servers.py:179-201,873-877 | SAFE | 心跳 overlay;失败 log warning | +| H-Audit | servers.py: CUD/batch | SAFE | 写操作 AuditLog | +| H-Crypto | crypto.py:20-26 | SAFE | 无 ENCRYPTION_KEY 则 RuntimeError | +| H-Crypto | crypto.py:52-54 | SAFE | decrypt 失败 raise,非静默 | +| H-Capability | files_capability.py:31-39 | SAFE | 只读 probe,无密码回传 | +| H-Elevation | files_elevation.py:48-55 | SAFE | apply_files_elevation_payload | +| H-Purpose | webssh.py:48-49 | SAFE | 拒绝非 webssh purpose | +| H-Bind | webssh.py:106-109 | SAFE | token server_id 须匹配路径 | +| H-TV | webssh.py:66-76 | SAFE | tv 校验;legacy updated_at +5s grace | +| H-Close | webssh.py:97-104 | SAFE | 缺 token→4001;无效→4401 | +| H-Issue | auth.py:334-346 | SAFE | 签发前 JWT + server/domain 校验 | +| H-Scope | auth_service.py:455-470 | SAFE | JWT 含 server_id + purpose + tv | +| H-Expire | auth_service.py:467 | SAFE | 15 分钟短期令牌 | +| H-WSQuery | webssh.py:88, useTerminalSessions:293 | RISK | ADR-011 query token(已接受) | +| H-Cred | webssh.py:126-135 | SAFE | key/password 配置检查 | +| H-Audit | webssh.py:137-146,353-366 | SAFE | connect/disconnect 审计 | +| H-Session | webssh.py:148-157,369-376 | SAFE | SshSession 创建/关闭 | +| H-DB | webssh.py:111-158 | SAFE | 长连接前关闭 DB session | +| H-Pool | webssh.py:167,337 | SAFE | acquire/release + stale retry | +| H-CmdLog | webssh.py:277-290,379-398 | SAFE | Enter 触发;2000 字符截断 | +| H-Danger | dependencies.py:167-180 | RISK | 危险命令仅 WARN 不阻断(设计) | +| H-Resize | webssh.py:293-296 | SAFE | cols/rows 边界默认 80×24 | +| H-Error | webssh.py:171,204 | SAFE | SSH 失败不向客户端泄露栈 | +| H-Source | sync_engine_v2.py:72-76,327-330 | SAFE | `_nexus_source_path` 拒绝系统路径 | +| H-Conc | sync_engine_v2.py:38,79-80 | SAFE | MAX_CONCURRENT=10 + min 入参 | +| H-DBLock | sync_engine_v2.py:89,149,190 | SAFE | `_db_lock` 串行写 sync_log/retry | +| H-Cancel | sync_engine_v2.py:96-136 | SAFE | Redis cancel flag;失败则继续 push | +| H-Retry | sync_engine_v2.py:193-224 | SAFE | 失败自动 pending retry;去重 | +| H-Subproc | sync_engine_v2.py:468-473 | SAFE | create_subprocess_exec 参数化 | +| H-Shlex | sync_engine_v2.py:456-458 | SAFE | key path shlex.quote | +| H-KeyTmp | sync_engine_v2.py:449-455,491-495 | SAFE | 0600 临时 key + finally unlink | +| H-Pass | sync_engine_v2.py:440-446 | RISK | sshpass -e;/proc 可见(内网运维可接受) | +| H-Remote | sync_engine_v2.py:414 | SAFE | normalize_remote_abs_path | +| H-Timeout | sync_engine_v2.py:476-482 | SAFE | RSYNC_TIMEOUT+30 kill | +| H-Output | sync_engine_v2.py:486-487 | SAFE | stdout/stderr 截断 10KB | +| H-Staging | sync_engine_v2.py:498-516 | SAFE | 仅 manual 全成功才 rmtree staging | +| H-Preview | sync_engine_v2.py:364-365 | SAFE | verbose 文件列表上限 200 | +| H-Audit | sync_engine_v2.py:267-271,380-391 | SAFE | sync_files 审计;失败 log error | +| H-TG | sync_engine_v2.py:274-291 | SAFE | Telegram 失败不阻断 | +| H-Gather | sync_engine_v2.py:254-265 | SAFE | gather 异常计入 failed | +| H-JWT | 各页 http.* | SAFE | 经 `@/api` JWT 客户端 | +| H-WS | DashboardPage:393-397 | RISK | useWebSocket query token(已接受) | +| H-Nav | DashboardPage:383-387 | SAFE | server_id 数字 query 路由 | +| H-Err | DashboardPage:268-345 | SAFE | load 失败 snackbar | +| H-CSV | ServersPage:391-435 | SAFE | import FormData;export 无密码列 | +| H-Batch | ServersPage:325-388 | SAFE | batch 端点 JWT;confirm 删除 | +| H-Form | ServersPage:162-176 | SAFE | 凭据经 ServerFormDialog composable | +| H-Filter | AlertsPage:150-162 | SAFE | 只读分页 API | +| H-Audit | AuditPage:126-141 | SAFE | 只读;normalizeAuditList | +| H-TG | SettingsPage:272-275 | SAFE | GET 不返 token 明文;value_set | +| H-Reveal | SettingsPage:434-460 | SAFE | API Key/TG reveal 需 current_password | +| H-Pw | SettingsPage:339-359 | SAFE | 改密 POST;表单 type=password | +| H-TOTP | SettingsPage:362-404 | SAFE | setup/enable/disable 走 auth API | +| H-CredList | CredentialsPage:253-255 | SAFE | GET 列表无密码明文 | +| H-CredPost | CredentialsPage:323-327 | SAFE | encrypted_pw 仅 POST/PUT | +| H-CredEdit | CredentialsPage:306,340,357 | SAFE | 编辑留空不修改 | +| H-SSH | CredentialsPage:346-347 | SAFE | 私钥仅提交时传输 | +| H-Cron | SchedulesPage:177 | SAFE | cron 正则校验 | +| H-Sched | SchedulesPage:173-180 | SAFE | 路径/服务器必填 | +| H-Retry | RetriesPage:146 | SAFE | retry POST JWT | +| H-CmdView | CommandsPage:139-153 | SAFE | 只读 command-logs/sessions | +| H-ScriptExec | ScriptsPage:415-419,463-467 | SAFE | exec 走后端 JWT | +| H-Quick | ScriptsPage:459-467 | RISK | 临时命令;后端 check_dangerous | +| H-Poll | ScriptsPage:527-528 | SAFE | onUnmounted stopPolling | +| H-FilesShell | FilesPage.vue:33-37 | SAFE | 逻辑在 useFilesPage(D5) | +| H-PushShell | PushPage.vue:105 | SAFE | usePushPage(D4) | +| H-TermShell | TerminalPage.vue | SAFE | useTerminalSessions(D5) | +| H-Login | LoginPage.vue | SAFE | auth.login 内存 token(D6) | +| H-NoStore | 四页 | SAFE | 无 localStorage 存密码 | diff --git a/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-1.md b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-1.md new file mode 100644 index 00000000..850b3ef7 --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-1.md @@ -0,0 +1,65 @@ +# Phase 2 深审 — Wave P2-1(Files / SSH 基础设施) + +**日期**: 2026-06-04 +**范围**: 文件浏览 REST + browse service + SSH pool + 前端预读 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步(全文 Read) + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `server/api/files.py` | Python | 77 | 1–77 全文 | +| 2 | `server/application/services/files_browse_service.py` | Python | 167 | 1–167 全文 | +| 3 | `server/infrastructure/ssh/asyncssh_pool.py` | Python | 436 | 1–436 全文 | +| 4 | `server/utils/files_elevation.py` | Python | 55 | 1–55 全文 | +| 5 | `frontend/src/utils/filePreload.ts` | TS | 141 | 1–141 全文 | + +## 入口表 + +| 方法 | 路径 | 鉴权 | +|------|------|------| +| GET | `/api/files/browse?server_id=&path=` | JWT + If-None-Match | +| POST | `/sync/read-file`(filePreload 调用) | JWT | +| SSH | `list_remote_directory` → `ls -la` | 经 pool + server 凭据 | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Auth | files.py:44 | SAFE | `get_current_admin` | +| H-Path | files.py:57-60 | SAFE | `normalize_remote_abs_path` | +| H-Audit | files.py:72 | SAFE | browse 审计 | +| H-ETag | files.py:62-75 | SAFE | 304 减 SSH 负载 | +| H-Path | files_browse_service.py:111-116 | SAFE | normalize + shlex.quote | +| H-Shell | files_browse_service.py:117-125 | SAFE | 固定 ls 模板;path 已 quote | +| H-Cache | files_browse_service.py:46-62 | SAFE | 5s TTL + max 200 | +| H-Cred | asyncssh_pool.py:183-192 | SAFE | decrypt 仅内存 connect | +| H-HostKey | asyncssh_pool.py:176-179 | RISK | `SSH_STRICT_HOST_CHECKING=false` 可关;默认 strict | +| H-Shell | asyncssh_pool.py:306-339 | SAFE | tee/mv/mkdir 路径 shlex.quote | +| H-Sudo | asyncssh_pool.py:348-355 | SAFE | elevation 三态 OFF/AUTO/ALWAYS | +| H-Pool | asyncssh_pool.py:409-413 | SAFE | timeout 后 close_connection 不 reuse | +| H-Exec | asyncssh_pool.py:389-437 | RISK | `exec_ssh_command` 接受任意 command;调用方须 JWT+审计 | +| H-Elevation | files_elevation.py:21-28 | SAFE | 未知值回退 AUTO | +| H-Auth | filePreload.ts:101-105 | SAFE | read-file JWT + max_size | +| H-Cache | filePreload.ts:25-58 | SAFE | 内存 Map;prune 按目录 | +| H-Size | filePreload.ts:6-9,67-68 | SAFE | 300KB 预读 / 2MB 编辑上限 | + +**len(H)=17, Closure=17** + +## FINDING + +无 P0/P1 新 FINDING。 + +## L3 门控(同日记录) + +`bash deploy/pre_deploy_check.sh` → **6/7 PASS**,Gate 7 BLOCK(`HEAD~1` 与未提交改动 `.cursorrules`、`docker-compose.yml` 等未列入当日 audit 文件)。属工作区脏树预期;**非代码缺陷**。部署前需 commit + 审计清单对齐或放宽 Gate7 策略。 + +## DoD + +- [x] len(H) == Closure +- [x] 五文件全文 Read +- [x] local_verify 通过 + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-2.md b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-2.md new file mode 100644 index 00000000..fa1c4af3 --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-2.md @@ -0,0 +1,66 @@ +# Phase 2 深审 — Wave P2-2(sync_v2 全文 + 路径/Shell 依赖) + +**日期**: 2026-06-04 +**范围**: `sync_v2.py` 1656 行全文 + 路径校验与 SSH 包装 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `server/api/sync_v2.py` | Python | 1656 | 1–1656 全文(分段 Read 至 EOF) | +| 2 | `server/utils/posix_paths.py` | Python | 149 | 1–149 全文 | +| 3 | `server/infrastructure/ssh/remote_shell.py` | Python | 63 | 1–63 全文 | +| 4 | `server/api/remote_path_validation.py` | Python | 33 | 1–33 全文 | +| 5 | `server/utils/unix_ls.py` | Python | 115 | 1–115 全文 | + +## 入口表(sync_v2 全 22 路由) + +| 路由 | 鉴权 | +|------|------| +| POST `/files`, `/preview`, `/file-ops`, `/file-clipboard`, `/browse` | JWT | +| POST `/browse-local`, `/local-file-ops`, `/local-file-preview` | JWT + upload 沙箱 | +| POST `/cancel`, `/reconcile-stale-logs`, `/validate-source-path`, `/diagnose` | JWT | +| POST `/file-diff`, `/upload`, `/upload-zip`, `/verify` | JWT | +| POST `/download`, `/read-file`, `/write-file`, `/chmod`, `/compress`, `/decompress` | JWT | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Auth | sync_v2.py:74–1614 | SAFE | 22 路由均 `Depends(get_current_admin)` | +| H-Shell | sync_v2.py:156-168 | RISK | `rm -rf` 删目录;JWT+审计+前端 confirm | +| H-Shell | sync_v2.py:156,165,168,223-227 | SAFE | path shlex.quote | +| H-Path | sync_v2.py:149-165 | SAFE | normalize_remote_abs_path | +| H-Clipboard | sync_v2.py:207-208 | SAFE | assert_clipboard_transfer_safe | +| H-Sandbox | sync_v2.py:302,341,413,721 | SAFE | ensure_under_nexus_upload | +| H-Source | sync_v2.py:548,1096 | SAFE | FORBIDDEN prefixes + resolve | +| H-Audit | sync_v2.py:461-475 | SAFE | 失败 log warning+exc_info,非静默 pass | +| H-Upload | sync_v2.py:876-877,977-978 | SAFE | 100MB / 500MB 上限 | +| H-ZipSlip | sync_v2.py:1000-1005 | SAFE | assert_zip + is_path_under_prefix | +| H-Download | sync_v2.py:1244-1272 | SAFE | 100MB + filename sanitize | +| H-Read | sync_v2.py:1322-1326 | SAFE | max_size 来自 payload | +| H-Write | sync_v2.py:1394-1414 | SAFE | 5MB + etag 409 冲突 | +| H-Chmod | sync_v2.py:1507-1514 | SAFE | recursive policy + test -d | +| H-Verify | sync_v2.py:1145-1146 | SAFE | sha256sum 路径 shlex.quote | +| H-Path | posix_paths.py:46-59 | SAFE | 禁 `..` 与反斜杠 | +| H-Path | posix_paths.py:117-136 | SAFE | upload 前缀 + zip-slip | +| H-Sudo | remote_shell.py:35-53 | SAFE | bash -c + shlex.quote(command) | +| H-Clipboard | remote_path_validation.py:24-33 | SAFE | dest 非源子树 | +| H-Parse | unix_ls.py:70-71 | SAFE | 跳过 `.` `..` | + +**len(H)=20, Closure=20** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] sync_v2 全文 Read(D1 仅 grep+分段,本波补全) +- [x] len(H) == Closure +- [x] local_verify 通过 + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-3.md b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-3.md new file mode 100644 index 00000000..55ad1474 --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-3.md @@ -0,0 +1,61 @@ +# Phase 2 深审 — Wave P2-3(WebSocket / Dashboard 告警链) + +**日期**: 2026-06-04 +**范围**: 后端 WS 双通道 + 前端告警客户端 + Dashboard 刷新 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `server/api/websocket.py` | Python | 552 | 1–552 全文 | +| 2 | `frontend/src/composables/useWebSocket.ts` | TS | 178 | 1–178 全文 | +| 3 | `frontend/src/pages/DashboardPage.vue` | Vue | 415 | 1–415 全文 | +| 4 | `frontend/src/App.vue` | Vue | — | 247–260(WS 生命周期) | +| 5 | `server/api/settings.py` | Python | — | 759–828(alert-history GET) | + +## 入口表 + +| 通道 | 路径 | 鉴权 | +|------|------|------| +| WS | `/ws/alerts?token=` | `_verify_ws_token` | +| WS | `/ws/sync?token=` | 同上 | +| HTTP | GET `/api/alert-history/` | JWT | +| HTTP | GET `/api/servers/stats` | JWT(Dashboard) | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-WS-Auth | websocket.py:304-311,340-347 | SAFE | 无 token → 4001;无效 → 4401 | +| H-WS-Token | websocket.py:366-410 | SAFE | tv/updated_at 与 HTTP JWT 一致 | +| H-WS-ADR011 | websocket.py:9,296 | RISK | query JWT;单人运维已接受 | +| H-WS-Limit | websocket.py:49-52 | SAFE | MAX_CONNECTIONS=500 | +| H-WS-Heartbeat | websocket.py:139-165 | SAFE | 30s ping / 60s zombie | +| H-WS-Channel | websocket.py:246-249,531-551 | SAFE | alerts 与 sync 分 channel/manager | +| H-WS-Dedup | websocket.py:416-437 | SAFE | Telegram 5min 冷却;WS 仍实时 | +| H-WS-Recovery | websocket.py:512-513 | SAFE | recovery 清 cooldown | +| H-Frontend-Token | useWebSocket.ts:61 | RISK | URL query token;同 ADR-011 | +| H-Frontend-Auth | useWebSocket.ts:114-116 | SAFE | 4001/4401 → forceLogout | +| H-Frontend-XSS | useWebSocket.ts:99-102 | SAFE | snackbar 文本插值,无 v-html | +| H-Frontend-Singleton | useWebSocket.ts:17-18 | SAFE | 模块级单例;App 统一 connect | +| H-Dashboard-Refresh | DashboardPage.vue:393-397 | SAFE | WS alert → reload stats/alerts | +| H-Dashboard-API | DashboardPage.vue:302-337 | SAFE | http JWT 拉 stats/alert-history | +| H-App-Lifecycle | App.vue:257-259 | SAFE | login connect / logout disconnect | +| H-Alert-API | settings.py:768-828 | SAFE | alert-history JWT + 参数化 filter | + +**len(H)=16, Closure=16** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] len(H) == Closure +- [x] websocket 全文 Read +- [x] 端到端链:Agent→broadcast_alert→Redis→WS→Dashboard refresh + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-4.md b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-4.md new file mode 100644 index 00000000..08fb9142 --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-4.md @@ -0,0 +1,68 @@ +# Phase 2 深审 — Wave P2-4(servers.py 全文) + +**日期**: 2026-06-04 +**范围**: 服务器 CRUD/Agent/导入/批量 SSH 全文 + 凭据加密/文件能力探测 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `server/api/servers.py` | Python | 1742 | 1–1742 全文(分段 Read 至 EOF) | +| 2 | `server/infrastructure/database/crypto.py` | Python | 54 | 1–54 全文 | +| 3 | `server/infrastructure/ssh/files_capability.py` | Python | 63 | 1–63 全文 | +| 4 | `server/utils/files_elevation.py` | Python | 55 | 1–55 全文(P2-1 已读,本波交叉验证) | +| 5 | `server/infrastructure/ssh/remote_shell.py` | Python | 63 | 1–63 全文(P2-1 已读,setup-files-sudo 关联) | + +## 入口表(servers.py 26 路由) + +| 类别 | 路由数 | 鉴权 | +|------|--------|------| +| CRUD / 列表 / stats | GET/POST/PUT/DELETE | 全部 JWT | +| CSV import | POST `/import` | JWT + 1MB/500行 | +| 批量 Agent | POST `/batch/*` | JWT + Semaphore(5) | +| Agent 单台 | POST `/{id}/install|uninstall|upgrade-agent` | JWT | +| 敏感 reveal | POST `/{id}/agent-key`, `agent-install-cmd` | JWT + bcrypt re-auth | +| files | GET/POST `files-capability`, `setup-files-sudo` | JWT | +| health | POST `/check` | JWT | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Auth | servers.py:26×路由 | SAFE | 26 端点均 `get_current_admin` | +| H-Mask | servers.py:1692-1698 | SAFE | password_set / agent key 前缀截断 | +| H-Encrypt | servers.py:1096-1099,559-562 | SAFE | Fernet encrypt 入库 | +| H-Allowlist | servers.py:1163-1187 | SAFE | UPDATE 字段白名单;agent_api_key 排除 | +| H-Reauth | servers.py:1256-1260,1479-1483 | SAFE | agent-key/install-cmd 需当前密码 | +| H-Reveal | servers.py:1492-1502 | SAFE | install-cmd 不用全局 API_KEY | +| H-AgentKey | servers.py:1282-1288 | SAFE | 生成后 display_once 响应 | +| H-Fallback | servers.py:626,1321 | RISK | batch/single install 可回退 settings.API_KEY | +| H-Shell | servers.py:631-633,1330-1332 | SAFE | install shlex.quote url/key/port | +| H-Sudo | servers.py:36-60 | RISK | 临时 sudoers 白名单;运维必要 | +| H-SudoPwd | servers.py:1025-1027 | SAFE | sudo -S 密码走 stdin 非 argv | +| H-CSV | servers.py:376-388,445-446 | SAFE | formula injection 防御 + 1MB 上限 | +| H-CSV | servers.py:499-501 | SAFE | MAX_IMPORT_ROWS=500 | +| H-Batch | servers.py:615,686,772,850 | SAFE | Semaphore(5) 并发上限 | +| H-Redis | servers.py:179-201,873-877 | SAFE | 心跳 overlay;失败 log warning | +| H-Audit | servers.py: CUD/batch | SAFE | 写操作 AuditLog | +| H-Crypto | crypto.py:20-26 | SAFE | 无 ENCRYPTION_KEY 则 RuntimeError | +| H-Crypto | crypto.py:52-54 | SAFE | decrypt 失败 raise,非静默 | +| H-Capability | files_capability.py:31-39 | SAFE | 只读 probe,无密码回传 | +| H-Elevation | files_elevation.py:48-55 | SAFE | apply_files_elevation_payload | + +**len(H)=20, Closure=20** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] servers.py 1742 行全文 Read(补 D3 分段) +- [x] len(H) == Closure +- [x] local_verify 通过 + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-5.md b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-5.md new file mode 100644 index 00000000..b24cc887 --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-5.md @@ -0,0 +1,61 @@ +# Phase 2 深审 — Wave P2-5(webssh.py 全文) + +**日期**: 2026-06-04 +**范围**: WebSSH WebSocket 端点 + 令牌签发链 + 前端连接 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `server/api/webssh.py` | Python | 401 | 1–401 全文 | +| 2 | `server/api/auth.py` | Python | 374 | 330–349(webssh-token 端点) | +| 3 | `server/application/services/auth_service.py` | Python | 684 | 412–471(create_webssh_token) | +| 4 | `server/api/dependencies.py` | Python | — | 167–180(check_dangerous_command) | +| 5 | `frontend/src/composables/terminal/useTerminalSessions.ts` | TS | 749 | 277–311(令牌 + WS URL) | + +## 入口表 + +| 方法 | 路径 | 鉴权 | +|------|------|------| +| WS | `/ws/terminal/{server_id}?token=` | purpose=webssh JWT | +| POST | `/api/auth/webssh-token` | JWT + server 存在 | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Purpose | webssh.py:48-49 | SAFE | 拒绝非 webssh purpose | +| H-Bind | webssh.py:106-109 | SAFE | token server_id 须匹配路径 | +| H-TV | webssh.py:66-76 | SAFE | tv 校验;legacy updated_at +5s grace | +| H-Close | webssh.py:97-104 | SAFE | 缺 token→4001;无效→4401 | +| H-Issue | auth.py:334-346 | SAFE | 签发前 JWT + server/domain 校验 | +| H-Scope | auth_service.py:455-470 | SAFE | JWT 含 server_id + purpose + tv | +| H-Expire | auth_service.py:467 | SAFE | 15 分钟短期令牌 | +| H-WSQuery | webssh.py:88, useTerminalSessions:293 | RISK | ADR-011 query token(已接受) | +| H-Cred | webssh.py:126-135 | SAFE | key/password 配置检查 | +| H-Audit | webssh.py:137-146,353-366 | SAFE | connect/disconnect 审计 | +| H-Session | webssh.py:148-157,369-376 | SAFE | SshSession 创建/关闭 | +| H-DB | webssh.py:111-158 | SAFE | 长连接前关闭 DB session | +| H-Pool | webssh.py:167,337 | SAFE | acquire/release + stale retry | +| H-CmdLog | webssh.py:277-290,379-398 | SAFE | Enter 触发;2000 字符截断 | +| H-Danger | dependencies.py:167-180 | RISK | 危险命令仅 WARN 不阻断(设计) | +| H-Resize | webssh.py:293-296 | SAFE | cols/rows 边界默认 80×24 | +| H-Error | webssh.py:171,204 | SAFE | SSH 失败不向客户端泄露栈 | + +**len(H)=17, Closure=17** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] webssh.py 401 行全文 Read +- [x] 令牌签发链交叉验证 +- [x] len(H) == Closure +- [x] local_verify 通过 + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-6.md b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-6.md new file mode 100644 index 00000000..6ce4353c --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-6.md @@ -0,0 +1,61 @@ +# Phase 2 深审 — Wave P2-6(sync_engine_v2.py 全文) + +**日期**: 2026-06-04 +**范围**: 推送引擎服务层 — rsync/并发/预览/暂存清理 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 语言 | 行数 N | Read 范围 | +|---|------|------|--------|-----------| +| 1 | `server/application/services/sync_engine_v2.py` | Python | 552 | 1–552 全文 | +| 2 | `server/utils/posix_paths.py` | Python | — | resolve_nexus_push_source_path(P2-2 已审,交叉引用) | +| 3 | `server/utils/sync_error_message.py` | Python | — | translate_sync_error_message(错误脱敏) | +| 4 | `server/infrastructure/database/crypto.py` | Python | 54 | decrypt_value(P2-4 已审) | +| 5 | `server/api/sync_v2.py` | Python | 1656 | 调用方(P2-2 已审) | + +## 入口表(服务层,经 sync_v2 API 调用) + +| 方法 | 调用方 | 说明 | +|------|--------|------| +| `sync_files` | POST push/sync | 多机 rsync + WS 进度 | +| `preview_sync` | POST preview | dry-run 单机 | +| `_rsync_push` | 内部 | subprocess rsync | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-Source | sync_engine_v2.py:72-76,327-330 | SAFE | `_nexus_source_path` 拒绝系统路径 | +| H-Conc | sync_engine_v2.py:38,79-80 | SAFE | MAX_CONCURRENT=10 + min 入参 | +| H-DBLock | sync_engine_v2.py:89,149,190 | SAFE | `_db_lock` 串行写 sync_log/retry | +| H-Cancel | sync_engine_v2.py:96-136 | SAFE | Redis cancel flag;失败则继续 push | +| H-Retry | sync_engine_v2.py:193-224 | SAFE | 失败自动 pending retry;去重 | +| H-Subproc | sync_engine_v2.py:468-473 | SAFE | create_subprocess_exec 参数化 | +| H-Shlex | sync_engine_v2.py:456-458 | SAFE | key path shlex.quote | +| H-KeyTmp | sync_engine_v2.py:449-455,491-495 | SAFE | 0600 临时 key + finally unlink | +| H-Pass | sync_engine_v2.py:440-446 | RISK | sshpass -e;/proc 可见(内网运维可接受) | +| H-Remote | sync_engine_v2.py:414 | SAFE | normalize_remote_abs_path | +| H-Timeout | sync_engine_v2.py:476-482 | SAFE | RSYNC_TIMEOUT+30 kill | +| H-Output | sync_engine_v2.py:486-487 | SAFE | stdout/stderr 截断 10KB | +| H-Staging | sync_engine_v2.py:498-516 | SAFE | 仅 manual 全成功才 rmtree staging | +| H-Preview | sync_engine_v2.py:364-365 | SAFE | verbose 文件列表上限 200 | +| H-Audit | sync_engine_v2.py:267-271,380-391 | SAFE | sync_files 审计;失败 log error | +| H-TG | sync_engine_v2.py:274-291 | SAFE | Telegram 失败不阻断 | +| H-Gather | sync_engine_v2.py:254-265 | SAFE | gather 异常计入 failed | + +**len(H)=17, Closure=17** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] sync_engine_v2.py 552 行全文 Read +- [x] len(H) == Closure +- [x] local_verify 通过 + +## 验证 + +`bash scripts/local_verify.sh` — 全绿 diff --git a/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-7.md b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-7.md new file mode 100644 index 00000000..003602ec --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-7.md @@ -0,0 +1,44 @@ +# Phase 2 深审 — Wave P2-7(前端页 5/14) + +**日期**: 2026-06-04 +**范围**: Dashboard / Servers / Alerts / Audit / Settings 页面全文 +**标准**: `standards/line-walk-audit-standard-v2.md` 8 步 + +## 登记 + +| # | 文件 | 行数 N | Read 范围 | +|---|------|--------|-----------| +| 1 | `frontend/src/pages/DashboardPage.vue` | 415 | 1–415 全文 | +| 2 | `frontend/src/pages/ServersPage.vue` | 477 | 1–477 全文 | +| 3 | `frontend/src/pages/AlertsPage.vue` | 184 | 1–184 全文 | +| 4 | `frontend/src/pages/AuditPage.vue` | 154 | 1–154 全文 | +| 5 | `frontend/src/pages/SettingsPage.vue` | 497 | 1–497 全文 | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-JWT | 各页 http.* | SAFE | 经 `@/api` JWT 客户端 | +| H-WS | DashboardPage:393-397 | RISK | useWebSocket query token(已接受) | +| H-Nav | DashboardPage:383-387 | SAFE | server_id 数字 query 路由 | +| H-Err | DashboardPage:268-345 | SAFE | load 失败 snackbar | +| H-CSV | ServersPage:391-435 | SAFE | import FormData;export 无密码列 | +| H-Batch | ServersPage:325-388 | SAFE | batch 端点 JWT;confirm 删除 | +| H-Form | ServersPage:162-176 | SAFE | 凭据经 ServerFormDialog composable | +| H-Filter | AlertsPage:150-162 | SAFE | 只读分页 API | +| H-Audit | AuditPage:126-141 | SAFE | 只读;normalizeAuditList | +| H-TG | SettingsPage:272-275 | SAFE | GET 不返 token 明文;value_set | +| H-Reveal | SettingsPage:434-460 | SAFE | API Key/TG reveal 需 current_password | +| H-Pw | SettingsPage:339-359 | SAFE | 改密 POST;表单 type=password | +| H-TOTP | SettingsPage:362-404 | SAFE | setup/enable/disable 走 auth API | + +**len(H)=13, Closure=13** + +## FINDING + +无 P0/P1 新 FINDING。 + +## DoD + +- [x] 5 页全文 Read +- [x] local_verify 通过 diff --git a/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-8.md b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-8.md new file mode 100644 index 00000000..174f1416 --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-8.md @@ -0,0 +1,37 @@ +# Phase 2 深审 — Wave P2-8(前端页 5/14) + +**日期**: 2026-06-04 +**范围**: Credentials / Schedules / Retries / Commands / Scripts +**标准**: 8 步逐行 + +## 登记 + +| # | 文件 | 行数 N | Read 范围 | +|---|------|--------|-----------| +| 1 | `frontend/src/pages/CredentialsPage.vue` | 400 | 1–400 全文 | +| 2 | `frontend/src/pages/SchedulesPage.vue` | 295 | 1–295 全文 | +| 3 | `frontend/src/pages/RetriesPage.vue` | 191 | 1–191 全文 | +| 4 | `frontend/src/pages/CommandsPage.vue` | 168 | 1–168 全文 | +| 5 | `frontend/src/pages/ScriptsPage.vue` | 535 | 1–535 全文 | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-CredList | CredentialsPage:253-255 | SAFE | GET 列表无密码明文 | +| H-CredPost | CredentialsPage:323-327 | SAFE | encrypted_pw 仅 POST/PUT | +| H-CredEdit | CredentialsPage:306,340,357 | SAFE | 编辑留空不修改 | +| H-SSH | CredentialsPage:346-347 | SAFE | 私钥仅提交时传输 | +| H-Cron | SchedulesPage:177 | SAFE | cron 正则校验 | +| H-Sched | SchedulesPage:173-180 | SAFE | 路径/服务器必填 | +| H-Retry | RetriesPage:146 | SAFE | retry POST JWT | +| H-CmdView | CommandsPage:139-153 | SAFE | 只读 command-logs/sessions | +| H-ScriptExec | ScriptsPage:415-419,463-467 | SAFE | exec 走后端 JWT | +| H-Quick | ScriptsPage:459-467 | RISK | 临时命令;后端 check_dangerous | +| H-Poll | ScriptsPage:527-528 | SAFE | onUnmounted stopPolling | + +**len(H)=11, Closure=11** + +## FINDING + +无 P0/P1 新 FINDING。 diff --git a/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-9.md b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-9.md new file mode 100644 index 00000000..5c38081b --- /dev/null +++ b/docs/archive/audits/2026-06-04-phase2/audit-phase2-2026-06-04-waveP2-9.md @@ -0,0 +1,36 @@ +# Phase 2 深审 — Wave P2-9(前端页 4/14 + 编排层) + +**日期**: 2026-06-04 +**范围**: Files / Push / Terminal / Login 页面壳 + 关联 composables(交叉 D4–D6) + +## 登记 + +| # | 文件 | 行数 N | Read 范围 | +|---|------|--------|-----------| +| 1 | `frontend/src/pages/FilesPage.vue` | 38 | 1–38 全文 | +| 2 | `frontend/src/pages/PushPage.vue` | 106 | 1–106 全文 | +| 3 | `frontend/src/pages/TerminalPage.vue` | 408 | 交叉 D5 useTerminalSessions | +| 4 | `frontend/src/pages/LoginPage.vue` | 244 | 交叉 D6 全文 | +| 5 | `frontend/src/composables/files/useFilesPage.ts` | — | D5 已审 | + +## Closure 表 + +| H | 文件:行号 | 判定 | 理由 | +|---|-----------|------|------| +| H-FilesShell | FilesPage.vue:33-37 | SAFE | 逻辑在 useFilesPage(D5) | +| H-PushShell | PushPage.vue:105 | SAFE | usePushPage(D4) | +| H-TermShell | TerminalPage.vue | SAFE | useTerminalSessions(D5) | +| H-Login | LoginPage.vue | SAFE | auth.login 内存 token(D6) | +| H-NoStore | 四页 | SAFE | 无 localStorage 存密码 | + +**len(H)=5, Closure=5** + +## 交叉引用 + +- D4:`usePushForm/Progress/Preview` — waveD4 +- D5:`useFilesActions/TerminalSessions` — waveD5 +- D6:`LoginPage.vue` — waveD6 + +## FINDING + +无 P0/P1 新 FINDING。 diff --git a/docs/project/AI-HANDOFF-2026-05-23.md b/docs/archive/handoff/AI-HANDOFF-2026-05-23.md similarity index 96% rename from docs/project/AI-HANDOFF-2026-05-23.md rename to docs/archive/handoff/AI-HANDOFF-2026-05-23.md index df4d84a9..8fb7c1b9 100644 --- a/docs/project/AI-HANDOFF-2026-05-23.md +++ b/docs/archive/handoff/AI-HANDOFF-2026-05-23.md @@ -32,7 +32,7 @@ 【逐行审查】8步/文件、全文Read至EOF、Closure全表(含SAFE)、FINDING必须文件:行号、单回复≤5文件; 禁止grep/Top15冒充审计;P0/P1当场修+changelog+矩阵。提示词见 v2 §十四.1。 -【验收】完成前:pytest tests/test_security_unit.py + wsl_integration_smoke.sh + changelog; +【验收】完成前:bash scripts/local_verify.sh 或 pytest + local_integration_smoke.sh + changelog; 上线前:production-verification-checklist.md;宣称完成前读 verification-before-completion SKILL。 项目未部署。端口:子机出站443心跳;中心→子机SSH22;8601仅本机。 @@ -98,7 +98,7 @@ Nexus 6.0:2000+ 台服务器运维平台;FastAPI 四层架构 + Redis 实时 | TOTP 重绑 UX | `settings.html` | | 远程文件删/改名/建目录 | `sync_v2.py` | | Phase 2 审计 63 项 | 矩阵 `docs/reports/audit-phase-2-findings-matrix.md` | -| WSL 联调脚本/venv | `scripts/wsl_*.sh`, `docs/project/wsl-integration-test.md` | +| 本地联调脚本/venv | `scripts/start-dev.sh`, `scripts/local_verify.sh`, `docs/project/local-integration-test.md` | | 标准文档目录 | `standards/` + `docs/project/*-standard*.md` | ### 3.3 代码完成度(主观) @@ -166,7 +166,7 @@ Nexus 6.0:2000+ 台服务器运维平台;FastAPI 四层架构 + Redis 实时 |------|--------|----------| | L0 | 始终 | `perfect-implementation.mdc`、`standards/system-development-standard.md` | | L1 | 新功能/大改 | `docs/design/specs/`、`docs/design/plans/` 内验收标准 | -| L2 | 每次改代码合并前 | `pytest tests/test_security_unit.py`、`scripts/wsl_integration_smoke.sh` | +| L2 | 每次改代码合并前 | `bash scripts/local_verify.sh` 或 `pytest` + `local_integration_smoke.sh` | | L3 | 安全路径改动 | `standards/line-walk-audit-standard-v2.md`、`audit-core-principles.md` | | L4 | 模块 E2E | `script-execution.md` §11、`alert-push-policy.md`、T1~T5 | | L5 | 首次部署/上线 | `production-verification-checklist.md`(逐项勾选) | @@ -196,9 +196,9 @@ Nexus 6.0:2000+ 台服务器运维平台;FastAPI 四层架构 + Redis 实时 完整表:`docs/project/production-verification-checklist.md` -### 6.4 WSL 代码向(无密钥核对) +### 6.4 本地代码向(无密钥核对) -`docs/project/wsl-integration-test.md` + `scripts/wsl_integration_smoke.sh --code-only` +`docs/project/local-integration-test.md` + `bash scripts/local_integration_smoke.sh` ### 6.5 建议「最小首次部署 10 条」 @@ -267,7 +267,7 @@ Code Review 三批 changelog:`docs/changelog/2026-06-04-code-review-*.md` - **子机**: 宝塔面板;Python **3.7.16**(面板 pyenv)+ 系统 **3.12.3** - **Agent 安装**: 固定 **3.12 venv**,隔离于宝塔 pyenv 3.7 - **防火墙**: 多数子机**未开公网 8601**;推送/脚本依赖 **22**;心跳依赖 **出站 443** -- **WSL 联调**: 只验证代码路径,不纠结部署密钥是否入 git(install 生成) +- **本地联调**: Docker mysql+redis + `bash scripts/local_verify.sh` - **仓库**: 唯一 Nexus 仓库;worktree 开发 --- diff --git a/docs/project/AI-HANDOFF-2026-06-01-files.md b/docs/archive/handoff/AI-HANDOFF-2026-06-01-files.md similarity index 100% rename from docs/project/AI-HANDOFF-2026-06-01-files.md rename to docs/archive/handoff/AI-HANDOFF-2026-06-01-files.md diff --git a/docs/handoff-2026-05-31.md b/docs/archive/handoff/handoff-2026-05-31.md similarity index 100% rename from docs/handoff-2026-05-31.md rename to docs/archive/handoff/handoff-2026-05-31.md diff --git a/docs/handoff-2026-06-01.md b/docs/archive/handoff/handoff-2026-06-01.md similarity index 100% rename from docs/handoff-2026-06-01.md rename to docs/archive/handoff/handoff-2026-06-01.md diff --git a/docs/archive/memory/agentmemory-2026-05-merged.md b/docs/archive/memory/agentmemory-2026-05-merged.md new file mode 100644 index 00000000..c96082eb --- /dev/null +++ b/docs/archive/memory/agentmemory-2026-05-merged.md @@ -0,0 +1,96 @@ +# Agent Memory 合并卷(2026-05 迁移) + +> 生成: 2026-06-04 · 原 docs/memory/ 16 篇 + +请以 [nexus-functional-development-guide.md](../project/nexus-functional-development-guide.md) 为准。 + +## mem_key_files + +# Nexus 6.0 关键文件清单 (2026-05-21 更新) +## 后端 (server/) +### 入口与配置 +### API 层 +### 应用服务层 +### 后台任务 +### 基础设施 +## 前端 (web/) — PHP待替换 + +## mem_mpc4vjm8_caa29f573fd9 + +# MultiSync 2026-05-19 进度:Sprint P0-P2 全部完成(SSH线程隔离、Redis深度利用、审计日志)。生产环境 141/253 在 +MultiSync 2026-05-19 进度:Sprint P0-P2 全部完成(SSH线程隔离、Redis深度利用、审计日志)。生产环境 141/253 在线。文件管理器最终采用 WebFM 单文件版(1679行),6行最小改动集成。设计标准确立:鉴权即信任、浏览器验收、safePath规范。待办:代码审查#1-#3顺手改、WebFM浏览器验收。 +## 相关概念 + +## mem_mpc54lkr_68c4f408352b + +# Sprint 2026-05-19 全部 11 项任务完成。生产环境 217/253 在线,API/DB/Redis/WS 全 online。文档检查发现 3 +## 相关概念 + +## mem_new_decisions + +# Nexus 新增关键决策 (Phase D) +## 相关概念 + +## mem_nexus_config + +# Nexus install.php配置三写机制 +## 相关概念 + +## mem_nexus_dataflow + +# Nexus 心跳数据流与告警机制 +## 相关概念 + +## mem_nexus_decisions + +# Nexus 6.0 已确认关键决策汇总 +## 相关概念 + +## mem_nexus_guardian + +# Nexus 3层守护机制设计 +## 相关概念 + +## mem_nexus_modules + +# Nexus 6.0 Phase A+B+C 已完成模块 +E1 websocket.py(告警推送), E2 agent.py(心跳→Redis+告警), E3 heartbeat_flush.py(Redis→MySQL10min), E4 config.py(load_settings_from_db), E5 self_monitor.py(Python自检), E6 telegram/__init__(py)(推送模块), E7 servers. +## 相关概念 + +## mem_nexus_overview + +# Nexus 6.0 项目概述 +## 相关概念 + +## mem_nexus_repo + +# Nexus 仓库统一与Git状态 +## 相关概念 + +## mem_nexus_telegram + +# Nexus Telegram Bot告警推送设计 +## 相关概念 + +## mem_nexus_testing + +# Nexus Phase D 测试计划与流程 +## 相关概念 + +## mem_phase_d_bugfixes + +# Nexus Phase D 前置修复 (2026-05-20): 12项关键修复全部完成 +## 相关概念 + +## mem_team_agenda + +# Nexus 关键决策汇总(非部门编制) +> 原「团队讨论议程」已废弃虚拟部门分派;以下为仍有效的技术/产品决策摘要。 +## 配置与架构 +## 测试与交付 +## 历史待办(多数已在 2026-06 修复) + +## mem_wsl_deployment + +# Nexus WSL部署信息 (172.31.170.47) +## 相关概念 diff --git a/docs/memory/mem_key_files.md b/docs/archive/memory/raw/mem_key_files.md similarity index 100% rename from docs/memory/mem_key_files.md rename to docs/archive/memory/raw/mem_key_files.md diff --git a/docs/memory/mem_mpc4vjm8_caa29f573fd9.md b/docs/archive/memory/raw/mem_mpc4vjm8_caa29f573fd9.md similarity index 100% rename from docs/memory/mem_mpc4vjm8_caa29f573fd9.md rename to docs/archive/memory/raw/mem_mpc4vjm8_caa29f573fd9.md diff --git a/docs/memory/mem_mpc54lkr_68c4f408352b.md b/docs/archive/memory/raw/mem_mpc54lkr_68c4f408352b.md similarity index 100% rename from docs/memory/mem_mpc54lkr_68c4f408352b.md rename to docs/archive/memory/raw/mem_mpc54lkr_68c4f408352b.md diff --git a/docs/memory/mem_new_decisions.md b/docs/archive/memory/raw/mem_new_decisions.md similarity index 100% rename from docs/memory/mem_new_decisions.md rename to docs/archive/memory/raw/mem_new_decisions.md diff --git a/docs/memory/mem_nexus_config.md b/docs/archive/memory/raw/mem_nexus_config.md similarity index 100% rename from docs/memory/mem_nexus_config.md rename to docs/archive/memory/raw/mem_nexus_config.md diff --git a/docs/memory/mem_nexus_dataflow.md b/docs/archive/memory/raw/mem_nexus_dataflow.md similarity index 100% rename from docs/memory/mem_nexus_dataflow.md rename to docs/archive/memory/raw/mem_nexus_dataflow.md diff --git a/docs/memory/mem_nexus_decisions.md b/docs/archive/memory/raw/mem_nexus_decisions.md similarity index 100% rename from docs/memory/mem_nexus_decisions.md rename to docs/archive/memory/raw/mem_nexus_decisions.md diff --git a/docs/memory/mem_nexus_guardian.md b/docs/archive/memory/raw/mem_nexus_guardian.md similarity index 100% rename from docs/memory/mem_nexus_guardian.md rename to docs/archive/memory/raw/mem_nexus_guardian.md diff --git a/docs/memory/mem_nexus_modules.md b/docs/archive/memory/raw/mem_nexus_modules.md similarity index 100% rename from docs/memory/mem_nexus_modules.md rename to docs/archive/memory/raw/mem_nexus_modules.md diff --git a/docs/memory/mem_nexus_overview.md b/docs/archive/memory/raw/mem_nexus_overview.md similarity index 100% rename from docs/memory/mem_nexus_overview.md rename to docs/archive/memory/raw/mem_nexus_overview.md diff --git a/docs/memory/mem_nexus_repo.md b/docs/archive/memory/raw/mem_nexus_repo.md similarity index 100% rename from docs/memory/mem_nexus_repo.md rename to docs/archive/memory/raw/mem_nexus_repo.md diff --git a/docs/memory/mem_nexus_telegram.md b/docs/archive/memory/raw/mem_nexus_telegram.md similarity index 100% rename from docs/memory/mem_nexus_telegram.md rename to docs/archive/memory/raw/mem_nexus_telegram.md diff --git a/docs/memory/mem_nexus_testing.md b/docs/archive/memory/raw/mem_nexus_testing.md similarity index 100% rename from docs/memory/mem_nexus_testing.md rename to docs/archive/memory/raw/mem_nexus_testing.md diff --git a/docs/memory/mem_phase_d_bugfixes.md b/docs/archive/memory/raw/mem_phase_d_bugfixes.md similarity index 100% rename from docs/memory/mem_phase_d_bugfixes.md rename to docs/archive/memory/raw/mem_phase_d_bugfixes.md diff --git a/docs/memory/mem_team_agenda.md b/docs/archive/memory/raw/mem_team_agenda.md similarity index 100% rename from docs/memory/mem_team_agenda.md rename to docs/archive/memory/raw/mem_team_agenda.md diff --git a/docs/memory/mem_wsl_deployment.md b/docs/archive/memory/raw/mem_wsl_deployment.md similarity index 100% rename from docs/memory/mem_wsl_deployment.md rename to docs/archive/memory/raw/mem_wsl_deployment.md diff --git a/docs/archive/project/PROJECT_HANDOVER.md b/docs/archive/project/PROJECT_HANDOVER.md new file mode 100644 index 00000000..dca6b6af --- /dev/null +++ b/docs/archive/project/PROJECT_HANDOVER.md @@ -0,0 +1,320 @@ +# Nexus 6.0 项目交接文档 + +> **⚠️ 2026-05-23 起请以 SSOT 为准**: [`AI-HANDOFF`](docs/project/AI-HANDOFF-2026-05-23.md) · **全量标准** [`standards-transfer-package`](docs/project/standards-transfer-package.md) · 验收 [`development-acceptance-standard`](docs/project/development-acceptance-standard.md) +> 本文保留历史结构;端口模型、待办 backlog、验证清单、否决项均以 SSOT 为准。 + +## 项目概述 + +**项目名称**: Nexus 6.0 +**类型**: 2000+ 服务器运维管理平台 +**架构**: Clean Architecture (FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram) +**前端**: Tailwind CSS v4 + Alpine.js(18 个 HTML 页面,含 `alerts.html`) +**状态**: 核心代码 ~98% 完成;**尚未部署**;待办见 SSOT §4、验证见 SSOT §5 + +--- + +## 仓库信息 + +- **仓库地址**: Gitea (地址在 .env 中配置) +- **当前工作目录(Linux)**: `~/Nexus`(见 `docs/project/linux-dev-paths.md`) +- **Git分支**: 当前在 worktree 分支 + +--- + +## 技术栈 + +| 层级 | 技术 | +|------|------| +| 后端框架 | FastAPI (Python 3.9+) | +| 数据库 | MySQL 8.0 + Async SQLAlchemy 2.0 | +| 缓存 | Redis | +| 实时通信 | WebSocket | +| SSH连接 | asyncssh (连接池模式) | +| 告警推送 | Telegram Bot API | +| 前端 | Tailwind CSS v4 + Alpine.js | +| 进程守护 | Supervisor + Python自检 + Shell健康检查 | + +--- + +## 目录结构 + +``` +Nexus/ +├── server/ # Python FastAPI 后端 +│ ├── api/ # API路由层 (15个模块) +│ │ ├── agent.py # Agent心跳接收 +│ │ ├── assets.py # Platform/Node资产管理 +│ │ ├── auth.py # JWT登录/TOTP +│ │ ├── auth_jwt.py # JWT验证中间件 +│ │ ├── files.py # 文件浏览 +│ │ ├── install.py # 安装向导API +│ │ ├── push.py # 推送调度 +│ │ ├── scripts.py # 脚本库管理 +│ │ ├── servers.py # 服务器CRUD +│ │ ├── settings.py # 系统设置 +│ │ ├── sync_v2.py # 同步引擎v2 (4种模式) +│ │ ├── webssh.py # WebSSH终端 +│ │ └── websocket.py # WebSocket告警推送 +│ ├── application/ # 应用服务层 +│ │ └── services/ # 业务逻辑 (SyncEngineV2等) +│ ├── domain/ # 领域层 +│ │ └── models/ # SQLAlchemy ORM (14张表) +│ ├── infrastructure/ # 基础设施层 +│ │ ├── database/ # 数据库访问 (Repository模式) +│ │ ├── redis/ # Redis客户端 +│ │ ├── ssh/ # SSH连接池 (asyncssh) +│ │ └── telegram/ # Telegram推送 +│ ├── background/ # 后台任务 +│ │ ├── self_monitor.py # Python自检 (30s) +│ │ ├── heartbeat_flush.py # Redis→MySQL刷新 (10min) +│ │ ├── scheduler.py # 定时推送调度 +│ │ └── retry_worker.py # 失败重试队列 +│ └── config.py # Pydantic Settings +├── web/app/ # 前端页面 (15个HTML) +│ ├── install.html # 安装向导 (5步) +│ ├── login.html # JWT登录+TOTP +│ ├── index.html # 仪表盘 +│ ├── servers.html # 服务器管理 +│ ├── assets.html # Platform/Node管理 +│ ├── push.html # 文件推送 +│ ├── scripts.html # 脚本库 +│ ├── commands.html # 命令日志查询 +│ ├── files.html # 远程文件浏览 +│ ├── settings.html # 系统设置 +│ ├── audit.html # 审计日志 +│ ├── retries.html # 重试队列 +│ ├── terminal.html # WebSSH终端 +│ ├── api.js # 共享API模块 (JWT+Toast) +│ └── layout.js # 共享布局组件 +├── deploy/ # 部署配置 +│ ├── supervisor/ # Supervisor配置 +│ ├── nginx/ # Nginx配置 +│ └── db_backup.sh # 数据库备份脚本 +├── docs/ # 项目文档 +├── requirements.txt # Python依赖 +└── test_p1_p2.py # 验证测试脚本 +``` + +--- + +## 数据库模型 (14张表) + +| 表名 | 说明 | +|------|------| +| `admins` | 管理员用户 (JWT+TOTP支持) | +| `servers` | 服务器资产 (核心表) | +| `platforms` | 平台类型模板 | +| `nodes` | 资产节点树 | +| `sync_logs` | 同步操作日志 | +| `push_schedules` | 定时推送调度 | +| `push_retry_jobs` | 失败重试队列 | +| `audit_logs` | 审计日志 | +| `scripts` | 脚本库 | +| `script_executions` | 脚本执行记录 | +| `password_presets` | SSH密码预设 | +| `db_credentials` | 数据库凭据 | +| `ssh_sessions` | WebSSH会话 | +| `command_logs` | SSH命令日志 | +| `login_attempts` | 登录防暴破记录 | +| `settings` | 系统配置键值对 | + +--- + +## 核心功能清单 + +### P0 核心功能 (已完成) +- [x] JWT认证 + TOTP双因素 +- [x] 登录防暴破 (15分钟锁定) +- [x] Agent心跳上报 (Redis实时) +- [x] WebSocket实时告警推送 +- [x] Telegram告警通知 +- [x] 安装向导 (5步) + +### P1 功能 (已完成) +- [x] Platform/Node资产管理 +- [x] 服务器详情面板 (点击展开) +- [x] WebSSH终端 (xterm.js) +- [x] 推送页面增强 (逐服务器状态+进度条) +- [x] 脚本编辑+执行结果格式化 +- [x] 全局Toast通知系统 +- [x] 审计日志分页+过滤 +- [x] 重试队列手动操作 +- [x] 文件浏览 (面包屑导航) + +### P2 功能 (已完成) +- [x] 告警聚合防抖 (5分钟冷却) +- [x] 命令日志查询页面 +- [x] 服务器列表DB级分页 +- [x] Dashboard WebSocket实时刷新 +- [x] 移动端响应式适配 +- [x] 会话安全加固 (8小时超时) +- [x] 服务器凭据Fernet加密存储 +- [x] 凭据API脱敏 (password_set标记) +- [x] 数据库自动备份脚本 + +### Sync引擎v2 (4种模式) +- [x] S1: 文件同步 (rsync) +- [x] S2: 命令批量执行 (SSH) +- [x] S3: 配置推送 (sysctl) + 去重 + 回滚 +- [x] S4: SFTP文件传输 + +--- + +## 关键Bug修复记录 + +| 任务ID | 问题 | 修复内容 | +|--------|------|----------| +| #81 | DateTime默认求值BUG | 添加`_utcnow()`可调用函数,替换所有`default=datetime.now()` | +| #82 | session.py logger未定义 | 添加`import logging`和`logger`定义,移除@property死代码 | +| #83 | 审计日志缺失 | 验证所有CUD端点都有审计记录 | +| #84 | 模型缺失索引 | 添加7个索引(login_attempts, audit_logs等) | + +--- + +## 环境配置 + +### 必需环境变量 (.env文件) +```bash +# 数据库 +DATABASE_URL=mysql+aiomysql://user:pass@localhost/nexus + +# 安全密钥 (安装时生成) +SECRET_KEY=xxx +API_KEY=xxx +ENCRYPTION_KEY=xxx + +# Redis +REDIS_URL=redis://localhost:6379/0 + +# Telegram告警 (可选) +TELEGRAM_BOT_TOKEN=xxx +TELEGRAM_CHAT_ID=xxx + +# 告警阈值 +CPU_ALERT_THRESHOLD=80 +MEM_ALERT_THRESHOLD=80 +DISK_ALERT_THRESHOLD=80 +``` + +### 启动模式 +- **安装模式** (无.env): 仅 `/api/install/` + 静态文件可用 +- **正常模式** (有.env): 完整初始化 DB/Redis/后台任务 + +--- + +## 部署步骤 + +### 1. 安装依赖 +```bash +pip install -r requirements.txt +``` + +### 2. 运行安装向导 +访问 `http://localhost:8000/app/install.html` +- Step 1: 数据库配置 +- Step 2: Redis配置 +- Step 3: 安全密钥生成 +- Step 4: Telegram配置 (可选) +- Step 5: 创建管理员账号 + +### 3. 启动服务 (Supervisor) +```bash +# 复制配置 +cp deploy/supervisor/nexus.conf /etc/supervisor/conf.d/ +supervisorctl reread +supervisorctl update +supervisorctl start nexus +``` + +### 4. 验证运行 +```bash +# 健康检查 +curl http://localhost:8000/health + +# 运行测试 +python test_p1_p2.py +``` + +--- + +## 团队分工建议 + +| 角色 | 职责 | 相关文件 | +|------|------|----------| +| **后端开发** | API开发、业务逻辑 | `server/api/*.py`, `server/application/services/*.py` | +| **前端开发** | UI页面、交互逻辑 | `web/app/*.html`, `web/app/api.js`, `web/app/layout.js` | +| **DevOps** | 部署、监控、备份 | `deploy/`, `supervisor/`, `nginx/` | +| **DBA** | 数据库优化、迁移 | `server/domain/models/`, `server/infrastructure/database/` | +| **安全** | 审计、加密、认证 | `server/api/auth*.py`, 凭据加密逻辑 | + +--- + +## 监控与告警 + +### 3层守护机制 +1. **Supervisor**: Python崩溃自动重启 +2. **Python自检** (`self_monitor.py`): 30秒检查Redis/MySQL/WebSocket +3. **Shell健康检查** (`health_monitor.sh`): 1分钟HTTP检查,3次失败重启 + +### 告警通道 +- WebSocket → 前端实时通知 +- Telegram → 手机推送 + +### 关键指标 +- Agent心跳间隔: 60秒 +- Redis→MySQL刷新: 10分钟 +- 会话超时: 8小时 +- 告警冷却: 5分钟 + +--- + +## 测试验证 + +### 已完成的测试 +```bash +# 模块导入测试 (19/19通过) +python -c "import server.domain.models; ..." + +# 功能测试 (7/7通过) +python test_p1_p2.py +# - JWT updated_at claim +# - JWT password invalidation +# - Alert dedup cooldown +# - Server repo pagination +# - Config dedup command +# - Server dict no password +# - Admin.updated_at field +``` + +--- + +## 注意事项 + +### ⚠️ 安全相关 +1. **API_KEY**: 禁止修改,用于Agent认证 +2. **SECRET_KEY**: 禁止修改,用于JWT签名 +3. **ENCRYPTION_KEY**: 禁止修改,用于凭据加密 +4. 生产环境必须修改默认密码 + +### ⚠️ 数据库迁移 +首次启动会自动执行 `_apply_migrations()`: +- 添加 `admins.updated_at` 列 +- 创建7个索引 (如果不存在) + +### ⚠️ 文件权限 +- SSH私钥文件需要正确权限 (600) +- 日志目录需要写权限 + +--- + +## 联系方式 + +- 项目文档: `docs/` +- 配置文件: `.env` (不提交到Git) +- 测试脚本: `test_p1_p2.py` + +--- + +**交接日期**: 2026/05/22 +**代码状态**: ✅ 开发完成,待部署测试 +**Git提交**: 建议提交当前worktree更改到主分支 diff --git a/docs/project/line-walk-audit-standard.md b/docs/archive/project/line-walk-audit-standard.md similarity index 100% rename from docs/project/line-walk-audit-standard.md rename to docs/archive/project/line-walk-audit-standard.md diff --git a/docs/archive/project/nexus-full-site-features.md b/docs/archive/project/nexus-full-site-features.md new file mode 100644 index 00000000..8bcf2ac5 --- /dev/null +++ b/docs/archive/project/nexus-full-site-features.md @@ -0,0 +1,323 @@ +# Nexus 6.0 — 全站功能清单(SSOT) + +> **更新**: 2026-05-23 +> **读者**: 产品、运维、接续开发的 AI +> **HTML 版**: [`docs/Nexus-功能说明书.html`](../Nexus-功能说明书.html) +> **接续开发**: [`AI-HANDOFF-2026-05-23.md`](AI-HANDOFF-2026-05-23.md) + +--- + +## 0. 全站页面地图(18 页) + +| 页面 | 路径 | 功能摘要 | +|------|------|----------| +| 安装向导 | `/app/install.html` | 无 `.env` 时 5 步安装中心机 | +| 登录 | `/app/login.html` | JWT + TOTP + 防暴破 | +| 仪表盘 | `/app/index.html` | 统计、WebSocket 刷新、告警计数 | +| 服务器 | `/app/servers.html` | CRUD、详情、Agent 安装/升级、时钟漂移 | +| 资产管理 | `/app/assets.html` | Platform / Node 树 | +| 文件管理 | `/app/files.html` | SSH 浏览、删/改名/建目录 | +| 推送 | `/app/push.html` | rsync 批量、dry-run 预览、历史 | +| 脚本库 | `/app/scripts.html` | 脚本 CRUD、直接执行、$DB_* | +| 执行历史 | `/app/script-executions.html` | 停止/重试/日志/卡住检测 | +| 凭据 | `/app/credentials.html` | DB 凭据 + 密码预设 | +| 定时调度 | `/app/schedules.html` | Cron 推送 **或** 脚本执行 | +| 重试队列 | `/app/retries.html` | 推送失败指数退避重试 | +| 命令日志 | `/app/commands.html` | WebSSH 会话/命令 + **推送日志** | +| 告警中心 | `/app/alerts.html` | 告警历史、统计、时间过滤 | +| 审计 | `/app/audit.html` | 操作审计、时间/用户/类型过滤 | +| 设置 | `/app/settings.html` | 品牌、阈值、Telegram、TOTP、IP 白名单 | +| WebSSH | `/app/terminal.html` | xterm.js 终端(独立页) | + +共享:`layout.js`(侧栏)、`api.js`(JWT、toast、全局搜索) + +--- + +## 1. 网络与通道模型 + +| 通道 | 端口 | 用途 | +|------|------|------| +| 子机 → 中心 | **443 出站** | Agent 心跳、长任务完成回调 | +| 中心 → 子机 | **22 入站** | 推送、文件、**脚本**、手动健康检查、Agent 安装/升级 | +| 子机本机 | **127.0.0.1:8601** | Agent HTTP(可不暴露公网) | + +--- + +## 2. 认证与访问控制 + +- JWT 登录 / 刷新 / 登出(`POST /api/auth/*`) +- TOTP:启用、禁用、**重绑**(设置页) +- 登录防暴破:5 次/15 分钟 → 429 +- 会话:8 小时无操作退出;刷新令牌重用检测 +- **登录 IP 白名单**:总开关、手动 IP、**代理订阅 URL 解析**(2h 自动刷新)、与登录防暴破联动 +- WebSSH 专用短票:`POST /api/auth/webssh-token`(绑定 server_id) + +**不可改密钥**(仅 `.env`):`SECRET_KEY`、`API_KEY`、`ENCRYPTION_KEY`、`DATABASE_URL` + +--- + +## 3. 仪表盘(index.html) + +- 服务器总数 / 在线 / 离线 / 告警中(Redis 实时) +- WebSocket:告警/恢复时**刷新统计**(浏览器不响铃、不弹告警列表) +- 最近推送记录摘要 + +--- + +## 4. 告警中心(alerts.html)— 新增模块 + +- MySQL `alert_logs` 持久化告警与恢复记录 +- 列表:按服务器、类型、是否恢复、**日期范围**分页 +- 统计:近 N 日 Top 服务器、按日计数 +- API:`GET /api/alert-history/`、`GET /api/alert-history/stats` + +**实时告警路径**:Agent 心跳超阈值 → Redis + WebSocket Pub/Sub + Telegram(5 分钟防抖) + +--- + +## 5. 服务器管理(servers.html) + +- 分页列表;Redis 覆盖 `is_online`、`system_info`、**时钟漂移**(warn/crit 徽章) +- CRUD:SSH 密钥/密码(Fernet)、`platform_id`/`node_id`、`target_path`、`agent_port` +- 每机 **Agent API Key**(`nxs-*`,一次性展示) +- **Agent 安装**:复制 curl 命令 / **一键 SSH 远程安装**(实时日志) +- 安装后 **轮询在线状态** +- **Agent 升级**:`POST /api/servers/{id}/upgrade-agent`(SSH 拉 agent.py + restart) +- **健康检查**:`POST /api/servers/check`(**SSH 探测**,非 8601) +- 详情:系统信息、同步日志、WebSSH 入口 +- 推送:`POST /api/servers/push`;日志:`GET /api/servers/logs` + +**未实现**:CSV 批量导入 + +--- + +## 6. 资产管理(assets.html) + +- Platform 模板 CRUD +- Node 树形分组 CRUD +- SSH 会话列表、命令日志查询(与 commands.html 数据同源) + +API:`/api/assets/platforms`、`/api/assets/nodes`、`/api/assets/ssh-sessions`、`/api/assets/command-logs` + +--- + +## 7. WebSSH(terminal.html) + +- xterm.js + Koko 协议 + asyncssh 连接池 +- `webssh-token` 15 分钟、**绑定 server_id**(越权关闭码 4003) +- 全屏、自动 resize +- 会话与命令写入 `ssh_sessions` / `command_logs` + +**未实现**:断线自动重连(需刷新页面) + +--- + +## 8. 命令日志(commands.html) + +- **会话视图**:WebSSH 会话列表、过滤 +- **命令视图**:逐条命令、危险命令高亮 +- **推送日志视图**:rsync 批量推送历史、分页、服务器/状态/模式/触发源过滤 + +--- + +## 9. 批量推送(push.html) + +- SyncEngineV2:`sync_files` rsync-over-SSH +- 模式:增量 / 全量(--delete) / 校验和 / inplace +- 分批 50、并发 10;失败 → `push_retry_jobs` +- **dry-run 预览**(方案 D):首台 `--dry-run --stats`,可选 `-v` 前 200 行 +- 推送历史列表 + +API:`POST /api/sync/files`、`POST /api/sync/preview` + +--- + +## 10. Sync 引擎其他能力(API,部分无独立页) + +| 模式 | API | 说明 | +|------|-----|------| +| 命令批量 | `POST /api/sync/commands` | SSH 批量执行命令 | +| 配置推送 | `POST /api/sync/config` | 批量写配置项 | +| 配置回滚 | `POST /api/sync/config/rollback` | 回滚 | +| SFTP | `POST /api/sync/sftp` | 上传/下载 | +| 目录浏览 | `POST /api/sync/browse` | 文件页也用 | +| 文件操作 | `POST /api/sync/file-ops` | 删/改名/mkdir | + +--- + +## 11. 脚本与执行历史 + +### 脚本库(scripts.html) + +- 脚本 CRUD(分类:ops/deploy/check/cleanup) +- **直接执行命令**(无需入库) +- 批量选机执行;危险命令中心拦截(400) +- **执行通道:SSH 22**(结果 `channel: ssh`) +- $DB_* 凭据替换(中心替换后 SSH 下发) + +### 执行历史(script-executions.html) + +- 列表 / 详情 / 停止 / 重试 / 标记卡住 +- 长任务:nohup + 子机 `curl` 回调 `POST /api/agent/script-callback` +- Redis 热数据 2h + 60s 刷 MySQL + +API:`POST /api/scripts/exec`、`GET /api/scripts/executions/*` + +--- + +## 12. 远程文件管理(files.html) + +- SSH `ls -la` 浏览、面包屑、目录优先排序 +- 删除文件/目录、重命名、新建目录(confirm/二次确认) + +**未实现**:上传、在线预览、树形侧栏 + +--- + +## 13. 定时调度(schedules.html) + +- **类型**:`push`(文件推送)或 `script`(脚本执行) +- 5 字段 Cron;`schedule_runner` 60s 检查;仅 Primary Worker +- 脚本调度:关联 `script_id` 或内联 `script_content`、超时、长任务标志 + +--- + +## 14. 凭据管理(credentials.html) + +- **数据库凭据**:MySQL/PG 等,Fernet 加密,供 $DB_* +- **密码预设**:SSH 密码模板(推送场景) + +脚本页也可管理 DB 凭据(`/api/scripts/credentials`) + +--- + +## 15. 重试队列(retries.html) + +- 推送失败自动入队;`retry_runner` 5 分钟指数退避 +- 手动立即重试 / 删除任务 + +--- + +## 16. 全局搜索 + +- 侧栏搜索框:`GET /api/search/` 跨服务器/脚本/凭据/调度 + +--- + +## 17. 系统设置(settings.html) + +| 模块 | 功能 | +|------|------| +| 品牌 | system_name、title | +| 监控 | CPU/内存/磁盘阈值 | +| 连接 | redis_url、pool_size | +| Telegram | Token、Chat ID、**测试发送**、**getUpdates 解析 Chat ID** | +| 告警开关 | 各类型 Telegram 通知独立开关 | +| 安全 | 改密码、TOTP 启用/禁用/重绑、API Key 二次验证查看 | +| 登录白名单 | 开关、订阅 URL、手动 IP 列表、解析预览 | + +配置三写:安装时 `.env` + `settings` 表 + `web/data/config.php`(PHP 兼容) + +--- + +## 18. 审计日志(audit.html) + +- 全站 CUD 与关键操作写入 `audit_logs` +- 过滤:**日期起止**、管理员用户名、操作类型(分组下拉) +- 分页 50 条/页 + +**未实现**:导出 CSV/JSON(已否决) + +--- + +## 19. 安装向导(install.html) + +- 无 `.env` → 安装模式(其他 API 503) +- 步骤:环境 → DB/Redis → 管理员/品牌 → 完成 +- 生成密钥、写三处配置、Nginx 模板、cron 提示 +- 完成后 install API 锁定(403) + +--- + +## 20. 子机 Agent(web/agent/) + +| 能力 | 说明 | +|------|------| +| 心跳 | 60s → `POST /api/agent/heartbeat`;变化>10% 或超阈值加急 | +| 时钟漂移 | `agent_time` vs 中心;warn/crit + Telegram | +| IP 白名单 | `allowed_ips` 限制访问 Agent HTTP | +| 安装 | `install.sh`:python3.12 venv、127.0.0.1:8601 | +| 端点 | `/health`、`/exec*`(中心脚本已改 SSH,子机端点保留) | + +--- + +## 21. 后台任务(仅 Primary Worker) + +| 任务 | 间隔 | 文件 | +|------|------|------| +| heartbeat_flush | 10min | Redis → MySQL | +| self_monitor | 30s | Redis/MySQL/WS 自检 | +| schedule_runner | 60s | Cron 调度 | +| retry_runner | 5min | 推送重试 | +| ip_allowlist_refresh | 2h | 订阅 IP 刷新 | +| script_execution_flush | 60s | 执行记录刷盘 | +| asyncssh 清理 | 60s | 空闲 SSH 连接 | + +--- + +## 22. 三层守护 + +1. Supervisor — 进程崩溃重启 +2. Python self_monitor — 30s,Redis/MySQL 异常 Telegram +3. Shell `health_monitor.sh` — 1min,连续 3 次 `/health` 失败重启 + +--- + +## 23. 未实现(待开发) + +| 功能 | 优先级 | +|------|--------| +| WebSSH 断线重连 | P1 | +| 服务器 CSV 批量导入 | P1 | +| Agent upgrade 与 venv install 对齐 | P1 | +| 仪表盘历史趋势图 | P2 | +| 远程文件上传 / 内容预览 | P2 | +| 宝塔 API 监控增强 | 可选 | +| Agent mTLS | 可选 | + +--- + +## 24. 已否决(不做) + +文件编辑器、RBAC、移动端、会话录像、审计导出、邮件报告、Redis Cluster、Docker(当前阶段) + +--- + +## 25. 标准与验收(必查 · 与团队同等严谨) + +| 文档 | 路径 | +|------|------| +| **标准转接包(全量)** | [`standards-transfer-package.md`](standards-transfer-package.md) | +| 开发验收 L0~L5 | [`development-acceptance-standard.md`](development-acceptance-standard.md) | +| 系统开发标准 | [`standards/system-development-standard.md`](../../standards/system-development-standard.md) | +| 逐行审计 v2 | [`standards/line-walk-audit-standard-v2.md`](../../standards/line-walk-audit-standard-v2.md) | +| 审计原则 | [`standards/audit-core-principles.md`](../../standards/audit-core-principles.md) | +| Cursor 规则 | `.cursor/rules/*.mdc`(含 `audit-line-review.mdc`) | + +**逐行审查**:8 步/文件、Closure 全表、FINDING 必须 `文件:行号`、单回复 ≤5 文件 — **不可降级**。 + +| 层级 | 说明 | +|------|------| +| L0 | 完美实现 + 全部 mdc + system-development-standard | +| L2 | `pytest` + `local_integration_smoke.sh` | +| L3 | 逐行 DoD(同 standards-transfer-package §2) | +| L4 | 脚本 T-SE、告警策略、T1~T5 | +| L5 | `production-verification-checklist.md` | + +--- + +## 26. 待验证(非功能缺失) + +- 首次部署 E2E:`docs/project/production-verification-checklist.md` +- 脚本 T-SE1~8:`docs/project/script-execution.md` +- 本地代码向:`docs/project/local-integration-test.md` diff --git a/docs/reports/2026-05-23-full-audit-report.md b/docs/archive/reports/2026-05-reviews/2026-05-23-full-audit-report.md similarity index 100% rename from docs/reports/2026-05-23-full-audit-report.md rename to docs/archive/reports/2026-05-reviews/2026-05-23-full-audit-report.md diff --git a/docs/reports/2026-05-23-round2-merged-audit.md b/docs/archive/reports/2026-05-reviews/2026-05-23-round2-merged-audit.md similarity index 100% rename from docs/reports/2026-05-23-round2-merged-audit.md rename to docs/archive/reports/2026-05-reviews/2026-05-23-round2-merged-audit.md diff --git a/docs/reports/audit-full-vs-phase2-reconciliation.md b/docs/archive/reports/2026-05-reviews/audit-full-vs-phase2-reconciliation.md similarity index 100% rename from docs/reports/audit-full-vs-phase2-reconciliation.md rename to docs/archive/reports/2026-05-reviews/audit-full-vs-phase2-reconciliation.md diff --git a/docs/reports/audit-phase-2-findings-matrix.md b/docs/archive/reports/2026-05-reviews/audit-phase-2-findings-matrix.md similarity index 100% rename from docs/reports/audit-phase-2-findings-matrix.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2-findings-matrix.md diff --git a/docs/reports/audit-phase-2-walk-closure.md b/docs/archive/reports/2026-05-reviews/audit-phase-2-walk-closure.md similarity index 100% rename from docs/reports/audit-phase-2-walk-closure.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2-walk-closure.md diff --git a/docs/reports/audit-phase-2a-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2a-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2a-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2a-line-walk.md diff --git a/docs/reports/audit-phase-2b-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2b-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2b-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2b-line-walk.md diff --git a/docs/reports/audit-phase-2c-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2c-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2c-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2c-line-walk.md diff --git a/docs/reports/audit-phase-2d-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2d-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2d-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2d-line-walk.md diff --git a/docs/reports/audit-phase-2e-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2e-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2e-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2e-line-walk.md diff --git a/docs/reports/audit-phase-2f-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2f-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2f-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2f-line-walk.md diff --git a/docs/reports/audit-phase-2g-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2g-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2g-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2g-line-walk.md diff --git a/docs/reports/audit-phase-2h-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2h-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2h-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2h-line-walk.md diff --git a/docs/reports/audit-phase-2i-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2i-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2i-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2i-line-walk.md diff --git a/docs/reports/audit-phase-2j-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-2j-line-walk.md similarity index 100% rename from docs/reports/audit-phase-2j-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-2j-line-walk.md diff --git a/docs/reports/audit-phase-3-delta-2026-06-04.md b/docs/archive/reports/2026-05-reviews/audit-phase-3-delta-2026-06-04.md similarity index 100% rename from docs/reports/audit-phase-3-delta-2026-06-04.md rename to docs/archive/reports/2026-05-reviews/audit-phase-3-delta-2026-06-04.md diff --git a/docs/reports/audit-phase-3-frontend-line-walk.md b/docs/archive/reports/2026-05-reviews/audit-phase-3-frontend-line-walk.md similarity index 100% rename from docs/reports/audit-phase-3-frontend-line-walk.md rename to docs/archive/reports/2026-05-reviews/audit-phase-3-frontend-line-walk.md diff --git a/docs/reports/audit-phase-3-full-closure-2026-06-04.md b/docs/archive/reports/2026-05-reviews/audit-phase-3-full-closure-2026-06-04.md similarity index 100% rename from docs/reports/audit-phase-3-full-closure-2026-06-04.md rename to docs/archive/reports/2026-05-reviews/audit-phase-3-full-closure-2026-06-04.md diff --git a/docs/reports/audit-phase-3-walk-closure.md b/docs/archive/reports/2026-05-reviews/audit-phase-3-walk-closure.md similarity index 100% rename from docs/reports/audit-phase-3-walk-closure.md rename to docs/archive/reports/2026-05-reviews/audit-phase-3-walk-closure.md diff --git a/docs/reports/implementation-progress-2026-05-21.md b/docs/archive/reports/2026-05-reviews/implementation-progress-2026-05-21.md similarity index 100% rename from docs/reports/implementation-progress-2026-05-21.md rename to docs/archive/reports/2026-05-reviews/implementation-progress-2026-05-21.md diff --git a/docs/reports/review-cto-2026-05-21.md b/docs/archive/reports/2026-05-reviews/review-cto-2026-05-21.md similarity index 100% rename from docs/reports/review-cto-2026-05-21.md rename to docs/archive/reports/2026-05-reviews/review-cto-2026-05-21.md diff --git a/docs/reports/review-deploy-architecture-2026-05-21.md b/docs/archive/reports/2026-05-reviews/review-deploy-architecture-2026-05-21.md similarity index 100% rename from docs/reports/review-deploy-architecture-2026-05-21.md rename to docs/archive/reports/2026-05-reviews/review-deploy-architecture-2026-05-21.md diff --git a/docs/reports/review-quality-director-2026-05-21.md b/docs/archive/reports/2026-05-reviews/review-quality-director-2026-05-21.md similarity index 100% rename from docs/reports/review-quality-director-2026-05-21.md rename to docs/archive/reports/2026-05-reviews/review-quality-director-2026-05-21.md diff --git a/docs/reports/session-log-2026-05-21.md b/docs/archive/reports/2026-05-reviews/session-log-2026-05-21.md similarity index 100% rename from docs/reports/session-log-2026-05-21.md rename to docs/archive/reports/2026-05-reviews/session-log-2026-05-21.md diff --git a/docs/reports/signoff-2026-05-21.md b/docs/archive/reports/2026-05-reviews/signoff-2026-05-21.md similarity index 100% rename from docs/reports/signoff-2026-05-21.md rename to docs/archive/reports/2026-05-reviews/signoff-2026-05-21.md diff --git a/docs/reports/step-0-infrastructure/ag-code-review-report.md b/docs/archive/reports/2026-05-steps/step-0-infrastructure/ag-code-review-report.md similarity index 100% rename from docs/reports/step-0-infrastructure/ag-code-review-report.md rename to docs/archive/reports/2026-05-steps/step-0-infrastructure/ag-code-review-report.md diff --git a/docs/reports/step-0-infrastructure/ecc-security-report.md b/docs/archive/reports/2026-05-steps/step-0-infrastructure/ecc-security-report.md similarity index 100% rename from docs/reports/step-0-infrastructure/ecc-security-report.md rename to docs/archive/reports/2026-05-steps/step-0-infrastructure/ecc-security-report.md diff --git a/docs/reports/step-0-infrastructure/engineering-report.md b/docs/archive/reports/2026-05-steps/step-0-infrastructure/engineering-report.md similarity index 100% rename from docs/reports/step-0-infrastructure/engineering-report.md rename to docs/archive/reports/2026-05-steps/step-0-infrastructure/engineering-report.md diff --git a/docs/reports/step-0-infrastructure/testing-report.md b/docs/archive/reports/2026-05-steps/step-0-infrastructure/testing-report.md similarity index 100% rename from docs/reports/step-0-infrastructure/testing-report.md rename to docs/archive/reports/2026-05-steps/step-0-infrastructure/testing-report.md diff --git a/docs/reports/step-1-data-layer/engineering-report.md b/docs/archive/reports/2026-05-steps/step-1-data-layer/engineering-report.md similarity index 100% rename from docs/reports/step-1-data-layer/engineering-report.md rename to docs/archive/reports/2026-05-steps/step-1-data-layer/engineering-report.md diff --git a/docs/reports/step-2-auth/engineering-report.md b/docs/archive/reports/2026-05-steps/step-2-auth/engineering-report.md similarity index 100% rename from docs/reports/step-2-auth/engineering-report.md rename to docs/archive/reports/2026-05-steps/step-2-auth/engineering-report.md diff --git a/docs/reports/step-3-webssh/engineering-report.md b/docs/archive/reports/2026-05-steps/step-3-webssh/engineering-report.md similarity index 100% rename from docs/reports/step-3-webssh/engineering-report.md rename to docs/archive/reports/2026-05-steps/step-3-webssh/engineering-report.md diff --git a/docs/reports/step-4-sync/engineering-report.md b/docs/archive/reports/2026-05-steps/step-4-sync/engineering-report.md similarity index 100% rename from docs/reports/step-4-sync/engineering-report.md rename to docs/archive/reports/2026-05-steps/step-4-sync/engineering-report.md diff --git a/docs/reports/step-5-frontend/design-review-report.md b/docs/archive/reports/2026-05-steps/step-5-frontend/design-review-report.md similarity index 100% rename from docs/reports/step-5-frontend/design-review-report.md rename to docs/archive/reports/2026-05-steps/step-5-frontend/design-review-report.md diff --git a/docs/reports/step-5-frontend/engineering-report.md b/docs/archive/reports/2026-05-steps/step-5-frontend/engineering-report.md similarity index 100% rename from docs/reports/step-5-frontend/engineering-report.md rename to docs/archive/reports/2026-05-steps/step-5-frontend/engineering-report.md diff --git a/docs/reports/step-5-frontend/product-department-report.md b/docs/archive/reports/2026-05-steps/step-5-frontend/product-department-report.md similarity index 100% rename from docs/reports/step-5-frontend/product-department-report.md rename to docs/archive/reports/2026-05-steps/step-5-frontend/product-department-report.md diff --git a/docs/audit/2026-06-04-docs-consolidation.md b/docs/audit/2026-06-04-docs-consolidation.md new file mode 100644 index 00000000..b2b71efe --- /dev/null +++ b/docs/audit/2026-06-04-docs-consolidation.md @@ -0,0 +1,46 @@ +# 审计 — 文档归类合并(2026-06-04) + +## 审计信息 + +- **日期**: 2026-06-04 +- **触发原因**: 执行迭代计划 §2.6 / §2.7 — 项目记忆收敛 + 全库 MD 归档合并 +- **审计人**: Agent + +## 改动文件清单 + +| 文件 | 操作 | +|------|------| +| `scripts/consolidate_docs.py` | 新增 | +| `docs/archive/**` | 新建归档 + 4 合并卷 + memory/handoff | +| `docs/README.md` | 重写总索引 | +| `docs/audit/INDEX.md` | 新增 | +| `docs/changelog/INDEX.md` | 新增(195 篇索引) | +| `docs/project/nexus-full-site-features.md` | stub | +| `docs/memory/MEMORY.md` | stub | +| `AGENTS.md` / `CLAUDE.md` / `.cursorrules` | 薄 stub | +| `PROJECT_HANDOVER.md` | stub;原文 → archive | +| `deploy/pre_deploy_check.sh` | .venv 工具路径 | + +## Step 3: 规则扫描 H + +| H | 判定 | 依据 | +|---|------|------| +| H-文档 | PASS | 无删除原文;`git mv`/脚本移动至 archive | +| H-密钥 | PASS | `.cursorrules` 已移除明文密码 | +| H-SSOT | PASS | 单一功能指南 + 文档 README 入口 | + +## Closure 表 + +| ID | 文件 | 结论 | 依据 | +|----|------|------|------| +| D1 | consolidate_docs.py | OK | 移动+摘要合并,不删 changelog | +| D2 | AGENTS/CLAUDE | OK | 链 SSOT,去 Tailwind 过期描述 | +| D3 | archive/line-walk | OK | 74 batch → 1 合并卷 + raw 目录 | + +## DoD + +- [x] 活跃 SSOT 可经 `docs/README.md` 导航 +- [x] 合并卷含批次索引与 Closure 摘录 +- [x] changelog 195 篇保留 + INDEX +- [x] 无 `.env`/密钥写入文档 +- [x] changelog 记录本次变更 diff --git a/docs/audit/INDEX.md b/docs/audit/INDEX.md new file mode 100644 index 00000000..27ef92a0 --- /dev/null +++ b/docs/audit/INDEX.md @@ -0,0 +1,25 @@ +# 审计文档索引 + +> 更新: 2026-06-04 + +## 活跃(门控 / 登记) + +| 文件 | 用途 | +|------|------| +| [2026-06-04-bug-scan-registry.json](2026-06-04-bug-scan-registry.json) | FINDING 登记 registry | +| [2026-06-04-plugin-audit-gate7-closure.md](2026-06-04-plugin-audit-gate7-closure.md) | Gate7 文件清单 | +| [2026-06-04-docs-consolidation.md](2026-06-04-docs-consolidation.md) | 文档归类合并审计 | +| [TEMPLATE.md](TEMPLATE.md) | 审计模板 | + +## 战役 Closure(`docs/reports/`) + +| 报告 | +|------| +| [audit-plugin-run-final-2026-06-04.md](../reports/audit-plugin-run-final-2026-06-04.md) | +| [audit-frontend-14p-2026-06-04-closure.md](../reports/audit-frontend-14p-2026-06-04-closure.md) | +| [audit-phase-4-plugin-closure-2026-06-04.md](../reports/audit-phase-4-plugin-closure-2026-06-04.md) | +| [audit-bug-scan-closure-2026-06-04.md](../reports/audit-bug-scan-closure-2026-06-04.md) | + +## 合并卷(batch 原文) + +见 [archive/audits/](../archive/audits/) — line-walk / delta / phase2 / frontend-14p diff --git a/docs/changelog/2026-06-04-docs-consolidation.md b/docs/changelog/2026-06-04-docs-consolidation.md new file mode 100644 index 00000000..df327451 --- /dev/null +++ b/docs/changelog/2026-06-04-docs-consolidation.md @@ -0,0 +1,37 @@ +# Changelog: 文档归类合并 + 项目记忆收敛 + +**日期**: 2026-06-04 +**类型**: 文档 / 工具 +**动机**: 执行迭代计划 — ~494 篇 MD 归类;消除 AGENTS/CLAUDE/.cursorrules 重复与过期描述;审计 batch 合并卷 + archive 子目录。 + +## 变更摘要 + +1. 新增 `scripts/consolidate_docs.py`:74 line-walk + 8 delta + 9 phase2 + 3 frontend batch → 4 合并卷;原文进 `docs/archive/audits/*/` +2. `docs/memory/` 17 篇 → `archive/memory/` + 合并卷;`docs/archive/handoff/` 旧 handoff +3. 2026-05 审查报告 30 项 → `archive/reports/2026-05-reviews|steps` +4. 重写 `docs/README.md`;新增 `docs/audit/INDEX.md`、`docs/changelog/INDEX.md`(195 篇) +5. `AGENTS.md`、`CLAUDE.md`、`.cursorrules` 改为薄 stub(无明文密码);`PROJECT_HANDOVER` 归档 +6. `nexus-full-site-features.md`、`line-walk-audit-standard v1` 归档 + stub +7. `deploy/pre_deploy_check.sh`:优先 `.venv/bin/ruff|bandit|python3` + +## 涉及文件 + +见 `docs/audit/2026-06-04-docs-consolidation.md` 清单。 + +## 是否需迁移/重启 + +否。 + +## 验证 + +```bash +python3 scripts/consolidate_docs.py # 幂等:已移动文件 skip +test -f docs/archive/audits/2026-06-04-line-walk-merged.md +test -f docs/changelog/INDEX.md +wc -l AGENTS.md CLAUDE.md # 应 < 60 行 +``` + +## 未包含 + +- L5 生产部署(待用户批准) +- Phase 3 规模压测 / UX diff --git a/docs/changelog/2026-06-04-functional-development-guide.md b/docs/changelog/2026-06-04-functional-development-guide.md new file mode 100644 index 00000000..5b3fc291 --- /dev/null +++ b/docs/changelog/2026-06-04-functional-development-guide.md @@ -0,0 +1,35 @@ +# Changelog: Nexus 功能开发指南(SSOT) + +**日期**: 2026-06-04 +**类型**: 文档 +**动机**: 用户要求编写非常详细的功能文档,供后续开发接续使用;旧 `nexus-full-site-features.md` 基于 Tailwind 静态页,与当前 Vue 3 SPA 不一致。 + +## 变更摘要 + +1. 新增 `docs/project/nexus-functional-development-guide.md` 作为功能开发主参考(SSOT),覆盖架构、配置、19 表模型、Redis 数据流、后台任务、全量 API 索引、SyncEngineV2、14 页前端功能、Composables、WebSocket/WebSSH、Agent 协议、安装向导、本地验证/门控/部署及扩展开发 checklist。 +2. 新增 `docs/project/nexus-functional-development-guide-appendix.md`:附录 A–I,含 sync 全端点 Pydantic 字段、Files/Push/Terminal 调用链与 mermaid 时序、schedules/retries 等待补 API、14 页组件映射、Playwright/L4 对照、错误码约定、扩展 checklist。 +3. 主文档 §22 增加附录索引;AI-HANDOFF 文档列表已指向 SSOT。 + +## 涉及文件 + +| 文件 | 操作 | +|------|------| +| `docs/project/nexus-functional-development-guide.md` | 新增 / 更新 | +| `docs/project/nexus-functional-development-guide-appendix.md` | 新增 | +| `docs/changelog/2026-06-04-functional-development-guide.md` | 更新 | +| `docs/project/AI-HANDOFF-2026-06-03.md` | 更新文档索引 | + +## 是否需迁移/重启 + +否(纯文档)。 + +## 验证方式 + +- 人工通读附录 A 与 `server/api/sync_v2.py` 端点数量一致 +- 附录 B 与 `useFilesPage.ts` composable 导入一致 +- 附录 G 与 `full-acceptance.spec.mjs` 15 用例一致 + +## 关联 + +- 接续 handoff: `docs/project/AI-HANDOFF-2026-06-03.md` +- 旧功能清单(HTML 时代): `docs/project/nexus-full-site-features.md`(保留历史,以 SSOT+附录为准) diff --git a/docs/changelog/INDEX.md b/docs/changelog/INDEX.md new file mode 100644 index 00000000..9e1a0632 --- /dev/null +++ b/docs/changelog/INDEX.md @@ -0,0 +1,212 @@ +# Changelog 索引 + +> 按年月分组;正文不合并。 + + +## fix-verification + +- [fix-verification-report-2026-05-20.md](fix-verification-report-2026-05-20.md) + +## fix-plan + +- [fix-plan-2026-05-20.md](fix-plan-2026-05-20.md) +- [fix-plan-full-2026-05-20.md](fix-plan-full-2026-05-20.md) + +## 2026-06 + +- [2026-06-01-asyncssh-sftp-api-fix.md](2026-06-01-asyncssh-sftp-api-fix.md) +- [2026-06-01-audit-action-labels-zh.md](2026-06-01-audit-action-labels-zh.md) +- [2026-06-01-browser-verification.md](2026-06-01-browser-verification.md) +- [2026-06-01-bug-audit-fixes.md](2026-06-01-bug-audit-fixes.md) +- [2026-06-01-bug-remediation.md](2026-06-01-bug-remediation.md) +- [2026-06-01-compress-permission-fallback.md](2026-06-01-compress-permission-fallback.md) +- [2026-06-01-dashboard-audit-schedules-fix.md](2026-06-01-dashboard-audit-schedules-fix.md) +- [2026-06-01-deploy-files-posix.md](2026-06-01-deploy-files-posix.md) +- [2026-06-01-editor-dark-theme-sftp-write-fix.md](2026-06-01-editor-dark-theme-sftp-write-fix.md) +- [2026-06-01-editor-syntax-highlight.md](2026-06-01-editor-syntax-highlight.md) +- [2026-06-01-files-300k-preload.md](2026-06-01-files-300k-preload.md) +- [2026-06-01-files-browse-fix.md](2026-06-01-files-browse-fix.md) +- [2026-06-01-files-browse-sudo-fallback.md](2026-06-01-files-browse-sudo-fallback.md) +- [2026-06-01-files-capability-elevation.md](2026-06-01-files-capability-elevation.md) +- [2026-06-01-files-clipboard-transfer.md](2026-06-01-files-clipboard-transfer.md) +- [2026-06-01-files-editor-panel.md](2026-06-01-files-editor-panel.md) +- [2026-06-01-files-floating-editor.md](2026-06-01-files-floating-editor.md) +- [2026-06-01-files-monaco-editor-fix.md](2026-06-01-files-monaco-editor-fix.md) +- [2026-06-01-files-ownership-permission-ui.md](2026-06-01-files-ownership-permission-ui.md) +- [2026-06-01-files-page-iteration.md](2026-06-01-files-page-iteration.md) +- [2026-06-01-files-page-row-click.md](2026-06-01-files-page-row-click.md) +- [2026-06-01-files-phase2-recursive-read-hint.md](2026-06-01-files-phase2-recursive-read-hint.md) +- [2026-06-01-files-phase5-hardening.md](2026-06-01-files-phase5-hardening.md) +- [2026-06-01-files-sudo-hint.md](2026-06-01-files-sudo-hint.md) +- [2026-06-01-files-v2-complete.md](2026-06-01-files-v2-complete.md) +- [2026-06-01-full-acceptance-automation.md](2026-06-01-full-acceptance-automation.md) +- [2026-06-01-master-backlog-plan.md](2026-06-01-master-backlog-plan.md) +- [2026-06-01-master-plan-execution.md](2026-06-01-master-plan-execution.md) +- [2026-06-01-nexus-acceptance-runner.md](2026-06-01-nexus-acceptance-runner.md) +- [2026-06-01-posix-path-linux-only.md](2026-06-01-posix-path-linux-only.md) +- [2026-06-01-remote-write-ssh-fallback.md](2026-06-01-remote-write-ssh-fallback.md) +- [2026-06-01-remove-department-agents.md](2026-06-01-remove-department-agents.md) +- [2026-06-01-schedules-retries-route-fix.md](2026-06-01-schedules-retries-route-fix.md) +- [2026-06-01-schema-posix-path-validation.md](2026-06-01-schema-posix-path-validation.md) +- [2026-06-01-servers-batch-selection-fix.md](2026-06-01-servers-batch-selection-fix.md) +- [2026-06-01-single-owner-execution.md](2026-06-01-single-owner-execution.md) +- [2026-06-01-terminal-empty-layout-fix.md](2026-06-01-terminal-empty-layout-fix.md) +- [2026-06-01-terminal-quick-commands-settings.md](2026-06-01-terminal-quick-commands-settings.md) +- [2026-06-01-terminal-spa-iteration.md](2026-06-01-terminal-spa-iteration.md) +- [2026-06-01-test-api-health-prune-followup.md](2026-06-01-test-api-health-prune-followup.md) +- [2026-06-01-testing-workflow-ai-first.md](2026-06-01-testing-workflow-ai-first.md) +- [2026-06-01-unlock-login-lockout-script.md](2026-06-01-unlock-login-lockout-script.md) +- [2026-06-02-credentials-password-preset-fix.md](2026-06-02-credentials-password-preset-fix.md) +- [2026-06-02-editor-refactor-p0.md](2026-06-02-editor-refactor-p0.md) +- [2026-06-02-file-editor-monaco-markraw.md](2026-06-02-file-editor-monaco-markraw.md) +- [2026-06-02-file-editor-ref-props-fix.md](2026-06-02-file-editor-ref-props-fix.md) +- [2026-06-02-file-editor-tree-fix.md](2026-06-02-file-editor-tree-fix.md) +- [2026-06-02-file-editor-usability-fix.md](2026-06-02-file-editor-usability-fix.md) +- [2026-06-02-file-editor-word-wrap-default.md](2026-06-02-file-editor-word-wrap-default.md) +- [2026-06-02-files-context-vmodel-fix.md](2026-06-02-files-context-vmodel-fix.md) +- [2026-06-02-files-editor-copy-paste-improvements.md](2026-06-02-files-editor-copy-paste-improvements.md) +- [2026-06-02-files-list-action-buttons.md](2026-06-02-files-list-action-buttons.md) +- [2026-06-02-files-refactor-P1.md](2026-06-02-files-refactor-P1.md) +- [2026-06-02-files-refactor-P2.md](2026-06-02-files-refactor-P2.md) +- [2026-06-02-files-refactor-P4-P5.md](2026-06-02-files-refactor-P4-P5.md) +- [2026-06-02-frontend-build-in-git.md](2026-06-02-frontend-build-in-git.md) +- [2026-06-02-keep-session-no-refresh.md](2026-06-02-keep-session-no-refresh.md) +- [2026-06-02-medium-bug-fix-6.md](2026-06-02-medium-bug-fix-6.md) +- [2026-06-02-monaco-core-preload.md](2026-06-02-monaco-core-preload.md) +- [2026-06-02-proactive-jwt-refresh.md](2026-06-02-proactive-jwt-refresh.md) +- [2026-06-02-push-error-messages-zh.md](2026-06-02-push-error-messages-zh.md) +- [2026-06-02-push-post-b5-enhancements.md](2026-06-02-push-post-b5-enhancements.md) +- [2026-06-02-push-refactor-B0-B1.md](2026-06-02-push-refactor-B0-B1.md) +- [2026-06-02-push-refactor-B2.md](2026-06-02-push-refactor-B2.md) +- [2026-06-02-push-refactor-B3.md](2026-06-02-push-refactor-B3.md) +- [2026-06-02-push-refactor-B4.md](2026-06-02-push-refactor-B4.md) +- [2026-06-02-push-refactor-B5.md](2026-06-02-push-refactor-B5.md) +- [2026-06-02-server-form-redesign.md](2026-06-02-server-form-redesign.md) +- [2026-06-02-servers-stat-cards-align.md](2026-06-02-servers-stat-cards-align.md) +- [2026-06-02-spa-hash-login-redirect.md](2026-06-02-spa-hash-login-redirect.md) +- [2026-06-02-system-bug-fix-7-high.md](2026-06-02-system-bug-fix-7-high.md) +- [2026-06-02-terminal-refactor-T1-T5.md](2026-06-02-terminal-refactor-T1-T5.md) +- [2026-06-02-terminal-top-clipped-fix.md](2026-06-02-terminal-top-clipped-fix.md) +- [2026-06-02-unix-ls-longiso-parse-fix.md](2026-06-02-unix-ls-longiso-parse-fix.md) +- [2026-06-02-whitelist-bypass-lockout.md](2026-06-02-whitelist-bypass-lockout.md) +- [2026-06-02-windows-ubuntu-encoding-audit.md](2026-06-02-windows-ubuntu-encoding-audit.md) +- [2026-06-02-windows-ubuntu-encoding-deep-dive.md](2026-06-02-windows-ubuntu-encoding-deep-dive.md) +- [2026-06-03-docker.md](2026-06-03-docker.md) +- [2026-06-04-audit-frontend-14p-batch-deep.md](2026-06-04-audit-frontend-14p-batch-deep.md) +- [2026-06-04-audit-phase2-p2-1-files-ssh.md](2026-06-04-audit-phase2-p2-1-files-ssh.md) +- [2026-06-04-audit-phase2-p2-2-sync-v2-full.md](2026-06-04-audit-phase2-p2-2-sync-v2-full.md) +- [2026-06-04-audit-phase2-p2-3-websocket-dashboard.md](2026-06-04-audit-phase2-p2-3-websocket-dashboard.md) +- [2026-06-04-audit-phase2-p2-4-servers-full.md](2026-06-04-audit-phase2-p2-4-servers-full.md) +- [2026-06-04-audit-phase2-p2-5-webssh-full.md](2026-06-04-audit-phase2-p2-5-webssh-full.md) +- [2026-06-04-audit-phase2-p2-6-sync-engine-full.md](2026-06-04-audit-phase2-p2-6-sync-engine-full.md) +- [2026-06-04-audit-phase2-p2-7-9-closure.md](2026-06-04-audit-phase2-p2-7-9-closure.md) +- [2026-06-04-audit-plugin-run-final.md](2026-06-04-audit-plugin-run-final.md) +- [2026-06-04-audit-wave-d1-redis-port.md](2026-06-04-audit-wave-d1-redis-port.md) +- [2026-06-04-audit-wave-d2-auth-agent.md](2026-06-04-audit-wave-d2-auth-agent.md) +- [2026-06-04-audit-wave-d3-servers-settings.md](2026-06-04-audit-wave-d3-servers-settings.md) +- [2026-06-04-audit-wave-d4-push-frontend.md](2026-06-04-audit-wave-d4-push-frontend.md) +- [2026-06-04-audit-wave-d5-files-terminal.md](2026-06-04-audit-wave-d5-files-terminal.md) +- [2026-06-04-audit-wave-d6-auth-login.md](2026-06-04-audit-wave-d6-auth-login.md) +- [2026-06-04-audit-wave-d7-deploy-local.md](2026-06-04-audit-wave-d7-deploy-local.md) +- [2026-06-04-audit-wave-d8-phase1-closure.md](2026-06-04-audit-wave-d8-phase1-closure.md) +- [2026-06-04-bug-batch3-retry-sync-stats.md](2026-06-04-bug-batch3-retry-sync-stats.md) +- [2026-06-04-bug-batch4-push-etag-heartbeat.md](2026-06-04-bug-batch4-push-etag-heartbeat.md) +- [2026-06-04-bug-batch5-agent-etag.md](2026-06-04-bug-batch5-agent-etag.md) +- [2026-06-04-bug-batch6-auth-files-etag.md](2026-06-04-bug-batch6-auth-files-etag.md) +- [2026-06-04-bug-scan-b0-registry.md](2026-06-04-bug-scan-b0-registry.md) +- [2026-06-04-bug-scan-full-closure.md](2026-06-04-bug-scan-full-closure.md) +- [2026-06-04-code-review-p0-p1-fixes.md](2026-06-04-code-review-p0-p1-fixes.md) +- [2026-06-04-code-review-p1-p2-batch2.md](2026-06-04-code-review-p1-p2-batch2.md) +- [2026-06-04-code-review-p1-p2-batch3.md](2026-06-04-code-review-p1-p2-batch3.md) +- [2026-06-04-cursor-plugins-linux-mcp.md](2026-06-04-cursor-plugins-linux-mcp.md) +- [2026-06-04-docs-consolidation.md](2026-06-04-docs-consolidation.md) +- [2026-06-04-encoding-ubuntu-phase1.md](2026-06-04-encoding-ubuntu-phase1.md) +- [2026-06-04-frontend-typecheck-fixes.md](2026-06-04-frontend-typecheck-fixes.md) +- [2026-06-04-functional-development-guide.md](2026-06-04-functional-development-guide.md) +- [2026-06-04-install-lock-atomic.md](2026-06-04-install-lock-atomic.md) +- [2026-06-04-install-wizard-guard-fix.md](2026-06-04-install-wizard-guard-fix.md) +- [2026-06-04-l4-local-playwright-pass.md](2026-06-04-l4-local-playwright-pass.md) +- [2026-06-04-linux-paths-and-local-e2e.md](2026-06-04-linux-paths-and-local-e2e.md) +- [2026-06-04-local-verify-no-wsl.md](2026-06-04-local-verify-no-wsl.md) +- [2026-06-04-ls-timezone-parse-fix.md](2026-06-04-ls-timezone-parse-fix.md) +- [2026-06-04-monaco-vendor-selfhost.md](2026-06-04-monaco-vendor-selfhost.md) +- [2026-06-04-npm-proxy-mysql-mcp.md](2026-06-04-npm-proxy-mysql-mcp.md) +- [2026-06-04-preview-vendor-and-install-b904.md](2026-06-04-preview-vendor-and-install-b904.md) +- [2026-06-04-production-deploy.md](2026-06-04-production-deploy.md) +- [2026-06-04-risk-acceptance-single-operator.md](2026-06-04-risk-acceptance-single-operator.md) +- [2026-06-04-schedule-once-rollback.md](2026-06-04-schedule-once-rollback.md) +- [2026-06-04-ubuntu-dev-env-setup.md](2026-06-04-ubuntu-dev-env-setup.md) + +## 2026-05 + +- [2026-05-22-alert-push-dashboard.md](2026-05-22-alert-push-dashboard.md) +- [2026-05-22-audit-p2-fixes.md](2026-05-22-audit-p2-fixes.md) +- [2026-05-22-env-mysql-remote-config.md](2026-05-22-env-mysql-remote-config.md) +- [2026-05-22-frontend-vendor-selfhost.md](2026-05-22-frontend-vendor-selfhost.md) +- [2026-05-22-global-jwt-middleware.md](2026-05-22-global-jwt-middleware.md) +- [2026-05-22-implementation-standards-rule.md](2026-05-22-implementation-standards-rule.md) +- [2026-05-22-line-walk-audit-standard.md](2026-05-22-line-walk-audit-standard.md) +- [2026-05-22-local-mysql-full-access-node20-fix.md](2026-05-22-local-mysql-full-access-node20-fix.md) +- [2026-05-22-mysql-mcp-node20-fix.md](2026-05-22-mysql-mcp-node20-fix.md) +- [2026-05-22-script-exec-batching.md](2026-05-22-script-exec-batching.md) +- [2026-05-22-script-execution-platform.md](2026-05-22-script-execution-platform.md) +- [2026-05-22-script-job-callback.md](2026-05-22-script-job-callback.md) +- [2026-05-22-security-fixes-p0.md](2026-05-22-security-fixes-p0.md) +- [2026-05-22-security-fixes-p1.md](2026-05-22-security-fixes-p1.md) +- [2026-05-22-security-fixes-p2-queue.md](2026-05-22-security-fixes-p2-queue.md) +- [2026-05-22-superpowers-zh-install.md](2026-05-22-superpowers-zh-install.md) +- [2026-05-22-tech-stack-rules-mysql-mcp.md](2026-05-22-tech-stack-rules-mysql-mcp.md) +- [2026-05-22-telegram-sanitize-and-security-tests.md](2026-05-22-telegram-sanitize-and-security-tests.md) +- [2026-05-22-wsl-mysql-bootstrap.md](2026-05-22-wsl-mysql-bootstrap.md) +- [2026-05-23-ai-handoff-document.md](2026-05-23-ai-handoff-document.md) +- [2026-05-23-development-acceptance-standard.md](2026-05-23-development-acceptance-standard.md) +- [2026-05-23-full-audit-reconciliation-fixes.md](2026-05-23-full-audit-reconciliation-fixes.md) +- [2026-05-23-full-site-features-doc.md](2026-05-23-full-site-features-doc.md) +- [2026-05-23-mcp-memory-server.md](2026-05-23-mcp-memory-server.md) +- [2026-05-23-medium-fixes.md](2026-05-23-medium-fixes.md) +- [2026-05-23-phase1-audit-fixes.md](2026-05-23-phase1-audit-fixes.md) +- [2026-05-23-phase2-docs-sync.md](2026-05-23-phase2-docs-sync.md) +- [2026-05-23-phase3-audit-fixes.md](2026-05-23-phase3-audit-fixes.md) +- [2026-05-23-round2-audit-fixes.md](2026-05-23-round2-audit-fixes.md) +- [2026-05-23-ssh-exec-no-8601.md](2026-05-23-ssh-exec-no-8601.md) +- [2026-05-23-standards-transfer-package.md](2026-05-23-standards-transfer-package.md) +- [2026-05-23-wsl-integration-guide.md](2026-05-23-wsl-integration-guide.md) +- [2026-05-24-agent-api-key-auth-fix.md](2026-05-24-agent-api-key-auth-fix.md) +- [2026-05-24-agent-upgrade-deps-check.md](2026-05-24-agent-upgrade-deps-check.md) +- [2026-05-24-batch-review-fixes.md](2026-05-24-batch-review-fixes.md) +- [2026-05-25-server-form-preset-dropdown-ssh-key.md](2026-05-25-server-form-preset-dropdown-ssh-key.md) +- [2026-05-25-ssh-key-preset-system.md](2026-05-25-ssh-key-preset-system.md) +- [2026-05-26-batch-import-upload-agent.md](2026-05-26-batch-import-upload-agent.md) +- [2026-05-26-gate-v2-seven-gates.md](2026-05-26-gate-v2-seven-gates.md) +- [2026-05-26-gate3-test-fix.md](2026-05-26-gate3-test-fix.md) +- [2026-05-26-knowledge-graph-restructure.md](2026-05-26-knowledge-graph-restructure.md) +- [2026-05-26-pre-deploy-gates.md](2026-05-26-pre-deploy-gates.md) +- [2026-05-26-remove-asset-management.md](2026-05-26-remove-asset-management.md) +- [2026-05-26-server-form-ux-bugfix-security.md](2026-05-26-server-form-ux-bugfix-security.md) +- [2026-05-26-terminal-sidebar-panel-ssh-key-fix.md](2026-05-26-terminal-sidebar-panel-ssh-key-fix.md) +- [2026-05-26-webssh-command-input-bar.md](2026-05-26-webssh-command-input-bar.md) +- [2026-05-26-webssh-echo-delay-fix.md](2026-05-26-webssh-echo-delay-fix.md) +- [2026-05-26-webssh-terminal-fix.md](2026-05-26-webssh-terminal-fix.md) +- [2026-05-27-agent-install-fix-and-deploy.md](2026-05-27-agent-install-fix-and-deploy.md) +- [2026-05-27-agent-os-release.md](2026-05-27-agent-os-release.md) +- [2026-05-27-audit-i18n-and-batch-btn-fix.md](2026-05-27-audit-i18n-and-batch-btn-fix.md) +- [2026-05-27-fmttime-venv-batchinstall-fix.md](2026-05-27-fmttime-venv-batchinstall-fix.md) +- [2026-05-28-push-5-features.md](2026-05-28-push-5-features.md) +- [2026-05-29-push-round2-features.md](2026-05-29-push-round2-features.md) +- [2026-05-29-push-round2.md](2026-05-29-push-round2.md) +- [2026-05-29-push-round3.md](2026-05-29-push-round3.md) +- [2026-05-29-push-round4.md](2026-05-29-push-round4.md) +- [2026-05-30-files-iteration.md](2026-05-30-files-iteration.md) +- [2026-05-30-heartbeat-422-fix.md](2026-05-30-heartbeat-422-fix.md) +- [2026-05-30-monaco-ide-editor.md](2026-05-30-monaco-ide-editor.md) +- [2026-05-30-nginx-redirect-fix.md](2026-05-30-nginx-redirect-fix.md) +- [2026-05-30-ruff-cleanup.md](2026-05-30-ruff-cleanup.md) +- [2026-05-30-security-health-fix.md](2026-05-30-security-health-fix.md) +- [2026-05-30-servers-iteration.md](2026-05-30-servers-iteration.md) +- [2026-05-30-settings-inspection.md](2026-05-30-settings-inspection.md) +- [2026-05-30-settings-security-ux.md](2026-05-30-settings-security-ux.md) +- [2026-05-30-terminal-iteration.md](2026-05-30-terminal-iteration.md) +- [2026-05-31-terminal-quick-commands-mysql.md](2026-05-31-terminal-quick-commands-mysql.md) +- [2026-05-31-vuetify-audit-fix.md](2026-05-31-vuetify-audit-fix.md) +- [2026-05-31-vuetify-frontend-rebuild.md](2026-05-31-vuetify-frontend-rebuild.md) +- [2026-05-31-vuetify-gallery-redesign.md](2026-05-31-vuetify-gallery-redesign.md) diff --git a/docs/memory/MEMORY.md b/docs/memory/MEMORY.md index c76a3c9b..981562b7 100644 --- a/docs/memory/MEMORY.md +++ b/docs/memory/MEMORY.md @@ -1,25 +1,4 @@ -# 项目记忆 +# 项目记忆(已归档) -从 agentmemory 迁移(2026-05-21) - -## 数据流与机制 -- [Nexus 6.0 项目概述](mem_nexus_overview.md) -- [Nexus 6.0 已确认关键决策汇总](mem_nexus_decisions.md) -- [Nexus 心跳数据流与告警机制](mem_nexus_dataflow.md) -- [Nexus 3层守护机制设计](mem_nexus_guardian.md) -- [Nexus 6.0 Phase A+B+C 已完成模块](mem_nexus_modules.md) -- [Nexus Phase D 测试计划与流程](mem_nexus_testing.md) -- [Nexus Telegram Bot告警推送设计](mem_nexus_telegram.md) -- [Nexus Phase D 前置修复 (2026-05-20): 12项关键修复全部完成](mem_phase_d_bugfixes.md) -- [Nexus 团队讨论议程关键决策汇总](mem_team_agenda.md) -- [Nexus 6.0 关键文件清单](mem_key_files.md) -- [Nexus 新增关键决策 (Phase D)](mem_new_decisions.md) - -## 配置与部署 -- [Nexus install.php配置三写机制](mem_nexus_config.md) -- [Nexus 仓库统一与Git状态](mem_nexus_repo.md) -- [Nexus WSL部署信息 (172.31.170.47)](mem_wsl_deployment.md) - -## 团队与流程 -- [MultiSync 2026-05-19 进度:Sprint P0-P2 全部完成(SSH线程隔离、Redis深度利用、](mem_mpc4vjm8_caa29f573fd9.md) -- [Sprint 2026-05-19 全部 11 项任务完成。生产环境 217/253 在线,API/DB/Redis/W](mem_mpc54lkr_68c4f408352b.md) +见 [agentmemory-2026-05-merged.md](../archive/memory/agentmemory-2026-05-merged.md) +与 [功能开发指南](../project/nexus-functional-development-guide.md)。 diff --git a/docs/project/AI-HANDOFF-2026-06-03.md b/docs/project/AI-HANDOFF-2026-06-03.md index 0875245c..21f3c380 100644 --- a/docs/project/AI-HANDOFF-2026-06-03.md +++ b/docs/project/AI-HANDOFF-2026-06-03.md @@ -24,11 +24,11 @@ 【规范】.cursor/rules/perfect-implementation.mdc · 单 Agent · 改代码必 changelog -【文档】docs/project/AI-HANDOFF-2026-06-03.md · linux-dev-paths.md · docker/README.md +【文档】docs/README.md(总索引)· nexus-functional-development-guide.md + appendix · archive/README.md 【Code Review】批次 1~3 已本地验证;见 docs/changelog/2026-06-04-code-review-*.md 【风险接受 · 单人运维】docs/project/risk-acceptance-single-operator.md(WS ADR-011 + Agent global 不排期) 【插件】docs/project/cursor-plugins-for-nexus.md · MySQL MCP: scripts/linux_mcp_mysql.sh -【本地验收】seed_local_admin.py + frontend npm run test:e2e(见 linux-dev-paths.md) +【本地验收】bash scripts/local_verify.sh · seed_local_admin.py · frontend npm run test:e2e ``` ## 解压离线包后 @@ -57,3 +57,11 @@ cd "$NEXUS_ROOT" && git remote -v # 若无 .git:重新 clone 后覆盖源码 - Agent global `API_KEY` legacy 回退保留;batch3 已禁 unknown server_id 重评触发:新增管理员、日志外发、等保审计、global key 泄露或 Agent 全量 per-server 迁移完成。 + +## 本地验证(2026-06-04) + +```bash +bash scripts/local_verify.sh # Docker + API + smoke + test_api + ruff +``` + +文档:`docs/project/local-integration-test.md`(已取代 WSL 脚本) diff --git a/docs/project/development-acceptance-standard.md b/docs/project/development-acceptance-standard.md index 3301d80a..a44534e4 100644 --- a/docs/project/development-acceptance-standard.md +++ b/docs/project/development-acceptance-standard.md @@ -1,17 +1,18 @@ # Nexus 6.0 — 开发验收标准(SSOT) -> **更新**: 2026-05-23 +> **更新**: 2026-06-04 > **读者**: 开发 AI、测试、运维 -> **地位**: 宣称「功能完成 / 可合并 / 可上线」前**必须**对照本文;与功能清单、接续文档并列。 +> **地位**: 宣称「功能完成 / 可合并 / 可上线」前**必须**对照本文。 **相关文档** | 文档 | 路径 | |------|------| -| 全站功能 | [`nexus-full-site-features.md`](nexus-full-site-features.md) | -| AI 接续 | [`AI-HANDOFF-2026-05-23.md`](AI-HANDOFF-2026-05-23.md) | -| **标准转接包(全量)** | [`standards-transfer-package.md`](standards-transfer-package.md) | -| 功能说明书 HTML | [`../Nexus-功能说明书.html`](../Nexus-功能说明书.html) | +| **功能 SSOT** | [`nexus-functional-development-guide.md`](nexus-functional-development-guide.md) | +| AI 接续 | [`AI-HANDOFF-2026-06-03.md`](AI-HANDOFF-2026-06-03.md) | +| 文档总索引 | [`../README.md`](../README.md) | +| **标准转接包** | [`standards-transfer-package.md`](standards-transfer-package.md) | +| 生产验证 | [`production-verification-checklist.md`](production-verification-checklist.md) | --- @@ -20,13 +21,21 @@ ``` L0 原则与纪律 perfect-implementation + 架构规则(始终遵守) L1 设计验收 设计文档 / 技术文档中的「验收标准」章节 -L2 代码完成 单测 + WSL smoke +(改 API/前端时)对应模块手测 -L3 安全审计 逐行走读 DoD(改安全路径或大 diff 时) -L4 模块 E2E 脚本 T-SE、告警策略、推送 dry-run 等专项清单 -L5 首次部署 production-verification-checklist(上线前) +L2 代码完成 local_verify + pytest +(改 API/前端时)模块手测 +L3 门控 pre_deploy_check.sh 7/7 +L4 模块 E2E run_nexus_acceptance.py --with-ui +L5 生产部署 production-verification + deploy-production.sh ``` -**禁止**:未跑 L2 对应命令就声称「已修复 / 已完成」;未满足 L0 就合并。 +### 改动量级 → 最低验收 + +| 量级 | 范围 | 最低验收 | +|------|------|----------| +| **小** | ≤3 文件,非 auth/sync/ssh | L2 + changelog | +| **中** | 新 API/页面/composable | L2 + 模块 E2E + 精简审计 Closure | +| **大** | 认证、Agent、sync 引擎 | L2 + L3 + 完整审计 8 步 + 设计/技术文档 | + +**禁止**:未跑 L2 就声称「已修复 / 已完成」。 --- @@ -82,12 +91,13 @@ L5 首次部署 production-verification-checklist(上线前) | 场景 | 命令 | 通过标准 | |------|------|----------| | 任意后端改动 | `pytest tests/test_security_unit.py -q` | 全部 passed | -| WSL 全链路代码向 | `bash scripts/wsl_ensure_venv.sh`(首次) | 无 error | -| | `bash scripts/wsl_start_dev.sh` | 服务启动 | -| | `bash scripts/wsl_integration_smoke.sh` | security + `/health` + `/api/servers/` 401 | +| 本地全链路代码向 | `bash scripts/ensure_venv.sh`(首次) | 无 error | +| | `bash scripts/start-dev.sh` | 服务启动 | +| | `bash scripts/local_integration_smoke.sh` | security + `/health` + `/api/servers/` 401 | +| 一键 | `bash scripts/local_verify.sh` | smoke + test_api + ruff | | 有 API 契约变更 | `pytest tests/test_api.py`(需 `.env` + 测试账号) | 按项目约定 | -详见:[`wsl-integration-test.md`](wsl-integration-test.md) +详见:[`local-integration-test.md`](local-integration-test.md) ### 2.2 按改动类型的附加验收 diff --git a/docs/project/local-integration-test.md b/docs/project/local-integration-test.md new file mode 100644 index 00000000..672e0a59 --- /dev/null +++ b/docs/project/local-integration-test.md @@ -0,0 +1,87 @@ +# 本地代码验证(Ubuntu / Linux) + +> **只做一件事**:在本机确认代码能启动、单测通过、关键 HTTP 行为正确。 +> **不做**:生产部署清单、浏览器手测、Agent 全量 E2E。 + +环境:Ubuntu 原生 + Docker(MySQL + Redis)+ Python 3.12 + 项目根 `.env`。 + +--- + +## 一键(推荐) + +```bash +cd "$NEXUS_ROOT" # 例:~/桌面/Nexus +bash scripts/local_verify.sh +``` + +顺序:启动 Docker MySQL/Redis → uvicorn → smoke → `test_api.py` → ruff。 + +--- + +## 分步 + +**首次 — 依赖** + +```bash +bash scripts/ensure_venv.sh +python3 docker/generate_env.py # 若无 docker/.env +python3 docker/sync_root_env.py # 生成根 .env +``` + +**启动** + +```bash +bash scripts/start-dev.sh +``` + +**验证** + +```bash +bash scripts/local_integration_smoke.sh +.venv/bin/python tests/test_api.py +``` + +| 项 | 预期 | +|----|------| +| `tests/test_security_unit.py` + retry | 全部 passed | +| `GET /health` | 200 | +| `GET /api/servers/` | 401(JWT) | +| `tests/test_api.py` | 26/26 passed | + +--- + +## Docker 权限 + +若 `docker` 报 permission denied,脚本会自动 `sg docker`。或: + +```bash +sudo usermod -aG docker "$USER" # 重新登录后免 sg +``` + +Redis 检测:优先 `redis-cli`;未安装时用 `docker exec nexus-redis-1 redis-cli ping`(无需 apt 装 redis-tools)。 + +--- + +## 无 `.env` + +先 `bash scripts/start-dev.sh`,浏览器打开 `http://127.0.0.1:8600/app/install.html` 完成向导,或: + +```bash +NEXUS_TEST_ADMIN_PASSWORD='你的密码' python3 scripts/seed_local_admin.py +``` + +--- + +## 脚本索引 + +| 脚本 | 作用 | +|------|------| +| `scripts/start-dev.sh` | Docker mysql+redis + uvicorn | +| `scripts/local_verify.sh` | 一键启动 + 全量本地验证 | +| `scripts/local_integration_smoke.sh` | smoke(不启动服务) | +| `scripts/ensure_venv.sh` | 创建 `.venv` | +| `scripts/check_mysql.py` | MySQL 连通与表检查 | + +上线验收见 [`production-verification-checklist.md`](production-verification-checklist.md)。 + +路径 SSOT:[`linux-dev-paths.md`](linux-dev-paths.md) diff --git a/docs/project/nexus-full-site-features.md b/docs/project/nexus-full-site-features.md index 27e0bcb6..a14c5508 100644 --- a/docs/project/nexus-full-site-features.md +++ b/docs/project/nexus-full-site-features.md @@ -1,323 +1,5 @@ -# Nexus 6.0 — 全站功能清单(SSOT) +# 全站功能清单(已 supersede) -> **更新**: 2026-05-23 -> **读者**: 产品、运维、接续开发的 AI -> **HTML 版**: [`docs/Nexus-功能说明书.html`](../Nexus-功能说明书.html) -> **接续开发**: [`AI-HANDOFF-2026-05-23.md`](AI-HANDOFF-2026-05-23.md) +请以 **[nexus-functional-development-guide.md](nexus-functional-development-guide.md)** 为准。 ---- - -## 0. 全站页面地图(18 页) - -| 页面 | 路径 | 功能摘要 | -|------|------|----------| -| 安装向导 | `/app/install.html` | 无 `.env` 时 5 步安装中心机 | -| 登录 | `/app/login.html` | JWT + TOTP + 防暴破 | -| 仪表盘 | `/app/index.html` | 统计、WebSocket 刷新、告警计数 | -| 服务器 | `/app/servers.html` | CRUD、详情、Agent 安装/升级、时钟漂移 | -| 资产管理 | `/app/assets.html` | Platform / Node 树 | -| 文件管理 | `/app/files.html` | SSH 浏览、删/改名/建目录 | -| 推送 | `/app/push.html` | rsync 批量、dry-run 预览、历史 | -| 脚本库 | `/app/scripts.html` | 脚本 CRUD、直接执行、$DB_* | -| 执行历史 | `/app/script-executions.html` | 停止/重试/日志/卡住检测 | -| 凭据 | `/app/credentials.html` | DB 凭据 + 密码预设 | -| 定时调度 | `/app/schedules.html` | Cron 推送 **或** 脚本执行 | -| 重试队列 | `/app/retries.html` | 推送失败指数退避重试 | -| 命令日志 | `/app/commands.html` | WebSSH 会话/命令 + **推送日志** | -| 告警中心 | `/app/alerts.html` | 告警历史、统计、时间过滤 | -| 审计 | `/app/audit.html` | 操作审计、时间/用户/类型过滤 | -| 设置 | `/app/settings.html` | 品牌、阈值、Telegram、TOTP、IP 白名单 | -| WebSSH | `/app/terminal.html` | xterm.js 终端(独立页) | - -共享:`layout.js`(侧栏)、`api.js`(JWT、toast、全局搜索) - ---- - -## 1. 网络与通道模型 - -| 通道 | 端口 | 用途 | -|------|------|------| -| 子机 → 中心 | **443 出站** | Agent 心跳、长任务完成回调 | -| 中心 → 子机 | **22 入站** | 推送、文件、**脚本**、手动健康检查、Agent 安装/升级 | -| 子机本机 | **127.0.0.1:8601** | Agent HTTP(可不暴露公网) | - ---- - -## 2. 认证与访问控制 - -- JWT 登录 / 刷新 / 登出(`POST /api/auth/*`) -- TOTP:启用、禁用、**重绑**(设置页) -- 登录防暴破:5 次/15 分钟 → 429 -- 会话:8 小时无操作退出;刷新令牌重用检测 -- **登录 IP 白名单**:总开关、手动 IP、**代理订阅 URL 解析**(2h 自动刷新)、与登录防暴破联动 -- WebSSH 专用短票:`POST /api/auth/webssh-token`(绑定 server_id) - -**不可改密钥**(仅 `.env`):`SECRET_KEY`、`API_KEY`、`ENCRYPTION_KEY`、`DATABASE_URL` - ---- - -## 3. 仪表盘(index.html) - -- 服务器总数 / 在线 / 离线 / 告警中(Redis 实时) -- WebSocket:告警/恢复时**刷新统计**(浏览器不响铃、不弹告警列表) -- 最近推送记录摘要 - ---- - -## 4. 告警中心(alerts.html)— 新增模块 - -- MySQL `alert_logs` 持久化告警与恢复记录 -- 列表:按服务器、类型、是否恢复、**日期范围**分页 -- 统计:近 N 日 Top 服务器、按日计数 -- API:`GET /api/alert-history/`、`GET /api/alert-history/stats` - -**实时告警路径**:Agent 心跳超阈值 → Redis + WebSocket Pub/Sub + Telegram(5 分钟防抖) - ---- - -## 5. 服务器管理(servers.html) - -- 分页列表;Redis 覆盖 `is_online`、`system_info`、**时钟漂移**(warn/crit 徽章) -- CRUD:SSH 密钥/密码(Fernet)、`platform_id`/`node_id`、`target_path`、`agent_port` -- 每机 **Agent API Key**(`nxs-*`,一次性展示) -- **Agent 安装**:复制 curl 命令 / **一键 SSH 远程安装**(实时日志) -- 安装后 **轮询在线状态** -- **Agent 升级**:`POST /api/servers/{id}/upgrade-agent`(SSH 拉 agent.py + restart) -- **健康检查**:`POST /api/servers/check`(**SSH 探测**,非 8601) -- 详情:系统信息、同步日志、WebSSH 入口 -- 推送:`POST /api/servers/push`;日志:`GET /api/servers/logs` - -**未实现**:CSV 批量导入 - ---- - -## 6. 资产管理(assets.html) - -- Platform 模板 CRUD -- Node 树形分组 CRUD -- SSH 会话列表、命令日志查询(与 commands.html 数据同源) - -API:`/api/assets/platforms`、`/api/assets/nodes`、`/api/assets/ssh-sessions`、`/api/assets/command-logs` - ---- - -## 7. WebSSH(terminal.html) - -- xterm.js + Koko 协议 + asyncssh 连接池 -- `webssh-token` 15 分钟、**绑定 server_id**(越权关闭码 4003) -- 全屏、自动 resize -- 会话与命令写入 `ssh_sessions` / `command_logs` - -**未实现**:断线自动重连(需刷新页面) - ---- - -## 8. 命令日志(commands.html) - -- **会话视图**:WebSSH 会话列表、过滤 -- **命令视图**:逐条命令、危险命令高亮 -- **推送日志视图**:rsync 批量推送历史、分页、服务器/状态/模式/触发源过滤 - ---- - -## 9. 批量推送(push.html) - -- SyncEngineV2:`sync_files` rsync-over-SSH -- 模式:增量 / 全量(--delete) / 校验和 / inplace -- 分批 50、并发 10;失败 → `push_retry_jobs` -- **dry-run 预览**(方案 D):首台 `--dry-run --stats`,可选 `-v` 前 200 行 -- 推送历史列表 - -API:`POST /api/sync/files`、`POST /api/sync/preview` - ---- - -## 10. Sync 引擎其他能力(API,部分无独立页) - -| 模式 | API | 说明 | -|------|-----|------| -| 命令批量 | `POST /api/sync/commands` | SSH 批量执行命令 | -| 配置推送 | `POST /api/sync/config` | 批量写配置项 | -| 配置回滚 | `POST /api/sync/config/rollback` | 回滚 | -| SFTP | `POST /api/sync/sftp` | 上传/下载 | -| 目录浏览 | `POST /api/sync/browse` | 文件页也用 | -| 文件操作 | `POST /api/sync/file-ops` | 删/改名/mkdir | - ---- - -## 11. 脚本与执行历史 - -### 脚本库(scripts.html) - -- 脚本 CRUD(分类:ops/deploy/check/cleanup) -- **直接执行命令**(无需入库) -- 批量选机执行;危险命令中心拦截(400) -- **执行通道:SSH 22**(结果 `channel: ssh`) -- $DB_* 凭据替换(中心替换后 SSH 下发) - -### 执行历史(script-executions.html) - -- 列表 / 详情 / 停止 / 重试 / 标记卡住 -- 长任务:nohup + 子机 `curl` 回调 `POST /api/agent/script-callback` -- Redis 热数据 2h + 60s 刷 MySQL - -API:`POST /api/scripts/exec`、`GET /api/scripts/executions/*` - ---- - -## 12. 远程文件管理(files.html) - -- SSH `ls -la` 浏览、面包屑、目录优先排序 -- 删除文件/目录、重命名、新建目录(confirm/二次确认) - -**未实现**:上传、在线预览、树形侧栏 - ---- - -## 13. 定时调度(schedules.html) - -- **类型**:`push`(文件推送)或 `script`(脚本执行) -- 5 字段 Cron;`schedule_runner` 60s 检查;仅 Primary Worker -- 脚本调度:关联 `script_id` 或内联 `script_content`、超时、长任务标志 - ---- - -## 14. 凭据管理(credentials.html) - -- **数据库凭据**:MySQL/PG 等,Fernet 加密,供 $DB_* -- **密码预设**:SSH 密码模板(推送场景) - -脚本页也可管理 DB 凭据(`/api/scripts/credentials`) - ---- - -## 15. 重试队列(retries.html) - -- 推送失败自动入队;`retry_runner` 5 分钟指数退避 -- 手动立即重试 / 删除任务 - ---- - -## 16. 全局搜索 - -- 侧栏搜索框:`GET /api/search/` 跨服务器/脚本/凭据/调度 - ---- - -## 17. 系统设置(settings.html) - -| 模块 | 功能 | -|------|------| -| 品牌 | system_name、title | -| 监控 | CPU/内存/磁盘阈值 | -| 连接 | redis_url、pool_size | -| Telegram | Token、Chat ID、**测试发送**、**getUpdates 解析 Chat ID** | -| 告警开关 | 各类型 Telegram 通知独立开关 | -| 安全 | 改密码、TOTP 启用/禁用/重绑、API Key 二次验证查看 | -| 登录白名单 | 开关、订阅 URL、手动 IP 列表、解析预览 | - -配置三写:安装时 `.env` + `settings` 表 + `web/data/config.php`(PHP 兼容) - ---- - -## 18. 审计日志(audit.html) - -- 全站 CUD 与关键操作写入 `audit_logs` -- 过滤:**日期起止**、管理员用户名、操作类型(分组下拉) -- 分页 50 条/页 - -**未实现**:导出 CSV/JSON(已否决) - ---- - -## 19. 安装向导(install.html) - -- 无 `.env` → 安装模式(其他 API 503) -- 步骤:环境 → DB/Redis → 管理员/品牌 → 完成 -- 生成密钥、写三处配置、Nginx 模板、cron 提示 -- 完成后 install API 锁定(403) - ---- - -## 20. 子机 Agent(web/agent/) - -| 能力 | 说明 | -|------|------| -| 心跳 | 60s → `POST /api/agent/heartbeat`;变化>10% 或超阈值加急 | -| 时钟漂移 | `agent_time` vs 中心;warn/crit + Telegram | -| IP 白名单 | `allowed_ips` 限制访问 Agent HTTP | -| 安装 | `install.sh`:python3.12 venv、127.0.0.1:8601 | -| 端点 | `/health`、`/exec*`(中心脚本已改 SSH,子机端点保留) | - ---- - -## 21. 后台任务(仅 Primary Worker) - -| 任务 | 间隔 | 文件 | -|------|------|------| -| heartbeat_flush | 10min | Redis → MySQL | -| self_monitor | 30s | Redis/MySQL/WS 自检 | -| schedule_runner | 60s | Cron 调度 | -| retry_runner | 5min | 推送重试 | -| ip_allowlist_refresh | 2h | 订阅 IP 刷新 | -| script_execution_flush | 60s | 执行记录刷盘 | -| asyncssh 清理 | 60s | 空闲 SSH 连接 | - ---- - -## 22. 三层守护 - -1. Supervisor — 进程崩溃重启 -2. Python self_monitor — 30s,Redis/MySQL 异常 Telegram -3. Shell `health_monitor.sh` — 1min,连续 3 次 `/health` 失败重启 - ---- - -## 23. 未实现(待开发) - -| 功能 | 优先级 | -|------|--------| -| WebSSH 断线重连 | P1 | -| 服务器 CSV 批量导入 | P1 | -| Agent upgrade 与 venv install 对齐 | P1 | -| 仪表盘历史趋势图 | P2 | -| 远程文件上传 / 内容预览 | P2 | -| 宝塔 API 监控增强 | 可选 | -| Agent mTLS | 可选 | - ---- - -## 24. 已否决(不做) - -文件编辑器、RBAC、移动端、会话录像、审计导出、邮件报告、Redis Cluster、Docker(当前阶段) - ---- - -## 25. 标准与验收(必查 · 与团队同等严谨) - -| 文档 | 路径 | -|------|------| -| **标准转接包(全量)** | [`standards-transfer-package.md`](standards-transfer-package.md) | -| 开发验收 L0~L5 | [`development-acceptance-standard.md`](development-acceptance-standard.md) | -| 系统开发标准 | [`standards/system-development-standard.md`](../../standards/system-development-standard.md) | -| 逐行审计 v2 | [`standards/line-walk-audit-standard-v2.md`](../../standards/line-walk-audit-standard-v2.md) | -| 审计原则 | [`standards/audit-core-principles.md`](../../standards/audit-core-principles.md) | -| Cursor 规则 | `.cursor/rules/*.mdc`(含 `audit-line-review.mdc`) | - -**逐行审查**:8 步/文件、Closure 全表、FINDING 必须 `文件:行号`、单回复 ≤5 文件 — **不可降级**。 - -| 层级 | 说明 | -|------|------| -| L0 | 完美实现 + 全部 mdc + system-development-standard | -| L2 | `pytest` + `wsl_integration_smoke.sh` | -| L3 | 逐行 DoD(同 standards-transfer-package §2) | -| L4 | 脚本 T-SE、告警策略、T1~T5 | -| L5 | `production-verification-checklist.md` | - ---- - -## 26. 待验证(非功能缺失) - -- 首次部署 E2E:`docs/project/production-verification-checklist.md` -- 脚本 T-SE1~8:`docs/project/script-execution.md` -- WSL 代码向:`docs/project/wsl-integration-test.md` +历史 HTML 版: [archive](../archive/project/nexus-full-site-features.md) diff --git a/docs/project/nexus-functional-development-guide-appendix.md b/docs/project/nexus-functional-development-guide-appendix.md new file mode 100644 index 00000000..f9bd52db --- /dev/null +++ b/docs/project/nexus-functional-development-guide-appendix.md @@ -0,0 +1,458 @@ +# Nexus 6.0 — 功能开发指南 · 附录(详细参考) + +> **主文档**: [nexus-functional-development-guide.md](nexus-functional-development-guide.md) +> **版本**: 2026-06-04 +> **用途**: API 请求体、前端调用链、E2E/L4 对照、组件映射 — 接续开发时查表用 + +--- + +## 附录 A — `/api/sync` 端点与 Pydantic 模型 + +定义: `server/api/schemas.py` · 路由: `server/api/sync_v2.py` · 前缀: `/api/sync` + +| 方法 | 路径 | 请求模型 | 说明 | +|------|------|----------|------| +| POST | `/files` | `SyncFiles` | 批量 rsync 推送 | +| POST | `/preview` | `SyncPreview` | dry-run 预览(单台代表服务器) | +| POST | `/file-ops` | `FileOperation` | 远程 delete/rename/mkdir | +| POST | `/file-clipboard` | `FileClipboardApply` | 远程 copy/move 批量粘贴 | +| POST | `/browse` | `SyncBrowse` | 远程目录列表(POST 兼容路径) | +| POST | `/browse-local` | `SyncBrowseLocal` | Nexus 本机 staging 目录浏览 | +| POST | `/local-file-ops` | `LocalFileOperation` | staging 内 delete/rename | +| POST | `/local-file-preview` | `LocalFilePreview` | staging 文件预览 | +| POST | `/cancel` | `SyncCancel` | 按 batch_id 取消推送 | +| POST | `/reconcile-stale-logs` | `ReconcileStaleLogs` | 将 stuck `running` 日志标失败 | +| POST | `/validate-source-path` | `ValidateSourcePath` | 校验本机源目录 | +| POST | `/diagnose` | `SyncDiagnose` | 单台推送失败诊断 | +| POST | `/file-diff` | `FileSyncDiff` | 本地 vs 远程单文件 diff | +| POST | `/upload` | multipart | 上传到 staging | +| POST | `/upload-zip` | multipart | ZIP 解压到 staging | +| POST | `/verify` | `SyncVerify` | 推送后 md5 校验 | +| POST | `/download` | `FileDownload` | 远程文件下载流 | +| POST | `/read-file` | `FileRead` | 读远程文本(≤5MB) | +| POST | `/write-file` | `FileWrite` | 写远程文本 + 可选 etag 乐观锁 | +| POST | `/chmod` | `FileChmod` | chmod/chown | +| POST | `/compress` | `FileCompress` | tar.gz/zip 压缩 | +| POST | `/decompress` | `FileDecompress` | 解压到绝对路径 | + +### A.1 核心模型字段 + +**SyncFiles**(推送) + +| 字段 | 类型 | 默认 | 约束 | +|------|------|------|------| +| `server_ids` | `int[]` | — | min 1 | +| `source_path` | `str` | — | Nexus 本机绝对路径,禁系统敏感路径 | +| `target_path` | `str?` | null | 远程绝对路径;空则用各服务器 `target_path` | +| `sync_mode` | `str` | `incremental` | `incremental\|full\|overwrite\|checksum` | +| `batch_size` | `int` | 50 | 1–200 | +| `concurrency` | `int` | 10 | 1–50 | +| `batch_id` | `str?` | null | 12 位 hex;须先连 `/ws/sync` 再 POST | + +**SyncPreview** + +| 字段 | 说明 | +|------|------| +| `server_id` | 代表服务器(单台 dry-run) | +| `verbose` | true 时返回文件列表(≤200 行) | +| 其余 | 同 SyncFiles 的 path/mode | + +**FileOperation** + +| operation | 必填 | 远程命令 | +|-----------|------|----------| +| `delete` | `path` | `rm -rf` | +| `rename` | `path`, `new_path` | `mv` | +| `mkdir` | `path` | `mkdir -p` | + +**FileClipboardApply** + +| 字段 | 约束 | +|------|------| +| `mode` | `copy` → `cp -r`;`move` → `mv -t` | +| `sources` | 1–50 条远程绝对路径 | +| `dest_dir` | 目标目录绝对路径 | + +**FileRead / FileWrite** + +| 字段 | FileRead | FileWrite | +|------|----------|-----------| +| `max_size` | 默认 1MB,max 5MB | — | +| `content` | — | max 5MB | +| `etag` | — | 乐观锁,冲突 409 | + +**FileChmod** + +| 字段 | 说明 | +|------|------| +| `mode` | 3–4 位八进制 `^[0-7]{3,4}$` | +| `owner` / `group` | 可选;group 须同时有 owner | +| `recursive` | 目录递归 | + +### A.2 推送 WS 协议(`/ws/sync`) + +1. 前端生成 `batch_id`(12 hex) +2. **先** `WebSocket` 连接 `/ws/sync?token=&batch_id=` +3. **再** `POST /api/sync/files` 带相同 `batch_id` +4. 消息: per-server 状态(pending/running/success/failed/cancelled)、进度百分比、错误摘要 +5. 取消: `POST /api/sync/cancel` `{ batch_id }` + +### A.3 文件浏览双通道 + +| 通道 | 方法 | 优势 | +|------|------|------| +| REST | `GET /api/files/browse?server_id=&path=` | ETag + 304,前端首选 | +| Sync 兼容 | `POST /api/sync/browse` | 旧网关/部署回退 | + +前端 `useFilesBrowse.fetchBrowseListing` 先 GET,失败再 POST。 + +--- + +## 附录 B — 文件页(Files)调用链 + +### B.1 组件树 + +``` +FilesPage.vue +├── FilesToolbar.vue # 服务器选择、刷新、上传、新建 +├── FilesPermissionAlert.vue # files-capability / sudo 提示 +├── FilesStatusBar.vue # 条目统计、SSH 用户 +├── FilesBreadcrumb.vue # 路径面包屑 +├── FilesList.vue # v-data-table + 行操作 +├── FilesDialogs.vue # 删除/重命名/chmod/压缩等对话框 +└── FileEditorWorkbench.vue # Monaco 编辑 + 预览 +``` + +`provideFilesPage(page)` → 子组件通过 `injectFilesPage()` 取上下文(`filesPageContext.ts`)。 + +### B.2 Composable 依赖图 + +``` +useFilesPage +├── useFilesStore (Pinia) # selectedServer, currentPath, files, cache +├── useFilesSelection # selectedFiles 多选 +├── useFilesBrowse(fileFilter) # browse(), ETag, preload Monaco +│ └── GET /api/files/browse | POST /api/sync/browse +├── useFilesPermissions # files-capability, setup-files-sudo +│ └── GET /api/servers/{id}/files-capability +│ └── POST /api/servers/{id}/setup-files-sudo +├── useFilesNavigation # 面包屑、goUp、openEntry、?server_id= +├── useFilesEditor # read/write/preview +│ └── POST /api/sync/read-file | write-file +├── useFilesActions # CRUD、clipboard、upload、compress +│ └── POST /api/sync/file-ops | file-clipboard | upload | chmod | compress… +├── useFilesClipboard # 跨目录 copy/cut/paste 状态 +└── useFilesHotkeys # Ctrl+C/V、Delete、F5 刷新 +``` + +### B.3 关键 API 映射(用户操作 → 端点) + +| 用户操作 | Composable | API | +|----------|------------|-----| +| 选服务器/进目录 | `useFilesBrowse.browse` | `GET /files/browse` | +| 保存编辑器 | `useFilesEditor.save` | `POST /sync/write-file` | +| 删除/重命名/新建目录 | `useFilesActions` | `POST /sync/file-ops` | +| 复制/剪切/粘贴 | `useFilesActions` + clipboard | `POST /sync/file-clipboard` | +| 上传 | `useFilesActions.doUpload` | `POST /sync/upload` | +| chmod | `useFilesActions.doChmod` | `POST /sync/chmod` | +| 压缩/解压 | `useFilesActions` | `POST /sync/compress` / `decompress` | +| 下载 | `useFilesActions.downloadFile` | `POST /sync/download` | +| 配置 sudo | `useFilesPermissions.setupFilesSudo` | `POST /servers/{id}/setup-files-sudo` | +| 打开终端 | `useFilesNavigation.openInTerminal` | 路由 `#/terminal?server_id=` | + +### B.4 Store 缓存策略(`stores/files.ts`) + +- Key: `{serverId}:{path}` +- 存 ETag + entries + fetchedAt +- `invalidateAfterMutation` 在写操作后清除当前目录及父目录缓存 +- `pageReady`: 首次 browse 完成后为 true(避免空态闪烁) + +### B.5 路由 Query 参数 + +| 参数 | 行为 | +|------|------| +| `?server_id=123` | `useFilesNavigation` 自动选中并 browse | +| `?path=/var/www` | 初始路径(须与 server_id 同用) | + +--- + +## 附录 C — 推送页(Push)调用链 + +### C.1 Composable 依赖图 + +``` +usePushPage +├── usePushForm # source_path, target_path, sync_mode, batch 参数 +├── usePushServers # 服务器列表、分类、全选、在线过滤 +├── usePushLogs # sync_logs 历史分页 +├── usePushProgress # WS + doPush + cancel +│ └── WS /ws/sync +│ └── POST /api/sync/files, /cancel +└── usePushPreview # 预览对话框、confirmAndPush + └── POST /api/sync/preview (并发代表服务器) +``` + +### C.2 推送流程(时序) + +```mermaid +sequenceDiagram + participant UI as PushPage + participant WS as /ws/sync + participant API as /api/sync/files + participant Eng as SyncEngineV2 + + UI->>UI: generate batch_id (12 hex) + UI->>WS: connect(token, batch_id) + UI->>API: POST /files {batch_id, server_ids, ...} + Eng->>WS: per-server progress + WS->>UI: update pushStatus + Eng->>Eng: rsync over SSH (semaphore) + UI->>API: POST /cancel (optional) +``` + +### C.3 相关端点(Push 页间接使用) + +| 功能 | API | +|------|-----| +| 校验源路径 | `POST /sync/validate-source-path` | +| ZIP 源 | `POST /sync/upload-zip` | +| 失败诊断 | `POST /sync/diagnose` | +| 对账 stuck 日志 | `POST /sync/reconcile-stale-logs` | +| 推送后校验 | `POST /sync/verify` | + +--- + +## 附录 D — 终端页(Terminal)调用链 + +``` +TerminalPage.vue +├── TerminalToolbar.vue +├── TerminalTabBar.vue +├── TerminalServerPicker.vue +├── TerminalArea.vue # xterm 实例 +├── TerminalCmdBar.vue # 命令输入 + 高亮 +└── TerminalQuickBar.vue # 快捷命令 + +useTerminalSessions +├── POST /api/auth/webssh-token { server_id } +├── WebSocket /ws/terminal/{session_uuid}?token= +├── Koko: TERMINAL_INIT, DATA, RESIZE, CLOSE +└── onBeforeUnmount → disposeAllSessions + +useTerminalQuickCommands → GET/POST /api/terminal/quick-commands +useTerminalSettings → localStorage 主题/字体(非敏感) +``` + +**WebSSH JWT**: `purpose=webssh`, 绑定 `server_id`, 15min;路径 param `id` 须与 token 内 server_id 一致。 + +--- + +## 附录 E — 其余 API 模块明细 + +### E.1 调度 `/api/schedules`(`settings.py` 内) + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/` | 列表 | +| POST | `/` | 创建(cron + server_ids + source/target + sync_mode 或 script_id) | +| PUT | `/{id}` | 更新 | +| DELETE | `/{id}` | 删除 | + +后台 `schedule_runner` 每分钟扫描 `enabled=1` 且 cron 到期项 → 调 SyncEngine 或 ScriptService。 + +### E.2 重试 `/api/retries` + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/` | 待重试队列 | +| POST | `/{id}/retry` | 手动触发 | +| DELETE | `/{id}` | 移出队列 | + +`retry_runner` 每 5min,`SELECT … FOR UPDATE SKIP LOCKED`,指数退避,max 3 次。 + +### E.3 审计 `/api/audit` + +| 方法 | 路径 | Query | +|------|------|-------| +| GET | `/` | `page`, `page_size`, `action`, `username`, `date_from`, `date_to` | + +### E.4 告警 `/api/alert-history` + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/` | 分页列表 | +| GET | `/stats` | 汇总统计 | + +### E.5 预设 + +| 前缀 | 用途 | +|------|------| +| `/api/presets` | 密码预设 CRUD | +| `/api/ssh-key-presets` | SSH 密钥预设 CRUD | +| `/api/scripts/credentials` | DB 凭据(脚本 `$DB_*`) | + +### E.6 脚本 `/api/scripts` + +| 方法 | 路径 | 说明 | +|------|------|------| +| POST | `/exec` | `{ script_id?, command?, server_ids, timeout }` | +| GET | `/executions` | 分页执行记录 | +| POST | `/executions/{id}/stop` | SIGTERM/SIGKILL | +| POST | `/executions/{id}/retry` | 重新执行 | +| GET | `/exec-config` | 超时阈值等前端展示用 | + +### E.7 Agent `/api/agent` + +**Heartbeat body(摘要)** + +```json +{ + "server_id": 1, + "cpu": 12.5, + "memory": 45.0, + "disk": 60.0, + "load": [0.1, 0.2, 0.15], + "agent_version": "6.0.x", + "system_info": { "hostname": "...", "os": "..." } +} +``` + +**Script callback**: Agent 长任务完成后 POST,更新 Redis + MySQL execution。 + +### E.8 搜索 `/api/search` + +`GET /?q=` — 并行查 servers、scripts、db_credentials、schedules(limit 各 10)。 + +--- + +## 附录 F — 前端页面 ↔ 组件 ↔ Composable 映射 + +| 页面 | 主要 Composable | 关键子组件 | +|------|-----------------|------------| +| DashboardPage | `useWebSocket`, `useServerPagination` | StatCardsRow | +| ServersPage | `useServerFormDialog`, `useServerPagination` | ServerFormDialog | +| TerminalPage | `useTerminalSessions`, `useTerminalCmdBar` | TerminalArea, TerminalTabBar | +| FilesPage | `useFilesPage` | FilesToolbar, FilesList, FileEditorWorkbench | +| PushPage | `usePushPage` | PushToolbar, PushServerGrid, PushProgressList | +| ScriptsPage | 页内逻辑 + Monaco | ScriptEditorDialog | +| CredentialsPage | 三 Tab CRUD | — | +| SchedulesPage | cron 表单 | ScheduleFormDialog | +| RetriesPage | 列表 + retry | — | +| CommandsPage | 双视图切换 | — | +| AlertsPage | 过滤 + 分页 | — | +| AuditPage | `normalizeAuditList` | — | +| SettingsPage | TOTP/API Key/IP 白名单 | TerminalQuickCommandsSettings | +| LoginPage | `useAuthStore.login` | — | + +### F.1 全局布局(`App.vue`) + +- 侧栏 14 项导航(v-list) +- 顶栏:全局搜索 → `GET /api/search` +- 用户菜单:主题切换、退出 +- `useWebSocket` 告警 toast + Dashboard 刷新触发 + +### F.2 类型定义 + +所有 API 响应类型优先维护在 `frontend/src/types/api.ts`;新增字段先改类型再改 composable。 + +--- + +## 附录 G — 验收与 E2E 对照 + +### G.1 L4 统一入口 + +```bash +python3 scripts/run_nexus_acceptance.py --base http://127.0.0.1:8600 --with-ui +``` + +阶段: + +| Phase | 内容 | +|-------|------| +| API | `tests/test_api.py` + `tests/test_api_extended.py` | +| UI | `frontend/e2e/full-acceptance.spec.mjs`(15 用例) | +| Unit | `--with-unit` 时跑路径/权限单测 | + +功能 rollup 映射: `tests/acceptance_catalog.py` → `FEATURES[]`。 + +### G.2 Playwright 用例 ↔ 页面 + +| 用例 ID | 路由 | 验证点 | +|---------|------|--------| +| 01 | `#/` | 登录 + Dashboard 卡片 | +| 02 | `#/servers` | 添加对话框、批量选择 | +| 03 | `#/` | 全局搜索输入 | +| 04 | `#/terminal` | 终端页可见 | +| 05 | `#/files` | 文件页可见 | +| 06 | `#/push` | 预览按钮(不真推送) | +| 07 | `#/scripts` | 新建脚本对话框 | +| 08 | `#/credentials` | 三 Tab 切换 | +| 09 | `#/schedules` | 新建调度对话框 | +| 10 | `#/retries` | 重试列表 | +| 11 | `#/commands` | 命令/会话视图 | +| 12 | `#/alerts` | 告警页 | +| 13 | `#/audit` | 审计页 | +| 14 | `#/settings` | 设置区块 | +| 15 | `#/` | 主题切换 + 登出 | + +**环境变量** + +```bash +NEXUS_E2E_BASE=http://127.0.0.1:8600 +NEXUS_E2E_USER=admin +NEXUS_E2E_PASSWORD=*** # 必填;测试账号勿开 TOTP +``` + +### G.3 API 测试环境 + +与 E2E 共用 `.env` 中 `NEXUS_TEST_ADMIN_PASSWORD`(`seed_local_admin.py` 写入)。 + +### G.4 本地验证脚本 + +`bash scripts/local_verify.sh` — ruff、import、pytest 子集、前端 typecheck(若可用)。 + +--- + +## 附录 H — 错误码与前端处理约定 + +| HTTP | 场景 | 前端处理 | +|------|------|----------| +| 401 | JWT 过期 | `fetchAuthed` 自动 refresh 一次 | +| 202 | 需 TOTP | `TotpRequiredError` → 显示 TOTP 输入 | +| 304 | Browse ETag 命中 | 用缓存 entries | +| 409 | write-file etag 冲突 | 提示合并/覆盖 | +| 429 | 登录锁定 | Login 页显示剩余时间 | +| 503 | 安装模式 | 引导 `/app/install.html` | + +统一错误文案: `formatApiError(err)` + `$snackbar`。 + +--- + +## 附录 I — 新增功能检查清单(扩展) + +### 新 Sync 相关端点 + +- [ ] `schemas.py` Pydantic + path validator +- [ ] `sync_v2.py` 路由 + `_audit_sync` +- [ ] `tests/test_api.py` 或 `test_sync_*.py` +- [ ] 前端 `http.post('/sync/...')` + types +- [ ] 更新附录 A + 主文档 §10 +- [ ] changelog ≥10 行 + +### 新 Files 操作 + +- [ ] `useFilesActions` 方法 + `FilesDialogs` UI +- [ ] 热键(若适用)注册到 `useFilesHotkeys` +- [ ] browse 缓存 invalidate +- [ ] E2E 05 或专项用例 + +### 新页面(第 15 页) + +- [ ] `pages/XxxPage.vue` +- [ ] `router/index.ts` + `App.vue` nav +- [ ] `acceptance_catalog.py` + Playwright 用例 +- [ ] `run_nexus_acceptance` 报告可 rollup + +--- + +**维护**: 改 API/composable 时同步更新对应附录章节。 diff --git a/docs/project/nexus-functional-development-guide.md b/docs/project/nexus-functional-development-guide.md new file mode 100644 index 00000000..70f37536 --- /dev/null +++ b/docs/project/nexus-functional-development-guide.md @@ -0,0 +1,859 @@ +# Nexus 6.0 — 功能开发指南(SSOT) + +> **版本**: 2026-06-04 +> **读者**: 接续开发工程师、AI Agent +> **定位**: 后续功能开发的**主参考文档**(比 handoff 更细、比 changelog 更稳) +> **关联**: [linux-dev-paths.md](linux-dev-paths.md) · [local-integration-test.md](local-integration-test.md) · [risk-acceptance-single-operator.md](risk-acceptance-single-operator.md) + +--- + +## 目录 + +1. [项目概述](#1-项目概述) +2. [技术栈与仓库结构](#2-技术栈与仓库结构) +3. [启动模式与配置](#3-启动模式与配置) +4. [架构分层与请求生命周期](#4-架构分层与请求生命周期) +5. [认证、会话与安全](#5-认证会话与安全) +6. [数据模型(19 表)](#6-数据模型19-表) +7. [Redis 与实时数据流](#7-redis-与实时数据流) +8. [后台任务(Primary Worker)](#8-后台任务primary-worker) +9. [后端 API 全览](#9-后端-api-全览) +10. [核心业务模块详解](#10-核心业务模块详解) +11. [前端 SPA 架构](#11-前端-spa-架构) +12. [14 个业务页面功能说明](#12-14-个业务页面功能说明) +13. [Composables 与状态管理](#13-composables-与状态管理) +14. [WebSocket 与 WebSSH](#14-websocket-与-webssh) +15. [Agent 与子机协议](#15-agent-与子机协议) +16. [安装向导](#16-安装向导) +17. [本地开发、测试与门控](#17-本地开发测试与门控) +18. [部署与运维](#18-部署与运维) +19. [扩展开发指南](#19-扩展开发指南) +20. [不可改项与已接受风险](#20-不可改项与已接受风险) +21. [文档索引](#21-文档索引) + +--- + +## 1. 项目概述 + +Nexus 是面向 **2000+ 子服务器** 的运维管理平台(中心机 + Agent 架构),核心能力: + +| 能力域 | 说明 | +|--------|------| +| **服务器资产** | CRUD、分类、Platform/Node、心跳监控、健康检查 | +| **文件管理** | SSH 远程浏览/编辑/chmod/压缩,sudo 提权 | +| **批量推送** | Nexus 主机 rsync → 子机,4 种 sync 模式,ZIP 上传,调度与重试 | +| **脚本执行** | 脚本库 + 临时命令,SSH 并行或 Agent 长任务 | +| **WebSSH** | 浏览器终端,多 Tab,命令日志 | +| **告警** | CPU/内存/磁盘阈值,WebSocket + Telegram,恢复通知 | +| **审计** | 全 CUD + 登录/WebSSH/推送 审计 | +| **安全** | JWT + TOTP + IP 白名单 + Fernet 凭据加密 | + +**生产域名**: `https://api.synaglobal.vip` +**后端端口**: `8600` +**前端入口**: `/app/`(Vue 3 SPA,Vite 构建到 `web/app/`) + +--- + +## 2. 技术栈与仓库结构 + +### 2.1 技术栈 + +| 层 | 技术 | +|----|------| +| 后端 | Python 3.11+ · FastAPI · Async SQLAlchemy · Pydantic v2 | +| 数据库 | MySQL 8.x | +| 缓存/实时 | Redis 7(心跳、告警、WS 跨 worker、脚本执行状态) | +| SSH | asyncssh 连接池 | +| 前端 | Vue 3 · TypeScript · Vuetify 4 · Pinia · Vite | +| 编辑器/终端 | Monaco Editor · xterm.js | +| 进程守护 | Supervisor + Python self_monitor + Shell health_monitor | + +### 2.2 目录结构 + +``` +Nexus/ +├── server/ # FastAPI 后端(Clean Architecture) +│ ├── main.py # 入口、lifespan、中间件、路由挂载 +│ ├── config.py # Pydantic Settings + DB 覆盖 +│ ├── api/ # 路由层(JWT、校验、审计) +│ ├── application/services/ # 业务编排 +│ ├── domain/models/ # SQLAlchemy ORM(19 表) +│ ├── infrastructure/ # DB/Redis/SSH/Telegram 实现 +│ └── background/ # 后台循环任务 +├── frontend/ # Vue 3 SPA 源码 +│ └── src/ +│ ├── pages/ # 14 个页面 +│ ├── components/ # 按模块分子目录 +│ ├── composables/ # 业务逻辑(files/push/terminal…) +│ ├── stores/ # Pinia(auth、files) +│ ├── api/index.ts # HTTP 客户端 +│ └── router/index.ts # Hash 路由 +├── web/app/ # 静态挂载点(index.html + assets/) +│ └── install.html # 安装向导(独立静态页,非 Vue) +├── deploy/ # Supervisor、nginx、门控、部署脚本 +├── docker/ # compose 环境生成 +├── scripts/ # 本地 dev、验收、MCP +├── tests/ # pytest API 测试 +└── docs/ # 设计、审计、changelog +``` + +### 2.3 架构分层(禁止跨层直连) + +``` +frontend/pages → api/index.ts → server/api/*.py + → application/services/*.py + → infrastructure/* + → domain/models +``` + +- **API 层**: 路由 + Pydantic + `Depends(get_current_admin)`,不写裸 SQL +- **Service 层**: 业务编排,经 Repository 访问 DB +- **Infrastructure**: SSH 池、Redis、Telegram、Fernet +- **Domain**: ORM 模型,无 FastAPI 依赖 + +--- + +## 3. 启动模式与配置 + +### 3.1 两种启动模式 + +| 模式 | 条件 | 可用能力 | +|------|------|----------| +| **安装模式** | 仓库根无 `.env` | `/api/install/*`、`/app/install.html`、静态文件;其他 API **503** | +| **正常模式** | 存在 `.env` 且 `SECRET_KEY` / `API_KEY` / `ENCRYPTION_KEY` / `DATABASE_URL` 齐全 | 全功能 + 后台任务 | + +`is_install_mode()` 在 **运行时** 检测 `.env`,安装向导写入后可立即切换(需重启 worker 加载完整 lifespan)。 + +### 3.2 配置三写(安装向导 Step 3) + +安装成功时**同时写入**: + +| 目标 | 内容 | +|------|------| +| `web/data/config.json` | 共享配置(API_BASE_URL、DB、API_KEY) | +| `.env` | `NEXUS_*` 前缀,Python 启动必需 | +| MySQL `settings` 表 | 可热覆盖的动态项(阈值、Telegram、pool 等) | + +**不可从 DB 覆盖**(仅 `.env`):`SECRET_KEY`、`API_KEY`、`ENCRYPTION_KEY`、`DATABASE_URL`。 + +### 3.3 重要环境变量(`NEXUS_` 前缀) + +| 变量 | 说明 | 可 DB 覆盖 | +|------|------|------------| +| `NEXUS_DATABASE_URL` | `mysql+aiomysql://...` | ❌ | +| `NEXUS_SECRET_KEY` | JWT HS256 | ❌ | +| `NEXUS_API_KEY` | Agent 全局密钥 | ❌ | +| `NEXUS_ENCRYPTION_KEY` | Fernet 凭据加密 | ❌ | +| `NEXUS_REDIS_URL` | 默认 `redis://127.0.0.1:6379/0` | ✅ | +| `NEXUS_API_BASE_URL` | 公网 URL(Agent curl 安装) | ✅ | +| `NEXUS_CORS_ORIGINS` | 逗号分隔 | ✅ | +| `NEXUS_DEPLOY_PATH` | 部署根路径 | ✅ | +| `NEXUS_DB_POOL_SIZE` / `MAX_OVERFLOW` | 连接池 | ✅ | +| `NEXUS_CPU/MEM/DISK_ALERT_THRESHOLD` | 告警阈值 % | ✅ | +| `NEXUS_TELEGRAM_BOT_TOKEN` / `CHAT_ID` | 告警推送 | ✅ | +| `NEXUS_LOGIN_ALLOWLIST_*` | 登录 IP 白名单 | ✅ | +| `NEXUS_JWT_ACCESS_TOKEN_EXPIRE_MINUTES` | 默认 60 | ✅ | +| `NEXUS_TEST_ADMIN_PASSWORD` | 本地测试登录(不入 git) | — | + +完整映射见 `server/config.py` 的 `DB_OVERRIDE_MAP`。 + +--- + +## 4. 架构分层与请求生命周期 + +### 4.1 HTTP 请求(普通 API) + +``` +Client → CORS → JwtAuthMiddleware → DbSessionMiddleware → Router + → request.state.db + → Service → Repo → MySQL +``` + +- **DbSessionMiddleware**: 每请求一个 `AsyncSession`,请求结束 close +- **例外**: WebSocket、`/api/install/` 自建 session + +### 4.2 Primary Worker 锁 + +多 worker uvicorn 时,**仅一个** worker 运行后台任务: + +1. Redis `SETNX nexus:primary_worker`(TTL 30s,续期) +2. Redis 不可用时 fallback:`flock /tmp/nexus-primary.lock` + +后台任务列表见 [§8](#8-后台任务primary-worker)。 + +### 4.3 静态文件与 SPA + +- FastAPI 挂载 `web/app/` → `/app/` +- Vue 使用 **Hash 路由** `#/servers`,刷新不依赖 nginx try_files +- 构建: `cd frontend && npx vite build` → 输出 `web/app/index.html` + `assets/` + +--- + +## 5. 认证、会话与安全 + +### 5.1 管理端 JWT + +| 项目 | 说明 | +|------|------| +| 登录 | `POST /api/auth/login`(username + password + 可选 TOTP) | +| Access Token | 响应 body,**仅存内存**(Pinia `auth.ts`) | +| Refresh Token | HttpOnly Cookie `nexus_refresh`,`POST /api/auth/refresh` | +| 过期 | Access 默认 60min;前端过期前 5min 主动 refresh | +| 失效 | 改密/TOTP 变更 → `token_version` 递增,旧 JWT 失效 | +| 防暴破 | 5 次失败 / 15min → HTTP 429 | +| 会话空闲 | 8 小时(refresh 重用检测) | + +**JWT 中间件公开前缀**(无需 Bearer): + +`/api/auth/login` · `/api/auth/refresh` · `/api/auth/logout` · `/api/agent/` · `/api/install/` · `/api/settings/bing-wallpapers` · `/health` · `/ws/` · OpenAPI + +### 5.2 TOTP + +| API | 说明 | +|-----|------| +| `POST /api/auth/totp/setup` | 返回 QR + secret | +| `POST /api/auth/totp/enable` | 验证码确认 | +| `POST /api/auth/totp/disable` | 需当前密码 + TOTP | + +### 5.3 敏感操作二次验证(Re-auth) + +| 场景 | API | 需当前密码 | +|------|-----|------------| +| 查看 API Key | `POST /api/settings/api-key/reveal` | ✅ | +| 查看 Telegram Token | `POST /api/settings/telegram/reveal-token` | ✅ | +| 查看 Agent Key | `POST /api/servers/{id}/agent-key` | ✅ | +| 生成安装命令 | `POST /api/servers/{id}/agent-install-cmd` | ✅ | +| 改密 | `PUT /api/auth/password` | ✅ | + +### 5.4 Agent API Key + +| 层级 | 行为 | +|------|------| +| Per-server | `servers.agent_api_key`(`nxs-*`),优先 | +| 全局回退 | `NEXUS_API_KEY`(legacy,单人运维已接受) | +| 未知 server_id | **拒绝**(batch 安装仍可能用 global key) | + +Header: `X-API-Key` 或 query(Agent 脚本约定)。 + +### 5.5 凭据存储 + +- `Server.password` / `ssh_key_private` → Fernet(`ENCRYPTION_KEY`) +- API 响应: `password_set: true`,**不返明文** +- 密码预设: `encrypted_pw` 字段,前端 POST 后不入 localStorage + +### 5.6 登录 IP 白名单 + +- `settings` + `.env`: `LOGIN_ALLOWLIST_ENABLED` +- 手动 IP + 订阅 URL 解析(`ip_allowlist_refresh` 每 2h) +- 登录 API 在 JWT 之前校验客户端 IP + +--- + +## 6. 数据模型(19 表) + +定义文件: `server/domain/models/__init__.py` + +| ORM | 表名 | 用途 | 关键字段 | +|-----|------|------|----------| +| `Platform` | `platforms` | 资产模板 | `name`, `category`, `default_protocols` | +| `Node` | `nodes` | 资产树节点 | `parent_id`, `sort_order` | +| `Server` | `servers` | 子服务器 | `domain`, `port`, SSH 凭据, `target_path`, `agent_api_key`, `is_online`, `system_info`, `files_elevation` | +| `SyncLog` | `sync_logs` | 推送历史 | `status`, `sync_mode`, 字节/文件统计, `operator` | +| `Admin` | `admins` | 管理员 | `password_hash`, `totp_*`, `token_version` | +| `LoginAttempt` | `login_attempts` | 登录尝试 | 防暴破 | +| `Setting` | `settings` | KV 配置 | `key` PK, `value` | +| `PasswordPreset` | `password_presets` | SSH 密码模板 | `encrypted_pw` | +| `SshKeyPreset` | `ssh_key_presets` | SSH 密钥模板 | `encrypted_private_key` | +| `PushSchedule` | `push_schedules` | 定时任务 | `cron_expr`, `server_ids`, `schedule_type` push/script | +| `PushRetryJob` | `push_retry_jobs` | 失败重试 | 指数退避, `max_retries=3` | +| `AuditLog` | `audit_logs` | 审计 | `action`, `target_*`, `ip_address` | +| `Script` | `scripts` | 脚本库 | `content`, `category` | +| `ScriptExecution` | `script_executions` | 执行记录 | `results` JSON, `status` | +| `DbCredential` | `db_credentials` | DB 凭据 | 脚本内 `$DB_*` 替换 | +| `AlertLog` | `alert_logs` | 告警历史 | `is_recovery` | +| `SshSession` | `ssh_sessions` | WebSSH 会话 | UUID `id` | +| `CommandLog` | `command_logs` | 终端命令 | `command` ≤2000 字符 | +| `QuickCommand` | `quick_commands` | 终端快捷命令 | `sort_order` | + +--- + +## 7. Redis 与实时数据流 + +### 7.1 Key 约定 + +| Key 模式 | TTL | 内容 | +|----------|-----|------| +| `heartbeat:{server_id}` | 600s | 最新心跳字段(HSET) | +| `alerts:{server_id}` | 3600s | 活跃告警集合 | +| `sync:cancel:{batch_id}` | — | 推送取消标记 | +| `nexus:alerts` | Pub/Sub | 跨 worker WS 广播 | +| `script:exec:{id}` | — | 脚本执行实时状态 | +| `nexus:primary_worker` | 30s | Primary 锁 | + +### 7.2 心跳数据流 + +``` +Agent(60s) → POST /api/agent/heartbeat + → Redis 实时写入 + → 前端 Dashboard 读 API(overlay Redis) + → 每 600s heartbeat_flush → MySQL servers 历史字段 + → 超阈值 → WebSocket alert + Telegram(5min 防抖) + → 恢复 → recovery 通知 +``` + +--- + +## 8. 后台任务(Primary Worker) + +| 模块 | 间隔 | 文件 | 职责 | +|------|------|------|------| +| `heartbeat_flush` | 600s | `background/heartbeat_flush.py` | Redis → MySQL 心跳持久化 | +| `script_execution_flush` | 60s | `background/script_execution_flush.py` | 脚本状态 Redis → MySQL;stuck 检测 | +| `self_monitor` | 30s | `background/self_monitor.py` | Redis/MySQL/WS 自检;Telegram | +| `schedule_runner` | 60s | `background/schedule_runner.py` | Cron/once 调度 → 推送或脚本 | +| `retry_runner` | 300s | `background/retry_runner.py` | `push_retry_jobs` SKIP LOCKED 重试 | +| `ip_allowlist_refresh` | 7200s | `background/ip_allowlist_refresh.py` | 订阅 URL 更新白名单 | +| `upload_staging_cleanup` | 3600s | `background/upload_staging_cleanup.py` | 清理 `/tmp/nexus_upload_*` >24h | + +--- + +## 9. 后端 API 全览 + +### 9.1 认证 `/api/auth` + +| 方法 | 路径 | 鉴权 | +|------|------|------| +| POST | `/login` | 公开 | +| POST | `/refresh` | Cookie | +| POST | `/logout` | 公开 | +| POST | `/totp/setup|enable|disable` | JWT | +| PUT | `/password` | JWT + re-auth | +| POST | `/webssh-token` | JWT | +| GET | `/me` | JWT | + +### 9.2 Agent `/api/agent` + +| 方法 | 路径 | 鉴权 | +|------|------|------| +| POST | `/heartbeat` | X-API-Key | +| POST | `/script-callback` | X-API-Key + job token | + +### 9.3 服务器 `/api/servers` + +CRUD、stats、categories、logs、CSV import/export、batch agent install/upgrade/uninstall、health check、files-capability、setup-files-sudo、单台 agent 操作。 + +### 9.4 同步 `/api/sync`(`sync_v2.py`,核心) + +| 分类 | 端点示例 | +|------|----------| +| 推送 | `POST /files`, `/preview`, `/cancel` | +| 远程文件 | `/browse`, `/file-ops`, `/read-file`, `/write-file`, `/chmod`, `/compress`… | +| 本机文件 | `/browse-local`, `/local-file-ops`, `/upload`, `/upload-zip` | +| 工具 | `/validate-source-path`, `/diagnose`, `/reconcile-stale-logs` | + +### 9.5 文件浏览 `/api/files` + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/browse?server_id=&path=` | JWT + ETag 缓存 | + +### 9.6 脚本 `/api/scripts` + +脚本 CRUD、`POST /exec`、executions 停止/重试/stuck、DB 凭据 CRUD。 + +### 9.7 设置族 `/api/settings` + 子路由 + +| 路由器 | 前缀 | 内容 | +|--------|------|------| +| settings | `/api/settings` | 系统 KV、Telegram、IP 白名单、bing 壁纸 | +| schedule | `/api/schedules` | 调度 CRUD | +| preset | `/api/presets` | 密码预设 | +| ssh_key_preset | `/api/ssh-key-presets` | SSH 密钥预设 | +| alert_history | `/api/alert-history` | 告警列表/统计 | +| audit | `/api/audit` | 审计分页 | +| retry | `/api/retries` | 重试队列 | + +### 9.8 其他 + +| 模块 | 前缀 | 说明 | +|------|------|------| +| assets | `/api/assets` | Platform/Node/ssh-sessions/command-logs | +| terminal | `/api/terminal` | 快捷命令 CRUD | +| search | `/api/search` | 全局搜索 | +| install | `/api/install` | 安装向导 | +| health | `/health`, `/health/detail` | 探活 | + +### 9.9 WebSocket + +| 路径 | Token | 用途 | +|------|-------|------| +| `/ws/alerts` | Access JWT | 告警/恢复/系统 | +| `/ws/sync` | Access JWT | 推送进度 | +| `/ws/terminal/{id}` | WebSSH JWT | 终端 Koko 协议 | + +--- + +## 10. 核心业务模块详解 + +### 10.1 推送引擎 SyncEngineV2 + +文件: `server/application/services/sync_engine_v2.py` + +| 概念 | 说明 | +|------|------| +| 执行位置 | **Nexus 中心机** 上执行 `rsync`,SSH 到子机 | +| 并发 | `asyncio.Semaphore`,默认 max 10 | +| 超时 | rsync 300s + 30s grace | +| 认证 | sshpass -e(密码)或临时 key 文件 0600 | +| 失败 | 写 `sync_logs` + 可选 `push_retry_jobs` | +| 取消 | Redis `sync:cancel:{batch_id}` | +| 预览 | `rsync --dry-run --stats` | + +**Sync 模式**(`sync_mode`): + +| 模式 | rsync 参数 | 行为 | +|------|------------|------| +| `incremental` | `-az` | 默认增量 | +| `full` | `-az --delete` | 删除目标多余文件 | +| `checksum` | `-az --checksum` | 校验和 | +| `overwrite` | `-az --inplace` | 原地覆盖 | + +**源路径安全**: `resolve_nexus_push_source_path()` 禁止 `/etc` 等系统路径;ZIP 解压至 `UPLOAD_STAGING_PREFIX` 下暂存目录。 + +### 10.2 远程文件浏览 + +- `GET /api/files/browse` → `files_browse_service.list_remote_directory` +- 远程命令: `ls -la` + `shlex.quote(path)` +- ETag: 目录 mtime + 条目数,支持 `If-None-Match` → 304 +- 前端: `useFilesStore` 内存缓存 + TTL + +**Files elevation**(`files_elevation` 字段): + +| 值 | 行为 | +|----|------| +| `off` | 不 sudo | +| `auto` | 写失败时尝试 sudo | +| `always_sudo` | 始终 sudo | + +`POST /api/servers/{id}/setup-files-sudo` 远程配置 sudoers(密码走 stdin)。 + +### 10.3 脚本执行 + +文件: `server/application/services/script_service.py` + +| 模式 | 条件 | 路径 | +|------|------|------| +| SSH 短命令 | 超时内完成 | asyncssh 并行,Semaphore | +| Agent 长任务 | 超时 > 阈值 | nohup + callback URL + Redis 状态 | + +- DB 凭据: 脚本内 `$DB_HOST` 等占位符替换 +- 危险命令: `check_dangerous_command()` WARN 日志(不阻断) +- 停止: `POST /scripts/executions/{id}/stop` + +### 10.4 服务器 Agent + +| 操作 | API | 方式 | +|------|-----|------| +| 安装 | batch/single install | SSH curl agent 脚本 | +| 升级 | upgrade-agent | SSH 拉取 agent.py | +| 卸载 | uninstall-agent | SSH systemctl stop | +| 安装命令 | agent-install-cmd | 返回 curl(**禁止**暴露 global API_KEY) | + +Agent 心跳 JSON 含 CPU/内存/磁盘/负载;变化 >10% 或超阈值时主动告警。 + +### 10.5 告警与 Telegram + +- 阈值: `CPU/MEM/DISK_ALERT_THRESHOLD`(默认 80%) +- 防抖: WebSocket 5min;Telegram 同类型去重 +- 恢复: 指标回落 → recovery 事件 +- 推送完成: `send_telegram_sync_complete` + +--- + +## 11. 前端 SPA 架构 + +### 11.1 构建与开发 + +| 项 | 值 | +|----|-----| +| 开发 | `cd frontend && npm run dev` → `http://localhost:3000/app/` | +| API 代理 | Vite proxy `/api`、`/ws` → `127.0.0.1:8600` | +| 构建输出 | `web/app/`(`base: '/app/'`) | +| 路由 | Hash `#/path` | + +### 11.2 入口链路 + +``` +main.ts → App.vue(侧栏/搜索)→ router-view + → pages/*.vue + → composables → api/index.ts → /api/* +``` + +### 11.3 HTTP 客户端(`src/api/index.ts`) + +| 能力 | 实现 | +|------|------| +| Token | 内存 access JWT | +| 401 | 自动 refresh 一次 | +| 202 | `TotpRequiredError` | +| 429 | 锁定文案 | +| 304 | 文件 browse ETag | +| Upload | FormData 不设 JSON Content-Type | + +### 11.4 Pinia Stores + +| Store | 职责 | +|-------|------| +| `auth` | token、admin、login/logout/refresh | +| `files` | selectedServer、currentPath、browse 缓存 | + +其余状态在 composable 或页面 `ref` 中。 + +--- + +## 12. 14 个业务页面功能说明 + +> 路由均位于 `#/` 下;除 Login 外需 JWT。 + +### 12.1 DashboardPage `/` + +| 功能 | API/机制 | +|------|----------| +| 统计卡片 | `GET /servers/stats` | +| 服务器分页表 | `useServerPagination` | +| 告警摘要 | `GET /alert-history/?limit=5` | +| 资源概览 | 拉 200 台算 CPU/内存均值 | +| 分类分布 | stats.categories | +| 最近审计 | `GET /audit/?limit=10` | +| 实时刷新 | `useWebSocket` → 告警时 reload stats | +| 快捷跳转 | 终端/文件 `?server_id=` | + +### 12.2 ServersPage `/servers` + +| 功能 | API | +|------|-----| +| CRUD | `/servers/` | +| 批量选择 | 安装/升级/卸载 Agent、健康检查、删除 | +| CSV 导出 | 客户端生成(无密码列) | +| CSV 导入 | `POST /servers/import` FormData | +| 详情面板 | 系统信息 + `GET /servers/{id}/logs` | +| 表单 | `ServerFormDialog` + `useServerFormDialog` | + +### 12.3 TerminalPage `/terminal` + +| 功能 | 说明 | +|------|------| +| 多 Tab | `useTerminalSessions` | +| WebSSH | `POST /auth/webssh-token` → `WS /ws/terminal/{id}?token=` | +| xterm | FitAddon、256 色 | +| 命令栏 | shell 高亮、`sendCmd`/`sendCtrl` | +| 快捷命令 | `GET /terminal/quick-commands` | +| 路由入参 | `#/terminal?server_id=123` 自动开 Tab | +| 清理 | `onBeforeUnmount` → `disposeAllSessions` | + +### 12.4 FilesPage `/files` + +薄编排页,逻辑在 composables: + +| 子模块 | 能力 | +|--------|------| +| Toolbar | 上传、刷新、上级目录 | +| List | 排序、多选、双击进目录 | +| Editor | Monaco,`POST /sync/read-file|write-file` | +| 权限 | files-capability 检测、sudo 提示 | +| 热键 | 复制/粘贴/删除(`useFilesHotkeys`) | + +### 12.5 PushPage `/push` + +| 功能 | API/WS | +|------|--------| +| 源/目标路径 | 表单校验 | +| ZIP 上传 | `POST /sync/upload-zip` | +| 服务器网格 | 分类全选 | +| 预览 | `POST /sync/preview` 并发 | +| 推送 | `POST /sync/files` + `/ws/sync` 进度 | +| 取消 | `POST /sync/cancel` | +| 历史 | sync_logs 分页、诊断、对账 | + +### 12.6 ScriptsPage `/scripts` + +| 功能 | API | +|------|-----| +| 脚本 CRUD | `/scripts/` | +| Monaco 编辑 | content 字段 | +| 执行 | `POST /scripts/exec` + 轮询 executions | +| 临时命令 | quick exec 面板 | +| 停止 | `POST /scripts/executions/{id}/stop` | + +### 12.7 CredentialsPage `/credentials` + +三 Tab:密码预设、SSH 密钥、DB 凭据;编辑时空密码表示不修改。 + +### 12.8 SchedulesPage `/schedules` + +Cron 调度推送;`runNow` → `POST /sync/files`;cron 前端正则校验。 + +### 12.9 RetriesPage `/retries` + +失败推送重试队列;`POST /retries/{id}/retry`。 + +### 12.10 CommandsPage `/commands` + +命令视图 / 会话视图;`GET /assets/command-logs|ssh-sessions`。 + +### 12.11 AlertsPage `/alerts` + +告警统计 + 分页;按 type/status 过滤。 + +### 12.12 AuditPage `/audit` + +操作审计;action/user/date 过滤;`normalizeAuditList`。 + +### 12.13 SettingsPage `/settings` + +系统名/阈值/连接池、Telegram、改密、TOTP、API Key reveal、IP 白名单、终端快捷命令设置。 + +### 12.14 LoginPage `/login` + +JWT 登录、TOTP、429 锁定、开放重定向防护(`//` 拒绝)、bing 壁纸背景。 + +--- + +## 13. Composables 与状态管理 + +### 13.1 模块索引 + +| 目录 | 入口 | 用途 | +|------|------|------| +| `composables/files/` | `useFilesPage` | 文件页总编排 | +| `composables/push/` | `usePushPage` | 推送页总编排 | +| `composables/terminal/` | `useTerminalSessions` | WebSSH 会话 | +| `composables/servers/` | `useServerFormDialog` | 服务器表单 | +| `composables/useWebSocket.ts` | — | 告警 WS | +| `composables/useServerPagination.ts` | — | 分页表 | + +### 13.2 新增页面 Checklist + +1. `frontend/src/pages/XxxPage.vue` +2. `router/index.ts` 注册路由 +3. `App.vue` 侧栏 nav 项 +4. `types/api.ts` 补充类型 +5. 后端 API + 审计日志 +6. E2E: `frontend/e2e/full-acceptance.spec.mjs` + +--- + +## 14. WebSocket 与 WebSSH + +### 14.1 告警 WS `/ws/alerts` + +- 连接: `buildWebSocketUrl('/ws/alerts', { token: accessToken })` +- 消息类型: alert / recovery / system +- App.vue 或 Dashboard 订阅 + +### 14.2 推送 WS `/ws/sync` + +- batch_id 维度进度 +- `usePushProgress` 维护 per-server 状态 + +### 14.3 WebSSH + +- 独立 JWT: `purpose=webssh`, `server_id`, 15min +- 绑定路径 server_id,防 IDOR +- Koko 消息: `TERMINAL_INIT`, `DATA`, `RESIZE`, `CLOSE` +- 命令日志: Enter 时写 `command_logs` + +**已接受风险**: JWT 走 query string(ADR-011),见 risk-acceptance 文档。 + +--- + +## 15. Agent 与子机协议 + +### 15.1 网络模型 + +| 方向 | 端口 | 用途 | +|------|------|------| +| 子机 → 中心 | 443 出站 | 心跳、script callback | +| 中心 → 子机 | 22 | 推送、文件、脚本、Agent 安装 | +| 子机本机 | 127.0.0.1:8601 | Agent HTTP(可选) | + +### 15.2 心跳 Payload(摘要) + +`server_id`, `cpu`, `memory`, `disk`, `load`, `uptime`, `agent_version`, `system_info`, ... + +### 15.3 脚本回调 + +长任务完成后 Agent `POST /api/agent/script-callback`,携带 job id 与 per-server 结果。 + +--- + +## 16. 安装向导 + +| 步骤 | UI | API | +|------|-----|-----| +| 1 | 环境检查 | `GET /install/env-check` | +| 2 | MySQL/Redis 配置 | `POST /install/init-db` | +| 3 | 三写配置 | 同上(写 .env + config.json + settings) | +| 4 | 创建管理员 | `POST /install/create-admin`(install_token) | +| 5 | 锁定 | `POST /install/lock` | + +静态页: `web/app/install.html`(Tailwind,非 Vue SPA)。 +锁定后 `/install/status` → 404,防止信息泄露。 + +--- + +## 17. 本地开发、测试与门控 + +### 17.1 快速启动 + +```bash +# Docker MySQL + Redis +docker compose up -d mysql redis + +# 生成 .env(若无) +python3 docker/generate_env.py && python3 docker/sync_root_env.py + +# 启动 API +bash scripts/start-dev.sh # → http://127.0.0.1:8600 + +# 前端 +cd frontend && npm run dev # → http://localhost:3000/app/ +``` + +### 17.2 验证命令 + +| 级别 | 命令 | +|------|------| +| L2b | `bash scripts/local_verify.sh` | +| L2c | `.venv/bin/pytest tests/ -q` | +| L3 | `bash deploy/pre_deploy_check.sh` | +| L4 | `python3 scripts/run_nexus_acceptance.py --base http://127.0.0.1:8600 --with-ui` | +| E2E | `cd frontend && NEXUS_E2E_BASE=http://127.0.0.1:8600 npm run test:e2e` | + +### 17.3 七道门控 + +见 `deploy/pre_deploy_check.sh`:Changelog、Audit、Test、Ruff、Import、Bandit、Review。 + +--- + +## 18. 部署与运维 + +### 18.1 生产部署 + +```bash +git push origin main +bash deploy/pre_deploy_check.sh +bash deploy/deploy-production.sh +# 或手动: ssh nexus "cd $DEPLOY && git reset --hard origin/main && supervisorctl restart nexus" +# 前端: bash deploy/deploy-frontend.sh +``` + +### 18.2 三层守护 + +| 层 | 机制 | +|----|------| +| 1 | Supervisor 进程重启 | +| 2 | `self_monitor` 30s | +| 3 | `health_monitor.sh` cron 1min → 连续失败 restart + Telegram | + +### 18.3 健康检查 + +- `GET /health` → 纯文本 `ok` +- `GET /health/detail` → JSON(需 JWT) + +--- + +## 19. 扩展开发指南 + +### 19.1 新增 REST API + +1. 设计文档 `docs/design/specs/YYYY-MM-DD-*.md` +2. Service + Repository(若需) +3. `server/api/xxx.py` + `Depends(get_current_admin)` +4. `main.py` include_router +5. 审计: `AuditLog` 写入 +6. `tests/test_api.py` 或专项测试 +7. Changelog + 审计 8 步 + +### 19.2 新增前端功能 + +1. 明确页面 vs 对话框 vs composable 边界 +2. 类型先进 `types/api.ts` +3. 错误用 `formatApiError` + snackbar,**禁止静默吞错** +4. 敏感数据不进 localStorage +5. Playwright 抽测关键路径 + +### 19.3 新增后台任务 + +1. 仅 primary worker 注册(`main.py` lifespan) +2. 循环内 try/except + logger,不可空 pass +3. 需可关闭(CancelledError) +4. 文档 + changelog + +### 19.4 数据库变更 + +1. 修改 `domain/models` +2. 启动时 `init_db` 或手写迁移 SQL(生产谨慎) +3. 不可破坏 `ENCRYPTION_KEY` 下已有密文 + +--- + +## 20. 不可改项与已接受风险 + +### 20.1 不可改(架构/安全一致性) + +| 项 | 原因 | +|----|------| +| `API_KEY` | Agent 与加密回退一致 | +| `SECRET_KEY` | JWT 与已有 token | +| `ENCRYPTION_KEY` | 已加密凭据 | +| `DATABASE_URL` | 启动绑定 | + +### 20.2 已接受风险(单人运维) + +见 `docs/project/risk-acceptance-single-operator.md`: + +- WebSocket / WebSSH JWT 在 query +- Agent global API_KEY 回退 +- 危险命令仅 WARN 不阻断 +- dev docker-compose 默认密码 + +--- + +## 21. 文档索引 + +| 文档 | 用途 | +|------|------| +| **本文** | 功能开发 SSOT(架构 + 模块概览) | +| **[附录](nexus-functional-development-guide-appendix.md)** | API 字段表、Files/Push/Terminal 调用链、E2E/L4 对照、组件映射 | +| [AI-HANDOFF-2026-06-03.md](AI-HANDOFF-2026-06-03.md) | 会话接续 | +| [linux-dev-paths.md](linux-dev-paths.md) | Linux 路径 | +| [local-integration-test.md](local-integration-test.md) | 本地验收 | +| [script-execution.md](script-execution.md) | 脚本执行细节 | +| [alert-push-policy.md](alert-push-policy.md) | 告警策略 | +| [deploy.md](deploy.md) | 部署补充 | +| [development-acceptance-standard.md](development-acceptance-standard.md) | L0–L5 验收 | +| `docs/design/specs/` | 新功能设计 | +| `docs/changelog/` | 每次变更记录 | + +--- + +## 22. 详细参考(附录摘要) + +完整查表见 **[nexus-functional-development-guide-appendix.md](nexus-functional-development-guide-appendix.md)**。 + +| 附录 | 内容 | +|------|------| +| **A** | `/api/sync` 全 21 端点 + Pydantic 字段 + WS 推送时序 | +| **B** | Files 页组件树、composable 依赖图、操作→API 映射 | +| **C** | Push 页 composable 与推送时序 | +| **D** | Terminal / WebSSH 调用链 | +| **E** | schedules/retries/audit/scripts/agent/search API 明细 | +| **F** | 14 页 ↔ composable ↔ 组件对照表 | +| **G** | L4 验收 + Playwright 15 用例对照 | +| **H** | HTTP 错误码与前端处理 | +| **I** | 扩展开发检查清单 | + +--- + +**维护约定**: 新增模块或变更 API/页面时,**同步更新本文 + 附录对应章节** + changelog(≥10 行)。 diff --git a/docs/reports/README.md b/docs/reports/README.md index bf0eb1dd..0c507d1b 100644 --- a/docs/reports/README.md +++ b/docs/reports/README.md @@ -1,119 +1,27 @@ -# Nexus 工作报告索引 - - - -> 所有部门工作报告统一存放于此 - - - ---- - - - -## Phase 2 逐行走读(2026-05-22~23) +# Nexus 活跃报告 +> 更新: 2026-06-04 · 批量 batch 已迁至 [archive/audits/](../archive/audits/) +## 2026-06 审计 closure | 文件 | 说明 | - |------|------| +| [audit-plugin-run-final-2026-06-04.md](audit-plugin-run-final-2026-06-04.md) | 总验收 | +| [audit-frontend-14p-2026-06-04-closure.md](audit-frontend-14p-2026-06-04-closure.md) | 前端 14 页 | +| [audit-phase-4-plugin-closure-2026-06-04.md](audit-phase-4-plugin-closure-2026-06-04.md) | Phase4 | +| [audit-bug-scan-closure-2026-06-04.md](audit-bug-scan-closure-2026-06-04.md) | Bug scan | +| [audit-bug-coverage-master-2026-06-04.md](audit-bug-coverage-master-2026-06-04.md) | 覆盖率 | +| [audit-bug-assets-gate-2026-06-04.md](audit-bug-assets-gate-2026-06-04.md) | Assets gate | -| **[`audit-phase-2-findings-matrix.md`](audit-phase-2-findings-matrix.md)** | 63 条 FINDING 全量状态(✅52 / 📋7 / 🟡3) | - -| [`../project/phase-2-audit-remediation.md`](../project/phase-2-audit-remediation.md) | **开发 SSOT** — 按主题汇总已修复项与接受决策 | - -| [`../project/production-verification-checklist.md`](../project/production-verification-checklist.md) | 外网验证清单 | - -| [`audit-phase-2-walk-closure.md`](audit-phase-2-walk-closure.md) | Phase 2 走读闭环 | - -| **[`audit-phase-3-walk-closure.md`](audit-phase-3-walk-closure.md)** | **Phase 3 走读闭环**(100% 全文重读,12 FINDING,代码待办 0) | - -| [`2026-05-23-full-audit-report.md`](2026-05-23-full-audit-report.md) | 7 部门并行初审(部分与 Phase 2 重叠) | - -| [`audit-full-vs-phase2-reconciliation.md`](audit-full-vs-phase2-reconciliation.md) | **C1–C12 与 Phase 2 对照表** | - -| `audit-phase-2a-line-walk.md` … `audit-phase-2j-line-walk.md` | 各批次逐行报告 | - - - -**结论**:Phase 2 **代码修复已闭环**。项目 **未部署** — 无 API Key 轮换;**首次上线前** 跑 E2E 清单。 - - - ---- - - - -## 审查阶段报告(2026-05-21) - - - -| 文件 | 部门 | 说明 | - -|------|------|------| - -| `review-cto-2026-05-21.md` | CTO | 技术路线评估 | - -| `review-quality-director-2026-05-21.md` | 质量总监 | 全流程质量标准审查 | - -| `review-deploy-architecture-2026-05-21.md` | 运维总监/JC组 | 运维架构评估 + 部署建议 | - - - -## 会话档案 - +合并卷: [line-walk](../archive/audits/2026-06-04-line-walk-merged.md) · [delta](../archive/audits/2026-06-04-delta-merged.md) · [phase2](../archive/audits/2026-06-04-phase2-merged.md) · [frontend-14p](../archive/audits/2026-06-04-frontend-14p-merged.md) +## 生产 / 验收 | 文件 | 说明 | - |------|------| +| [2026-06-01-production-verification.md](2026-06-01-production-verification.md) | 生产验证 | +| [2026-06-01-final-acceptance-checklist.md](2026-06-01-final-acceptance-checklist.md) | 终验清单 | +| [2026-06-01-full-acceptance-report.md](2026-06-01-full-acceptance-report.md) | 全量验收 | +| [2026-06-01-browser-verification.md](2026-06-01-browser-verification.md) | 浏览器抽测 | -| `session-log-2026-05-21.md` | **完整对话记录(技术选型→6步实施→质量门禁→团队整理)** | - - - -## 实施阶段报告 - - - -| 文件 | 说明 | - -|------|------| - -| `implementation-progress-2026-05-21.md` | **6步实施进度总报告** | - -| `signoff-2026-05-21.md` | 各部门认领签字表 | - - - -## 实施状态 - - - -| 步骤 | 目录 | 代码 | 测试 | 审查 | - -|------|------|------|------|------| - -| 第零步:基础设施加固 | `step-0-infrastructure/` | ✅ | ⏳ | ⏳ | - -| 第一步:数据层 | `step-1-data-layer/` | ✅ | ⏳ | ⏳ | - -| 第二步:认证层 | `step-2-auth/` | ✅ | ⏳ | ⏳ | - -| 第三步:Web SSH 终端 | `step-3-webssh/` | ✅ | ⏳ | ⏳ | - -| 第四步:Sync 引擎升级 | `step-4-sync/` | ✅ | ⏳ | ⏳ | - -| 第五步:前端全量迁移 | `step-5-frontend/` | ✅ | ⏳ | ⏳ | - -| **Phase 2 安全走读** | `audit-phase-2*` | ✅ | 🟡 | ✅ | - - - ---- - - - -> 更新: 2026-05-23 | Phase 2 代码修复闭环,待外网 E2E - - +历史: [archive/reports/](../archive/reports/) diff --git a/docs/reports/audit-frontend-14p-2026-06-04-closure.md b/docs/reports/audit-frontend-14p-2026-06-04-closure.md new file mode 100644 index 00000000..6ead0535 --- /dev/null +++ b/docs/reports/audit-frontend-14p-2026-06-04-closure.md @@ -0,0 +1,46 @@ +# 前端 14 页分批深审 — 总 Closure + +**日期**: 2026-06-04 +**范围**: `frontend/src/pages/*Page.vue` 全部 14 页 +**总行数**: 4112 + +## 批次索引 + +| 批次 | 页面 | 报告 | H | +|------|------|------|---| +| 1/3 | Dashboard, Servers, Terminal, Files, Push | [batch1](audit-frontend-14p-2026-06-04-batch1.md) | 14 | +| 2/3 | Scripts, Credentials, Schedules, Retries, Commands | [batch2](audit-frontend-14p-2026-06-04-batch2.md) | 15 | +| 3/3 | Alerts, Audit, Settings, Login | [batch3](audit-frontend-14p-2026-06-04-batch3.md) | 14 | +| **合计** | **14 页** | | **43** | + +## 跨页 RISK(已接受,不重复开 FINDING) + +| 项 | 页面 | 文档 | +|----|------|------| +| WS query JWT | Terminal, Push(composable) | risk-acceptance-single-operator.md | +| 临时命令 exec | ScriptsPage | 后端 check_dangerous_command | +| bing-wallpaper 公开 GET | Login, Dashboard | 后端只读缓存 | + +## 编排页说明 + +| 页 | 行数 | 逻辑位置 | +|----|------|----------| +| FilesPage | 38 | `useFilesPage` + D5 composables | +| PushPage | 106 | `usePushPage` + D4 composables | +| TerminalPage | 408 | 页内 UI + `useTerminalSessions` | + +页壳已全文 Read;Sink 在 composable 层另有 D4/D5/P2 深审。 + +## DoD + +- [x] 14 页每页 1–N 全文 Read +- [x] 3 批 8 步报告 + 本 closure +- [x] 0 P0/P1 新 FINDING +- [x] Playwright E2E 15 路由已绿(L4) + +## 验证 + +```bash +bash scripts/local_verify.sh +cd frontend && NEXUS_E2E_BASE=http://127.0.0.1:8600 npm run test:e2e +``` diff --git a/docs/reports/audit-phase-4-plugin-closure-2026-06-04.md b/docs/reports/audit-phase-4-plugin-closure-2026-06-04.md new file mode 100644 index 00000000..f0b0953f --- /dev/null +++ b/docs/reports/audit-phase-4-plugin-closure-2026-06-04.md @@ -0,0 +1,58 @@ +# Phase 4 — 插件驱动审计收尾 Closure + +**日期**: 2026-06-04 +**计划**: `.cursor/plans/插件驱动审计验证_5bf6bf55.plan.md` + +## 完成矩阵 + +| 阶段 | 内容 | 状态 | 证据 | +|------|------|------|------| +| Phase 0 | local_verify 基线 + npm 代理文档 | ✅ | `docs/changelog/2026-06-04-npm-proxy-mysql-mcp.md` | +| Phase 1 | D1–D8 delta 审计 | ✅ | `audit-delta-2026-06-04-waveD*.md` | +| Phase 2 | P2-1~P2-9 深审 | ✅ | `audit-phase2-2026-06-04-waveP2-*.md` | +| L2b | local_verify | ✅ | 每波全绿 | +| L2c | pytest 157 | ✅ | 2026-06-04 | +| L3 | pre_deploy_check | ⚠️ Gate7 需 commit 后复验 | `docs/audit/2026-06-04-plugin-audit-gate7-closure.md` | +| L4 | Playwright 本地 55/55 | ✅ | `docs/changelog/2026-06-04-l4-local-playwright-pass.md` | +| L5 | 生产部署 | ❌ 未执行 | 需用户批准 | + +## 前端 14 页覆盖(SSOT) + +**专用深审**: `docs/reports/audit-frontend-14p-2026-06-04-closure.md` + +| 批次 | 页面 | H | +|------|------|---| +| batch1 | Dashboard, Servers, Terminal, Files, Push | 14 | +| batch2 | Scripts, Credentials, Schedules, Retries, Commands | 15 | +| batch3 | Alerts, Audit, Settings, Login | 14 | +| **合计 14 页 / 4112 行** | | **43** | + +## FINDING 汇总 + +| 级别 | 新增(本计划) | 已接受 RISK | +|------|----------------|-------------| +| P0/P1 | **0** | WS query JWT、Agent global key、sshpass | +| P2 | 0 待修 | install-deps 包名 questing 差异 | + +## 插件使用记录 + +| 插件 | 用途 | 状态 | +|------|------|------| +| mysql-mcp | 项目配置 | 可用 | +| Playwright CLI | L4 E2E | ✅ 55 pass | +| Playwright MCP | 浏览器 | errored,CLI 替代 | +| Chainguard | 镜像扫描 | 用户跳过 | +| security-reviewer | 各波 H 扫描 | 报告内 Closure | + +## DoD + +- [x] Phase 1 + Phase 2 全波报告 +- [x] 14 页前端 closure +- [x] L4 本地验收 +- [x] Gate7 审计清单文件 +- [ ] L5 生产(可选) + +## 下一步 + +1. `git add` + commit 工作区 → 复跑 `pre_deploy_check.sh` +2. 用户批准 → L5 SSH 部署 + 生产 smoke diff --git a/docs/reports/audit-plugin-run-final-2026-06-04.md b/docs/reports/audit-plugin-run-final-2026-06-04.md new file mode 100644 index 00000000..b7e73257 --- /dev/null +++ b/docs/reports/audit-plugin-run-final-2026-06-04.md @@ -0,0 +1,52 @@ +# 插件驱动审计 — 最终验收报告 + +**日期**: 2026-06-04 +**计划**: 插件驱动审计验证(Phase 0 → L4) + +## 执行摘要 + +| 维度 | 结果 | +|------|------| +| Phase 1 Delta D1–D8 | ✅ 135 H,0 P0/P1 | +| Phase 2 后端 P2-1~P2-6 | ✅ 107 H,0 P0/P1 | +| 前端 14 页 3 批深审 | ✅ 4112 行,43 H,0 P0/P1 | +| L2b local_verify | ✅ | +| L2c pytest | ✅ **157 passed** | +| L3 pre_deploy_check | ✅ **7/7**(Lint/Security 系统 PATH skip;.venv 内 ruff/bandit 可过) | +| L4 Playwright | ✅ **55/55**(1 项 SSH 跳过) | +| L5 生产部署 | ❌ 未执行(需用户批准) | + +## 报告索引 + +| 类型 | 路径 | +|------|------| +| Phase1 汇总 | `docs/reports/audit-delta-2026-06-04-waveD8-closure.md` | +| Phase2 | `docs/reports/audit-phase2-2026-06-04-waveP2-*.md` | +| 前端 14 页 SSOT | `docs/reports/audit-frontend-14p-2026-06-04-closure.md` | +| 插件收尾 | `docs/reports/audit-phase-4-plugin-closure-2026-06-04.md` | +| Gate7 | `docs/audit/2026-06-04-plugin-audit-gate7-closure.md` | +| Registry | `docs/audit/2026-06-04-bug-scan-registry.json` → `delta_waves[]` | + +## 复验命令(2026-06-04 末轮) + +```bash +bash scripts/local_verify.sh # OK +.venv/bin/pytest tests/ -q # 157 passed +bash deploy/pre_deploy_check.sh # 7/7 PASS +python3 scripts/run_nexus_acceptance.py \ + --base http://127.0.0.1:8600 --with-ui # 55 pass +``` + +## L5 部署前置(待用户说「部署」) + +```bash +git add ... && git commit ... && git push origin main +bash deploy/pre_deploy_check.sh +bash deploy/deploy-production.sh +curl -s https://api.synaglobal.vip/health # 预期 ok +curl -s -o /dev/null -w "%{http_code}" https://api.synaglobal.vip/app/ # 200 +``` + +## 结论 + +本地审计与验收链路 **全部 closure**;唯一待办为 **L5 生产部署**(需 SSH + git push 权限与用户明确批准)。 diff --git a/scripts/consolidate_docs.py b/scripts/consolidate_docs.py new file mode 100644 index 00000000..49a32035 --- /dev/null +++ b/scripts/consolidate_docs.py @@ -0,0 +1,273 @@ +#!/usr/bin/env python3 +"""Consolidate Nexus docs: move batches to docs/archive/ and generate merged volumes.""" + +from __future__ import annotations + +import shutil +from datetime import date +from pathlib import Path + +REPO = Path(__file__).resolve().parents[1] +DOCS = REPO / "docs" +ARCHIVE = DOCS / "archive" +TODAY = date.today().isoformat() + + +def ensure_dirs() -> None: + for sub in ( + "audits/2026-06-04-line-walk", + "audits/2026-06-04-delta", + "audits/2026-06-04-phase2", + "audits/2026-06-04-frontend-14p", + "memory/raw", + "handoff", + "project", + "reports/2026-05-reviews", + "reports/2026-05-steps", + ): + (ARCHIVE / sub).mkdir(parents=True, exist_ok=True) + + +def extract_summary(text: str, max_lines: int = 12) -> str: + lines: list[str] = [] + for line in text.splitlines(): + s = line.strip() + if not s: + continue + if s.startswith("#"): + lines.append(s) + elif any(k in s for k in ("Closure", "DoD", "P0", "P1", "FINDING", "结论", "摘要")): + lines.append(s[:200]) + if len(lines) >= max_lines: + break + return "\n".join(lines) if lines else (text.splitlines()[0][:200] if text.splitlines() else "(empty)") + + +def extract_closure_rows(text: str) -> list[str]: + rows: list[str] = [] + in_table = False + for line in text.splitlines(): + if "|" in line and ("Closure" in line or "H " in line or "FINDING" in line): + in_table = True + if in_table and line.strip().startswith("|") and "---" not in line: + rows.append(line.strip()) + if in_table and not line.strip() and rows: + break + return rows[:80] + + +def merge_glob( + pattern: str, + out_name: str, + title: str, + archive_subdir: str, +) -> None: + base = DOCS / "reports" + files = sorted(base.glob(pattern)) + if not files: + print(f" skip merge (no files): {pattern}") + return + + out_path = ARCHIVE / "audits" / out_name + parts = [ + f"# {title}", + "", + f"> 生成日期: {TODAY} · 源文件 {len(files)} 篇 · 原文 `docs/archive/{archive_subdir}/`", + "", + "## 批次索引", + "", + ] + archive_dir = ARCHIVE / archive_subdir + archive_dir.mkdir(parents=True, exist_ok=True) + + all_closure: list[str] = [] + for f in files: + dest = archive_dir / f.name + if f.resolve() != dest.resolve(): + if dest.exists(): + dest.unlink() + shutil.move(str(f), str(dest)) + text = dest.read_text(encoding="utf-8", errors="replace") + parts.append(f"### `{f.name}`") + parts.append("") + parts.append(extract_summary(text)) + parts.append("") + all_closure.extend(extract_closure_rows(text)) + + if all_closure: + parts.extend(["## Closure 摘录(合并)", ""]) + seen: set[str] = set() + for row in all_closure: + if row not in seen: + seen.add(row) + parts.append(row) + parts.append("") + + out_path.write_text("\n".join(parts), encoding="utf-8") + print(f" merged {len(files)} → {out_path.relative_to(REPO)}") + + +def merge_memory() -> None: + mem_dir = DOCS / "memory" + if not mem_dir.is_dir(): + return + files = sorted(p for p in mem_dir.glob("*.md") if p.name != "MEMORY.md") + if not files: + return + raw_dir = ARCHIVE / "memory/raw" + raw_dir.mkdir(parents=True, exist_ok=True) + parts = [ + "# Agent Memory 合并卷(2026-05 迁移)", + "", + f"> 生成: {TODAY} · 原 docs/memory/ {len(files)} 篇", + "", + "请以 [nexus-functional-development-guide.md](../project/nexus-functional-development-guide.md) 为准。", + "", + ] + for f in files: + text = f.read_text(encoding="utf-8", errors="replace") + dest = raw_dir / f.name + if f.resolve() != dest.resolve(): + shutil.move(str(f), str(dest)) + parts.extend([f"## {f.stem}", "", extract_summary(text, 8), ""]) + out = ARCHIVE / "memory/agentmemory-2026-05-merged.md" + out.write_text("\n".join(parts), encoding="utf-8") + (mem_dir / "MEMORY.md").write_text( + "# 项目记忆(已归档)\n\n" + "见 [agentmemory-2026-05-merged.md](../archive/memory/agentmemory-2026-05-merged.md)\n" + "与 [功能开发指南](../project/nexus-functional-development-guide.md)。\n", + encoding="utf-8", + ) + print(f" memory merged → {out.relative_to(REPO)}") + + +def archive_handoffs() -> None: + for name in ("handoff-2026-05-31.md", "handoff-2026-06-01.md"): + src = DOCS / name + if src.is_file(): + shutil.move(str(src), str(ARCHIVE / "handoff" / name)) + for f in sorted((DOCS / "project").glob("AI-HANDOFF-2026-05*.md")): + shutil.move(str(f), str(ARCHIVE / "handoff" / f.name)) + old = DOCS / "project" / "AI-HANDOFF-2026-06-01-files.md" + if old.is_file(): + shutil.move(str(old), str(ARCHIVE / "handoff" / old.name)) + print(" handoffs archived") + + +def archive_nexus_full_site_features() -> None: + src = DOCS / "project" / "nexus-full-site-features.md" + if not src.is_file(): + return + shutil.move(str(src), str(ARCHIVE / "project" / src.name)) + (DOCS / "project" / "nexus-full-site-features.md").write_text( + "# 全站功能清单(已 supersede)\n\n" + "请以 **[nexus-functional-development-guide.md](nexus-functional-development-guide.md)** 为准。\n\n" + "历史 HTML 版: [archive](../archive/project/nexus-full-site-features.md)\n", + encoding="utf-8", + ) + print(" nexus-full-site-features → archive + stub") + + +def archive_old_line_walk_standard() -> None: + v1 = DOCS / "project" / "line-walk-audit-standard.md" + if v1.is_file(): + shutil.move(str(v1), str(ARCHIVE / "project" / v1.name)) + print(" line-walk v1 archived") + + +def archive_phase2_reviews() -> None: + dest = ARCHIVE / "reports/2026-05-reviews" + patterns = ( + "review-*-2026-05-21.md", + "signoff-2026-05-21.md", + "session-log-2026-05-21.md", + "2026-05-23-full-audit-report.md", + "audit-full-vs-phase2-reconciliation.md", + "audit-phase-2*.md", + "audit-phase-3*.md", + "implementation-progress-2026-05-21.md", + ) + n = 0 + reports = DOCS / "reports" + for pat in patterns: + for g in reports.glob(pat): + if g.is_file(): + t = dest / g.name + if t.exists(): + t.unlink() + shutil.move(str(g), str(t)) + n += 1 + step_dir = ARCHIVE / "reports/2026-05-steps" + for f in reports.glob("step-*"): + if f.is_dir(): + target = step_dir / f.name + if target.exists(): + shutil.rmtree(target) + shutil.move(str(f), str(target)) + n += 1 + if n: + print(f" archived {n} legacy review/step items") + + +def write_archive_readme() -> None: + (ARCHIVE / "README.md").write_text( + f"""# Nexus 文档归档区 + +> 更新: {TODAY} + +历史审计、旧 handoff、agentmemory。**日常请先读** [docs/README.md](../README.md)。 + +## 合并卷 + +| 文件 | 内容 | +|------|------| +| [audits/2026-06-04-line-walk-merged.md](audits/2026-06-04-line-walk-merged.md) | Line-walk batch | +| [audits/2026-06-04-delta-merged.md](audits/2026-06-04-delta-merged.md) | Delta D1–D8 | +| [audits/2026-06-04-phase2-merged.md](audits/2026-06-04-phase2-merged.md) | Phase2 P2 | +| [audits/2026-06-04-frontend-14p-merged.md](audits/2026-06-04-frontend-14p-merged.md) | 前端 14p | +| [memory/agentmemory-2026-05-merged.md](memory/agentmemory-2026-05-merged.md) | 旧 memory | + +原文在对应子目录;changelog 不归档。 +""", + encoding="utf-8", + ) + + +def main() -> None: + print("=== Nexus docs consolidation ===") + ensure_dirs() + merge_glob( + "audit-bug-line-walk-2026-06-04-batch*.md", + "2026-06-04-line-walk-merged.md", + "Bug Scan Line-Walk 合并卷", + "audits/2026-06-04-line-walk", + ) + merge_glob( + "audit-delta-2026-06-04-waveD*.md", + "2026-06-04-delta-merged.md", + "Delta D1–D8 合并卷", + "audits/2026-06-04-delta", + ) + merge_glob( + "audit-phase2-2026-06-04-waveP2-*.md", + "2026-06-04-phase2-merged.md", + "Phase2 P2 合并卷", + "audits/2026-06-04-phase2", + ) + merge_glob( + "audit-frontend-14p-2026-06-04-batch*.md", + "2026-06-04-frontend-14p-merged.md", + "前端 14p batch 合并卷", + "audits/2026-06-04-frontend-14p", + ) + merge_memory() + archive_handoffs() + archive_nexus_full_site_features() + archive_old_line_walk_standard() + archive_phase2_reviews() + write_archive_readme() + print("=== done ===") + + +if __name__ == "__main__": + main()