Ctrl K
ComunidadGuías…

lib/update-manifest.mjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * lib/update-manifest.mjs — the system layer the updater ships (#5554).
 *
 * `node update-system.mjs apply` checks out exactly these paths from upstream
 * and nothing else. A PR that adds a file every install should receive (a
 * script, a mode, a provider, a doc) must add that file's entry here. A
 * trailing `/` makes an entry a directory prefix; every other entry names one
 * file.
 *
 * The updater READS this file; it does not import it. update-system.mjs must
 * stay self-loading (#1706): a pre-#1245 client re-execs the new updater with
 * only update-system.mjs checked out, so a static import of this module would
 * crash that upgrade before it starts. Instead the updater extracts the array
 * below from source with extractArrayFromSource(), the same parser it uses on
 * the TARGET release's manifest and on a rollback's backup ref. Keep the
 * declaration in that shape:
 *
 *   - one exported SYSTEM_PATHS array literal, closed by a bracket and a
 *     semicolon, holding quoted string literals only: no spread, no template
 *     literals, no computed entries, and no bracket-semicolon inside an entry;
 *   - comments anywhere (the parser blanks them first);
 *   - no imports in this file, so it loads wherever it is read.
 *
 * tests/update-manifest.test.mjs fails when the parsed list and the imported
 * one disagree, which is what an unparseable entry would look like.
 *
 * The user layer stays in update-system.mjs (USER_PATHS, LOCAL_PATHS_FILE and
 * MANIFEST_USER_PATH_OVERLAPS). Every entry here is checked against it at run
 * time — canonical form before any checkout, then rejectUserLayerPaths() per
 * entry in apply() and isSafeManifestPath() in rollback() — so an entry that
 * names user data is refused rather than shipped. Those checks cover the user
 * layer only. Some system files must stay out of this list for other reasons
 * (.gitignore, SIGNATURES.md: see their notes below and in update-system.mjs),
 * and the order matters for one entry (.gitattributes, first).
 */
export const SYSTEM_PATHS = [
  // .gitattributes governs how every other path below is written to disk, and
  // `apply` checks paths out one at a time in this order: if it landed later,
  // everything before it would be written under the old core.autocrlf setting
  // on an existing install, silently (once text=auto is live, git status stays
  // clean and only a second update would repair it).
  '.gitattributes',
  'dead-boards.mjs',
  'provider-id-cache.mjs',
  'modes/README.md',
  'modes/_shared.md',
  'modes/_writing.md',
  'modes/_profile.template.md',
  'modes/_custom.template.md',
  'modes/_brief.template.md',
  'voice-dna.template.md',
  'modes/oferta.md',
  'modes/oferta-signals/',
  'modes/master-profile.md',
  'modes/pdf.md',
  'modes/ats.md',
  'modes/text.md',
  'modes/pdf/',
  'modes/cover.md',
  'modes/email.md',
  'modes/add.md',
  'modes/expand.md',
  'modes/scan.md',
  'modes/discover.md',
  'modes/batch.md',
  'modes/apply.md',
  'modes/auto-pipeline.md',
  'modes/contacto.md',
  'modes/deep.md',
  'modes/ofertas.md',
  'modes/pipeline.md',
  'modes/triage.md',
  'modes/project.md',
  'modes/tracker.md',
  'modes/training.md',
  'modes/interview.md',
  'modes/interview-redflag.md',
  'modes/latex.md',
  'modes/latex-tex.md',
  'modes/followup.md',
  'modes/offer-prep.md',
  'modes/interview-prep.md',
  'modes/interview/',
  'interview-prep/sessions/.gitkeep',
  'interview-prep/sessions/README.md',
  'modes/patterns.md',
  'modes/calibrate.md',
  'modes/titles.md',
  'modes/upskill.md',
  'modes/intake.md',
  'modes/retro.md',
  'documents/.gitkeep',
  // Empty scaffolds are system-owned exceptions inside otherwise user-owned
  // directories. Ship only these exact files; the data they sit beside stays
  // in USER_PATHS and is never checked out by the updater.
  'data/.gitkeep',
  'data/offers/.gitkeep',
  'data/parser-output/.gitkeep',
  'jds/.gitkeep',
  'output/.gitkeep',
  'reports/.gitkeep',
  'documents/README.md',
  'modes/update.md',
  'modes/agent-inbox.md',
  'modes/reply-watch.md',
  'modes/outcome.md',
  'modes/ar/',
  'modes/da/',
  'modes/de/',
  'modes/de/interview/',
  'modes/fr/',
  'modes/fr/interview/',
  'modes/hi/',
  'modes/es/',
  'modes/es/interview/',
  'modes/id/',
  'modes/id/interview/',
  'modes/it/',
  'modes/it/interview/',
  'modes/ja/',
  'modes/ja/interview/',
  'modes/ko/',
  'modes/ko/interview/',
  'modes/nb/',
  'modes/nl/',
  'modes/pl/',
  'modes/pl/interview/',
  'modes/pt/',
  'modes/pt/interview/',
  'modes/ru/',
  'modes/ru/interview/',
  'modes/sg/',
  'modes/tr/',
  'modes/ua/',
  'modes/ua/interview/',
  'modes/vi/',
  'modes/heuristics/',
  'modes/regional/',
  'modes/zh/',
  'modes/zh/interview/',
  'modes/zh-TW/',
  'CLAUDE.md',
  'CODEX.md',
  'OPENCODE.md',
  'AGENTS.md',
  'GEMINI.md',
  'KIMI.md',
  'build-dashboard.mjs',
  'clean-markers.mjs',
  'cv-experience-order.mjs',
  'generate-pdf.mjs',
  'hired-share.mjs',
  'community-asks.mjs',
  'hired-wall-build.mjs',
  'HIRED.md',
  'theme-style.mjs',
  'generate-latex.mjs',
  'install-latex-engine.mjs',
  'extract-latex-content.mjs',
  'patch-latex-content.mjs',
  'lib/ascii-fold.mjs',
  'lib/cli-flags.mjs',
  'lib/cli-launch.mjs',
  'lib/failure-excerpt.mjs',
  'lib/endpoint-headers.mjs',
  'lib/entry-response-cap.mjs',
  'lib/entry-timeout.mjs',
  // Imported by scan.mjs: the one reading of the providers partial-read signal.
  'lib/board-truncation.mjs',
  'lib/gemini-node-floor.mjs',
  'lib/jd-page-fetch.mjs',
  'lib/jd-parse.mjs',
  'lib/inbox-rank.mjs',
  'lib/node-floor.mjs',
  'lib/chromium-launch-error.mjs',
  // Shared by every browser-backed command and imported by doctor.mjs.
  'lib/browser-launch.mjs',
  'lib/local-today.mjs',
  'lib/jd-archive-section.mjs',
  'lib/machine-summary-section.mjs',
  'lib/parse-date.mjs',
  'lib/personalization.mjs',
  'lib/reply-proposals.mjs',
  'lib/placeholder-cell.mjs',
  'lib/tracker-addition.mjs',
  'lib/scan-summary-marker.mjs',
  'lib/scan-history-columns.mjs',
  'lib/posting-close.mjs',
  'lib/pipeline-sections.mjs',
  'lib/small-board.mjs',
  'lib/admission-gate.mjs',
  'lib/tsv-formula-escape.mjs',
  'lib/is-main-module.mjs',
  // This file. update-system.mjs reads it at run time (see the header), so it
  // ships like any other system file.
  'lib/update-manifest.mjs',
  'lib/mjs-files.mjs',
  'lib/syntax-check.mjs',
  'lib/syntax-check-child.mjs',
  'lib/walk-tree.mjs',
  'lib/dir-lock.mjs',
  // The shared PDF painter. generate-pdf.mjs imports it when a batch opts in.
  'lib/pdf-server.mjs',
  // Ships alongside test-all.mjs, which imports it.
  'lib/test-queue.mjs',
  'lib/run-bounded.mjs',
  'lib/status-hooks.mjs',
  'lib/scratch-dirs.mjs',
  'lib/story-bank.mjs',
  'lib/outcome-dir.mjs',
  'lib/outcome-types.mjs',
  'lib/latex-escape.mjs',
  'lib/cv-payload-schema.mjs',
  'lib/cv-payload-facts.mjs',
  'lib/career-profile.mjs',
  'lib/profile-cv-selection.mjs',
  'lib/cv-markdown.mjs',
  'lib/page-format.mjs',
  'lib/template-manifest.mjs',
  'lib/agent-cli.mjs',
  'lib/agent-launch.mjs',
  'remember-cli.mjs',
  'lib/yaml-document.mjs',
  'scan-hn.mjs',
  'scripts/check-syntax.mjs',
  'scripts/claude-plugin-session-start.mjs',
  'scripts/export-ats-text.mjs',
  'scripts/followup-sweep.sh',
  'scripts/ui-server.mjs',
  'story-provenance-check.mjs',
  'lib/latex-content.mjs',
  'lib/context-budget.mjs',
  // Ship alongside linkedin-watch.mjs and the scan schedule.
  'lib/linkedin-mail-drop.mjs',
  'lib/linkedin-auto.mjs',
  // Ships alongside doctor.mjs, which imports it: an upgraded install whose
  // updater had no entry for it would check out a doctor that cannot load.
  'lib/title-filter-conflicts.mjs',
  // Ships alongside liveness-api.mjs, which imports it.
  'lib/linkedin-url.mjs',
  // Ships alongside linkedin-import.mjs, which imports it.
  'lib/linkedin-import.mjs',
  // Retired 2026-09-05: the suite moved to tests/context-budget.test.mjs. The
  // entry stays so staleSystemFiles() prunes the orphan on an upgraded install;
  // drop it once a release has shipped past that move.
  'lib/context-budget.test.mjs',
  'lib/golden-budget-analysis.mjs',
  'lib/privacy-guard.mjs',
  'lib/llm-outbound.mjs',
  'lib/pii-interceptor.mjs',
  'img-to-pdf.mjs',
  'apply-scope.mjs',
  'archive-posting.mjs',
  'jd-capture.mjs',
  'application-answers.mjs',
  'generate-cover-letter.mjs',
  'merge-tracker.mjs',
  'persist-evaluation-report.mjs',
  'url-key.mjs',
  'sync-pdf-flags.mjs',
  'tracker-links.mjs',
  'tracker.mjs',
  'find.mjs',
  'verify-pipeline.mjs',
  'verify-tracker-url-match.mjs',
  'discard-analytics.mjs',
  'sync-batch-input.mjs',
  'reconcile-pipeline.mjs',
  'dedup-tracker.mjs',
  'precheck-duplicate.mjs',
  'add-entry.mjs',
  'github-evidence.mjs',
  'evidence-freshness.mjs',
  'role-matcher.mjs',
  'tracker-utils.mjs',
  'tracker-parse.mjs',
  'tracker-aliases.json',
  'session-activity.mjs',
  'set-status.mjs',
  'onboard-write.mjs',
  'mark-pdf-ready.mjs',
  'normalize-statuses.mjs',
  'fix-report-links.mjs',
  'cv-sync-check.mjs',
  'i18n-drift.mjs',
  'verify-cv-facts.mjs',
  'cv-voice.mjs',
  'verify-cv-structure.mjs',
  'verify-ats.mjs',
  'ats-payload.mjs',
  'update-system.mjs',
  'path-resolver.mjs',
  'ats-vendor.mjs',
  'history-ats-seeds.mjs',
  'branded-successfactors.mjs',

  'reserve-report-num.mjs',
  'scan.mjs',
  'migrate-scan-runs.mjs',
  'pipeline-lock.mjs',
  'portal-health-lock.mjs',
  'classify-tier.mjs',
  'scan-ats-full.mjs',
  'scan-interamt.mjs',
  'scan-dayforce.mjs',
  'scan-seek.mjs',
  'scan-local-lib.mjs',
  'company-funded.mjs',
  'match-star.mjs',
  'jd-skill-gap.mjs',
  'role-clarity.mjs',
  'career-profile.mjs',
  'cv-title-check.mjs',
  'filter-audit.mjs',
  'prepare-application.mjs',
  'application-artifacts.mjs',
  'evaluation-cache.mjs',
  'batch-evaluate-gemini.mjs',
  'providers/',
  'data-static/',
  'seeds/',
  'tests/',

  // ── Retired paths ─────────────────────────────────────────────────────────
  // These files no longer exist upstream: #3765 moved four root suites into
  // tests/, and #4758 moved tracker-columns-tests.mjs once it no longer
  // needed its own timeout. They
  // stay in the manifest anyway, because SYSTEM_PATHS is what `apply()` prunes
  // AGAINST — `staleSystemFiles` (see pathMatchesManifest) only deletes a local
  // file that is gone from the remote tree AND matches an entry here. Drop the
  // entry and an upgrading install keeps its copy of the old root file forever,
  // where tests/root-tests-registration.test.mjs then reports it as an
  // unregistered suite and turns `node test-all.mjs` red on a healthy install.
  //
  // Probe on this list vs. the pre-#3765 one, with a local tree holding the
  // four and a remote tree without them: without these entries the prune
  // returns nothing at all; with them it returns all four.
  //
  // NB: keep square brackets out of every comment in this array. Several
  // assertions in test-all.mjs extract the manifest with a NON-GREEDY regex
  // that ends at the first closing bracket, so one inside a comment truncates
  // the parsed list and every entry below it reads as missing. That is not
  // hypothetical: the first draft of this block wrote the probe result as an
  // empty-array literal and turned the check-table-freshness assertion red.
  //
  // They are therefore expected to be ABSENT from the working tree, which is
  // why updater-migration-tests.mjs lists them in ALLOWED_MISSING_ENTRIES.
  // Safe to delete once no supported install can still be carrying them.
  'agent-inbox-tests.mjs',
  'followup-seed-tests.mjs',
  'paste-reply-tests.mjs',
  'set-status-tests.mjs',
  'tracker-columns-tests.mjs',
  // ── end retired paths ─────────────────────────────────────────────────────
  'user-agent.mjs',
  'doctor.mjs',
  'jsonc-parse.mjs',
  'check-liveness.mjs',
  'liveness-core.mjs',
  'liveness-api.mjs',
  'liveness-browser.mjs',
  'robots-check.mjs',
  'browser-extract.mjs',
  'fetch-jd.mjs',
  'himalayas-posting.mjs',
  'jd-years.mjs',
  'analyze-patterns.mjs',
  'keyword-match.mjs',
  'calibrate.mjs',
  'upskill.mjs',
  'skill-extract.mjs',
  'skip-blockers.mjs',
  'intake.mjs',
  'learn.mjs',
  'stats.mjs',
  'funnel-stages.mjs',
  'detect-reposts.mjs',
  'rank-pipeline.mjs',
  'discover-ats.mjs',
  'discover-new-companies.mjs',
  'check-table-freshness.mjs',
  'check-jd-archive.mjs',
  'fingerprint-core.mjs',
  'listing-fingerprint.mjs',
  'process-quality.mjs',
  'company-history.mjs',
  'rejection-latency.mjs',
  'closing-soon.mjs',
  'close-stale.mjs',
  'import-tracker.mjs',
  'reeval-candidates.mjs',
  'salary-gap.mjs',
  'negotiation-roi.mjs',
  'funnel-velocity.mjs',
  'assessment-log.mjs',
  'contacts.mjs',
  'contact-lookup.mjs',
  'linkedin-join.mjs',
  'linkedin-import.mjs',
  'sponsor-check.mjs',
  'weekly-digest.mjs',
  'linkedin-watch.mjs',
  'tracker-sync-check.mjs',
  'followup-cadence.mjs',
  'invite-match.mjs',
  'ics-interview.mjs',
  'panelist-roles.mjs',
  'coverage-check.mjs',
  'agent-inbox.mjs',
  'followup-seed.mjs',
  'debrief-sync.mjs',
  'profile-language.mjs',
  'title-keywords.mjs',
  'gemini-eval.mjs',
  'ollama-eval.mjs',
  'openai-eval.mjs',
  'openai-tailor.mjs',
  'eval-golden.mjs',
  'evals/',
  'openrouter-runner.mjs',
  'privacy-status.mjs',
  'jd-similarity.mjs',
  'test-all.mjs',
  // Retired 2026-10-04: the suite moved to tests/tracker-writer-lock.test.mjs
  // (#4759). The entry stays so staleSystemFiles() prunes the orphan on an
  // upgraded install; drop it once a release has shipped past that move.
  'tracker-writer-lock-tests.mjs',
  'validate-portals.mjs',
  'validate-profile.mjs',
  'verify-portals.mjs',
  'audit-portals.mjs',
  'fix-slugs.mjs',
  'updater-migration-tests.mjs',
  'validate-system-paths-coverage.mjs',
  'validate-untrusted-content-coverage.mjs',
  'reply-matcher.mjs',
  'reply-watch.mjs',
  'paste-reply.mjs',
  'contact-extract.mjs',
  // Retired 2026-10-04: the suite moved to tests/contact-extract.test.mjs. The
  // entry stays so staleSystemFiles() prunes the orphan on an upgraded install;
  // drop it once a release has shipped past that move.
  'contact-extract-tests.mjs',
  'outcome.mjs',
  'batch/batch-prompt.md',
  'batch/batch-prompt-match.md',
  'batch/batch-runner.sh',
  'batch/company-scope.mjs',
  'batch/jd-rescue.mjs',
  'batch/aggregate-tokens.mjs',
  'batch/README.md',
  'utils/privacy-filter.mjs',
  'utils/token-tracker.mjs',
  'batch-tailor.mjs',
  'dashboard/',
  'templates/',
  'config/cv-facts.example.json',
  'fonts/',
  'examples/',
  'config/profile.example.yml',
  'config/privacy.example.yml',
  'config/local-paths.example.txt',
  '.env.example',
  '.editorconfig',
  '.agents/',
  '.claude/skills/',
  '.opencode/skills/',
  '.opencode/commands/',
  '.claude-plugin/',
  '.codex-plugin/',
  'claude-directory/',
  'openai-directory/',
  '.cursor-plugin/',
  'cursor-directory/',
  'antigravity-directory/',
  'hooks/hooks.json',
  '.qwen/',
  '.antigravitycli/skills/',
  '.grok/skills/',
  '.kimi/skills/',
  '.omp/AGENTS.md',
  'docs/',
  'writing-samples/README.md',
  'VERSION',
  'DATA_CONTRACT.md',
  'MANIFESTO.md',
  'manifesto.mjs',
  // SIGNATURES.md cannot join SYSTEM_PATHS: unlike every other system file it
  // is a pure append-only ledger of who signed the manifesto, and it churns
  // far faster than the code it would ship beside (49 commits in the 30 days
  // before this was written). Nothing on an install reads it — manifesto.mjs
  // parses MANIFESTO.md and never opens it — so shipping it buys an install
  // nothing, while listing it here puts it in the pathspec check() diffs via
  // systemTreeDiffers, which turns every new signature into a
  // system-files-changed report on every install in the world that no apply
  // can clear for long (#4062). That is one cause of the #3149 class of
  // permanent update-available, beside the SHA-vs-content bug of #2630, the
  // ignore-rule route of #2756, and the symlinked skill entrypoints that a
  // core.symlinks=false checkout materialises into regular files. Do not fix
  // that last one the way this entry was fixed: the entrypoints must stay in
  // SYSTEM_PATHS and be excluded from the drift comparison instead, because
  // ensureSkillEntrypoints only refreshes an entry that still holds the
  // pointer, so an entrypoint dropped from the manifest silently freezes.
  // The SIGNATURES.md repo-only coverage is declared in
  // validate-system-paths-coverage.mjs, and the behaviour is pinned by
  // tests/updater-signature-ledger-drift.test.mjs.
  //
  // Keep this comment free of straight quotes: updater-migration-tests.mjs
  // parses this array with a comment-blind regex, so an apostrophe here
  // becomes a phantom manifest entry.
  'CONTRIBUTING.md',
  'MAINTAINERS.md',
  'ARCHITECTURE.md',
  'README.md',
  'README.ar.md',
  'README.cn.md',
  'README.da.md',
  'README.de.md',
  'README.es.md',
  'README.fr.md',
  'README.hi.md',
  'README.ja.md',
  'README.ko-KR.md',
  'README.pl.md',
  'README.pt-BR.md',
  'README.ru.md',
  'README.ta.md',
  'README.ua.md',
  'README.zh-TW.md',
  'README.tr.md',
  'README.vi.md',
  'README.id.md',
  'CHANGELOG.md',
  'CODE_OF_CONDUCT.md',
  'CONTRIBUTORS.md',
  '.all-contributorsrc',
  'GOVERNANCE.md',
  'LEGAL_DISCLAIMER.md',
  'SECURITY.md',
  'SUPPORT.md',
  'TRADEMARK.md',
  'LICENSE',
  'CITATION.cff',
  'funding.json',
  '.well-known/',
  '.editorconfig',
  '.github/',
  'package.json',
  'build-cv-latex.mjs',
  'build-cv-html.mjs',
  'cv-sections-core.mjs',
  'cv-templates.mjs',
  'playwright.cv.config.mjs',
  'scaffolder/',
  'Dockerfile',
  'docker-compose.yml',
  '.dockerignore',
  '.codexignore',
  'cops',
  'DOCKER.md',
  'plugins/',
  'plugins.mjs',
  'plugins-registry/',
  'plugin-install.mjs',
  'plugin-audit.mjs',
  'validate-plugin-registry.mjs',
  'config/plugins.example.yml',
  'opencode.example.json',
  'seed-fixture.mjs',
  'test-fixtures/',
  'upgrade-tests.mjs',
];

// Frozen after the literal, not with `Object.freeze([...])` around it, so the
// declaration keeps the `const NAME = [ ... ];` shape the parser matches.
Object.freeze(SYSTEM_PATHS);