• The third real self-hosting attempt (first to actually reach stage_deployment
    itself, past the earlier bootstrap/commit bugs) hit an uncaught
    FileNotFoundError: _copy_prod_db() assumed prod_db_path always exists and
    shutil.copy2()'d it unconditionally. graphlemon has never actually run as a
    persistent service, so ~/.graphlemon/graphlemon.db never existed.
    stage_deployment() already handles this exact class of "no prior state"
    bootstrap case for previous_commit_hash/previous_instance_dir -- prod_db_path
    never got the same treatment, and every existing test seeds a prod db in
    setUp so this was never exercised.
    
    Fix: when prod_db_path doesn't exist, create a fresh schema'd db instead of
    copying -- semantically correct, since a genuinely-first deployment has no
    production data to inherit. New regression test (BootstrapProdDbTest) covers
    it. 555 tests green (435 src + 120 supervisor).
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »

  • Adds supervisor/deploy_stage.py: stage_deployment() creates a deployment row,
    git-worktree-checks-out the target commit into a fresh directory (--detach,
    never in-place git pull), copies the production DB to a one-time candidate
    copy, and Popens a real candidate backend process on a free port.
    
    Return value follows 04-P §4.6's state-machine table (status after the call
    is 'candidate_starting') rather than 03-C's one-line 'staged' summary --
    04-P's own trigger text ("c_deploy_supervisor_stage 完成" moves the row to
    candidate_starting) is the more detailed/authoritative source when the two
    disagree, same precedent used throughout this project.
    
    Found and closed two real gaps along the way:
    - deployment's own field list never included where a candidate's checkout
      directory lives -- added candidate_instance_dir to schema.py (also what
      the NEXT staging call's previous_instance_dir bootstraps from once a
      deployment reaches 'finalized').
    - backend_server.py had no CLI entry point at all since U-007 -- create_server()
      was only ever instantiated in-process by tests. Added main() (argparse +
      serve_forever + SIGTERM->shutdown() from a separate thread, per
      http.server's own same-thread-deadlock warning).
    
    RealCandidateLaunchTest spawns and HTTP-probes a genuine
    `python3 -m src.backend_server` subprocess against a real git-worktree
    checkout of this repo (not mocked) -- caught a real ordering issue doing so:
    git worktree only sees committed content, so testing before this Unit's own
    commit landed would check out backend_server.py without main() at all.
    Fixed by using `git stash create` (builds a commit object from the current
    working tree without touching HEAD/index) as the commit-to-test-against,
    falling back to plain HEAD once the tree is clean post-commit.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »