Legacy modernization playbook
Skill OmarEltak/legacy-prod-survival-kit/skills/legacy-modernization-playbook
Claude Code skills for the solo engineer who just inherited a 17-year-old production system. Audit, deploy, monitor, and report — without a DevOps team.
npx -y skills add OmarEltak/legacy-prod-survival-kit --skill legacy-modernization-playbookAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use FIRST when starting work on an inherited long-running production system maintained historically by a single developer. The senior architect's checklist for "what to do, in what order, when you've inherited a 17-year-old PHP system with no engineering practices around it." Don't refactor; build the safety net. Backups before deploys. Audit before automation. Sets correct priorities at minute 1 and prevents months of misdirected effort.
SKILL.md
13.7 KB, ~3.2k tokens by cl100k_base, as published. Nobody here has run it
Legacy modernization playbook
When to use this
You have inherited a production system with these properties:
- Has been running for 5+ years (often 10–20+).
- Was maintained by one developer (or a tiny team), often the same person for the entire time.
- That person has departed (left, retired, deceased) or is leaving soon.
- The codebase is unfamiliar, undocumented, or both.
- The hosting environment is constrained (shared, legacy, or both).
- You are now responsible. The business expects "things to keep working" with no degradation.
This skill is the senior architect's checklist for the first 1–4 weeks. It does not tell you HOW to do each thing (other skills in this kit cover the how). It tells you WHAT to do, in WHAT ORDER, and crucially WHAT NOT TO DO.
The one rule that overrides every other rule:
Don't try to modernize the code. Build the safety net around it. Modernization comes later, after the lights stay on reliably.
The strongest temptation is to "just refactor this part" or "rewrite this in a framework." Resist. The best return on engineering effort, by an order of magnitude, is in the layer above the code: deployment, monitoring, backups, audit trail.
The order
This is the order. Do them in sequence. Do not skip ahead.
Phase 0: Recon (Day 1, 2–4 hours)
Before you do anything else, audit:
- Hosting capabilities. Run
shared-hosting-recon(separate skill in this kit). Output: a structured Markdown document covering disabled PHP functions, available APIs,/tmpquirks, security holes. - Existing repos. Are there any git repositories already? Where? In what state? Do not delete or touch them. Just inventory.
- Existing automation. What cron jobs are scheduled? What scripts run automatically? Read each one. Don't disable anything yet.
- Database. Take a one-time snapshot via phpMyAdmin Export. Save it locally. This is your "oh shit" recovery point if everything else fails.
- DNS, SSL, domain registration. Confirm where the domain is registered (it might be with a different vendor than the hosting). Confirm SSL renewal isn't going to expire next week.
Output: a single document (e.g., audit-2026-05.md) committed to wherever you keep working notes. Refer to it often.
Don't skip this. Every architectural decision you make later will reference findings from this audit.
Phase 1: Source of truth (Day 1–2, 2–4 hours)
You don't have a reliable source of truth yet. Establish one.
- Pull the live site's code into a brand-new private git repository. Don't trust any existing repo. Don't merge into any existing repo. Start fresh, name it like
<project>-production, mark it private, push it.- Excludes at this stage: media files (videos, audio, large images), user-uploaded content, log files, database dumps,
.git,.svn, anything 100 MB+. - Goal: get all the code under version control. Roughly 50–500 MB depending on the project.
- Excludes at this stage: media files (videos, audio, large images), user-uploaded content, log files, database dumps,
- Treat this repo as canonical from now on. It is the single source of truth. Any other repo (dev repos, archives, the previous developer's home directory backups) is reference-only.
- Set up
.gitignoreand.gitattributesproperly. Especially: preserve line endings (* -text) so that subsequent diffs reflect content, not line-ending churn.
Output: a private GitHub (or GitLab/whatever) repository, byte-for-byte mirroring production code at a known timestamp.
Why this is Phase 1: every subsequent step depends on having a known-good baseline. You cannot deploy if you don't know what's currently deployed. You cannot rollback if you don't know what to roll back to.
Phase 2: Off-server backups (Day 2–3, 2–4 hours)
Before any deploy automation. Before any code changes. Backups first.
- Database: nightly
mysqldumpcron, gzipped, uploaded to off-server storage (B2, S3, Dropbox — whatever you control). 30-day retention minimum. - User-uploaded files: weekly tarball of upload directories, also uploaded off-server.
- Test the restore. Once. Document the restore procedure. The backup that has never been restored doesn't actually exist.
- Document the runbook: "If the entire account is wiped tomorrow, here's how I rebuild." One page. Stored where you can find it without the production server.
Why backups go before deploys: a deploy can break things. If the deploy breaks things and you don't have backups, you've now broken production with no recovery. Backups are the prerequisite, not the dessert.
Phase 3: Security cleanup (Day 3–5, 2–6 hours)
Your audit (Phase 0) surfaced security holes. Fix them now, before automation goes live, because automation will then preserve their absence.
Common findings, ordered by typical severity:
- Public PHP info-disclosure files (
phpinfo.php,info.php). Delete. - Public DB admin tools (
mysqldumper.php,adminer.phpoutside its proper directory). Move outside web root. - Public database dumps (
*.sql,dump.sql.gzin the web root). Move outside web root. - Old backup zips in the web root. Same.
- Unidentified large binary files at the web root. Investigate. (We found 37 GB of unknown binaries during one engagement — turned out to be old account-transfer artifacts left by the host's migration tool, but they were publicly downloadable.)
- Backup copies of code with non-standard extensions (
*.bak,*~,*_old.php). Audit; delete or move. - Exposed
.git,.svndirectories — block via.htaccessor remove.
This phase is grunt work. Do it carefully. Document each thing you removed. If you accidentally remove something the previous developer was actively using, you'll need to put it back.
Phase 4: Deploy pipeline (Day 5–7, 4–8 hours)
NOW you can build deployment automation. With backups in place (Phase 2) and the security floor raised (Phase 3), this is safe.
Use the solo-engineer-pipeline skill. Specifically for shared-hosting environments without shell access. Outputs: _deploy.php, smoke tests, GitHub Actions for lint + deploy + monitoring.
Important order within Phase 4:
- Build the pipeline.
- Test with a NO-OP first deploy (the source repo state matches prod, so the deploy should be 0 files copied, 11000+ unchanged). This proves the mechanism works without changing anything.
- Test with a TRIVIAL change (one HTML comment in a low-traffic file). Push, watch the action, verify on prod.
- Only then start real changes.
Phase 5: Continuous monitoring (Day 7, 1–2 hours)
The pipeline can deploy. Now ensure you know if prod is broken.
- Smoke tests run every 10 minutes via GitHub Actions cron (in the pipeline skill).
- Failure → auto-create a GitHub issue (which auto-emails the repo owner).
- Optional layer: UptimeRobot, Pingdom, Cloudflare Health Checks (some of these have free tiers). Adds external perspective.
- PHP error log monitoring — if a logging library exists in the codebase, ensure errors flow somewhere visible.
You now know within 15 minutes if production is broken. Before this phase, your Mean Time to Detect was however long until a user complained.
Phase 6: Audit trail / observability (Day 8–10, 2–4 hours)
Now make every change traceable.
- Every deploy creates a log file with timestamp, commit SHA, files changed, rollback target.
- Every code change is a git commit with a clear message and your name on it.
- Branch protection on
main— require PRs, even for solo work. Forces a 30-second pause. - Calendar reminders for known maintenance: SSL cert expiry, PAT/token rotation, DB migration cycle, backup test.
You can now answer "what was different about the registration page on October 14?" — to the byte.
Phase 7: Documentation (Day 10–14, 4–8 hours)
Write the runbooks. Two specifically:
DEPLOY.md— the daily operations runbook. How to ship. How to rollback. How to debug a failure. What to check when monitoring fires.DEPLOYMENT-PIPELINE.md— the engineering reference. Why decisions were made. What was tried and rejected. How to extend.
Use the bilingual-exec-report skill if a status report for non-technical leadership is needed.
What NOT to do
These are the temptations. Avoid each one for at least 6 months.
Don't refactor
Especially: don't refactor anything you don't deeply understand. Especially-especially: don't refactor with no test coverage. The code that looks "ugly" or "wrong" probably encodes 17 years of bug fixes, edge-case handling, and reverse-engineered customer requirements that nobody documented. Touch it now and you'll discover this the painful way.
Don't migrate to a framework
Migrating an existing legacy app to a framework is one of the most cited engineering disasters in our industry. The pattern: begins with optimism, takes 3x longer than estimated, never quite finishes, leaves a half-migrated codebase that's worse than the original. Don't.
If you really want a framework: build the new system in parallel, route specific URLs at it, migrate one feature at a time over 12–18 months. The legacy system continues to serve everything else.
Don't upgrade PHP / language version yet
PHP 5.6 → PHP 8 in place is a 2-month project minimum. There are silent behaviour changes (string-to-number comparisons, default error reporting, deprecated functions). Without test coverage you cannot verify the upgrade didn't break anything. Defer this until after Phase 7 + you have monitoring + you're ready to spend the time.
Don't add new features yet
Stabilize the system first. Adding features on top of a system with no safety net means each feature ships at risk. Adding features after Phases 0–7 means each feature ships through tests and rollback safety. Same feature, different risk profile.
Don't try to test everything
Legacy code is often untestable without significant refactoring (see "Don't refactor"). Don't attempt comprehensive test coverage of the existing code. Instead:
- HTTP smoke tests that verify "this URL returns 200" — easy, useful.
- Tests for new code only, written as you write it.
- PHP
php -lsyntax checks via CI — basically free, catches dumb errors.
Don't try to do all this alone in one week
Phases 0–7 takes 1–4 weeks of solo work, depending on the system size and the host's quirks. Don't compress it into a weekend. The goal is reliability; rushing introduces the same kinds of unsafe changes you're building the safety net to prevent.
What to communicate to your boss / stakeholders
The instinct is to under-communicate technical work. Resist. Here's the framing that works:
- "I am building the safety net the system needs to keep running reliably."
- "This work doesn't change what users see. It changes what we can recover from."
- "If we don't do this, the next outage is unrecoverable. If we do this, the next outage is a 14-second rollback."
- (When pressed for visible features:) "Features are next. Features built without this foundation are unsafe — every feature deploy is a coin flip. Features built on this foundation are safe — every feature deploy is verified and rollback-able."
Use the bilingual-exec-report skill for a formal status report.
When you're done with Phase 7
You now have:
- Production code in version control.
- Off-server backups (DB + files), tested.
- No public security holes (the obvious ones, anyway).
- One-button deploys with auto-rollback.
- Smoke tests and monitoring with alerting.
- Runbooks.
- Audit trail.
What you DON'T have (and what's fine):
- Modernized code.
- A test suite for legacy logic.
- A new framework.
- A "rewrite plan."
You have built the foundation. The legacy system is now safe to operate. Modernization is the next 12–24 months, done in carefully scoped projects, each one bounded and reversible because of the foundation you just built.
Why this playbook exists
The senior engineer's instinct, when handed a legacy system, is something like: "OK, I'll just refactor this module first, then upgrade PHP, then add tests, then..." This produces 6 months of half-finished work and a system that's now both legacy AND unstable.
The right instinct, learned the hard way: do nothing to the code. Build the safety net first. Then, once the system is observable, deployable, and recoverable, consider modernization — slowly, in scoped projects, with the safety net catching mistakes.
This is the playbook every senior architect writes for themselves after their first painful encounter with legacy modernization. Most engineers have to learn it the slow way. This skill compresses it into a checklist.
Estimated total time
| Phase | Description | Time |
|---|---|---|
| 0 | Recon | 2–4 hours |
| 1 | Source of truth | 2–4 hours |
| 2 | Off-server backups | 2–4 hours |
| 3 | Security cleanup | 2–6 hours |
| 4 | Deploy pipeline | 4–8 hours |
| 5 | Continuous monitoring | 1–2 hours |
| 6 | Audit trail | 2–4 hours |
| 7 | Documentation | 4–8 hours |
| Total | Phases 0–7 | ~20–40 hours of focused work |
For a solo engineer working evenings/weekends: ~3–6 weeks elapsed time. Worth it. The system is yours to operate sustainably from here.