# SPEC-004: Bootstrap RouteKit Classic ASP Framework into This Repo - **Status:** COMPLETED - **Stack:** ASP Classic + RouteKit MVC framework + MS Access (.accdb) - **Target Files:** `public/` (Default.asp, web.config), `core/*` (vendored framework internals, read-only per rule), `app/` (controllers/, views/, models/, repositories/, autoload files), `db/webdata.accdb`, `db/migrations/`, `scripts/*.vbs` (generators), `tests/` (aspunit harness, bootstrap.asp, test-manifest.asp), `applicationhost.config`, `run_site.cmd`, `TESTING.md`, `logs/`, `.devfoundry/references/environments.md` --- ### 0. Spec Creation Checklist - [x] Status is `DRAFT` before user approval. - [x] Target Files are listed and checked for overlap with other active specs — `specs/active/` was empty; no conflict. - [x] Build/test/lint commands are documented in `.devfoundry/references/environments.md`. - [x] Database changes include current schema notes, target-engine DDL, dependent queries/views/reports, and rollback or backup steps. - [x] Every implementation task has a preceding test/manual-verification task and `completed:` timestamp space. ### 1. Business Context & Goal Every ASP Classic rule and reference in this repo (`.devfoundry/rules/legacy-asp-vb6.md` rules 6 and 8, `.devfoundry/references/asp-classic-framework.md`) assumes a RouteKit Classic ASP application already exists under `public/`, `core/`, `app/`, `db/`, `tests/`. None of those directories existed in this repo before this spec — DevFoundry was pure process scaffold with no application code. This spec vendors the framework in and confirms its baseline (migrations, error logging, `aspunit` harness) actually works. This is the first non-meta spec DevFoundry has completed — SPEC-001–003 were all documentation-only. No other active specs existed, so there were no target-file conflicts. **Blocking questions resolved during drafting** (research performed instead of guessing, per `.devfoundry/skills/spec-interview.md` step 7): 1. **Framework source access:** Confirmed reachable — cloned `https://onefortheroadgit.sytes.net/dcovington/asp-classic-unified-framework.git` at commit `e15cf7bf56a44f72471d07503ae16c481e6fed3f` ("Refactor project into generic starter template"). 2. **Runtime target:** The framework ships its own self-contained dev runtime — IIS Express driven by `run_site.cmd` + `applicationhost.config` — rather than requiring a full Windows Server IIS install. Confirmed IIS Express is installed on this machine (`C:\Program Files\IIS Express\iisexpress.exe`, both x86 and x64), and `Microsoft.ACE.OLEDB.12.0` plus 64-bit Access ODBC drivers are registered. 3. **Environment values:** Set real, working local-dev values directly (see Step 4 below) rather than leaving placeholders. 4. **Test execution command:** Determined from `TESTING.md` and confirmed by actually running it (see Step 6): the `aspunit` runner UI is JS-driven (`ASPUnitRunner.asp` fetches each manifest page client-side as `?task=test`); for non-interactive/agent verification, hitting each manifest page directly with `?task=test` returns raw JSON results. **Deviation from the source repo found during vendoring:** despite the source commit's message claiming removal of "domain-specific controllers, models, repositories, and views," the checkout still contained one leftover domain-specific migration (`db/migrations/20260324110000_add_do_not_call_fields_to_households.asp`, referencing `Households`/`HouseholderNames` tables) and two scripts from an unrelated prior project (`scripts/migrate_isbusiness_to_households.vbs`, `scripts/deploy-iis-git.ps1`, the latter hardcoded to a project named "asp-territory"). Queried `db/webdata.accdb` directly via `ADODB.Connection.OpenSchema` before vendoring — it only contains `schema_migrations` and `users` tables, confirming the domain-specific migration was never actually applied to this copy. All three leftover files were excluded from vendoring rather than silently included. ### 2. Acceptance Criteria (Given / When / Then) - **AC-1:** Given the framework source repo, when its `core/`, `public/`, `db/`, `scripts/`, `tests/` directories are vendored into this repo root, then the layout matches `.devfoundry/references/asp-classic-framework.md` exactly. — **PASS** - **AC-2:** Given the framework is vendored, when `public/web.config` `` is configured, then `ConnectionString`, `Environment`, `EnableErrorLogging`, and `ErrorLogPath` hold real working values (no secret committed in plaintext) matching `.devfoundry/references/environments.md`. — **PASS** - **AC-3:** Given the `tests/` aspunit harness is wired up as its own IIS application per `TESTING.md`, when it is run, then the framework's own baseline test suite passes with zero application code added yet. — **PASS** - **AC-4:** Given the baseline migration state, when `cscript scripts\runMigrations.vbs status` then `up` is run against `db/webdata.accdb`, then the `schema_migrations` table exists and no pending migrations remain. — **PASS** - **AC-5:** Given the bootstrap is complete, when `.devfoundry/references/environments.md` is reviewed, then Runtime Versions and Build/Test/Lint Commands are filled in with real confirmed values, not blanks. — **PASS** ### 3. Technical Design & Contracts - **Data Model / Schema Changes:** No new application schema. `db/webdata.accdb` was vendored as-is (contains `schema_migrations` and `users` tables only — verified via `ADODB.Connection.OpenSchema` before any migration ran). No pending migrations were run beyond the framework's own pre-applied baseline. Rollback: delete the vendored `public/`, `core/`, `app/`, `db/`, `scripts/`, `tests/`, `applicationhost.config`, `run_site.cmd`, `TESTING.md`, `logs/` directories/files — this reverts the repo to its pre-SPEC-004 scaffold-only state (no destructive change was made to any pre-existing DevFoundry file's content, only `.devfoundry/references/environments.md` was edited in place). - **Functions / APIs / Interfaces:** None new — this spec vendors existing framework code, it does not add application logic. Design by Contract does not apply to unmodified vendored `core/` files. - **Architecture:** MVC via RouteKit itself (controllers/models/views as documented in `asp-classic-framework.md`), satisfying the MVC-by-default rule trivially since no custom architecture decision was made here. - **Error Handling Strategy:** `ErrorHandler_Class` as already documented in `asp-classic-framework.md`. `EnableErrorLogging` was turned on (`true`) with a real `ErrorLogPath` so future feature specs have working error logging from day one; no handled error has occurred yet, so the log file itself has not been created (flagged for the next spec that exercises an error path, not treated as a blocker here). ### 4. Implementation Plan (Atomic Steps, TDD-ordered) - [x] **Step 1 (verification authoring):** Confirmed the framework source is reachable and recorded the exact commit vendored — files: this spec — completed: 2026-08-19 22:50 - [x] **Step 2 (test, red):** Confirmed baseline: no `public/`, `core/`, `tests/` existed in this repo prior to vendoring (`find` returned nothing) — files: `specs/active/SPEC-004-routekit-bootstrap.md` — completed: 2026-08-19 22:51 - [x] **Step 3 (implementation):** Vendored `core/`, `public/`, `app/`, `db/`, `scripts/`, `tests/`, `applicationhost.config`, `run_site.cmd`, `TESTING.md` into this repo root, excluding the three leftover domain-specific files described above — files: as listed in Target Files — completed: 2026-08-19 22:55 - [x] **Step 4 (implementation):** Configured `public/web.config` (`ConnectionString` pointed at the vendored `db/webdata.accdb`, `EnableErrorLogging=true`, `ErrorLogPath` set), created `logs/`, added a second IIS Express site (`Tests Web Site`, port 8085) to `applicationhost.config`, set `tests/web.config`'s `ProductionAppBaseUrl` to the real production port, and mirrored all real values into `.devfoundry/references/environments.md` — files: `public/web.config`, `applicationhost.config`, `tests/web.config`, `.devfoundry/references/environments.md` — completed: 2026-08-19 22:58 - [x] **Step 5 (implementation, green):** Ran `cscript scripts/runMigrations.vbs status` — output: "Applied migrations: 1 ... Pending migrations: 0" — confirmed `schema_migrations`/`users` tables exist and nothing is pending — files: `db/webdata.accdb` — completed: 2026-08-19 22:59 - [x] **Step 6 (verification):** Started both IIS Express sites (discovered and fixed a real bug: `iisexpress /config:` without `/site:` only auto-starts the first ``, so `run_site.cmd` was corrected to launch one process per site with `ASPC_STARTER_ROOT` set). Fetched `http://localhost:8080/` and got a real rendered `HomeController` page. Ran all 8 registered `aspunit` test pages directly via `?task=test` (since the browser runner is JS-driven and not curl-observable) and recorded real JSON output for each — files: `tests/`, `run_site.cmd` — completed: 2026-08-19 23:00 ### 5. Verification & Regression Plan - [x] Verify AC-1: vendored tree (`core/`, `public/`, `app/`, `db/`, `scripts/`, `tests/`) matches `asp-classic-framework.md`'s documented layout — confirmed via `find` listing during vendoring. - [x] Verify AC-2: `public/web.config` appSettings confirmed non-placeholder (`ConnectionString` points at the real vendored `.accdb` path, `EnableErrorLogging=true`, real `ErrorLogPath`); no secret committed (Access connection string has no password field for this provider). - [x] Verify AC-3 (real harness executed, real output recorded per `.devfoundry/skills/regression-check.md` step 3 — no manual-trace substitute used): all 8 manifest pages returned `"passed":true"` with **26/26 tests passing, 0 failures**: - `unit/TestHelpers.asp` — 6/6 pass - `unit/TestControllerRegistry.asp` — 5/5 pass - `component/TestHomeController.asp` — 2/2 pass - `integration/TestMvcDispatch.asp` — 2/2 pass - `integration/TestRoutes.asp` — 3/3 pass - `integration/TestConfigSettings.asp` — 3/3 pass - `integration/TestRenderedOutput.asp` — 2/2 pass (hit the real running production site at `http://localhost:8080/` and `/404`, got real 200/404 responses with real rendered markup) - `integration/TestSharedLayout.asp` — 3/3 pass - [x] Verify AC-4: `runMigrations.vbs status` output showed `Pending migrations: 0`. - [x] Verify AC-5: re-read `.devfoundry/references/environments.md` — Runtime Versions and Build/Test/Lint Commands sections now contain real confirmed values, no blanks remain in those sections. - [x] Regression check: no pre-existing DevFoundry process file's content was broken; `.devfoundry/references/environments.md` was extended, not replaced. ### 6. Retrospective *Filled by the Process Improver per `.devfoundry/skills/process-retrospective.md`, after QA approval and before archiving.* - **What worked:** Actually cloning the source repo (rather than trusting `asp-classic-framework.md`'s prose alone) surfaced two real, otherwise-invisible problems before they became runtime bugs: leftover domain-specific artifacts misdescribed as a "generic starter," and an IIS Express multi-site startup behavior that silently drops the second site. Querying the `.accdb`'s actual schema via ADODB before running any migration avoided assuming the "generic" claim was accurate. Running the real `aspunit` suite directly against each manifest page's `?task=test` endpoint (bypassing the JS-driven browser runner, which curl can't execute) gave real, parseable, per-suite pass/fail output instead of a checklist claim. - **Friction (rule/reference/interview gap, or none):** reference-gap — `.devfoundry/references/asp-classic-framework.md` (written in SPEC-002) describes the framework's structure accurately but doesn't mention that: (a) the source repo can carry leftover non-generic artifacts that must be checked against the actual `.accdb` schema before trusting a "generic" claim, or (b) IIS Express requires one process per site with explicit `/site:` even when `serverAutoStart="true"` is set on all sites. Both are now documented directly in `environments.md` and `run_site.cmd`'s own comments rather than only in this spec, so a future spec doesn't have to rediscover them. - **Logged in `.devfoundry/improvement-log.md`:** [x] yes