SamuelChien821/devopsbench-100
DevOpsBench-100 DevOpsBench-100 is a synthetic long-horizon software-engineering / SRE agent benchmark: 100 tasks over one executable world ("NovaCart", a mid-size e-commerce SaaS) with 72 SQLite tables, 1451 seeded rows, a 38-file monorepo with 417 commits, and 97 MCP tools spanning a first-party engineering stack (tickets, PRs, CI, deployments, canaries, migrations, feature flags, metrics, alerts, incidents, chat, knowledge base) plus deliberately disagreeing vendor-shaped… See the full description on the dataset page: https://huggingface.co/datasets/SamuelChien821/devopsbench-100.
02.5k
1def list_services(db_path=None, team=None, tier=None):2 """List all services with team, tier, kind, on-call engineer, repo HEAD version and deployed versions."""3 import sqlite3 as _sq4 import json as _json5 if db_path:6 conn = _sq.connect(db_path)7 else:8 conn = get_db()9 conn.row_factory = _sq.Row10 try:11 try:12 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_services',)); conn.commit()13 except Exception:14 pass15 sql = 'SELECT * FROM services'16 conds, args = [], []17 if team:18 conds.append('team=?'); args.append(team)19 if tier is not None:20 conds.append('tier=?'); args.append(int(tier))21 if conds:22 sql += ' WHERE ' + ' AND '.join(conds)23 out = []24 for s in conn.execute(sql + ' ORDER BY service_id', args).fetchall():25 d = dict(s)26 oc = conn.execute('SELECT engineer FROM oncall WHERE team=?', (s['team'],)).fetchone()27 d['oncall_engineer'] = oc[0] if oc else ''28 for _env in ('staging', 'production'):29 v = conn.execute("SELECT value FROM env_state WHERE service=? AND environment=? AND kind='version' AND key='current'", (s['name'], _env)).fetchone()30 d[_env + '_version'] = v[0] if v else ''31 out.append(d)32 return out33 finally:34 conn.close()35 36 37def get_service(db_path=None, service=None):38 """Full detail for one service: metadata, deployed config, modules, endpoints, dependencies, current metrics."""39 import sqlite3 as _sq40 import json as _json41 if db_path:42 conn = _sq.connect(db_path)43 else:44 conn = get_db()45 conn.row_factory = _sq.Row46 try:47 try:48 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('get_service',)); conn.commit()49 except Exception:50 pass51 if service is None:52 return {'ok': False, 'error': 'missing required parameter: service'}53 row = conn.execute('SELECT * FROM services WHERE name=?', (service,)).fetchone()54 if row is None:55 return {'ok': False, 'error': 'unknown service: ' + str(service)}56 d = dict(row)57 d['production'] = {}58 for r in conn.execute("SELECT kind, key, value FROM env_state WHERE service=? AND environment='production' ORDER BY kind, key", (service,)).fetchall():59 d['production'].setdefault(r['kind'], {})[r['key']] = r['value']60 d['depends_on'] = [dict(r) for r in conn.execute('SELECT depends_on, kind FROM service_dependencies WHERE service=? ORDER BY depends_on', (service,)).fetchall()]61 d['metrics'] = {r['metric']: r['value'] for r in conn.execute("SELECT metric, value FROM service_metrics WHERE service=? AND environment='production'", (service,)).fetchall()}62 oc = conn.execute('SELECT engineer FROM oncall WHERE team=?', (row['team'],)).fetchone()63 d['oncall_engineer'] = oc[0] if oc else ''64 return d65 finally:66 conn.close()67 68 69def list_infra(db_path=None):70 """List infrastructure components of the application stack (databases, caches, queues, object stores, CDN)."""71 import sqlite3 as _sq72 import json as _json73 if db_path:74 conn = _sq.connect(db_path)75 else:76 conn = get_db()77 conn.row_factory = _sq.Row78 try:79 try:80 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_infra',)); conn.commit()81 except Exception:82 pass83 return [dict(r) for r in conn.execute('SELECT * FROM infra_components ORDER BY component_id').fetchall()]84 finally:85 conn.close()86 87 88def list_files(db_path=None, service=None, path_contains=None):89 """List monorepo files, optionally filtered by service or path substring."""90 import sqlite3 as _sq91 import json as _json92 if db_path:93 conn = _sq.connect(db_path)94 else:95 conn = get_db()96 conn.row_factory = _sq.Row97 try:98 try:99 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_files',)); conn.commit()100 except Exception:101 pass102 sql = 'SELECT file_id, service, path, language, owner, loc FROM repo_files'103 conds, args = [], []104 if service:105 conds.append('service=?'); args.append(service)106 if path_contains:107 conds.append('path LIKE ?'); args.append('%' + str(path_contains) + '%')108 if conds:109 sql += ' WHERE ' + ' AND '.join(conds)110 return [dict(r) for r in conn.execute(sql + ' ORDER BY path', args).fetchall()]111 finally:112 conn.close()113 114 115def read_file(db_path=None, path=None):116 """Read a monorepo source file. Returns its full current content."""117 import sqlite3 as _sq118 import json as _json119 if db_path:120 conn = _sq.connect(db_path)121 else:122 conn = get_db()123 conn.row_factory = _sq.Row124 try:125 try:126 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('read_file',)); conn.commit()127 except Exception:128 pass129 if path is None:130 return {'ok': False, 'error': 'missing required parameter: path'}131 row = conn.execute('SELECT * FROM repo_files WHERE path=?', (path,)).fetchone()132 if row is None:133 return {'ok': False, 'error': 'no such file: ' + str(path)}134 return dict(row)135 finally:136 conn.close()137 138 139def search_code(db_path=None, query=None, service=None, limit=20):140 """Search monorepo file contents for a substring; returns matching files with matching line numbers."""141 import sqlite3 as _sq142 import json as _json143 if db_path:144 conn = _sq.connect(db_path)145 else:146 conn = get_db()147 conn.row_factory = _sq.Row148 try:149 try:150 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('search_code',)); conn.commit()151 except Exception:152 pass153 if query is None:154 return {'ok': False, 'error': 'missing required parameter: query'}155 sql = 'SELECT service, path, content FROM repo_files WHERE content LIKE ?'156 args = ['%' + str(query) + '%']157 if service:158 sql += ' AND service=?'; args.append(service)159 out = []160 for r in conn.execute(sql + ' ORDER BY path LIMIT ?', args + [int(limit)]).fetchall():161 hits = []162 for i, line in enumerate(r['content'].split(chr(10)), 1):163 if str(query) in line:164 hits.append({'line': i, 'text': line.strip()[:200]})165 out.append({'service': r['service'], 'path': r['path'], 'matches': hits[:8]})166 return out167 finally:168 conn.close()169 170 171def list_commits(db_path=None, service=None, query=None, path=None, limit=20):172 """Browse monorepo commit history (most recent first)."""173 import sqlite3 as _sq174 import json as _json175 if db_path:176 conn = _sq.connect(db_path)177 else:178 conn = get_db()179 conn.row_factory = _sq.Row180 try:181 try:182 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_commits',)); conn.commit()183 except Exception:184 pass185 sql = 'SELECT sha, service, author, day, message, files, additions, deletions FROM commits'186 conds, args = [], []187 if service:188 conds.append('service=?'); args.append(service)189 if query:190 conds.append('message LIKE ?'); args.append('%' + str(query) + '%')191 if path:192 conds.append('files LIKE ?'); args.append('%' + str(path) + '%')193 if conds:194 sql += ' WHERE ' + ' AND '.join(conds)195 return [dict(r) for r in conn.execute(sql + ' ORDER BY day DESC, commit_id DESC LIMIT ?', args + [int(limit)]).fetchall()]196 finally:197 conn.close()198 199 200def search_docs(db_path=None, query='', kind=None, service=None, limit=10):201 """Search the engineering knowledge base (runbooks, policies, design docs, ADRs, postmortems, API specs)."""202 import sqlite3 as _sq203 import json as _json204 if db_path:205 conn = _sq.connect(db_path)206 else:207 conn = get_db()208 conn.row_factory = _sq.Row209 try:210 try:211 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('search_docs',)); conn.commit()212 except Exception:213 pass214 sql = 'SELECT doc_id, kind, title, service, author, day FROM documents'215 conds, args = [], []216 if query:217 conds.append('(title LIKE ? OR body LIKE ?)'); args += ['%' + str(query) + '%', '%' + str(query) + '%']218 if kind:219 conds.append('kind=?'); args.append(kind)220 if service:221 conds.append('service=?'); args.append(service)222 if conds:223 sql += ' WHERE ' + ' AND '.join(conds)224 return [dict(r) for r in conn.execute(sql + ' ORDER BY doc_id LIMIT ?', args + [int(limit)]).fetchall()]225 finally:226 conn.close()227 228 229def get_document(db_path=None, doc_id=None, title=None):230 """Read one knowledge-base document in full by doc_id (or exact title)."""231 import sqlite3 as _sq232 import json as _json233 if db_path:234 conn = _sq.connect(db_path)235 else:236 conn = get_db()237 conn.row_factory = _sq.Row238 try:239 try:240 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('get_document',)); conn.commit()241 except Exception:242 pass243 row = None244 if doc_id is not None:245 row = conn.execute('SELECT * FROM documents WHERE doc_id=?', (int(doc_id),)).fetchone()246 elif title:247 row = conn.execute('SELECT * FROM documents WHERE title=?', (title,)).fetchone()248 if row is None:249 row = conn.execute('SELECT * FROM documents WHERE title LIKE ?', ('%' + str(title) + '%',)).fetchone()250 else:251 return {'ok': False, 'error': 'provide doc_id or title'}252 if row is None:253 return {'ok': False, 'error': 'document not found'}254 return dict(row)255 finally:256 conn.close()257 258 259def list_tickets(db_path=None, status=None, service=None, ticket_type=None):260 """List issue-tracker tickets, optionally filtered by status, service, or type."""261 import sqlite3 as _sq262 import json as _json263 if db_path:264 conn = _sq.connect(db_path)265 else:266 conn = get_db()267 conn.row_factory = _sq.Row268 try:269 try:270 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_tickets',)); conn.commit()271 except Exception:272 pass273 sql = 'SELECT * FROM tickets'274 conds, args = [], []275 if status:276 conds.append('status=?'); args.append(status)277 if service:278 conds.append('service=?'); args.append(service)279 if ticket_type:280 conds.append('type=?'); args.append(ticket_type)281 if conds:282 sql += ' WHERE ' + ' AND '.join(conds)283 return [dict(r) for r in conn.execute(sql + ' ORDER BY ticket_id', args).fetchall()]284 finally:285 conn.close()286 287 288def get_ticket(db_path=None, key=None):289 """Fetch one ticket by key (e.g. ENG-2101)."""290 import sqlite3 as _sq291 import json as _json292 if db_path:293 conn = _sq.connect(db_path)294 else:295 conn = get_db()296 conn.row_factory = _sq.Row297 try:298 try:299 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('get_ticket',)); conn.commit()300 except Exception:301 pass302 if key is None:303 return {'ok': False, 'error': 'missing required parameter: key'}304 row = conn.execute('SELECT * FROM tickets WHERE key=?', (key,)).fetchone()305 if row is None:306 return {'ok': False, 'error': 'no such ticket: ' + str(key)}307 return dict(row)308 finally:309 conn.close()310 311 312def list_pull_requests(db_path=None, service=None, status=None):313 """List pull requests, optionally filtered by service or status."""314 import sqlite3 as _sq315 import json as _json316 if db_path:317 conn = _sq.connect(db_path)318 else:319 conn = get_db()320 conn.row_factory = _sq.Row321 try:322 try:323 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_pull_requests',)); conn.commit()324 except Exception:325 pass326 sql = 'SELECT * FROM pull_requests'327 conds, args = [], []328 if service:329 conds.append('service=?'); args.append(service)330 if status:331 conds.append('status=?'); args.append(status)332 if conds:333 sql += ' WHERE ' + ' AND '.join(conds)334 return [dict(r) for r in conn.execute(sql + ' ORDER BY number', args).fetchall()]335 finally:336 conn.close()337 338 339def get_pull_request(db_path=None, pr_number=None):340 """Fetch a PR with its structured changes and CI history."""341 import sqlite3 as _sq342 import json as _json343 if db_path:344 conn = _sq.connect(db_path)345 else:346 conn = get_db()347 conn.row_factory = _sq.Row348 try:349 try:350 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('get_pull_request',)); conn.commit()351 except Exception:352 pass353 if pr_number is None:354 return {'ok': False, 'error': 'missing required parameter: pr_number'}355 row = conn.execute('SELECT * FROM pull_requests WHERE number=?', (int(pr_number),)).fetchone()356 if row is None:357 return {'ok': False, 'error': 'no such pull request: ' + str(pr_number)}358 d = dict(row)359 d['changes'] = [{'change_type': c['change_type'], 'payload': _json.loads(c['payload'])}360 for c in conn.execute('SELECT change_type, payload FROM pr_changes WHERE pr_number=? ORDER BY change_id', (int(pr_number),)).fetchall()]361 d['ci_runs'] = [dict(c) for c in conn.execute('SELECT * FROM ci_runs WHERE pr_number=? ORDER BY run_id', (int(pr_number),)).fetchall()]362 return d363 finally:364 conn.close()365 366 367def list_ci_runs(db_path=None, service=None, pr_number=None, limit=20):368 """List CI runs (most recent first)."""369 import sqlite3 as _sq370 import json as _json371 if db_path:372 conn = _sq.connect(db_path)373 else:374 conn = get_db()375 conn.row_factory = _sq.Row376 try:377 try:378 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_ci_runs',)); conn.commit()379 except Exception:380 pass381 sql = 'SELECT * FROM ci_runs'382 conds, args = [], []383 if service:384 conds.append('service=?'); args.append(service)385 if pr_number is not None:386 conds.append('pr_number=?'); args.append(int(pr_number))387 if conds:388 sql += ' WHERE ' + ' AND '.join(conds)389 return [dict(r) for r in conn.execute(sql + ' ORDER BY run_id DESC LIMIT ?', args + [int(limit)]).fetchall()]390 finally:391 conn.close()392 393 394def get_ci_run(db_path=None, run_id=None):395 """Fetch one CI run with its per-stage results (build, unit, integration, regression)."""396 import sqlite3 as _sq397 import json as _json398 if db_path:399 conn = _sq.connect(db_path)400 else:401 conn = get_db()402 conn.row_factory = _sq.Row403 try:404 try:405 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('get_ci_run',)); conn.commit()406 except Exception:407 pass408 if run_id is None:409 return {'ok': False, 'error': 'missing required parameter: run_id'}410 row = conn.execute('SELECT * FROM ci_runs WHERE run_id=?', (int(run_id),)).fetchone()411 if row is None:412 return {'ok': False, 'error': 'no such CI run: ' + str(run_id)}413 d = dict(row)414 d['stages'] = [dict(s) for s in conn.execute('SELECT stage, status, detail FROM ci_stages WHERE run_id=? ORDER BY stage_id', (int(run_id),)).fetchall()]415 return d416 finally:417 conn.close()418 419 420def list_deployments(db_path=None, service=None, environment=None, limit=20):421 """List deployments (most recent first)."""422 import sqlite3 as _sq423 import json as _json424 if db_path:425 conn = _sq.connect(db_path)426 else:427 conn = get_db()428 conn.row_factory = _sq.Row429 try:430 try:431 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_deployments',)); conn.commit()432 except Exception:433 pass434 sql = 'SELECT * FROM deployments'435 conds, args = [], []436 if service:437 conds.append('service=?'); args.append(service)438 if environment:439 conds.append('environment=?'); args.append(environment)440 if conds:441 sql += ' WHERE ' + ' AND '.join(conds)442 return [dict(r) for r in conn.execute(sql + ' ORDER BY deployment_id DESC LIMIT ?', args + [int(limit)]).fetchall()]443 finally:444 conn.close()445 446 447def list_migrations(db_path=None, service=None, environment=None):448 """List database migrations and whether they are applied per environment."""449 import sqlite3 as _sq450 import json as _json451 if db_path:452 conn = _sq.connect(db_path)453 else:454 conn = get_db()455 conn.row_factory = _sq.Row456 try:457 try:458 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_migrations',)); conn.commit()459 except Exception:460 pass461 sql = 'SELECT * FROM migrations'462 conds, args = [], []463 if service:464 conds.append('service=?'); args.append(service)465 if environment:466 conds.append('environment=?'); args.append(environment)467 if conds:468 sql += ' WHERE ' + ' AND '.join(conds)469 rows = [dict(r) for r in conn.execute(sql + ' ORDER BY migration_id', args).fetchall()]470 pend = [dict(r) for r in conn.execute('SELECT service, module, migration_name FROM migration_requirements ORDER BY req_id').fetchall()]471 return {'applied': rows, 'declared_requirements': pend}472 finally:473 conn.close()474 475 476def query_metrics(db_path=None, service=None, metric=None):477 """Read current production service metrics (recomputed continuously from live traffic)."""478 import sqlite3 as _sq479 import json as _json480 if db_path:481 conn = _sq.connect(db_path)482 else:483 conn = get_db()484 conn.row_factory = _sq.Row485 try:486 try:487 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('query_metrics',)); conn.commit()488 except Exception:489 pass490 sql = "SELECT * FROM service_metrics WHERE environment='production'"491 args = []492 if service:493 sql += ' AND service=?'; args.append(service)494 if metric:495 sql += ' AND metric=?'; args.append(metric)496 return [dict(r) for r in conn.execute(sql + ' ORDER BY service, metric', args).fetchall()]497 finally:498 conn.close()499 500 501def get_traffic_stats(db_path=None, service=None):502 """Traffic-generator statistics: request rate per route with the current error rate and p99 of the owning service."""503 import sqlite3 as _sq504 import json as _json505 if db_path:506 conn = _sq.connect(db_path)507 else:508 conn = get_db()509 conn.row_factory = _sq.Row510 try:511 try:512 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('get_traffic_stats',)); conn.commit()513 except Exception:514 pass515 sql = 'SELECT * FROM traffic_profile'516 args = []517 if service:518 sql += ' WHERE service=?'; args.append(service)519 out = []520 for r in conn.execute(sql + ' ORDER BY route_id', args).fetchall():521 d = dict(r)522 for m in ('error_rate_pct', 'latency_p99_ms'):523 v = conn.execute("SELECT value FROM service_metrics WHERE service=? AND environment='production' AND metric=?", (r['service'], m)).fetchone()524 d[m] = v[0] if v else None525 if d.get('error_rate_pct') is not None:526 d['failed_requests_per_min'] = round(r['rps'] * 60.0 * d['error_rate_pct'] / 100.0, 1)527 out.append(d)528 return out529 finally:530 conn.close()531 532 533def get_slo_status(db_path=None, service=None):534 """List SLOs with current values and whether each is breaching."""535 import sqlite3 as _sq536 import json as _json537 if db_path:538 conn = _sq.connect(db_path)539 else:540 conn = get_db()541 conn.row_factory = _sq.Row542 try:543 try:544 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('get_slo_status',)); conn.commit()545 except Exception:546 pass547 sql = 'SELECT * FROM slos'548 args = []549 if service:550 sql += ' WHERE service=?'; args.append(service)551 out = []552 for r in conn.execute(sql + ' ORDER BY slo_id', args).fetchall():553 v = conn.execute("SELECT value FROM service_metrics WHERE service=? AND environment='production' AND metric=?", (r['service'], r['metric'])).fetchone()554 d = dict(r)555 d['current_value'] = v[0] if v else None556 d['breaching'] = (v is not None and v[0] > r['threshold'])557 out.append(d)558 return out559 finally:560 conn.close()561 562 563def list_alerts(db_path=None, status=None, service=None):564 """List alarms, optionally filtered by status (firing|acknowledged|resolved) or service."""565 import sqlite3 as _sq566 import json as _json567 if db_path:568 conn = _sq.connect(db_path)569 else:570 conn = get_db()571 conn.row_factory = _sq.Row572 try:573 try:574 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_alerts',)); conn.commit()575 except Exception:576 pass577 sql = 'SELECT * FROM alerts'578 conds, args = [], []579 if status:580 conds.append('status=?'); args.append(status)581 if service:582 conds.append('service=?'); args.append(service)583 if conds:584 sql += ' WHERE ' + ' AND '.join(conds)585 return [dict(r) for r in conn.execute(sql + ' ORDER BY alert_id', args).fetchall()]586 finally:587 conn.close()588 589 590def list_error_events(db_path=None, service=None, status=None):591 """Error-tracking issues (Sentry-style): grouped exceptions with culprit and event counts."""592 import sqlite3 as _sq593 import json as _json594 if db_path:595 conn = _sq.connect(db_path)596 else:597 conn = get_db()598 conn.row_factory = _sq.Row599 try:600 try:601 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_error_events',)); conn.commit()602 except Exception:603 pass604 sql = 'SELECT * FROM error_events'605 conds, args = [], []606 if service:607 conds.append('service=?'); args.append(service)608 if status:609 conds.append('status=?'); args.append(status)610 if conds:611 sql += ' WHERE ' + ' AND '.join(conds)612 return [dict(r) for r in conn.execute(sql + ' ORDER BY events DESC', args).fetchall()]613 finally:614 conn.close()615 616 617def search_logs(db_path=None, service=None, query='', level=None, limit=20):618 """Search application logs by substring, service, or level."""619 import sqlite3 as _sq620 import json as _json621 if db_path:622 conn = _sq.connect(db_path)623 else:624 conn = get_db()625 conn.row_factory = _sq.Row626 try:627 try:628 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('search_logs',)); conn.commit()629 except Exception:630 pass631 sql = 'SELECT * FROM logs'632 conds, args = [], []633 if service:634 conds.append('service=?'); args.append(service)635 if level:636 conds.append('level=?'); args.append(level)637 if query:638 conds.append('message LIKE ?'); args.append('%' + str(query) + '%')639 if conds:640 sql += ' WHERE ' + ' AND '.join(conds)641 return [dict(r) for r in conn.execute(sql + ' ORDER BY log_id LIMIT ?', args + [int(limit)]).fetchall()]642 finally:643 conn.close()644 645 646def list_feature_flags(db_path=None, service=None, environment=None):647 """List feature flags with per-environment state."""648 import sqlite3 as _sq649 import json as _json650 if db_path:651 conn = _sq.connect(db_path)652 else:653 conn = get_db()654 conn.row_factory = _sq.Row655 try:656 try:657 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_feature_flags',)); conn.commit()658 except Exception:659 pass660 sql = 'SELECT * FROM feature_flags'661 conds, args = [], []662 if service:663 conds.append('service=?'); args.append(service)664 if environment:665 conds.append('environment=?'); args.append(environment)666 if conds:667 sql += ' WHERE ' + ' AND '.join(conds)668 return [dict(r) for r in conn.execute(sql + ' ORDER BY key, environment', args).fetchall()]669 finally:670 conn.close()671 672 673def list_packages(db_path=None, service=None):674 """List package dependencies: version at repo HEAD and version deployed in production."""675 import sqlite3 as _sq676 import json as _json677 if db_path:678 conn = _sq.connect(db_path)679 else:680 conn = get_db()681 conn.row_factory = _sq.Row682 try:683 try:684 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_packages',)); conn.commit()685 except Exception:686 pass687 sql = "SELECT service, key, value FROM repo_state WHERE kind='dependency'"688 args = []689 if service:690 sql += ' AND service=?'; args.append(service)691 out = []692 for r in conn.execute(sql + ' ORDER BY service, key', args).fetchall():693 p = conn.execute("SELECT value FROM env_state WHERE service=? AND environment='production' AND kind='dependency' AND key=?", (r['service'], r['key'])).fetchone()694 out.append({'service': r['service'], 'package': r['key'], 'repo_version': r['value'],695 'production_version': p[0] if p else None})696 return out697 finally:698 conn.close()699 700 701def list_vulnerabilities(db_path=None, status=None, service=None):702 """List security-scanner findings."""703 import sqlite3 as _sq704 import json as _json705 if db_path:706 conn = _sq.connect(db_path)707 else:708 conn = get_db()709 conn.row_factory = _sq.Row710 try:711 try:712 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_vulnerabilities',)); conn.commit()713 except Exception:714 pass715 sql = 'SELECT * FROM vulnerabilities'716 conds, args = [], []717 if status:718 conds.append('status=?'); args.append(status)719 if service:720 conds.append('service=?'); args.append(service)721 if conds:722 sql += ' WHERE ' + ' AND '.join(conds)723 return [dict(r) for r in conn.execute(sql + ' ORDER BY vuln_id', args).fetchall()]724 finally:725 conn.close()726 727 728def list_api_endpoints(db_path=None, service=None):729 """List API endpoints with repo status, production status, and production traffic share."""730 import sqlite3 as _sq731 import json as _json732 if db_path:733 conn = _sq.connect(db_path)734 else:735 conn = get_db()736 conn.row_factory = _sq.Row737 try:738 try:739 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_api_endpoints',)); conn.commit()740 except Exception:741 pass742 sql = "SELECT service, key, value FROM repo_state WHERE kind='endpoint'"743 args = []744 if service:745 sql += ' AND service=?'; args.append(service)746 out = []747 for r in conn.execute(sql + ' ORDER BY service, key', args).fetchall():748 p = conn.execute("SELECT value FROM env_state WHERE service=? AND environment='production' AND kind='endpoint' AND key=?", (r['service'], r['key'])).fetchone()749 t = conn.execute("SELECT value FROM env_state WHERE service=? AND environment='production' AND kind='traffic' AND key=?", (r['service'], r['key'])).fetchone()750 out.append({'service': r['service'], 'path': r['key'], 'repo_status': r['value'],751 'production_status': p[0] if p else None,752 'production_traffic_percent': int(t[0]) if t else None})753 return out754 finally:755 conn.close()756 757 758def list_tests(db_path=None, service=None, status=None):759 """List the test catalog."""760 import sqlite3 as _sq761 import json as _json762 if db_path:763 conn = _sq.connect(db_path)764 else:765 conn = get_db()766 conn.row_factory = _sq.Row767 try:768 try:769 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_tests',)); conn.commit()770 except Exception:771 pass772 sql = 'SELECT * FROM tests_catalog'773 conds, args = [], []774 if service:775 conds.append('service=?'); args.append(service)776 if status:777 conds.append('status=?'); args.append(status)778 if conds:779 sql += ' WHERE ' + ' AND '.join(conds)780 return [dict(r) for r in conn.execute(sql + ' ORDER BY test_id', args).fetchall()]781 finally:782 conn.close()783 784 785def list_incidents(db_path=None, status=None):786 """List incidents."""787 import sqlite3 as _sq788 import json as _json789 if db_path:790 conn = _sq.connect(db_path)791 else:792 conn = get_db()793 conn.row_factory = _sq.Row794 try:795 try:796 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_incidents',)); conn.commit()797 except Exception:798 pass799 sql = 'SELECT * FROM incidents'800 args = []801 if status:802 sql += ' WHERE status=?'; args.append(status)803 return [dict(r) for r in conn.execute(sql + ' ORDER BY incident_id', args).fetchall()]804 finally:805 conn.close()806 807 808def get_status_page(db_path=None, limit=10):809 """Read the public system-status page."""810 import sqlite3 as _sq811 import json as _json812 if db_path:813 conn = _sq.connect(db_path)814 else:815 conn = get_db()816 conn.row_factory = _sq.Row817 try:818 try:819 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('get_status_page',)); conn.commit()820 except Exception:821 pass822 return [dict(r) for r in conn.execute('SELECT * FROM status_page ORDER BY post_id DESC LIMIT ?', (int(limit),)).fetchall()]823 finally:824 conn.close()825 826 827def list_messages(db_path=None, channel=None, limit=20):828 """Read chat messages."""829 import sqlite3 as _sq830 import json as _json831 if db_path:832 conn = _sq.connect(db_path)833 else:834 conn = get_db()835 conn.row_factory = _sq.Row836 try:837 try:838 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('list_messages',)); conn.commit()839 except Exception:840 pass841 sql = 'SELECT * FROM messages'842 args = []843 if channel:844 sql += ' WHERE channel=?'; args.append(channel)845 return [dict(r) for r in conn.execute(sql + ' ORDER BY message_id DESC LIMIT ?', args + [int(limit)]).fetchall()]846 finally:847 conn.close()848 849 850def create_ticket(db_path=None, title=None, description='', ticket_type='task', service='', priority='medium'):851 """Create a ticket. Returns the generated key."""852 import sqlite3 as _sq853 import json as _json854 if db_path:855 conn = _sq.connect(db_path)856 else:857 conn = get_db()858 conn.row_factory = _sq.Row859 try:860 try:861 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('create_ticket',)); conn.commit()862 except Exception:863 pass864 if title is None:865 return {'ok': False, 'error': 'missing required parameter: title'}866 def _audit(conn, _tool, _svc, _detail):867 conn.execute('INSERT INTO audit_events(tool, service, detail) VALUES (?,?,?)', (_tool, _svc, _json.dumps(_detail)))868 if ticket_type not in ('task', 'bug', 'feature', 'security', 'incident', 'postmortem'):869 return {'ok': False, 'error': 'invalid ticket_type: ' + str(ticket_type)}870 if service and conn.execute('SELECT 1 FROM services WHERE name=?', (service,)).fetchone() is None:871 return {'ok': False, 'error': 'unknown service: ' + str(service)}872 cur = conn.execute('INSERT INTO tickets(key, type, title, description, status, priority, service) VALUES (?,?,?,?,?,?,?)',873 ('', ticket_type, title, description, 'open', priority, service))874 tid = cur.lastrowid875 key = 'TKT-' + str(tid)876 conn.execute('UPDATE tickets SET key=? WHERE ticket_id=?', (key, tid))877 _audit(conn, 'create_ticket', service, {'key': key, 'type': ticket_type, 'title': title})878 conn.commit()879 return {'ok': True, 'key': key, 'ticket_id': tid, 'status': 'open'}880 finally:881 conn.close()882 883 884def update_ticket(db_path=None, key=None, status=None, assignee=None):885 """Update a ticket's status and/or assignee."""886 import sqlite3 as _sq887 import json as _json888 if db_path:889 conn = _sq.connect(db_path)890 else:891 conn = get_db()892 conn.row_factory = _sq.Row893 try:894 try:895 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('update_ticket',)); conn.commit()896 except Exception:897 pass898 if key is None:899 return {'ok': False, 'error': 'missing required parameter: key'}900 def _audit(conn, _tool, _svc, _detail):901 conn.execute('INSERT INTO audit_events(tool, service, detail) VALUES (?,?,?)', (_tool, _svc, _json.dumps(_detail)))902 row = conn.execute('SELECT * FROM tickets WHERE key=?', (key,)).fetchone()903 if row is None:904 return {'ok': False, 'error': 'no such ticket: ' + str(key)}905 if status is None and assignee is None:906 return {'ok': False, 'error': 'provide status and/or assignee'}907 if status is not None and status not in ('open', 'in_progress', 'in_review', 'done'):908 return {'ok': False, 'error': 'invalid status: ' + str(status)}909 ns = row['status'] if status is None else status910 na = row['assignee'] if assignee is None else assignee911 conn.execute('UPDATE tickets SET status=?, assignee=? WHERE key=?', (ns, na, key))912 _audit(conn, 'update_ticket', row['service'], {'key': key, 'status': ns})913 conn.commit()914 return {'ok': True, 'key': key, 'status': ns, 'assignee': na}915 finally:916 conn.close()917 918 919def open_pull_request(db_path=None, service=None, title=None, body='', ticket_key='', changes=None):920 """Open a pull request carrying structured changes. change_type is one of: config {key,value}; dependency {package,version}; endpoint {path,status: active|deprecated|retired}; module {name}; flag {key,description}; flag_cleanup {key}; test_fix {test_name, action: fix|quarantine}; migration {name}; code_edit {path, find, replace}. Changes apply at merge; deploys carry them to an environment."""921 import sqlite3 as _sq922 import json as _json923 if db_path:924 conn = _sq.connect(db_path)925 else:926 conn = get_db()927 conn.row_factory = _sq.Row928 try:929 try:930 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('open_pull_request',)); conn.commit()931 except Exception:932 pass933 if service is None:934 return {'ok': False, 'error': 'missing required parameter: service'}935 if title is None:936 return {'ok': False, 'error': 'missing required parameter: title'}937 if changes is None:938 return {'ok': False, 'error': 'missing required parameter: changes'}939 def _audit(conn, _tool, _svc, _detail):940 conn.execute('INSERT INTO audit_events(tool, service, detail) VALUES (?,?,?)', (_tool, _svc, _json.dumps(_detail)))941 if conn.execute('SELECT 1 FROM services WHERE name=?', (service,)).fetchone() is None:942 return {'ok': False, 'error': 'unknown service: ' + str(service)}943 if isinstance(changes, str):944 try:945 changes = _json.loads(changes)946 except Exception:947 return {'ok': False, 'error': 'changes must be a JSON list of {change_type, payload}'}948 if not isinstance(changes, list) or not changes:949 return {'ok': False, 'error': 'changes must be a non-empty list of {change_type, payload}'}950 norm = []951 for ch in changes:952 if not isinstance(ch, dict):953 return {'ok': False, 'error': 'each change must be an object with change_type and payload'}954 ct, pl = ch.get('change_type'), ch.get('payload')955 if isinstance(pl, str):956 try:957 pl = _json.loads(pl)958 except Exception:959 return {'ok': False, 'error': 'change payload must be an object'}960 if not isinstance(pl, dict):961 return {'ok': False, 'error': 'change payload must be an object'}962 if ct == 'config':963 if not pl.get('key') or 'value' not in pl:964 return {'ok': False, 'error': 'config change needs payload {key, value}'}965 pl = {'key': str(pl['key']), 'value': str(pl['value'])}966 elif ct == 'dependency':967 if not pl.get('package') or not pl.get('version'):968 return {'ok': False, 'error': 'dependency change needs payload {package, version}'}969 if conn.execute("SELECT 1 FROM repo_state WHERE service=? AND kind='dependency' AND key=?", (service, pl['package'])).fetchone() is None:970 return {'ok': False, 'error': service + ' has no dependency ' + str(pl['package'])}971 pl = {'package': str(pl['package']), 'version': str(pl['version'])}972 elif ct == 'endpoint':973 if not pl.get('path') or pl.get('status') not in ('active', 'deprecated', 'retired'):974 return {'ok': False, 'error': 'endpoint change needs payload {path, status: active|deprecated|retired}'}975 if conn.execute("SELECT 1 FROM repo_state WHERE service=? AND kind='endpoint' AND key=?", (service, pl['path'])).fetchone() is None:976 return {'ok': False, 'error': service + ' has no endpoint ' + str(pl['path'])}977 pl = {'path': str(pl['path']), 'status': str(pl['status'])}978 elif ct == 'module':979 if not pl.get('name'):980 return {'ok': False, 'error': 'module change needs payload {name}'}981 pl = {'name': str(pl['name'])}982 elif ct == 'flag':983 if not pl.get('key'):984 return {'ok': False, 'error': 'flag change needs payload {key, description}'}985 if conn.execute('SELECT 1 FROM feature_flags WHERE key=?', (pl['key'],)).fetchone() is not None:986 return {'ok': False, 'error': 'flag already exists: ' + str(pl['key'])}987 pl = {'key': str(pl['key']), 'description': str(pl.get('description', ''))}988 elif ct == 'flag_cleanup':989 if not pl.get('key'):990 return {'ok': False, 'error': 'flag_cleanup change needs payload {key}'}991 if conn.execute('SELECT 1 FROM feature_flags WHERE key=?', (pl['key'],)).fetchone() is None:992 return {'ok': False, 'error': 'no such flag: ' + str(pl['key'])}993 pl = {'key': str(pl['key'])}994 elif ct == 'test_fix':995 if not pl.get('test_name') or pl.get('action') not in ('fix', 'quarantine'):996 return {'ok': False, 'error': "test_fix change needs payload {test_name, action: fix|quarantine}"}997 if conn.execute('SELECT 1 FROM tests_catalog WHERE service=? AND name=?', (service, pl['test_name'])).fetchone() is None:998 return {'ok': False, 'error': service + ' has no test ' + str(pl['test_name'])}999 pl = {'test_name': str(pl['test_name']), 'action': str(pl['action'])}1000 elif ct == 'migration':1001 if not pl.get('name'):1002 return {'ok': False, 'error': 'migration change needs payload {name}'}1003 pl = {'name': str(pl['name'])}1004 elif ct == 'code_edit':1005 if not pl.get('path') or 'find' not in pl or 'replace' not in pl:1006 return {'ok': False, 'error': 'code_edit change needs payload {path, find, replace}'}1007 f = conn.execute('SELECT content, service FROM repo_files WHERE path=?', (pl['path'],)).fetchone()1008 if f is None:1009 return {'ok': False, 'error': 'no such file: ' + str(pl['path'])}1010 if str(pl['find']) not in f['content']:1011 return {'ok': False, 'error': 'find text not present in ' + str(pl['path'])}1012 pl = {'path': str(pl['path']), 'find': str(pl['find']), 'replace': str(pl['replace'])}1013 else:1014 return {'ok': False, 'error': 'invalid change_type: ' + str(ct)}1015 norm.append((ct, pl))1016 number = conn.execute('SELECT COALESCE(MAX(number), 9200) + 1 FROM pull_requests').fetchone()[0]1017 conn.execute('INSERT INTO pull_requests(number, service, title, body, author, ticket_key, status) VALUES (?,?,?,?,?,?,?)',1018 (number, service, title, body, 'agent', ticket_key, 'open'))1019 for ct, pl in norm:1020 conn.execute('INSERT INTO pr_changes(pr_number, change_type, payload) VALUES (?,?,?)', (number, ct, _json.dumps(pl)))1021 _audit(conn, 'open_pull_request', service, {'pr_number': number, 'ticket_key': ticket_key,1022 'change_count': len(norm),1023 'change_types': sorted(set(c[0] for c in norm))})1024 conn.commit()1025 return {'ok': True, 'pr_number': number, 'service': service, 'status': 'open',1026 'next': 'run_ci(pr_number=' + str(number) + ') then merge_pull_request(pr_number=' + str(number) + ')'}1027 finally:1028 conn.close()1029 1030 1031def run_ci(db_path=None, pr_number=None, service=None):1032 """Run the CI pipeline for an open PR (pr_number) or a service's main branch (service). Stages run in order: build, unit, integration, regression. The tool succeeds even when the pipeline fails - inspect the returned status and stages."""1033 import sqlite3 as _sq1034 import json as _json1035 if db_path:1036 conn = _sq.connect(db_path)1037 else:1038 conn = get_db()1039 conn.row_factory = _sq.Row1040 try:1041 try:1042 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('run_ci',)); conn.commit()1043 except Exception:1044 pass1045 def _audit(conn, _tool, _svc, _detail):1046 conn.execute('INSERT INTO audit_events(tool, service, detail) VALUES (?,?,?)', (_tool, _svc, _json.dumps(_detail)))1047 if pr_number is None and not service:1048 return {'ok': False, 'error': 'provide pr_number (PR pipeline) or service (main-branch pipeline)'}1049 if pr_number is not None:1050 pr_number = int(pr_number)1051 pr = conn.execute('SELECT * FROM pull_requests WHERE number=?', (pr_number,)).fetchone()1052 if pr is None:1053 return {'ok': False, 'error': 'no such pull request: ' + str(pr_number)}1054 if pr['status'] != 'open':1055 return {'ok': False, 'error': 'PR ' + str(pr_number) + ' is not open; for main-branch runs use run_ci(service=...)'}1056 service = pr['service']1057 elif conn.execute('SELECT 1 FROM services WHERE name=?', (service,)).fetchone() is None:1058 return {'ok': False, 'error': 'unknown service: ' + str(service)}1059 changes = []1060 if pr_number is not None:1061 changes = [(c['change_type'], _json.loads(c['payload'])) for c in1062 conn.execute('SELECT change_type, payload FROM pr_changes WHERE pr_number=? ORDER BY change_id', (pr_number,)).fetchall()]1063 stages = []1064 # --- build: schema changes need their migration in the same PR1065 bstatus, bdetail = 'passed', 'compiled and packaged'1066 for ct, pl in changes:1067 if ct != 'module':1068 continue1069 req = conn.execute('SELECT migration_name FROM migration_requirements WHERE service=? AND module=?', (service, pl['name'])).fetchone()1070 if req is not None and not any(c[0] == 'migration' and c[1].get('name') == req[0] for c in changes):1071 bstatus = 'failed'1072 bdetail = 'missing database migration: module ' + pl['name'] + ' requires migration ' + req[0] + " (add a 'migration' change to this PR)"1073 break1074 stages.append(('build', bstatus, bdetail))1075 # --- unit1076 if bstatus == 'passed':1077 failing = [r['name'] for r in conn.execute("SELECT name FROM tests_catalog WHERE service=? AND suite='unit' AND status='failing' AND quarantined=0", (service,)).fetchall()]1078 stages.append(('unit', 'failed' if failing else 'passed',1079 ('failing unit tests: ' + ', '.join(failing)) if failing else 'unit suite green'))1080 else:1081 stages.append(('unit', 'skipped', 'build failed'))1082 # --- integration: contract checks + flaky suite1083 istatus, idetail = 'passed', 'integration suite green'1084 if stages[-1][1] != 'passed':1085 istatus, idetail = 'skipped', 'upstream stage failed'1086 else:1087 for ct, pl in changes:1088 if ct == 'endpoint' and pl.get('status') == 'retired':1089 t = conn.execute("SELECT value FROM env_state WHERE service=? AND environment='production' AND kind='traffic' AND key=?", (service, pl['path'])).fetchone()1090 if t is not None and int(t[0]) > 0:1091 istatus = 'failed'1092 idetail = 'cannot retire ' + pl['path'] + ': still serving ' + str(t[0]) + '% of production traffic - drain it first'1093 break1094 if istatus == 'passed':1095 flaky = [r['name'] for r in conn.execute("SELECT name FROM tests_catalog WHERE service=? AND suite='integration' AND status='flaky' AND quarantined=0", (service,)).fetchall()]1096 if pr_number is not None:1097 seen_red = conn.execute("SELECT COUNT(*) FROM ci_runs WHERE pr_number=? AND status='failed'", (pr_number,)).fetchone()[0]1098 trips = bool(flaky) and seen_red == 01099 else:1100 n_prior = conn.execute('SELECT COUNT(*) FROM ci_runs WHERE service=? AND pr_number IS NULL', (service,)).fetchone()[0]1101 trips = bool(flaky) and n_prior % 2 == 01102 if trips:1103 istatus, idetail = 'failed', 'intermittent failure: ' + ', '.join(flaky) + ' (rerun may pass)'1104 else:1105 failing = [r['name'] for r in conn.execute("SELECT name FROM tests_catalog WHERE service=? AND suite='integration' AND status='failing' AND quarantined=0", (service,)).fetchall()]1106 if failing:1107 istatus, idetail = 'failed', 'failing integration tests: ' + ', '.join(failing)1108 stages.append(('integration', istatus, idetail))1109 # --- regression: cross-service consumer contracts1110 rstatus, rdetail = 'passed', 'no regressions in dependent services'1111 if istatus != 'passed':1112 rstatus, rdetail = 'skipped', 'upstream stage failed'1113 else:1114 for ct, pl in changes:1115 if ct != 'endpoint' or pl.get('status') != 'retired':1116 continue1117 for cr in conn.execute('SELECT * FROM contract_rules WHERE producer_service=? AND endpoint=?', (service, pl['path'])).fetchall():1118 cv = conn.execute("SELECT value FROM env_state WHERE service=? AND environment='production' AND kind='config' AND key=?", (cr['consumer_service'], cr['consumer_key'])).fetchone()1119 if cv is None or cv[0] != cr['consumer_required_value']:1120 rstatus = 'failed'1121 rdetail = cr['message']1122 break1123 if rstatus == 'failed':1124 break1125 stages.append(('regression', rstatus, rdetail))1126 status = 'passed' if all(s[1] == 'passed' for s in stages) else 'failed'1127 detail = 'all stages passed' if status == 'passed' else next(s[2] for s in stages if s[1] == 'failed')1128 cur = conn.execute('INSERT INTO ci_runs(service, pr_number, status, detail) VALUES (?,?,?,?)', (service, pr_number, status, detail))1129 rid = cur.lastrowid1130 for st, sv, sd in stages:1131 conn.execute('INSERT INTO ci_stages(run_id, stage, status, detail) VALUES (?,?,?,?)', (rid, st, sv, sd))1132 _audit(conn, 'run_ci', service, {'pr_number': pr_number, 'status': status,1133 'stages': {s[0]: s[1] for s in stages}})1134 conn.commit()1135 return {'ok': True, 'run_id': rid, 'service': service, 'pr_number': pr_number, 'status': status,1136 'detail': detail, 'stages': [{'stage': s[0], 'status': s[1], 'detail': s[2]} for s in stages]}1137 finally:1138 conn.close()1139 1140 1141def merge_pull_request(db_path=None, pr_number=None):1142 """Merge an open PR. Blocked unless its latest CI run passed. Applies the PR's changes to repo HEAD (including code edits) and cuts a new deployable version."""1143 import sqlite3 as _sq1144 import json as _json1145 if db_path:1146 conn = _sq.connect(db_path)1147 else:1148 conn = get_db()1149 conn.row_factory = _sq.Row1150 try:1151 try:1152 conn.execute('INSERT INTO tool_calls(tool) VALUES (?)', ('merge_pull_request',)); conn.commit()1153 except Exception:1154 pass1155 if pr_number is None:1156 return {'ok': False, 'error': 'missing required parameter: pr_number'}1157 def _audit(conn, _tool, _svc, _detail):1158 conn.execute('INSERT INTO audit_events(tool, service, detail) VALUES (?,?,?)', (_tool, _svc, _json.dumps(_detail)))1159 pr_number = int(pr_number)1160 pr = conn.execute('SELECT * FROM pull_requests WHERE number=?', (pr_number,)).fetchone()1161 if pr is None:1162 return {'ok': False, 'error': 'no such pull request: ' + str(pr_number)}1163 if pr['status'] != 'open':1164 return {'ok': False, 'error': 'PR ' + str(pr_number) + ' is not open'}1165 last = conn.execute('SELECT status FROM ci_runs WHERE pr_number=? ORDER BY run_id DESC LIMIT 1', (pr_number,)).fetchone()1166 if last is None:1167 return {'ok': False, 'error': 'no CI run recorded for PR ' + str(pr_number) + '; call run_ci(pr_number=...) first'}1168 if last[0] != 'passed':1169 return {'ok': False, 'error': 'latest CI run for PR ' + str(pr_number) + ' is ' + last[0] + '; merge blocked'}1170 service = pr['service']1171 requires_migration = ''1172 for c in conn.execute('SELECT change_type, payload FROM pr_changes WHERE pr_number=? ORDER BY change_id', (pr_number,)).fetchall():1173 ct, pl = c['change_type'], _json.loads(c['payload'])1174 if ct == 'config':1175 conn.execute("INSERT INTO repo_state(service, kind, key, value) VALUES (?,'config',?,?) ON CONFLICT(service, kind, key) DO UPDATE SET value=excluded.value", (service, pl['key'], pl['value']))1176 elif ct == 'dependency':1177 conn.execute("UPDATE repo_state SET value=? WHERE service=? AND kind='dependency' AND key=?", (pl['version'], service, pl['package']))1178 elif ct == 'endpoint':1179 conn.execute("UPDATE repo_state SET value=? WHERE service=? AND kind='endpoint' AND key=?", (pl['status'], service, pl['path']))1180 elif ct == 'module':1181 conn.execute("INSERT INTO repo_state(service, kind, key, value) VALUES (?,'module',?,'present') ON CONFLICT(service, kind, key) DO UPDATE SET value=excluded.value", (service, pl['name']))1182 elif ct == 'flag':1183 for _env in ('staging', 'production'):1184 conn.execute('INSERT OR IGNORE INTO feature_flags(key, service, description, environment, enabled, rollout_percent) VALUES (?,?,?,?,0,0)', (pl['key'], service, pl.get('description', ''), _env))1185 elif ct == 'flag_cleanup':1186 conn.execute('DELETE FROM feature_flags WHERE key=?', (pl['key'],))1187 elif ct == 'test_fix':1188 if pl['action'] == 'fix':1189 conn.execute("UPDATE tests_catalog SET status='passing', quarantined=0 WHERE service=? AND name=?", (service, pl['test_name']))1190 else:1191 conn.execute('UPDATE tests_catalog SET quarantined=1 WHERE service=? AND name=?', (service, pl['test_name']))1192 elif ct == 'migration':1193 requires_migration = pl['name']1194 conn.execute('INSERT OR IGNORE INTO migrations(service, name, environment, status) VALUES (?,?,?,?)', (service, pl['name'], '', 'pending'))1195 elif ct == 'code_edit':1196 f = conn.execute('SELECT content FROM repo_files WHERE path=?', (pl['path'],)).fetchone()1197 if f is not None and pl['find'] in f['content']:1198 conn.execute('UPDATE repo_files SET content=? WHERE path=?', (f['content'].replace(pl['find'], pl['replace']), pl['path']))1199 old = conn.execute('SELECT repo_version FROM services WHERE name=?', (service,)).fetchone()[0]1200 parts = old.lstrip('v').split('.')