KB-7501

Lifecycle DDL Ratification · 02 Repo Placement Decision

6 min read Revision 1
dot-iu-cutterv0.5lifecycle-ddl-ratificationrepo-placementg2-passdieu442026-05-20

dot-iu-cutter v0.5 — Lifecycle DDL Ratification · Repo Placement Decision

doc 2 of 6 · 2026-05-20

phase    : G2 — least-surprising location for operator-runbook SQL
outcome  : sql/lifecycle/ (new top-level dir)  — PASS

1. Discovery — what already exists in the repo

repo                : /Users/nmhuyen/iu-cutter-build/repo/iu-cutter
head_pre_commit     : 32cfa93 (main = feature, both pointed at 32cfa93)
existing_top_level  :
  - README.md
  - cli.py
  - constitution-normalized-17660443e0f23e99.md  (data; source snapshot)
  - cutter_agent/                                (Python package)
  - tests/                                       (Python regression)
  - .gitignore                                   (ignores __pycache__/*.pyc)
existing_sql_dirs   : NONE  (`find -type d \( -name sql -o -name ddl -o
                              -name migrations -o -name runbooks -o
                              -name specs -o -name schema \)` returned 0)
existing_sql_files  : NONE  (`find -name '*.sql'` returned 0)
migration_framework : NONE  (no Alembic/Flyway/sqlx-migrate/django-migrations)
README_doctrine     : "DRY-RUN-SAFE SKELETON ONLY. No production DB connection."

2. Options considered

OPT_P1_new_top_level_sql_lifecycle:
  path  : sql/lifecycle/
  pros  :
    - clearly separated from Python (cutter_agent/) so no auto-apply temptation
    - top-level visibility for operators
    - room for future sql/governance/ or sql/cutter_governance/ siblings
    - matches README's "skeleton, not auto-applied" doctrine
  cons  :
    - new top-level dir; minor repo churn
  recommended: YES

OPT_P2_inside_cutter_agent:
  path  : cutter_agent/sql/lifecycle/
  pros  : co-located with Python module that conceptually owns it
  cons  :
    - cutter_agent/ is a Python package; import-time scans might find .sql
    - operator runbook = NOT application code; mixing roles is confusing
    - README states Python module does NOT connect to production
  recommended: NO

OPT_P3_inside_tests_fixtures:
  path  : tests/fixtures/sql/
  pros  : single existing data-ish folder; minimal churn
  cons  :
    - "fixtures" implies test-only data, not an operator runbook
    - would confuse anyone running `pytest --collect-only`
  recommended: NO

OPT_P4_inside_specs_or_runbooks:
  path  : specs/ or runbooks/
  pros  : explicit "runbook" naming
  cons  :
    - neither directory exists; creating them adds top-level dir anyway
    - "specs" suggests an unimplemented design; this is the opposite
    - "runbooks" is unspecific (operator runbooks for what?)
  recommended: NO  (P1 is more descriptive)

3. Decision

chosen        : OPT_P1 — sql/lifecycle/
rationale     :
  - LOWEST surprise: top-level `sql/` is the canonical convention for
    SQL artefacts in mixed-language repos; `lifecycle/` scopes the
    M3a substrate without claiming all-future-SQL territory
  - MOST honest: name reflects role (operator runbook), not pretends
    to be a migration framework
  - MOST extensible: leaves room for sql/governance/ etc. without
    re-organizing
  - MOST isolated: Python code in cutter_agent/ cannot accidentally
    import or auto-execute these files

4. Inner layout (chosen)

sql/lifecycle/
├── README.md                                     operator usage + warnings
├── bundle_a_vocab_and_log.sql                    TXN-1
├── bundle_b_immutability.sql                     TXN-2
├── bundle_c_fn_iu_enact.sql                      TXN-3
├── bundle_d_gateway_and_grants.sql               TXN-4
├── bundle_e_fn_iu_apply_edit_draft_patch.sql     TXN-5
├── verify_preflight.sql                          pre-apply absence probes
├── verify_postapply.sql                          post-apply presence probes
├── verify_behavioral_probes.sql                  B-1..B-8 ROLLBACK-only
├── rollback_runbook.sql                          reverse order + safety
└── fingerprints.yaml                             md5 / count pins

Naming conventions:

  • bundle_<letter>_<short_name>.sql — apply-order is encoded in the letter, matching the M3a-retry TXN sequence.
  • verify_<phase>.sql — explicit "what phase to run this in" prefix.
  • rollback_runbook.sql — singular file because rollback is one operator decision, not five.
  • fingerprints.yaml — machine-readable manifest; consumed by future audit macros.
  • README.md — first thing an operator reads; the WARNING block lives at the top so it cannot be missed.

5. No duplication

duplicate_check :
  KB authoring docs (v0.5-lifecycle-enactment-implementation-authoring/)
  are NOT mirrored verbatim into the repo. The repo SQL contains only the
  ratified live bodies; the authoring docs remain the design narrative.
KB_role  : design intent + authoring decisions
repo_role : reproducible bytes
SSOT_for_apply : repo SQL files + fingerprints.yaml
SSOT_for_why   : KB authoring docs

6. Forbidden actions baked into the layout

no_auto_apply_hook :
  - .gitignore does NOT reference sql/
  - no setup.py / pyproject.toml entry point reads sql/
  - no CI workflow in repo (repo has no .github/ tree)
  - Python tests intentionally do NOT import or read sql/

no_silent_drift :
  - fingerprints.yaml pins md5(prosrc) for every function
  - verify_postapply.sql asserts the same md5s after apply
  - any future edit to bundle bodies must update fingerprints.yaml +
    cross-reference the M3a-retry KB trail (drift would invalidate the
    runbook's promise)

7. Gate disposition

G2_repo_layout_discovered            : PASS
G2_no_existing_SQL_directory_found   : PASS
G2_least_surprising_location_chosen  : PASS  (sql/lifecycle/)
G2_no_duplication_introduced         : PASS
G2_no_auto_apply_wiring              : PASS  (operator-runbook semantics
                                              enforced by layout)

8. STOP

Repo placement decided. Proceed to doc 03 (runbook artefact summary).

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.5-lifecycle-ddl-ratification-runbook/02-repo-placement-decision-2026-05-20.md