110 parser = argparse.ArgumentParser(
111 prog=
"python -m oc_chat.registry",
112 description=
"Orchestration registry operator commands.",
114 subcommands = parser.add_subparsers(dest=
"command")
116 init_parser = subcommands.add_parser(
118 help=
"Create and seed a registry SQLite database.",
120 init_parser.add_argument(
123 help=
"Registry SQLite path. Defaults to the discovery algorithm.",
125 init_parser.add_argument(
127 help=
"Workspace root to record in the initial workspaces row.",
129 init_parser.add_argument(
131 help=
"Initial human operator slot. Defaults to the local hostname.",
133 init_parser.add_argument(
136 help=
"Suppress success output.",
138 init_parser.set_defaults(handler=_cmd_init)
140 doctor_parser = subcommands.add_parser(
142 help=
"Run registry health checks and safe repairs.",
144 doctor_parser.add_argument(
147 help=
"Registry SQLite path. Defaults to the discovery algorithm.",
149 doctor_parser.add_argument(
152 help=
"Repair .option_c and agent_secrets.json modes where supported.",
154 doctor_parser.add_argument(
157 help=
"Skip local filesystem permission inspection.",
159 doctor_parser.add_argument(
162 help=
"Do not remove stray .tmp-* files below .option_c/orchestration.",
164 doctor_parser.add_argument(
167 help=
"Do not sweep expired volatile lock rows.",
169 doctor_parser.add_argument(
170 "--no-credential-check",
172 help=
"Do not compare agent_secrets.json fingerprints to the registry.",
174 doctor_parser.add_argument(
177 help=
"Emit the structured doctor report as JSON.",
179 doctor_parser.add_argument(
180 "--resolve-snapshot-conflict",
182 help=
"Resolve drifted rendered artifacts.",
184 doctor_parser.add_argument(
185 "--yes-trust-registry",
187 help=
"Resolve snapshot drift by overwriting from the registry.",
189 doctor_parser.add_argument(
192 help=
"Resolve snapshot drift by keeping supported local edits.",
194 doctor_parser.set_defaults(handler=_cmd_doctor)
196 rotate_parser = subcommands.add_parser(
198 help=
"Start or finalize HMAC credential rotation.",
200 rotate_parser.add_argument(
203 help=
"Registry SQLite path. Defaults to the discovery algorithm.",
205 rotate_scope = rotate_parser.add_mutually_exclusive_group()
206 rotate_scope.add_argument(
"--slot", help=
"Slot to rotate.")
207 rotate_scope.add_argument(
210 help=
"Rotate every active slot.",
212 rotate_parser.add_argument(
215 help=
"Rotation grace window override.",
217 rotate_parser.add_argument(
220 help=
"Finalize an in-flight rotation instead of starting one.",
222 rotate_parser.set_defaults(handler=_cmd_rotate_secrets)
224 handover_parser = subcommands.add_parser(
226 help=
"Initiate or accept orchestrator handover.",
228 handover_parser.add_argument(
231 help=
"Registry SQLite path. Defaults to the discovery algorithm.",
233 handover_action = handover_parser.add_mutually_exclusive_group(required=
True)
234 handover_action.add_argument(
"--to", help=
"Incoming orchestrator slot.")
235 handover_action.add_argument(
238 metavar=
"HANDOVER_ID",
239 help=
"Accept a handover-start operation id.",
241 handover_parser.add_argument(
"--from-slot", help=
"Outgoing orchestrator slot.")
242 handover_parser.add_argument(
"--reason", default=
"operator handover")
243 handover_parser.set_defaults(handler=_cmd_handover)
245 auth_parser = subcommands.add_parser(
247 help=
"Actor-auth inspection and bootstrap commands.",
251 db_parser = subcommands.add_parser(
253 help=
"Database maintenance and inspection commands.",
255 add_db_subcommands(db_parser)
257 migrate_parser = subcommands.add_parser(
259 help=
"Legacy registry migration commands.",
261 add_migrate_subcommands(migrate_parser)
263 queue_parser = subcommands.add_parser(
265 help=
"Registry-native queue commands.",
267 add_queue_subcommands(queue_parser)
269 plan_parser = subcommands.add_parser(
271 help=
"Registry-native plan commands.",
273 add_plan_subcommands(plan_parser)
275 round_parser = subcommands.add_parser(
277 help=
"Registry-native round-close commands.",
279 add_round_subcommands(round_parser)
281 add_sync_subcommand(subcommands)
282 add_roadmap_subcommands(subcommands)
283 add_regenerate_subcommand(subcommands)
285 checkpoint_parser = subcommands.add_parser(
287 help=
"Export and import registry JSON checkpoints.",
289 add_checkpoint_subcommands(checkpoint_parser)
291 add_inspect_subcommands(subcommands)
296 location = discover_registry_location(
297 registry_path=args.registry,
298 workspace_root=args.workspace_root,
300 raw_secret = secrets.token_bytes(32)
303 workspace_id=str(uuid.uuid4()),
304 registry_id=str(uuid.uuid4()),
305 workspace_root=str(location.workspace_root),
306 git_common_dir=str(location.git_common_dir),
307 registry_path=str(location.registry_path),
308 checkpoint_path=str(location.checkpoint_path),
309 operator_slot=operator_slot,
310 hmac_key_id=str(uuid.uuid4()),
311 secret_fingerprint=hashlib.sha256(raw_secret).hexdigest(),
312 app_version=resolve_version(),
315 backend.initialize(seed)
316 secret_block = block_from_secret(
319 hmac_key_id=seed.hmac_key_id,
320 raw_secret=raw_secret,
321 created_at=backend.clock.now_wall(),
323 write_secrets({operator_slot: {
"active": secret_block}},
_secrets_path(location))
324 backend.startup_sweep()
326 print(f
"initialised registry: {location.registry_path}")
327 print(f
"operator slot: {operator_slot}")
332 location = discover_registry_location(registry_path=args.registry)
338 location.workspace_root,
340 fix_perms=args.fix_perms,
341 skip_perms=args.skip_perms,
342 sweep_temps=
not args.no_sweep_temps,
343 lock_sweep=
not args.no_lock_sweep,
344 credential_check=
not args.no_credential_check,
345 resolve_snapshot_conflict=args.resolve_snapshot_conflict,
346 yes_trust_registry=args.yes_trust_registry,
347 yes_trust_local=args.yes_trust_local,
351 print(json.dumps(report, indent=2, sort_keys=
True))
353 print(format_doctor_report(report))
358 """Register actor-auth subcommands."""
360 subcommands = parser.add_subparsers(dest=
"auth_command")
362 show = subcommands.add_parser(
"show", help=
"Show credential state.")
363 show.add_argument(
"registry", nargs=
"?")
364 show.add_argument(
"--slot")
365 show.set_defaults(handler=_cmd_auth_show)
367 verify = subcommands.add_parser(
"verify", help=
"Verify recent auth metadata.")
368 verify.add_argument(
"registry", nargs=
"?")
369 verify.add_argument(
"--slot")
370 verify.add_argument(
"--all", action=
"store_true")
371 verify.set_defaults(handler=_cmd_auth_verify)
373 export = subcommands.add_parser(
"export-secrets", help=
"Export local secrets.")
374 export.add_argument(
"registry", nargs=
"?")
375 export.add_argument(
"--slot")
376 export.add_argument(
"--out", required=
True)
377 export.add_argument(
"--encrypt-command")
378 export.set_defaults(handler=_cmd_auth_export)
380 bootstrap = subcommands.add_parser(
382 help=
"Install local secrets from a bundle.",
384 bootstrap.add_argument(
"registry", nargs=
"?")
385 bootstrap.add_argument(
"--secrets", required=
True)
386 bootstrap.add_argument(
"--decrypt-command")
387 bootstrap.set_defaults(handler=_cmd_auth_bootstrap)