From ed0f9f42f4feeee1313dbfdd2ab46100b1e8a06b Mon Sep 17 00:00:00 2001
From: centra
Date: Fri, 20 Mar 2026 16:25:11 +0900
Subject: [PATCH] WIP snapshot: preserve dirty worktree
---
.claude.json | 0
.github/workflows/nix.yml | 36 +-
.gitignore | 18 +
CONTRIBUTING.md | 27 +
FOREMAN_TASK.md | 35 -
LICENSE | 202 +
Makefile | 37 +
Nix-NOS.md | 398 --
PROJECT.md | 105 -
README.md | 527 +-
SECURITY.md | 13 +
T003-architectural-gap-analysis.md | 54 -
TOAGENT.md | 5 -
advice.md | 5094 -------------
apigateway/Cargo.lock | 819 ++-
apigateway/Cargo.toml | 4 +-
.../crates/apigateway-server/Cargo.toml | 1 +
.../crates/apigateway-server/src/main.rs | 661 +-
baremetal/first-boot/ARCHITECTURE.md | 763 --
baremetal/first-boot/README.md | 858 ---
baremetal/first-boot/bootstrap-detector.sh | 6 +-
baremetal/first-boot/cluster-join.sh | 22 +-
.../examples/cluster-config-all-in-one.json | 77 -
.../examples/cluster-config-bootstrap.json | 68 -
.../examples/cluster-config-join.json | 68 -
baremetal/first-boot/health-check.sh | 11 +-
baremetal/image-builder/OVERVIEW.md | 570 --
baremetal/image-builder/README.md | 388 -
baremetal/image-builder/build-images.sh | 16 +-
.../image-builder/examples/custom-netboot.nix | 361 -
.../examples/hardware-specific.nix | 442 --
baremetal/vm-cluster/README.md | 42 +-
baremetal/vm-cluster/alpine-answers.txt | 46 -
baremetal/vm-cluster/legacy/README.md | 18 +
.../{ => legacy}/alpine-ssh-setup.sh | 0
.../vm-cluster/{ => legacy}/deploy-all.sh | 10 +-
.../{ => legacy}/launch-node01-disk.sh | 0
.../{ => legacy}/launch-node01-dual.sh | 0
.../{ => legacy}/launch-node01-from-disk.sh | 0
.../{ => legacy}/launch-node01-iso.sh | 0
.../{ => legacy}/launch-node01-netboot.sh | 10 +-
.../{ => legacy}/launch-node01-vde.sh | 0
.../vm-cluster/{ => legacy}/launch-node01.sh | 2 +-
.../{ => legacy}/launch-node02-alpine.sh | 0
.../{ => legacy}/launch-node02-disk.sh | 0
.../{ => legacy}/launch-node02-from-disk.sh | 0
.../{ => legacy}/launch-node02-iso.sh | 0
.../{ => legacy}/launch-node02-netboot.sh | 10 +-
.../{ => legacy}/launch-node02-recovery.sh | 0
.../{ => legacy}/launch-node02-vde.sh | 0
.../vm-cluster/{ => legacy}/launch-node02.sh | 2 +-
.../{ => legacy}/launch-node03-disk.sh | 0
.../{ => legacy}/launch-node03-from-disk.sh | 0
.../{ => legacy}/launch-node03-iso.sh | 0
.../{ => legacy}/launch-node03-netboot.sh | 10 +-
.../{ => legacy}/launch-node03-recovery.sh | 0
.../{ => legacy}/launch-node03-vde.sh | 0
.../vm-cluster/{ => legacy}/launch-node03.sh | 2 +-
.../{ => legacy}/launch-pxe-server-install.sh | 0
.../{ => legacy}/launch-pxe-server-iso.sh | 0
.../{ => legacy}/launch-pxe-server.sh | 0
.../{ => legacy}/pxe-server-setup.sh | 0
.../{ => legacy}/validate-cluster.sh | 35 +-
baremetal/vm-cluster/netboot-initrd | 1 -
baremetal/vm-cluster/netboot-kernel | 1 -
.../vm-cluster/pxe-server/configuration.nix | 27 +-
bin/cloud-cli | 135 +
chainfire/advice.md | 87 -
chainfire/baremetal/pxe-server/OVERVIEW.md | 295 -
chainfire/baremetal/pxe-server/QUICKSTART.md | 177 -
chainfire/baremetal/pxe-server/README.md | 829 ---
.../examples/nixos-config-examples.nix | 392 -
.../pxe-server/http/directory-structure.txt | 81 -
.../pxe-server/ipxe/mac-mappings.txt | 47 -
chainfire/chainfire-client/examples/basic.rs | 15 -
.../chainfire-client/examples/cleanup.rs | 27 -
chainfire/chainfire-client/src/client.rs | 41 +
.../crates/chainfire-api/src/kv_service.rs | 18 +-
.../chainfire-core/tests/integration.rs | 52 -
.../chainfire-raft/tests/leader_election.rs | 613 --
.../chainfire-raft/tests/proptest_sim.rs | 274 -
.../tests/cluster_integration.rs | 658 --
.../tests/integration_test.rs | 175 -
chainfire/data/CURRENT | 1 -
chainfire/data/IDENTITY | 1 -
chainfire/data/LOCK | 0
chainfire/data/LOG | 3410 ---------
chainfire/data/MANIFEST-000005 | Bin 355 -> 0 bytes
chainfire/data/OPTIONS-000007 | 684 --
chainfire_t003_gap_analysis.md | 240 -
coronafs/Cargo.lock | 1165 +++
coronafs/Cargo.toml | 32 +
coronafs/README.md | 18 +
coronafs/crates/coronafs-server/Cargo.toml | 27 +
coronafs/crates/coronafs-server/src/config.rs | 61 +
coronafs/crates/coronafs-server/src/main.rs | 748 ++
crates/photon-auth-client/Cargo.toml | 10 +
crates/photon-auth-client/src/lib.rs | 10 +
crates/photon-config/Cargo.toml | 11 +
crates/photon-config/src/lib.rs | 58 +
crates/photon-runtime/Cargo.toml | 10 +
crates/photon-runtime/src/lib.rs | 10 +
crates/photon-state/Cargo.toml | 10 +
crates/photon-state/src/lib.rs | 99 +
creditservice/Cargo.lock | 1546 +++-
creditservice/Cargo.toml | 9 +-
creditservice/README.md | 39 +
.../crates/creditservice-api/Cargo.toml | 9 +-
.../src/chainfire_storage.rs | 222 -
.../creditservice-api/src/credit_service.rs | 532 +-
.../creditservice-api/src/flaredb_storage.rs | 323 +
.../src/gateway_credit_service.rs | 146 +-
.../crates/creditservice-api/src/lib.rs | 14 +-
.../creditservice-api/src/sql_storage.rs | 396 +
.../crates/creditservice-proto/Cargo.toml | 3 +-
.../crates/creditservice-proto/build.rs | 2 +
.../crates/creditservice-server/Cargo.toml | 9 +-
.../crates/creditservice-server/src/config.rs | 58 +
.../crates/creditservice-server/src/main.rs | 253 +-
.../crates/creditservice-server/src/rest.rs | 256 +-
.../tests/mtls_integration.rs | 77 -
.../crates/creditservice-types/Cargo.toml | 2 +-
creditservice/creditservice-client/Cargo.toml | 2 +-
.../creditservice-client/examples/basic.rs | 18 -
.../creditservice-client/examples/builder.rs | 27 -
creditservice/proto/creditservice.proto | 12 +-
data/CURRENT | 1 -
data/IDENTITY | 1 -
data/LOCK | 0
data/LOG | 4951 -------------
data/MANIFEST-000005 | Bin 290 -> 0 bytes
data/OPTIONS-000007 | 567 --
deployer/Cargo.lock | 2027 +++++-
deployer/Cargo.toml | 14 +
deployer/crates/cert-authority/src/main.rs | 210 +-
deployer/crates/deployer-ctl/Cargo.toml | 2 +-
deployer/crates/deployer-ctl/src/chainfire.rs | 891 ++-
deployer/crates/deployer-ctl/src/main.rs | 50 +-
deployer/crates/deployer-ctl/src/model.rs | 86 -
deployer/crates/deployer-server/Cargo.toml | 4 +
deployer/crates/deployer-server/src/admin.rs | 410 +-
deployer/crates/deployer-server/src/auth.rs | 101 +
.../crates/deployer-server/src/cloud_init.rs | 179 +
.../crates/deployer-server/src/cluster.rs | 1 +
deployer/crates/deployer-server/src/config.rs | 192 +-
deployer/crates/deployer-server/src/lib.rs | 50 +-
.../deployer-server/src/local_storage.rs | 362 +
deployer/crates/deployer-server/src/main.rs | 35 +-
.../crates/deployer-server/src/phone_home.rs | 880 ++-
deployer/crates/deployer-server/src/state.rs | 75 +-
.../crates/deployer-server/src/storage.rs | 209 +-
deployer/crates/deployer-server/src/tls.rs | 66 +
.../crates/deployer-server/src/validation.rs | 63 +
deployer/crates/deployer-types/src/lib.rs | 712 ++
deployer/crates/fleet-scheduler/Cargo.toml | 29 +
deployer/crates/fleet-scheduler/src/auth.rs | 79 +
deployer/crates/fleet-scheduler/src/main.rs | 1314 ++++
.../crates/fleet-scheduler/src/publish.rs | 1214 ++++
deployer/crates/node-agent/Cargo.toml | 2 +-
deployer/crates/node-agent/src/agent.rs | 592 +-
deployer/crates/node-agent/src/main.rs | 36 +-
deployer/crates/node-agent/src/process.rs | 556 +-
deployer/crates/node-agent/src/watcher.rs | 9 +-
.../scripts/verify-deployer-bootstrap-e2e.sh | 378 +
.../scripts/verify-fleet-scheduler-e2e.sh | 420 ++
dev-certs/ca/ca.crt | 34 -
dev-certs/ca/ca.key | 52 -
dev-certs/ca/ca.srl | 1 -
dev-certs/chainfire/server.crt | 30 -
dev-certs/chainfire/server.key | 28 -
dev-certs/flaredb/server.crt | 30 -
dev-certs/flaredb/server.key | 28 -
dev-certs/iam/server.crt | 30 -
dev-certs/iam/server.key | 28 -
docs/Nix-NOS.md | 398 --
docs/README-dependency-graphs.md | 64 -
docs/README.md | 20 +
docs/api/rest-api-guide.md | 1197 ----
docs/architecture/api-gateway.md | 111 -
docs/architecture/baremetal-mesh-migration.md | 113 -
docs/architecture/mvp-beta-tenant-path.md | 468 --
docs/benchmarks/storage-layer-baseline.md | 243 -
docs/cert-authority-usage.md | 124 -
docs/component-dependencies-detailed.dot | 174 -
docs/component-dependencies.dot | 131 -
docs/component-matrix.md | 57 +
docs/deployment/bare-metal.md | 643 --
.../cluster-config.json | 1 -
.../test.nix | 53 -
.../first-boot-automation-cluster-config.txt | 21 -
docs/getting-started/tenant-onboarding.md | 647 --
docs/implementation-status.md | 74 -
docs/implementation-summary.md | 91 -
docs/nixos-deployment-challenges.md | 448 --
docs/ops/backup-restore.md | 345 -
docs/ops/ha-behavior.md | 246 -
docs/ops/integration-matrix.md | 43 -
docs/ops/nested-kvm-setup.md | 38 -
docs/ops/qcow2-artifact-plan.md | 26 -
docs/ops/scale-out.md | 286 -
docs/ops/troubleshooting.md | 809 ---
docs/ops/upgrade.md | 532 --
.../chainfire_architecture_redefinition.md | 89 -
docs/plans/metadata_unification.md | 45 -
docs/por/POR.md | 300 -
docs/por/T001-stabilize-tests/task.yaml | 33 -
docs/por/T002-specifications/task.yaml | 36 -
docs/por/T003-feature-gaps/T003-report.md | 104 -
docs/por/T003-feature-gaps/chainfire-gaps.md | 35 -
docs/por/T003-feature-gaps/flaredb-gaps.md | 40 -
docs/por/T003-feature-gaps/iam-gaps.md | 39 -
docs/por/T003-feature-gaps/task.yaml | 62 -
docs/por/T004-p0-fixes/task.yaml | 115 -
docs/por/T005-plasmavmc-spec/task.yaml | 49 -
docs/por/T006-p1-features/task.yaml | 167 -
docs/por/T007-plasmavmc-impl/task.yaml | 131 -
docs/por/T008-lightningstor/task.yaml | 111 -
docs/por/T009-flashdns/task.yaml | 113 -
docs/por/T010-fiberlb/task.yaml | 113 -
docs/por/T011-plasmavmc-deepening/task.yaml | 115 -
.../por/T012-vm-tenancy-persistence/task.yaml | 64 -
.../T013-vm-chainfire-persistence/schema.md | 138 -
.../T013-vm-chainfire-persistence/task.yaml | 77 -
.../config-schema.md | 112 -
docs/por/T014-plasmavmc-firecracker/design.md | 213 -
.../integration-test-evidence.md | 80 -
docs/por/T014-plasmavmc-firecracker/task.yaml | 118 -
.../plasmavmc-integration.md | 619 --
.../research-summary.md | 199 -
docs/por/T015-overlay-networking/task.yaml | 113 -
.../tenant-network-model.md | 503 --
.../T016-lightningstor-deepening/task.yaml | 122 -
docs/por/T017-flashdns-deepening/task.yaml | 133 -
docs/por/T018-fiberlb-deepening/task.yaml | 173 -
.../task.yaml | 226 -
docs/por/T020-flaredb-metadata/design.md | 123 -
docs/por/T020-flaredb-metadata/task.yaml | 63 -
docs/por/T021-flashdns-parity/design.md | 207 -
docs/por/T021-flashdns-parity/task.yaml | 181 -
docs/por/T022-novanet-control-plane/task.yaml | 148 -
docs/por/T023-e2e-tenant-path/SUMMARY.md | 396 -
docs/por/T023-e2e-tenant-path/e2e_test.md | 336 -
docs/por/T023-e2e-tenant-path/task.yaml | 192 -
docs/por/T024-nixos-packaging/task.yaml | 237 -
docs/por/T025-k8s-hosting/research.md | 844 ---
docs/por/T025-k8s-hosting/spec.md | 2396 -------
docs/por/T025-k8s-hosting/task.yaml | 495 --
docs/por/T026-practical-test/task.yaml | 121 -
docs/por/T027-production-hardening/task.yaml | 99 -
docs/por/T028-feature-completion/task.yaml | 53 -
.../task.yaml | 127 -
docs/por/T029-practical-app-demo/Cargo.lock | 2974 --------
docs/por/T029-practical-app-demo/Cargo.toml | 29 -
docs/por/T029-practical-app-demo/README.md | 132 -
.../e2e-test-results.md | 108 -
docs/por/T029-practical-app-demo/results.md | 160 -
docs/por/T029-practical-app-demo/src/main.rs | 253 -
docs/por/T029-practical-app-demo/task.yaml | 62 -
.../T030-multinode-raft-join-fix/task.yaml | 79 -
.../T031-security-hardening-phase2/task.yaml | 133 -
.../T032-baremetal-provisioning/COMMANDS.md | 922 ---
.../T032-baremetal-provisioning/HARDWARE.md | 898 ---
.../T032-baremetal-provisioning/NETWORK.md | 919 ---
.../T032-baremetal-provisioning/QUICKSTART.md | 529 --
.../T032-baremetal-provisioning/RUNBOOK.md | 2178 ------
.../por/T032-baremetal-provisioning/design.md | 1553 ----
.../diagrams/deployment-flow.md | 492 --
.../diagrams/network-topology.md | 362 -
.../diagrams/service-dependencies.md | 492 --
.../por/T032-baremetal-provisioning/task.yaml | 156 -
docs/por/T033-metricstor/DESIGN.md | 3744 ----------
docs/por/T033-metricstor/E2E_VALIDATION.md | 247 -
docs/por/T033-metricstor/VALIDATION_PLAN.md | 388 -
docs/por/T033-metricstor/task.yaml | 516 --
docs/por/T034-test-drift-fix/task.yaml | 76 -
.../build-all-services.sh | 68 -
docs/por/T035-vm-integration-test/results.md | 85 -
docs/por/T035-vm-integration-test/task.yaml | 86 -
.../vm-all-services.nix | 70 -
.../T036-vm-cluster-deployment/DEPLOYMENT.md | 272 -
.../T036-vm-cluster-deployment/LEARNINGS.md | 244 -
.../certs/ca-cert.pem | 30 -
.../certs/ca-cert.srl | 1 -
.../certs/ca-key.pem | 52 -
.../certs/node01-cert.pem | 30 -
.../certs/node01-csr.pem | 26 -
.../certs/node01-key.pem | 52 -
.../certs/node02-cert.pem | 30 -
.../certs/node02-csr.pem | 26 -
.../certs/node02-key.pem | 52 -
.../certs/node03-cert.pem | 30 -
.../certs/node03-csr.pem | 26 -
.../certs/node03-key.pem | 52 -
.../node01/configuration-simple.nix | 86 -
.../node01/configuration.nix | 140 -
.../node01/disko.nix | 63 -
.../node01/secrets/README.md | 30 -
.../node01/secrets/ca.crt | 30 -
.../node01/secrets/cluster-config.json | 30 -
.../node01/secrets/node01.crt | 30 -
.../node01/secrets/node01.key | 52 -
.../node02/configuration-simple.nix | 86 -
.../node02/configuration.nix | 140 -
.../node02/disko.nix | 63 -
.../node02/secrets/README.md | 30 -
.../node02/secrets/ca.crt | 30 -
.../node02/secrets/cluster-config.json | 30 -
.../node02/secrets/node02.crt | 30 -
.../node02/secrets/node02.key | 52 -
.../node03/configuration-simple.nix | 86 -
.../node03/configuration.nix | 140 -
.../node03/disko.nix | 63 -
.../node03/secrets/README.md | 30 -
.../node03/secrets/ca.crt | 30 -
.../node03/secrets/cluster-config.json | 30 -
.../node03/secrets/node03.crt | 30 -
.../node03/secrets/node03.key | 52 -
docs/por/T036-vm-cluster-deployment/task.yaml | 289 -
docs/por/T037-flaredb-sql-layer/DESIGN.md | 299 -
.../T037-flaredb-sql-layer/IMPLEMENTATION.md | 322 -
.../example-crud/Cargo.toml | 13 -
.../example-crud/README.md | 90 -
.../example-crud/main.rs | 93 -
docs/por/T037-flaredb-sql-layer/task.yaml | 148 -
docs/por/T038-code-drift-cleanup/task.yaml | 105 -
.../S6-integration-test-plan.md | 245 -
docs/por/T039-production-deployment/task.yaml | 287 -
.../s2-raft-resilience-runbook.md | 208 -
.../s3-plasmavmc-ha-runbook.md | 147 -
.../T040-ha-validation/s4-test-scenarios.md | 166 -
docs/por/T040-ha-validation/task.yaml | 217 -
.../openraft-issue.md | 85 -
.../option-c-snapshot-preseed.md | 121 -
.../T041-chainfire-cluster-join-fix/task.yaml | 364 -
docs/por/T042-creditservice/task.yaml | 165 -
docs/por/T043-naming-cleanup/task.yaml | 45 -
docs/por/T044-por-accuracy-fix/task.yaml | 71 -
docs/por/T045-service-integration/task.yaml | 123 -
docs/por/T046-multi-raft-design/design.md | 302 -
docs/por/T046-multi-raft-design/task.yaml | 291 -
docs/por/T047-lightningstor-s3/task.yaml | 150 -
docs/por/T048-sdk-improvements/task.yaml | 83 -
docs/por/T049-component-audit/FINDINGS.md | 98 -
docs/por/T049-component-audit/task.yaml | 204 -
docs/por/T050-rest-api/task.yaml | 515 --
docs/por/T051-fiberlb-integration/task.yaml | 219 -
.../T052-creditservice-persistence/task.yaml | 82 -
docs/por/T052-qemu-cluster-testing/task.yaml | 173 -
.../task.yaml | 114 -
docs/por/T054-plasmavmc-ops/task.yaml | 181 -
.../S2-l7-loadbalancing-spec.md | 808 ---
.../S3-bgp-integration-spec.md | 369 -
docs/por/T055-fiberlb-features/task.yaml | 244 -
docs/por/T056-flashdns-pagination/task.yaml | 79 -
.../S1-ipam-spec.md | 328 -
.../task.yaml | 139 -
docs/por/T058-s3-auth-hardening/task.yaml | 124 -
docs/por/T059-audit-fix/task.yaml | 34 -
docs/por/T060-iam-credentials/task.yaml | 38 -
docs/por/T061-deployer-nixnos/task.yaml | 219 -
docs/por/T062-nix-nos-generic/task.yaml | 191 -
docs/por/VM_CLUSTER_VALIDATION_NOTES.md | 19 -
docs/por/VM_CLUSTER_VALIDATION_PLAN.md | 452 --
docs/por/scope.yaml | 65 -
docs/storage-benchmarks.baseline.md | 107 +
docs/storage-benchmarks.md | 107 +
docs/testing.md | 53 +
examples/mtls-agent-config.toml | 17 -
examples/photoncloud-test-cluster.json | 79 -
fiberlb/Cargo.lock | 1493 +++-
fiberlb/crates/fiberlb-api/Cargo.toml | 1 +
fiberlb/crates/fiberlb-api/build.rs | 3 +
fiberlb/crates/fiberlb-server/Cargo.toml | 7 +
fiberlb/crates/fiberlb-server/src/config.rs | 63 +-
.../crates/fiberlb-server/src/dataplane.rs | 182 +-
.../crates/fiberlb-server/src/healthcheck.rs | 2 +-
.../crates/fiberlb-server/src/l7_dataplane.rs | 204 +-
fiberlb/crates/fiberlb-server/src/main.rs | 311 +-
fiberlb/crates/fiberlb-server/src/metadata.rs | 565 +-
.../fiberlb-server/src/services/backend.rs | 262 +-
.../src/services/certificate.rs | 133 +-
.../src/services/health_check.rs | 105 +-
.../fiberlb-server/src/services/l7_policy.rs | 161 +-
.../fiberlb-server/src/services/l7_rule.rs | 172 +-
.../fiberlb-server/src/services/listener.rs | 260 +-
.../src/services/loadbalancer.rs | 126 +-
.../fiberlb-server/src/services/pool.rs | 201 +-
fiberlb/crates/fiberlb-server/src/tls.rs | 93 +-
.../crates/fiberlb-server/src/vip_manager.rs | 2 +-
.../fiberlb-server/tests/integration.rs | 656 --
flake.nix | 217 +-
flaredb/.specify/memory/constitution.md | 41 -
.../.specify/templates/agent-file-template.md | 28 -
.../.specify/templates/checklist-template.md | 40 -
flaredb/.specify/templates/plan-template.md | 104 -
flaredb/.specify/templates/spec-template.md | 115 -
flaredb/.specify/templates/tasks-template.md | 251 -
flaredb/Cargo.lock | 2 +
flaredb/advice.md | 124 -
flaredb/chat.md | 1935 -----
flaredb/crates/flaredb-client/Cargo.toml | 2 +
.../crates/flaredb-client/examples/basic.rs | 16 -
flaredb/crates/flaredb-client/src/client.rs | 728 +-
flaredb/crates/flaredb-client/src/main.rs | 4 +-
.../crates/flaredb-client/src/region_cache.rs | 17 +
.../flaredb-client/tests/test_rpc_connect.rs | 329 -
flaredb/crates/flaredb-pd/src/main.rs | 2 +-
flaredb/crates/flaredb-raft/src/network.rs | 52 +-
.../flaredb-raft/src/persistent_storage.rs | 24 +
flaredb/crates/flaredb-raft/src/raft_node.rs | 89 +-
flaredb/crates/flaredb-raft/src/storage.rs | 24 +
.../flaredb-server/examples/test_cluster.rs | 69 -
.../crates/flaredb-server/src/config/mod.rs | 23 +-
flaredb/crates/flaredb-server/src/main.rs | 90 +-
.../crates/flaredb-server/src/pd_client.rs | 67 +-
flaredb/crates/flaredb-server/src/rest.rs | 6 +-
flaredb/crates/flaredb-server/src/service.rs | 392 +-
flaredb/crates/flaredb-server/src/store.rs | 4 +
.../flaredb-server/tests/region_failover.rs | 230 -
.../flaredb-server/tests/test_consistency.rs | 209 -
.../flaredb-server/tests/test_multi_region.rs | 132 -
.../crates/flaredb-server/tests/test_split.rs | 85 -
.../tests/test_split_trigger.rs | 53 -
.../flaredb-server/tests/test_strong_mode.rs | 76 -
flaredb/data/CURRENT | 1 -
flaredb/data/IDENTITY | 1 -
flaredb/data/LOCK | 0
flaredb/data/LOG | 587 --
flaredb/data/MANIFEST-000005 | Bin 170 -> 0 bytes
flaredb/data/OPTIONS-000007 | 333 -
flaredb/scripts/verify-core.sh | 14 +-
flaredb/scripts/verify-sharding.sh | 10 +-
.../checklists/requirements.md | 34 -
.../specs/001-distributed-core/data-model.md | 52 -
flaredb/specs/001-distributed-core/plan.md | 95 -
.../specs/001-distributed-core/quickstart.md | 64 -
.../specs/001-distributed-core/research.md | 19 -
flaredb/specs/001-distributed-core/spec.md | 87 -
flaredb/specs/001-distributed-core/tasks.md | 220 -
flaredb/specs/001-multi-raft/spec.md | 115 -
.../checklists/requirements.md | 34 -
.../contracts/raft-service.md | 35 -
flaredb/specs/002-raft-features/data-model.md | 34 -
flaredb/specs/002-raft-features/plan.md | 69 -
flaredb/specs/002-raft-features/quickstart.md | 39 -
flaredb/specs/002-raft-features/research.md | 23 -
flaredb/specs/002-raft-features/spec.md | 92 -
flaredb/specs/002-raft-features/tasks.md | 128 -
.../checklists/requirements.md | 34 -
.../003-kvs-consistency/contracts/kv_cas.md | 29 -
.../003-kvs-consistency/contracts/kv_raw.md | 25 -
.../contracts/raft_service.md | 33 -
.../specs/003-kvs-consistency/data-model.md | 26 -
flaredb/specs/003-kvs-consistency/plan.md | 76 -
.../specs/003-kvs-consistency/quickstart.md | 78 -
flaredb/specs/003-kvs-consistency/research.md | 15 -
flaredb/specs/003-kvs-consistency/spec.md | 88 -
flaredb/specs/003-kvs-consistency/tasks.md | 119 -
.../004-multi-raft/checklists/requirements.md | 34 -
flaredb/specs/004-multi-raft/contracts/pd.md | 36 -
flaredb/specs/004-multi-raft/data-model.md | 45 -
flaredb/specs/004-multi-raft/plan.md | 62 -
flaredb/specs/004-multi-raft/quickstart.md | 44 -
flaredb/specs/004-multi-raft/spec.md | 208 -
flaredb/specs/004-multi-raft/tasks.md | 125 -
flashdns/Cargo.lock | 1064 ++-
flashdns/crates/flashdns-api/Cargo.toml | 1 +
flashdns/crates/flashdns-api/build.rs | 4 +-
flashdns/crates/flashdns-server/Cargo.toml | 2 +
flashdns/crates/flashdns-server/src/config.rs | 59 +-
flashdns/crates/flashdns-server/src/lib.rs | 2 +-
flashdns/crates/flashdns-server/src/main.rs | 235 +-
.../crates/flashdns-server/src/metadata.rs | 412 +-
.../flashdns-server/src/record_service.rs | 147 +-
.../src/reverse_zone_service.rs | 93 +-
.../flashdns-server/src/zone_service.rs | 138 +-
.../flashdns-server/tests/integration.rs | 544 --
.../tests/reverse_dns_integration.rs | 165 -
foreman_to_peer.md | 38 -
foreman_to_peer_latest.md | 17 -
iam/Cargo.lock | 531 +-
iam/Cargo.toml | 2 +
iam/config/iam.example.toml | 24 +-
iam/crates/iam-api/Cargo.toml | 1 +
.../iam-api/src/gateway_auth_service.rs | 42 +-
iam/crates/iam-api/src/iam_service.rs | 124 +-
iam/crates/iam-api/src/lib.rs | 3 +
iam/crates/iam-api/src/token_service.rs | 83 +
.../iam-api/tests/tenant_path_integration.rs | 756 --
iam/crates/iam-authn/src/jwt.rs | 48 +-
iam/crates/iam-authn/src/provider.rs | 90 +-
iam/crates/iam-authn/src/token.rs | 6 +
iam/crates/iam-authz/src/cache.rs | 23 +-
iam/crates/iam-authz/src/evaluator.rs | 119 +-
iam/crates/iam-authz/src/lib.rs | 4 +-
iam/crates/iam-client/examples/basic.rs | 14 -
iam/crates/iam-server/Cargo.toml | 1 +
iam/crates/iam-server/src/config.rs | 118 +-
iam/crates/iam-server/src/main.rs | 311 +-
iam/crates/iam-server/src/rest.rs | 79 +-
iam/crates/iam-service-auth/Cargo.toml | 13 +
iam/crates/iam-service-auth/src/lib.rs | 471 ++
iam/crates/iam-store/Cargo.toml | 1 +
iam/crates/iam-store/src/backend.rs | 918 ++-
iam/crates/iam-store/src/binding_store.rs | 15 +-
iam/crates/iam-store/src/principal_store.rs | 36 +-
iam/crates/iam-store/src/role_store.rs | 8 +-
iam/crates/iam-types/src/resource.rs | 2 +-
iam/crates/iam-types/src/role.rs | 55 +-
k8shost/Cargo.lock | 524 +-
k8shost/T025-S4-COMPLETION-REPORT.md | 270 -
k8shost/crates/k8shost-cni/src/main.rs | 28 +-
k8shost/crates/k8shost-csi/Cargo.toml | 4 +
k8shost/crates/k8shost-server/Cargo.toml | 2 +
k8shost/crates/k8shost-server/src/auth.rs | 232 +-
k8shost/crates/k8shost-server/src/cni.rs | 2 +-
k8shost/crates/k8shost-server/src/config.rs | 19 +-
.../k8shost-server/src/fiberlb_controller.rs | 130 +-
.../k8shost-server/src/flashdns_controller.rs | 193 +-
.../crates/k8shost-server/src/ipam_client.rs | 161 +-
k8shost/crates/k8shost-server/src/main.rs | 137 +-
k8shost/crates/k8shost-server/src/rest.rs | 72 +-
.../k8shost-server/src/services/node.rs | 57 +-
.../crates/k8shost-server/src/services/pod.rs | 124 +-
.../k8shost-server/src/services/service.rs | 116 +-
.../k8shost-server/src/services/tests.rs | 82 +-
.../tests/cni_integration_test.rs | 298 -
.../tests/creditservice_pod_integration.rs | 349 -
.../k8shost-server/tests/integration_test.rs | 523 --
.../k8shost-server/tests/vm_cross_comm.rs | 901 ---
lightningstor/Cargo.lock | 1225 +++-
lightningstor/Cargo.toml | 4 +
.../crates/lightningstor-api/Cargo.toml | 1 +
.../crates/lightningstor-api/build.rs | 5 +-
.../src/backends/erasure_coded.rs | 29 +-
.../src/backends/replicated.rs | 1219 +++-
.../lightningstor-distributed/src/config.rs | 2 +-
.../src/node/client.rs | 548 +-
.../src/node/mock.rs | 4 +-
.../src/node/registry.rs | 37 +-
.../src/placement/mod.rs | 114 +-
.../crates/lightningstor-node/build.rs | 1 +
.../crates/lightningstor-node/src/config.rs | 5 +
.../crates/lightningstor-node/src/main.rs | 32 +-
.../crates/lightningstor-node/src/service.rs | 137 +-
.../crates/lightningstor-node/src/storage.rs | 169 +-
.../crates/lightningstor-server/Cargo.toml | 6 +-
.../src/bucket_service.rs | 88 +-
.../crates/lightningstor-server/src/config.rs | 90 +-
.../crates/lightningstor-server/src/main.rs | 383 +-
.../lightningstor-server/src/metadata.rs | 1034 ++-
.../src/object_service.rs | 962 ++-
.../lightningstor-server/src/s3/auth.rs | 96 +-
.../lightningstor-server/src/s3/router.rs | 123 +-
.../lightningstor-server/tests/integration.rs | 359 -
.../lightningstor-storage/src/local_fs.rs | 130 +-
mtls-agent/src/client.rs | 97 +-
mtls-agent/src/discovery.rs | 41 +-
mtls-agent/src/main.rs | 342 +
mtls-agent/src/policy.rs | 9 +-
nightlight/README.md | 349 -
.../examples/push_metrics.rs | 156 -
.../examples/query_metrics.rs | 157 -
.../nightlight-server/tests/ingestion_test.rs | 331 -
.../tests/integration_test.rs | 199 -
.../nightlight-server/tests/query_test.rs | 204 -
nightlight/tests/integration_test.rs | 263 -
nix-nos/README.md | 165 -
nix-nos/examples/datacenter-node.nix | 55 -
nix-nos/examples/edge-router.nix | 52 -
nix-nos/examples/home-router.nix | 41 -
nix/ci/flake.nix | 64 +-
nix/images/netboot-all-in-one.nix | 2 +-
nix/images/netboot-control-plane.nix | 2 +-
nix/images/netboot-worker.nix | 2 +-
nix/iso/plasmacloud-iso.nix | 141 +-
nix/modules/apigateway.nix | 25 +-
nix/modules/chainfire.nix | 138 +-
nix/modules/cluster-config-lib.nix | 464 ++
nix/modules/coronafs.nix | 152 +
nix/modules/creditservice.nix | 94 +-
nix/modules/default.nix | 5 +
nix/modules/deployer.nix | 301 +
nix/modules/fiberlb.nix | 71 +-
nix/modules/first-boot-automation.nix | 46 +-
nix/modules/flaredb.nix | 147 +-
nix/modules/flashdns.nix | 79 +-
nix/modules/fleet-scheduler.nix | 142 +
nix/modules/iam.nix | 86 +-
nix/modules/k8shost.nix | 76 +-
nix/modules/lightningstor.nix | 329 +-
.../nix-nos/cluster-config-generator.nix | 43 +-
nix/modules/nix-nos/topology.nix | 80 +-
nix/modules/node-agent.nix | 117 +
nix/modules/observability.nix | 30 +-
nix/modules/plasmacloud-cluster.nix | 192 +-
nix/modules/plasmacloud-network.nix | 21 +-
nix/modules/plasmavmc.nix | 221 +-
nix/modules/prismnet.nix | 89 +-
nix/nodes/vm-cluster/node01/configuration.nix | 138 +
nix/nodes/vm-cluster/node01/disko.nix | 33 +
nix/nodes/vm-cluster/node02/configuration.nix | 148 +
nix/nodes/vm-cluster/node02/disko.nix | 33 +
nix/nodes/vm-cluster/node03/configuration.nix | 148 +
nix/nodes/vm-cluster/node03/disko.nix | 33 +
nix/test-cluster/README.md | 91 +
nix/test-cluster/common.nix | 237 +
nix/test-cluster/flake.lock | 156 +
nix/test-cluster/flake.nix | 123 +
nix/test-cluster/nightlight_remote_write.py | 117 +
nix/test-cluster/node01.nix | 168 +
nix/test-cluster/node02.nix | 73 +
nix/test-cluster/node03.nix | 73 +
nix/test-cluster/node04.nix | 64 +
nix/test-cluster/node05.nix | 64 +
nix/test-cluster/node06.nix | 103 +
nix/test-cluster/run-cluster.sh | 6339 +++++++++++++++++
nix/test-cluster/storage-node01.nix | 132 +
nix/test-cluster/storage-node02.nix | 75 +
nix/test-cluster/storage-node03.nix | 75 +
nix/test-cluster/storage-node04.nix | 69 +
nix/test-cluster/storage-node05.nix | 69 +
nix/test-cluster/vm-bench-guest-image.nix | 180 +
nix/test-cluster/vm-guest-image.nix | 148 +
plans/architecture-diagram.mmd | 80 +
.../README.md | 22 +
.../component-clarity-findings.md | 175 +
.../deployment-architecture-findings.md | 156 +
.../issue-register.md | 28 +
.../verification-commands.md | 135 +
...deployment-scheduler-roadmap-2026-03-20.md | 319 +
plans/photoncloud-design-patterns-analysis.md | 635 ++
plans/photoncloud-radical-redesign.md | 1360 ++++
...toncloud-standalone-integration-balance.md | 1124 +++
plasmavmc/Cargo.lock | 521 +-
.../crates/plasmavmc-firecracker/src/lib.rs | 120 +-
.../tests/integration.rs | 113 -
.../plasmavmc-hypervisor/src/backend.rs | 23 +-
plasmavmc/crates/plasmavmc-kvm/src/env.rs | 83 +
plasmavmc/crates/plasmavmc-kvm/src/lib.rs | 753 +-
plasmavmc/crates/plasmavmc-kvm/src/qmp.rs | 135 +-
plasmavmc/crates/plasmavmc-server/Cargo.toml | 6 +
.../plasmavmc-server/src/artifact_store.rs | 973 +++
.../crates/plasmavmc-server/src/config.rs | 50 +-
plasmavmc/crates/plasmavmc-server/src/lib.rs | 3 +-
plasmavmc/crates/plasmavmc-server/src/main.rs | 266 +-
plasmavmc/crates/plasmavmc-server/src/rest.rs | 197 +-
.../crates/plasmavmc-server/src/storage.rs | 775 +-
.../crates/plasmavmc-server/src/vm_service.rs | 3347 ++++++++-
.../plasmavmc-server/src/volume_manager.rs | 940 +++
.../crates/plasmavmc-server/src/watcher.rs | 68 +-
.../plasmavmc-server/tests/common/mod.rs | 165 -
.../tests/creditservice_integration.rs | 304 -
.../tests/flaredb_iam_integration.rs | 987 ---
.../plasmavmc-server/tests/grpc_smoke.rs | 278 -
.../tests/prismnet_integration.rs | 1074 ---
plasmavmc/crates/plasmavmc-types/src/vm.rs | 408 ++
plasmavmc/proto/plasmavmc.proto | 189 +-
prismnet/Cargo.lock | 1429 +++-
prismnet/T022-S2-IMPLEMENTATION-SUMMARY.md | 157 -
prismnet/crates/prismnet-server/Cargo.toml | 3 +
prismnet/crates/prismnet-server/src/config.rs | 63 +-
prismnet/crates/prismnet-server/src/main.rs | 307 +-
.../crates/prismnet-server/src/metadata.rs | 323 +-
.../crates/prismnet-server/src/ovn/client.rs | 8 +-
prismnet/crates/prismnet-server/src/rest.rs | 117 +-
.../prismnet-server/src/services/ipam.rs | 118 +-
.../prismnet-server/src/services/port.rs | 138 +-
.../src/services/security_group.rs | 172 +-
.../prismnet-server/src/services/subnet.rs | 114 +-
.../prismnet-server/src/services/vpc.rs | 108 +-
.../tests/control_plane_integration.rs | 534 --
specifications/TEMPLATE.md | 148 -
specifications/aegis/README.md | 830 ---
specifications/chainfire/README.md | 433 --
specifications/configuration.md | 146 -
specifications/creditservice/spec.md | 378 -
specifications/deployer/README.md | 354 -
specifications/fiberlb/README.md | 1686 -----
.../fiberlb/S2-l7-loadbalancing-spec.md | 808 ---
.../fiberlb/S3-bgp-integration-spec.md | 369 -
.../checklists/requirements.md | 34 -
.../contracts/kvrpc.proto | 55 -
.../001-distributed-core/contracts/pdpb.proto | 56 -
.../001-distributed-core/data-model.md | 52 -
.../flaredb/001-distributed-core/plan.md | 95 -
.../001-distributed-core/quickstart.md | 64 -
.../flaredb/001-distributed-core/research.md | 19 -
.../flaredb/001-distributed-core/spec.md | 87 -
.../flaredb/001-distributed-core/tasks.md | 220 -
specifications/flaredb/001-multi-raft/spec.md | 115 -
.../checklists/requirements.md | 34 -
.../contracts/raft-service.md | 35 -
.../flaredb/002-raft-features/data-model.md | 34 -
.../flaredb/002-raft-features/plan.md | 69 -
.../flaredb/002-raft-features/quickstart.md | 39 -
.../flaredb/002-raft-features/research.md | 23 -
.../flaredb/002-raft-features/spec.md | 92 -
.../flaredb/002-raft-features/tasks.md | 128 -
.../checklists/requirements.md | 34 -
.../003-kvs-consistency/contracts/kv_cas.md | 29 -
.../003-kvs-consistency/contracts/kv_raw.md | 25 -
.../contracts/raft_service.md | 33 -
.../flaredb/003-kvs-consistency/data-model.md | 26 -
.../flaredb/003-kvs-consistency/plan.md | 76 -
.../flaredb/003-kvs-consistency/quickstart.md | 78 -
.../flaredb/003-kvs-consistency/research.md | 15 -
.../flaredb/003-kvs-consistency/spec.md | 88 -
.../flaredb/003-kvs-consistency/tasks.md | 119 -
.../004-multi-raft/checklists/requirements.md | 34 -
.../flaredb/004-multi-raft/contracts/pd.md | 36 -
.../flaredb/004-multi-raft/data-model.md | 45 -
specifications/flaredb/004-multi-raft/plan.md | 62 -
.../flaredb/004-multi-raft/quickstart.md | 44 -
specifications/flaredb/004-multi-raft/spec.md | 208 -
.../flaredb/004-multi-raft/tasks.md | 125 -
specifications/flaredb/README.md | 526 --
specifications/flaredb/sql-layer-design.md | 299 -
specifications/flashdns/README.md | 1166 ---
specifications/k8shost/S1-ipam-spec.md | 328 -
specifications/lightningstor/README.md | 948 ---
specifications/metricstor-design.md | 3744 ----------
specifications/overlay-network/README.md | 744 --
specifications/plasmavmc/README.md | 1017 ---
specifications/rest-api-patterns.md | 363 -
testing/qemu-cluster/README.md | 96 -
.../qemu-cluster/configs/cluster-config.json | 50 -
.../qemu-cluster/scripts/create-base-image.sh | 36 -
.../scripts/deploy-photoncloud.sh | 59 -
testing/qemu-cluster/scripts/start-cluster.sh | 73 -
testing/qemu-cluster/scripts/stop-cluster.sh | 23 -
testing/run-s3-test.sh | 84 -
testing/s3-test.nix | 25 -
tmp_test.txt | 0
tmp_test_write.txt | 1 -
tmp_write_check.txt | 1 -
736 files changed, 62387 insertions(+), 111098 deletions(-)
delete mode 100644 .claude.json
create mode 100644 CONTRIBUTING.md
delete mode 100644 FOREMAN_TASK.md
create mode 100644 LICENSE
create mode 100644 Makefile
delete mode 100644 Nix-NOS.md
delete mode 100644 PROJECT.md
create mode 100644 SECURITY.md
delete mode 100644 T003-architectural-gap-analysis.md
delete mode 100644 TOAGENT.md
delete mode 100644 advice.md
delete mode 100644 baremetal/first-boot/ARCHITECTURE.md
delete mode 100644 baremetal/first-boot/README.md
delete mode 100644 baremetal/first-boot/examples/cluster-config-all-in-one.json
delete mode 100644 baremetal/first-boot/examples/cluster-config-bootstrap.json
delete mode 100644 baremetal/first-boot/examples/cluster-config-join.json
delete mode 100644 baremetal/image-builder/OVERVIEW.md
delete mode 100644 baremetal/image-builder/README.md
delete mode 100644 baremetal/image-builder/examples/custom-netboot.nix
delete mode 100644 baremetal/image-builder/examples/hardware-specific.nix
delete mode 100644 baremetal/vm-cluster/alpine-answers.txt
create mode 100644 baremetal/vm-cluster/legacy/README.md
rename baremetal/vm-cluster/{ => legacy}/alpine-ssh-setup.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/deploy-all.sh (80%)
rename baremetal/vm-cluster/{ => legacy}/launch-node01-disk.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node01-dual.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node01-from-disk.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node01-iso.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node01-netboot.sh (88%)
rename baremetal/vm-cluster/{ => legacy}/launch-node01-vde.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node01.sh (95%)
rename baremetal/vm-cluster/{ => legacy}/launch-node02-alpine.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node02-disk.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node02-from-disk.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node02-iso.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node02-netboot.sh (88%)
rename baremetal/vm-cluster/{ => legacy}/launch-node02-recovery.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node02-vde.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node02.sh (95%)
rename baremetal/vm-cluster/{ => legacy}/launch-node03-disk.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node03-from-disk.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node03-iso.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node03-netboot.sh (88%)
rename baremetal/vm-cluster/{ => legacy}/launch-node03-recovery.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node03-vde.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-node03.sh (95%)
rename baremetal/vm-cluster/{ => legacy}/launch-pxe-server-install.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-pxe-server-iso.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/launch-pxe-server.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/pxe-server-setup.sh (100%)
rename baremetal/vm-cluster/{ => legacy}/validate-cluster.sh (56%)
delete mode 120000 baremetal/vm-cluster/netboot-initrd
delete mode 120000 baremetal/vm-cluster/netboot-kernel
create mode 100755 bin/cloud-cli
delete mode 100644 chainfire/advice.md
delete mode 100644 chainfire/baremetal/pxe-server/OVERVIEW.md
delete mode 100644 chainfire/baremetal/pxe-server/QUICKSTART.md
delete mode 100644 chainfire/baremetal/pxe-server/README.md
delete mode 100644 chainfire/baremetal/pxe-server/examples/nixos-config-examples.nix
delete mode 100644 chainfire/baremetal/pxe-server/http/directory-structure.txt
delete mode 100644 chainfire/baremetal/pxe-server/ipxe/mac-mappings.txt
delete mode 100644 chainfire/chainfire-client/examples/basic.rs
delete mode 100644 chainfire/chainfire-client/examples/cleanup.rs
delete mode 100644 chainfire/crates/chainfire-core/tests/integration.rs
delete mode 100644 chainfire/crates/chainfire-raft/tests/leader_election.rs
delete mode 100644 chainfire/crates/chainfire-raft/tests/proptest_sim.rs
delete mode 100644 chainfire/crates/chainfire-server/tests/cluster_integration.rs
delete mode 100644 chainfire/crates/chainfire-server/tests/integration_test.rs
delete mode 100644 chainfire/data/CURRENT
delete mode 100644 chainfire/data/IDENTITY
delete mode 100644 chainfire/data/LOCK
delete mode 100644 chainfire/data/LOG
delete mode 100644 chainfire/data/MANIFEST-000005
delete mode 100644 chainfire/data/OPTIONS-000007
delete mode 100644 chainfire_t003_gap_analysis.md
create mode 100644 coronafs/Cargo.lock
create mode 100644 coronafs/Cargo.toml
create mode 100644 coronafs/README.md
create mode 100644 coronafs/crates/coronafs-server/Cargo.toml
create mode 100644 coronafs/crates/coronafs-server/src/config.rs
create mode 100644 coronafs/crates/coronafs-server/src/main.rs
create mode 100644 crates/photon-auth-client/Cargo.toml
create mode 100644 crates/photon-auth-client/src/lib.rs
create mode 100644 crates/photon-config/Cargo.toml
create mode 100644 crates/photon-config/src/lib.rs
create mode 100644 crates/photon-runtime/Cargo.toml
create mode 100644 crates/photon-runtime/src/lib.rs
create mode 100644 crates/photon-state/Cargo.toml
create mode 100644 crates/photon-state/src/lib.rs
create mode 100644 creditservice/README.md
delete mode 100644 creditservice/crates/creditservice-api/src/chainfire_storage.rs
create mode 100644 creditservice/crates/creditservice-api/src/flaredb_storage.rs
create mode 100644 creditservice/crates/creditservice-api/src/sql_storage.rs
create mode 100644 creditservice/crates/creditservice-server/src/config.rs
delete mode 100644 creditservice/crates/creditservice-server/tests/mtls_integration.rs
delete mode 100644 creditservice/creditservice-client/examples/basic.rs
delete mode 100644 creditservice/creditservice-client/examples/builder.rs
delete mode 100644 data/CURRENT
delete mode 100644 data/IDENTITY
delete mode 100644 data/LOCK
delete mode 100644 data/LOG
delete mode 100644 data/MANIFEST-000005
delete mode 100644 data/OPTIONS-000007
delete mode 100644 deployer/crates/deployer-ctl/src/model.rs
create mode 100644 deployer/crates/deployer-server/src/auth.rs
create mode 100644 deployer/crates/deployer-server/src/cloud_init.rs
create mode 100644 deployer/crates/deployer-server/src/cluster.rs
create mode 100644 deployer/crates/deployer-server/src/local_storage.rs
create mode 100644 deployer/crates/deployer-server/src/tls.rs
create mode 100644 deployer/crates/deployer-server/src/validation.rs
create mode 100644 deployer/crates/fleet-scheduler/Cargo.toml
create mode 100644 deployer/crates/fleet-scheduler/src/auth.rs
create mode 100644 deployer/crates/fleet-scheduler/src/main.rs
create mode 100644 deployer/crates/fleet-scheduler/src/publish.rs
create mode 100755 deployer/scripts/verify-deployer-bootstrap-e2e.sh
create mode 100755 deployer/scripts/verify-fleet-scheduler-e2e.sh
delete mode 100644 dev-certs/ca/ca.crt
delete mode 100644 dev-certs/ca/ca.key
delete mode 100644 dev-certs/ca/ca.srl
delete mode 100644 dev-certs/chainfire/server.crt
delete mode 100644 dev-certs/chainfire/server.key
delete mode 100644 dev-certs/flaredb/server.crt
delete mode 100644 dev-certs/flaredb/server.key
delete mode 100644 dev-certs/iam/server.crt
delete mode 100644 dev-certs/iam/server.key
delete mode 100644 docs/Nix-NOS.md
delete mode 100644 docs/README-dependency-graphs.md
create mode 100644 docs/README.md
delete mode 100644 docs/api/rest-api-guide.md
delete mode 100644 docs/architecture/api-gateway.md
delete mode 100644 docs/architecture/baremetal-mesh-migration.md
delete mode 100644 docs/architecture/mvp-beta-tenant-path.md
delete mode 100644 docs/benchmarks/storage-layer-baseline.md
delete mode 100644 docs/cert-authority-usage.md
delete mode 100644 docs/component-dependencies-detailed.dot
delete mode 100644 docs/component-dependencies.dot
create mode 100644 docs/component-matrix.md
delete mode 100644 docs/deployment/bare-metal.md
delete mode 100644 docs/evidence/first-boot-automation-20251220-050900/cluster-config.json
delete mode 100644 docs/evidence/first-boot-automation-20251220-050900/test.nix
delete mode 100644 docs/evidence/first-boot-automation-cluster-config.txt
delete mode 100644 docs/getting-started/tenant-onboarding.md
delete mode 100644 docs/implementation-status.md
delete mode 100644 docs/implementation-summary.md
delete mode 100644 docs/nixos-deployment-challenges.md
delete mode 100644 docs/ops/backup-restore.md
delete mode 100644 docs/ops/ha-behavior.md
delete mode 100644 docs/ops/integration-matrix.md
delete mode 100644 docs/ops/nested-kvm-setup.md
delete mode 100644 docs/ops/qcow2-artifact-plan.md
delete mode 100644 docs/ops/scale-out.md
delete mode 100644 docs/ops/troubleshooting.md
delete mode 100644 docs/ops/upgrade.md
delete mode 100644 docs/plans/chainfire_architecture_redefinition.md
delete mode 100644 docs/plans/metadata_unification.md
delete mode 100644 docs/por/POR.md
delete mode 100644 docs/por/T001-stabilize-tests/task.yaml
delete mode 100644 docs/por/T002-specifications/task.yaml
delete mode 100644 docs/por/T003-feature-gaps/T003-report.md
delete mode 100644 docs/por/T003-feature-gaps/chainfire-gaps.md
delete mode 100644 docs/por/T003-feature-gaps/flaredb-gaps.md
delete mode 100644 docs/por/T003-feature-gaps/iam-gaps.md
delete mode 100644 docs/por/T003-feature-gaps/task.yaml
delete mode 100644 docs/por/T004-p0-fixes/task.yaml
delete mode 100644 docs/por/T005-plasmavmc-spec/task.yaml
delete mode 100644 docs/por/T006-p1-features/task.yaml
delete mode 100644 docs/por/T007-plasmavmc-impl/task.yaml
delete mode 100644 docs/por/T008-lightningstor/task.yaml
delete mode 100644 docs/por/T009-flashdns/task.yaml
delete mode 100644 docs/por/T010-fiberlb/task.yaml
delete mode 100644 docs/por/T011-plasmavmc-deepening/task.yaml
delete mode 100644 docs/por/T012-vm-tenancy-persistence/task.yaml
delete mode 100644 docs/por/T013-vm-chainfire-persistence/schema.md
delete mode 100644 docs/por/T013-vm-chainfire-persistence/task.yaml
delete mode 100644 docs/por/T014-plasmavmc-firecracker/config-schema.md
delete mode 100644 docs/por/T014-plasmavmc-firecracker/design.md
delete mode 100644 docs/por/T014-plasmavmc-firecracker/integration-test-evidence.md
delete mode 100644 docs/por/T014-plasmavmc-firecracker/task.yaml
delete mode 100644 docs/por/T015-overlay-networking/plasmavmc-integration.md
delete mode 100644 docs/por/T015-overlay-networking/research-summary.md
delete mode 100644 docs/por/T015-overlay-networking/task.yaml
delete mode 100644 docs/por/T015-overlay-networking/tenant-network-model.md
delete mode 100644 docs/por/T016-lightningstor-deepening/task.yaml
delete mode 100644 docs/por/T017-flashdns-deepening/task.yaml
delete mode 100644 docs/por/T018-fiberlb-deepening/task.yaml
delete mode 100644 docs/por/T019-overlay-network-implementation/task.yaml
delete mode 100644 docs/por/T020-flaredb-metadata/design.md
delete mode 100644 docs/por/T020-flaredb-metadata/task.yaml
delete mode 100644 docs/por/T021-flashdns-parity/design.md
delete mode 100644 docs/por/T021-flashdns-parity/task.yaml
delete mode 100644 docs/por/T022-novanet-control-plane/task.yaml
delete mode 100644 docs/por/T023-e2e-tenant-path/SUMMARY.md
delete mode 100644 docs/por/T023-e2e-tenant-path/e2e_test.md
delete mode 100644 docs/por/T023-e2e-tenant-path/task.yaml
delete mode 100644 docs/por/T024-nixos-packaging/task.yaml
delete mode 100644 docs/por/T025-k8s-hosting/research.md
delete mode 100644 docs/por/T025-k8s-hosting/spec.md
delete mode 100644 docs/por/T025-k8s-hosting/task.yaml
delete mode 100644 docs/por/T026-practical-test/task.yaml
delete mode 100644 docs/por/T027-production-hardening/task.yaml
delete mode 100644 docs/por/T028-feature-completion/task.yaml
delete mode 100644 docs/por/T029-comprehensive-integration-tests/task.yaml
delete mode 100644 docs/por/T029-practical-app-demo/Cargo.lock
delete mode 100644 docs/por/T029-practical-app-demo/Cargo.toml
delete mode 100644 docs/por/T029-practical-app-demo/README.md
delete mode 100644 docs/por/T029-practical-app-demo/e2e-test-results.md
delete mode 100644 docs/por/T029-practical-app-demo/results.md
delete mode 100644 docs/por/T029-practical-app-demo/src/main.rs
delete mode 100644 docs/por/T029-practical-app-demo/task.yaml
delete mode 100644 docs/por/T030-multinode-raft-join-fix/task.yaml
delete mode 100644 docs/por/T031-security-hardening-phase2/task.yaml
delete mode 100644 docs/por/T032-baremetal-provisioning/COMMANDS.md
delete mode 100644 docs/por/T032-baremetal-provisioning/HARDWARE.md
delete mode 100644 docs/por/T032-baremetal-provisioning/NETWORK.md
delete mode 100644 docs/por/T032-baremetal-provisioning/QUICKSTART.md
delete mode 100644 docs/por/T032-baremetal-provisioning/RUNBOOK.md
delete mode 100644 docs/por/T032-baremetal-provisioning/design.md
delete mode 100644 docs/por/T032-baremetal-provisioning/diagrams/deployment-flow.md
delete mode 100644 docs/por/T032-baremetal-provisioning/diagrams/network-topology.md
delete mode 100644 docs/por/T032-baremetal-provisioning/diagrams/service-dependencies.md
delete mode 100644 docs/por/T032-baremetal-provisioning/task.yaml
delete mode 100644 docs/por/T033-metricstor/DESIGN.md
delete mode 100644 docs/por/T033-metricstor/E2E_VALIDATION.md
delete mode 100644 docs/por/T033-metricstor/VALIDATION_PLAN.md
delete mode 100644 docs/por/T033-metricstor/task.yaml
delete mode 100644 docs/por/T034-test-drift-fix/task.yaml
delete mode 100755 docs/por/T035-vm-integration-test/build-all-services.sh
delete mode 100644 docs/por/T035-vm-integration-test/results.md
delete mode 100644 docs/por/T035-vm-integration-test/task.yaml
delete mode 100644 docs/por/T035-vm-integration-test/vm-all-services.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/DEPLOYMENT.md
delete mode 100644 docs/por/T036-vm-cluster-deployment/LEARNINGS.md
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/ca-cert.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/ca-cert.srl
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/ca-key.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/node01-cert.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/node01-csr.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/node01-key.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/node02-cert.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/node02-csr.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/node02-key.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/node03-cert.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/node03-csr.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/certs/node03-key.pem
delete mode 100644 docs/por/T036-vm-cluster-deployment/node01/configuration-simple.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/node01/configuration.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/node01/disko.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/node01/secrets/README.md
delete mode 100644 docs/por/T036-vm-cluster-deployment/node01/secrets/ca.crt
delete mode 100644 docs/por/T036-vm-cluster-deployment/node01/secrets/cluster-config.json
delete mode 100644 docs/por/T036-vm-cluster-deployment/node01/secrets/node01.crt
delete mode 100644 docs/por/T036-vm-cluster-deployment/node01/secrets/node01.key
delete mode 100644 docs/por/T036-vm-cluster-deployment/node02/configuration-simple.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/node02/configuration.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/node02/disko.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/node02/secrets/README.md
delete mode 100644 docs/por/T036-vm-cluster-deployment/node02/secrets/ca.crt
delete mode 100644 docs/por/T036-vm-cluster-deployment/node02/secrets/cluster-config.json
delete mode 100644 docs/por/T036-vm-cluster-deployment/node02/secrets/node02.crt
delete mode 100644 docs/por/T036-vm-cluster-deployment/node02/secrets/node02.key
delete mode 100644 docs/por/T036-vm-cluster-deployment/node03/configuration-simple.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/node03/configuration.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/node03/disko.nix
delete mode 100644 docs/por/T036-vm-cluster-deployment/node03/secrets/README.md
delete mode 100644 docs/por/T036-vm-cluster-deployment/node03/secrets/ca.crt
delete mode 100644 docs/por/T036-vm-cluster-deployment/node03/secrets/cluster-config.json
delete mode 100644 docs/por/T036-vm-cluster-deployment/node03/secrets/node03.crt
delete mode 100644 docs/por/T036-vm-cluster-deployment/node03/secrets/node03.key
delete mode 100644 docs/por/T036-vm-cluster-deployment/task.yaml
delete mode 100644 docs/por/T037-flaredb-sql-layer/DESIGN.md
delete mode 100644 docs/por/T037-flaredb-sql-layer/IMPLEMENTATION.md
delete mode 100644 docs/por/T037-flaredb-sql-layer/example-crud/Cargo.toml
delete mode 100644 docs/por/T037-flaredb-sql-layer/example-crud/README.md
delete mode 100644 docs/por/T037-flaredb-sql-layer/example-crud/main.rs
delete mode 100644 docs/por/T037-flaredb-sql-layer/task.yaml
delete mode 100644 docs/por/T038-code-drift-cleanup/task.yaml
delete mode 100644 docs/por/T039-production-deployment/S6-integration-test-plan.md
delete mode 100644 docs/por/T039-production-deployment/task.yaml
delete mode 100644 docs/por/T040-ha-validation/s2-raft-resilience-runbook.md
delete mode 100644 docs/por/T040-ha-validation/s3-plasmavmc-ha-runbook.md
delete mode 100644 docs/por/T040-ha-validation/s4-test-scenarios.md
delete mode 100644 docs/por/T040-ha-validation/task.yaml
delete mode 100644 docs/por/T041-chainfire-cluster-join-fix/openraft-issue.md
delete mode 100644 docs/por/T041-chainfire-cluster-join-fix/option-c-snapshot-preseed.md
delete mode 100644 docs/por/T041-chainfire-cluster-join-fix/task.yaml
delete mode 100644 docs/por/T042-creditservice/task.yaml
delete mode 100644 docs/por/T043-naming-cleanup/task.yaml
delete mode 100644 docs/por/T044-por-accuracy-fix/task.yaml
delete mode 100644 docs/por/T045-service-integration/task.yaml
delete mode 100644 docs/por/T046-multi-raft-design/design.md
delete mode 100644 docs/por/T046-multi-raft-design/task.yaml
delete mode 100644 docs/por/T047-lightningstor-s3/task.yaml
delete mode 100644 docs/por/T048-sdk-improvements/task.yaml
delete mode 100644 docs/por/T049-component-audit/FINDINGS.md
delete mode 100644 docs/por/T049-component-audit/task.yaml
delete mode 100644 docs/por/T050-rest-api/task.yaml
delete mode 100644 docs/por/T051-fiberlb-integration/task.yaml
delete mode 100644 docs/por/T052-creditservice-persistence/task.yaml
delete mode 100644 docs/por/T052-qemu-cluster-testing/task.yaml
delete mode 100644 docs/por/T053-chainfire-core-finalization/task.yaml
delete mode 100644 docs/por/T054-plasmavmc-ops/task.yaml
delete mode 100644 docs/por/T055-fiberlb-features/S2-l7-loadbalancing-spec.md
delete mode 100644 docs/por/T055-fiberlb-features/S3-bgp-integration-spec.md
delete mode 100644 docs/por/T055-fiberlb-features/task.yaml
delete mode 100644 docs/por/T056-flashdns-pagination/task.yaml
delete mode 100644 docs/por/T057-k8shost-resource-management/S1-ipam-spec.md
delete mode 100644 docs/por/T057-k8shost-resource-management/task.yaml
delete mode 100644 docs/por/T058-s3-auth-hardening/task.yaml
delete mode 100644 docs/por/T059-audit-fix/task.yaml
delete mode 100644 docs/por/T060-iam-credentials/task.yaml
delete mode 100644 docs/por/T061-deployer-nixnos/task.yaml
delete mode 100644 docs/por/T062-nix-nos-generic/task.yaml
delete mode 100644 docs/por/VM_CLUSTER_VALIDATION_NOTES.md
delete mode 100644 docs/por/VM_CLUSTER_VALIDATION_PLAN.md
delete mode 100644 docs/por/scope.yaml
create mode 100644 docs/storage-benchmarks.baseline.md
create mode 100644 docs/storage-benchmarks.md
create mode 100644 docs/testing.md
delete mode 100644 examples/mtls-agent-config.toml
delete mode 100644 examples/photoncloud-test-cluster.json
delete mode 100644 fiberlb/crates/fiberlb-server/tests/integration.rs
delete mode 100644 flaredb/.specify/memory/constitution.md
delete mode 100644 flaredb/.specify/templates/agent-file-template.md
delete mode 100644 flaredb/.specify/templates/checklist-template.md
delete mode 100644 flaredb/.specify/templates/plan-template.md
delete mode 100644 flaredb/.specify/templates/spec-template.md
delete mode 100644 flaredb/.specify/templates/tasks-template.md
delete mode 100644 flaredb/advice.md
delete mode 100644 flaredb/chat.md
delete mode 100644 flaredb/crates/flaredb-client/examples/basic.rs
delete mode 100644 flaredb/crates/flaredb-client/tests/test_rpc_connect.rs
delete mode 100644 flaredb/crates/flaredb-server/examples/test_cluster.rs
delete mode 100644 flaredb/crates/flaredb-server/tests/region_failover.rs
delete mode 100644 flaredb/crates/flaredb-server/tests/test_consistency.rs
delete mode 100644 flaredb/crates/flaredb-server/tests/test_multi_region.rs
delete mode 100644 flaredb/crates/flaredb-server/tests/test_split.rs
delete mode 100644 flaredb/crates/flaredb-server/tests/test_split_trigger.rs
delete mode 100644 flaredb/crates/flaredb-server/tests/test_strong_mode.rs
delete mode 100644 flaredb/data/CURRENT
delete mode 100644 flaredb/data/IDENTITY
delete mode 100644 flaredb/data/LOCK
delete mode 100644 flaredb/data/LOG
delete mode 100644 flaredb/data/MANIFEST-000005
delete mode 100644 flaredb/data/OPTIONS-000007
delete mode 100644 flaredb/specs/001-distributed-core/checklists/requirements.md
delete mode 100644 flaredb/specs/001-distributed-core/data-model.md
delete mode 100644 flaredb/specs/001-distributed-core/plan.md
delete mode 100644 flaredb/specs/001-distributed-core/quickstart.md
delete mode 100644 flaredb/specs/001-distributed-core/research.md
delete mode 100644 flaredb/specs/001-distributed-core/spec.md
delete mode 100644 flaredb/specs/001-distributed-core/tasks.md
delete mode 100644 flaredb/specs/001-multi-raft/spec.md
delete mode 100644 flaredb/specs/002-raft-features/checklists/requirements.md
delete mode 100644 flaredb/specs/002-raft-features/contracts/raft-service.md
delete mode 100644 flaredb/specs/002-raft-features/data-model.md
delete mode 100644 flaredb/specs/002-raft-features/plan.md
delete mode 100644 flaredb/specs/002-raft-features/quickstart.md
delete mode 100644 flaredb/specs/002-raft-features/research.md
delete mode 100644 flaredb/specs/002-raft-features/spec.md
delete mode 100644 flaredb/specs/002-raft-features/tasks.md
delete mode 100644 flaredb/specs/003-kvs-consistency/checklists/requirements.md
delete mode 100644 flaredb/specs/003-kvs-consistency/contracts/kv_cas.md
delete mode 100644 flaredb/specs/003-kvs-consistency/contracts/kv_raw.md
delete mode 100644 flaredb/specs/003-kvs-consistency/contracts/raft_service.md
delete mode 100644 flaredb/specs/003-kvs-consistency/data-model.md
delete mode 100644 flaredb/specs/003-kvs-consistency/plan.md
delete mode 100644 flaredb/specs/003-kvs-consistency/quickstart.md
delete mode 100644 flaredb/specs/003-kvs-consistency/research.md
delete mode 100644 flaredb/specs/003-kvs-consistency/spec.md
delete mode 100644 flaredb/specs/003-kvs-consistency/tasks.md
delete mode 100644 flaredb/specs/004-multi-raft/checklists/requirements.md
delete mode 100644 flaredb/specs/004-multi-raft/contracts/pd.md
delete mode 100644 flaredb/specs/004-multi-raft/data-model.md
delete mode 100644 flaredb/specs/004-multi-raft/plan.md
delete mode 100644 flaredb/specs/004-multi-raft/quickstart.md
delete mode 100644 flaredb/specs/004-multi-raft/spec.md
delete mode 100644 flaredb/specs/004-multi-raft/tasks.md
delete mode 100644 flashdns/crates/flashdns-server/tests/integration.rs
delete mode 100644 flashdns/crates/flashdns-server/tests/reverse_dns_integration.rs
delete mode 100644 foreman_to_peer.md
delete mode 100644 foreman_to_peer_latest.md
delete mode 100644 iam/crates/iam-api/tests/tenant_path_integration.rs
delete mode 100644 iam/crates/iam-client/examples/basic.rs
create mode 100644 iam/crates/iam-service-auth/Cargo.toml
create mode 100644 iam/crates/iam-service-auth/src/lib.rs
delete mode 100644 k8shost/T025-S4-COMPLETION-REPORT.md
delete mode 100644 k8shost/crates/k8shost-server/tests/cni_integration_test.rs
delete mode 100644 k8shost/crates/k8shost-server/tests/creditservice_pod_integration.rs
delete mode 100644 k8shost/crates/k8shost-server/tests/integration_test.rs
delete mode 100644 k8shost/crates/k8shost-server/tests/vm_cross_comm.rs
delete mode 100644 lightningstor/crates/lightningstor-server/tests/integration.rs
delete mode 100644 nightlight/README.md
delete mode 100644 nightlight/crates/nightlight-server/examples/push_metrics.rs
delete mode 100644 nightlight/crates/nightlight-server/examples/query_metrics.rs
delete mode 100644 nightlight/crates/nightlight-server/tests/ingestion_test.rs
delete mode 100644 nightlight/crates/nightlight-server/tests/integration_test.rs
delete mode 100644 nightlight/crates/nightlight-server/tests/query_test.rs
delete mode 100644 nightlight/tests/integration_test.rs
delete mode 100644 nix-nos/README.md
delete mode 100644 nix-nos/examples/datacenter-node.nix
delete mode 100644 nix-nos/examples/edge-router.nix
delete mode 100644 nix-nos/examples/home-router.nix
create mode 100644 nix/modules/cluster-config-lib.nix
create mode 100644 nix/modules/coronafs.nix
create mode 100644 nix/modules/deployer.nix
create mode 100644 nix/modules/fleet-scheduler.nix
create mode 100644 nix/modules/node-agent.nix
create mode 100644 nix/nodes/vm-cluster/node01/configuration.nix
create mode 100644 nix/nodes/vm-cluster/node01/disko.nix
create mode 100644 nix/nodes/vm-cluster/node02/configuration.nix
create mode 100644 nix/nodes/vm-cluster/node02/disko.nix
create mode 100644 nix/nodes/vm-cluster/node03/configuration.nix
create mode 100644 nix/nodes/vm-cluster/node03/disko.nix
create mode 100644 nix/test-cluster/README.md
create mode 100644 nix/test-cluster/common.nix
create mode 100644 nix/test-cluster/flake.lock
create mode 100644 nix/test-cluster/flake.nix
create mode 100644 nix/test-cluster/nightlight_remote_write.py
create mode 100644 nix/test-cluster/node01.nix
create mode 100644 nix/test-cluster/node02.nix
create mode 100644 nix/test-cluster/node03.nix
create mode 100644 nix/test-cluster/node04.nix
create mode 100644 nix/test-cluster/node05.nix
create mode 100644 nix/test-cluster/node06.nix
create mode 100755 nix/test-cluster/run-cluster.sh
create mode 100644 nix/test-cluster/storage-node01.nix
create mode 100644 nix/test-cluster/storage-node02.nix
create mode 100644 nix/test-cluster/storage-node03.nix
create mode 100644 nix/test-cluster/storage-node04.nix
create mode 100644 nix/test-cluster/storage-node05.nix
create mode 100644 nix/test-cluster/vm-bench-guest-image.nix
create mode 100644 nix/test-cluster/vm-guest-image.nix
create mode 100644 plans/architecture-diagram.mmd
create mode 100644 plans/cluster-investigation-2026-03-02/README.md
create mode 100644 plans/cluster-investigation-2026-03-02/component-clarity-findings.md
create mode 100644 plans/cluster-investigation-2026-03-02/deployment-architecture-findings.md
create mode 100644 plans/cluster-investigation-2026-03-02/issue-register.md
create mode 100644 plans/cluster-investigation-2026-03-02/verification-commands.md
create mode 100644 plans/nixos-deployment-scheduler-roadmap-2026-03-20.md
create mode 100644 plans/photoncloud-design-patterns-analysis.md
create mode 100644 plans/photoncloud-radical-redesign.md
create mode 100644 plans/photoncloud-standalone-integration-balance.md
delete mode 100644 plasmavmc/crates/plasmavmc-firecracker/tests/integration.rs
create mode 100644 plasmavmc/crates/plasmavmc-server/src/artifact_store.rs
create mode 100644 plasmavmc/crates/plasmavmc-server/src/volume_manager.rs
delete mode 100644 plasmavmc/crates/plasmavmc-server/tests/common/mod.rs
delete mode 100644 plasmavmc/crates/plasmavmc-server/tests/creditservice_integration.rs
delete mode 100644 plasmavmc/crates/plasmavmc-server/tests/flaredb_iam_integration.rs
delete mode 100644 plasmavmc/crates/plasmavmc-server/tests/grpc_smoke.rs
delete mode 100644 plasmavmc/crates/plasmavmc-server/tests/prismnet_integration.rs
delete mode 100644 prismnet/T022-S2-IMPLEMENTATION-SUMMARY.md
delete mode 100644 prismnet/crates/prismnet-server/tests/control_plane_integration.rs
delete mode 100644 specifications/TEMPLATE.md
delete mode 100644 specifications/aegis/README.md
delete mode 100644 specifications/chainfire/README.md
delete mode 100644 specifications/configuration.md
delete mode 100644 specifications/creditservice/spec.md
delete mode 100644 specifications/deployer/README.md
delete mode 100644 specifications/fiberlb/README.md
delete mode 100644 specifications/fiberlb/S2-l7-loadbalancing-spec.md
delete mode 100644 specifications/fiberlb/S3-bgp-integration-spec.md
delete mode 100644 specifications/flaredb/001-distributed-core/checklists/requirements.md
delete mode 100644 specifications/flaredb/001-distributed-core/contracts/kvrpc.proto
delete mode 100644 specifications/flaredb/001-distributed-core/contracts/pdpb.proto
delete mode 100644 specifications/flaredb/001-distributed-core/data-model.md
delete mode 100644 specifications/flaredb/001-distributed-core/plan.md
delete mode 100644 specifications/flaredb/001-distributed-core/quickstart.md
delete mode 100644 specifications/flaredb/001-distributed-core/research.md
delete mode 100644 specifications/flaredb/001-distributed-core/spec.md
delete mode 100644 specifications/flaredb/001-distributed-core/tasks.md
delete mode 100644 specifications/flaredb/001-multi-raft/spec.md
delete mode 100644 specifications/flaredb/002-raft-features/checklists/requirements.md
delete mode 100644 specifications/flaredb/002-raft-features/contracts/raft-service.md
delete mode 100644 specifications/flaredb/002-raft-features/data-model.md
delete mode 100644 specifications/flaredb/002-raft-features/plan.md
delete mode 100644 specifications/flaredb/002-raft-features/quickstart.md
delete mode 100644 specifications/flaredb/002-raft-features/research.md
delete mode 100644 specifications/flaredb/002-raft-features/spec.md
delete mode 100644 specifications/flaredb/002-raft-features/tasks.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/checklists/requirements.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/contracts/kv_cas.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/contracts/kv_raw.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/contracts/raft_service.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/data-model.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/plan.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/quickstart.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/research.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/spec.md
delete mode 100644 specifications/flaredb/003-kvs-consistency/tasks.md
delete mode 100644 specifications/flaredb/004-multi-raft/checklists/requirements.md
delete mode 100644 specifications/flaredb/004-multi-raft/contracts/pd.md
delete mode 100644 specifications/flaredb/004-multi-raft/data-model.md
delete mode 100644 specifications/flaredb/004-multi-raft/plan.md
delete mode 100644 specifications/flaredb/004-multi-raft/quickstart.md
delete mode 100644 specifications/flaredb/004-multi-raft/spec.md
delete mode 100644 specifications/flaredb/004-multi-raft/tasks.md
delete mode 100644 specifications/flaredb/README.md
delete mode 100644 specifications/flaredb/sql-layer-design.md
delete mode 100644 specifications/flashdns/README.md
delete mode 100644 specifications/k8shost/S1-ipam-spec.md
delete mode 100644 specifications/lightningstor/README.md
delete mode 100644 specifications/metricstor-design.md
delete mode 100644 specifications/overlay-network/README.md
delete mode 100644 specifications/plasmavmc/README.md
delete mode 100644 specifications/rest-api-patterns.md
delete mode 100644 testing/qemu-cluster/README.md
delete mode 100644 testing/qemu-cluster/configs/cluster-config.json
delete mode 100755 testing/qemu-cluster/scripts/create-base-image.sh
delete mode 100755 testing/qemu-cluster/scripts/deploy-photoncloud.sh
delete mode 100755 testing/qemu-cluster/scripts/start-cluster.sh
delete mode 100755 testing/qemu-cluster/scripts/stop-cluster.sh
delete mode 100644 testing/run-s3-test.sh
delete mode 100644 testing/s3-test.nix
delete mode 100644 tmp_test.txt
delete mode 100644 tmp_test_write.txt
delete mode 100644 tmp_write_check.txt
diff --git a/.claude.json b/.claude.json
deleted file mode 100644
index e69de29..0000000
diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml
index 65240be..c8354ae 100644
--- a/.github/workflows/nix.yml
+++ b/.github/workflows/nix.yml
@@ -14,6 +14,7 @@ jobs:
workspaces: ${{ steps.filter.outputs.changes }}
any_changed: ${{ steps.filter.outputs.workspaces_any_changed }}
global_changed: ${{ steps.filter.outputs.global }}
+ shared_crates_changed: ${{ steps.filter.outputs.shared_crates }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
@@ -24,9 +25,17 @@ jobs:
- 'flake.nix'
- 'flake.lock'
- 'nix/**'
+ - 'nix-nos/**'
- '.github/workflows/nix.yml'
- 'Cargo.toml'
- 'Cargo.lock'
+ - 'crates/**'
+ - 'client-common/**'
+ - 'baremetal/**'
+ - 'scripts/**'
+ - 'specifications/**'
+ - 'docs/**'
+ shared_crates: 'crates/**'
chainfire: 'chainfire/**'
flaredb: 'flaredb/**'
iam: 'iam/**'
@@ -60,7 +69,21 @@ jobs:
- name: Run PhotonCloud Gate
run: |
- nix run .#gate-ci -- --workspace ${{ matrix.workspace }} --tier 0 --no-logs
+ nix run ./nix/ci#gate-ci -- --workspace ${{ matrix.workspace }} --tier 0 --no-logs
+
+ shared-crates-gate:
+ needs: filter
+ if: ${{ needs.filter.outputs.shared_crates_changed == 'true' }}
+ runs-on: ubuntu-latest
+ name: gate (shared crates)
+ steps:
+ - uses: actions/checkout@v4
+ - uses: DeterminateSystems/nix-installer-action@v11
+ - uses: DeterminateSystems/magic-nix-cache-action@v8
+
+ - name: Run Shared Crates Gate
+ run: |
+ nix run ./nix/ci#gate-ci -- --shared-crates --tier 0 --no-logs
# Build server packages (tier 1+)
build:
@@ -88,7 +111,7 @@ jobs:
# Summary job for PR status checks
ci-status:
- needs: [filter, gate]
+ needs: [filter, gate, shared-crates-gate]
if: always()
runs-on: ubuntu-latest
steps:
@@ -97,10 +120,19 @@ jobs:
if [[ "${{ needs.gate.result }}" == "failure" ]]; then
exit 1
fi
+ if [[ "${{ needs.shared-crates-gate.result }}" == "failure" ]]; then
+ exit 1
+ fi
if [[ "${{ needs.filter.outputs.any_changed }}" == "true" || "${{ needs.filter.outputs.global_changed }}" == "true" ]]; then
if [[ "${{ needs.gate.result }}" == "skipped" ]]; then
echo "Gate was skipped despite changes. This is unexpected."
exit 1
fi
fi
+ if [[ "${{ needs.filter.outputs.shared_crates_changed }}" == "true" ]]; then
+ if [[ "${{ needs.shared-crates-gate.result }}" == "skipped" ]]; then
+ echo "Shared crates gate was skipped despite crates/** changes. This is unexpected."
+ exit 1
+ fi
+ fi
echo "CI passed or was correctly skipped."
diff --git a/.gitignore b/.gitignore
index fa8a172..fa11ae8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,10 @@
# Claude Code
.cccc/
+.code/
+.codex/
+.claude.json
+.ralphrc
+.sisyphus/
# Rust
target/
@@ -9,6 +14,7 @@ target/
# Nix
result
result-*
+plasmavmc/result
# local CI artifacts
work/
@@ -33,6 +39,8 @@ Thumbs.db
# Logs
*.log
+quanta/test_output_renamed.log
+plasmavmc/kvm_test_output.log
# VM disk images and ISOs (large binary files)
**/*.qcow2
@@ -54,3 +62,13 @@ flaredb/repomix-output.xml
# Temporary files
*.tmp
*.bak
+tmp_test.txt
+tmp_test_write.txt
+tmp_write_check.txt
+
+# Runtime state
+data/
+chainfire/data/
+flaredb/data/
+creditservice/.tmp/
+nightlight/.tmp/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..c701f62
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,27 @@
+# Contributing
+
+PhotonCloud uses Nix as the primary development and validation entrypoint.
+
+## Setup
+
+```bash
+nix develop
+```
+
+## Before sending changes
+
+Run the strongest local validation you can afford.
+
+```bash
+nix run ./nix/test-cluster#cluster -- fresh-smoke
+```
+
+For smaller changes, use the narrower commands under `nix/test-cluster`.
+
+## Expectations
+
+- keep service startup on file-first `--config` paths
+- prefer Nix-native workflows over ad hoc host scripts
+- do not commit secrets, private keys, runtime state, or generated disk images
+- document new validation entrypoints in `README.md` or `docs/`
+- when changing multi-node behavior, validate on the VM cluster rather than only with unit tests
diff --git a/FOREMAN_TASK.md b/FOREMAN_TASK.md
deleted file mode 100644
index 836d105..0000000
--- a/FOREMAN_TASK.md
+++ /dev/null
@@ -1,35 +0,0 @@
-Title: Foreman Task Brief (Project-specific)
-
-Purpose (free text)
-- Complete PROJECT.md Item 12 (Nightlight) - the FINAL infrastructure component (COMPLETE)
-- Achieve 12/12 PROJECT.md deliverables (NOW 12/12)
-- Prepare for production deployment using T032 bare-metal provisioning
-
-Current objectives (ranked, short)
-- 1) T033 Nightlight completion: S4 PromQL Engine (P0), S5 Storage, S6 Integration
-- 2) Production deployment prep: NixOS modules + Nightlight observability stack
-- 3) Deferred features: T029.S5 practical app demo, FlareDB SQL layer (post-MVP)
-
-Standing work (edit freely)
-- Task status monitoring: Check docs/por/T*/task.yaml for stale/blocked tasks
-- Risk radar: Monitor POR.md Risk Radar for new/escalating risks
-- Progress tracking: Verify step completion matches claimed LOC/test counts
-- Stale task alerts: Flag tasks with no progress >48h
-- Evidence validation: Spot-check evidence trail (cargo check, test counts)
-
-Useful references
-- PROJECT.md
-- docs/por/POR.md
-- docs/por/T*/task.yaml (active tasks)
-- docs/evidence/** and .cccc/work/**
-
-How to act each run
-- Do one useful, non-interactive step within the time box (≤ 30m).
-- Save temporary outputs to .cccc/work/foreman//.
-- Write one message to .cccc/mailbox/foreman/to_peer.md with header To: Both|PeerA|PeerB and wrap body in ...
-
-Escalation
-- If a decision is needed, write a 6–10 line RFD and ask the peer.
-
-Safety
-- Do not modify orchestrator code/policies; provide checkable artifacts.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..6f994ac
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,37 @@
+# PhotonCloud Makefile
+# Unifies build and test commands
+
+.PHONY: all build cluster-up cluster-down cluster-status cluster-validate cluster-smoke cluster-matrix cluster-bench-storage clean
+
+# Build all services (using Nix)
+build:
+ nix build .#packages.x86_64-linux.default
+
+# Cluster Management
+cluster-up:
+ nix run ./nix/test-cluster#cluster -- start
+
+cluster-down:
+ nix run ./nix/test-cluster#cluster -- stop
+
+cluster-status:
+ nix run ./nix/test-cluster#cluster -- status
+
+cluster-validate:
+ nix run ./nix/test-cluster#cluster -- validate
+
+cluster-smoke:
+ nix run ./nix/test-cluster#cluster -- fresh-smoke
+
+cluster-matrix:
+ nix run ./nix/test-cluster#cluster -- fresh-matrix
+
+cluster-bench-storage:
+ nix run ./nix/test-cluster#cluster -- fresh-storage-bench
+
+cluster-clean:
+ nix run ./nix/test-cluster#cluster -- clean
+
+# Clean up build artifacts
+clean:
+ rm -rf result
diff --git a/Nix-NOS.md b/Nix-NOS.md
deleted file mode 100644
index fa95be5..0000000
--- a/Nix-NOS.md
+++ /dev/null
@@ -1,398 +0,0 @@
-# PlasmaCloud/PhotonCloud と Nix-NOS の統合分析
-
-## Architecture Decision (2025-12-13)
-
-**決定:** Nix-NOSを汎用ネットワークモジュールとして別リポジトリに分離する。
-
-### Three-Layer Architecture
-
-```
-Layer 3: PlasmaCloud Cluster (T061)
- - plasmacloud-cluster.nix
- - cluster-config.json生成
- - Deployer (Rust)
- depends on ↓
-
-Layer 2: PlasmaCloud Network (T061)
- - plasmacloud-network.nix
- - FiberLB BGP連携
- - PrismNET統合
- depends on ↓
-
-Layer 1: Nix-NOS Generic (T062) ← 別リポジトリ
- - BGP (BIRD2/GoBGP)
- - VLAN
- - Network interfaces
- - PlasmaCloudを知らない汎用モジュール
-```
-
-### Repository Structure
-
-- **github.com/centra/nix-nos**: Layer 1 (汎用、VyOS/OpenWrt代替)
-- **github.com/centra/plasmacloud**: Layers 2+3 (既存リポジトリ)
-
----
-
-## 1. 既存プロジェクトの概要
-
-PlasmaCloud(PhotonCloud)は、以下のコンポーネントで構成されるクラウド基盤プロジェクト:
-
-### コアサービス
-| コンポーネント | 役割 | 技術スタック |
-|---------------|------|-------------|
-| **ChainFire** | 分散KVストア(etcd互換) | Rust, Raft (openraft) |
-| **FlareDB** | SQLデータベース | Rust, KVバックエンド |
-| **IAM** | 認証・認可 | Rust, JWT/mTLS |
-| **PlasmaVMC** | VM管理 | Rust, KVM/FireCracker |
-| **PrismNET** | オーバーレイネットワーク | Rust, OVN連携 |
-| **LightningSTOR** | オブジェクトストレージ | Rust, S3互換 |
-| **FlashDNS** | DNS | Rust, hickory-dns |
-| **FiberLB** | ロードバランサー | Rust, L4/L7, BGP予定 |
-| **NightLight** | メトリクス | Rust, Prometheus互換 |
-| **k8shost** | コンテナオーケストレーション | Rust, K8s API互換 |
-
-### インフラ層
-- **NixOSモジュール**: 各サービス用 (`nix/modules/`)
-- **first-boot-automation**: 自動クラスタ参加
-- **PXE/Netboot**: ベアメタルプロビジョニング
-- **TLS証明書管理**: 開発用証明書生成スクリプト
-
----
-
-## 2. Nix-NOS との統合ポイント
-
-### 2.1 Baremetal Provisioning → Deployer強化
-
-**既存の実装:**
-```
-first-boot-automation.nix
-├── cluster-config.json による設定注入
-├── bootstrap vs join の自動判定
-├── マーカーファイルによる冪等性
-└── systemd サービス連携
-```
-
-**Nix-NOSで追加すべき機能:**
-
-| 既存 | Nix-NOS追加 |
-|------|-------------|
-| cluster-config.json (手動作成) | topology.nix から自動生成 |
-| 単一クラスタ構成 | 複数クラスタ/サイト対応 |
-| nixos-anywhere 依存 | Deployer (Phone Home + Push) |
-| 固定IP設定 | IPAM連携による動的割当 |
-
-**統合設計:**
-
-```nix
-# topology.nix(Nix-NOS)
-{
- nix-nos.clusters.plasmacloud = {
- nodes = {
- "node01" = {
- role = "control-plane";
- ip = "10.0.1.10";
- services = [ "chainfire" "flaredb" "iam" ];
- };
- "node02" = { role = "control-plane"; ip = "10.0.1.11"; };
- "node03" = { role = "worker"; ip = "10.0.1.12"; };
- };
-
- # Nix-NOSが自動生成 → first-boot-automationが読む
- # cluster-config.json の内容をNix評価時に決定
- };
-}
-```
-
-### 2.2 Network Management → PrismNET + FiberLB + Nix-NOS BGP
-
-**既存の実装:**
-```
-PrismNET (prismnet/)
-├── VPC/Subnet/Port管理
-├── Security Groups
-├── IPAM
-└── OVN連携
-
-FiberLB (fiberlb/)
-├── L4/L7ロードバランシング
-├── ヘルスチェック
-├── VIP管理
-└── BGP統合(設計済み、GoBGPサイドカー)
-```
-
-**Nix-NOSで追加すべき機能:**
-
-```
-Nix-NOS Network Layer
-├── BGP設定生成(BIRD2)
-│ ├── iBGP/eBGP自動計算
-│ ├── Route Reflector対応
-│ └── ポリシー抽象化
-├── topology.nix → systemd-networkd
-├── OpenWrt/Cisco設定生成(将来)
-└── FiberLB BGP連携
-```
-
-**統合設計:**
-
-```nix
-# Nix-NOSのBGPモジュール → FiberLBのGoBGP設定に統合
-{
- nix-nos.network.bgp = {
- autonomousSystems = {
- "65000" = {
- members = [ "node01" "node02" "node03" ];
- ibgp.strategy = "route-reflector";
- ibgp.reflectors = [ "node01" ];
- };
- };
-
- # FiberLBのVIPをBGPで広報
- vipAdvertisements = {
- "fiberlb" = {
- vips = [ "10.0.100.1" "10.0.100.2" ];
- nextHop = "self";
- communities = [ "65000:100" ];
- };
- };
- };
-
- # FiberLBモジュールとの連携
- services.fiberlb.bgp = {
- enable = true;
- # Nix-NOSが生成するGoBGP設定を参照
- configFile = config.nix-nos.network.bgp.gobgpConfig;
- };
-}
-```
-
-### 2.3 K8sパチモン → k8shost + Pure NixOS Alternative
-
-**既存の実装:**
-```
-k8shost (k8shost/)
-├── Pod管理(gRPC API)
-├── Service管理(ClusterIP/NodePort)
-├── Node管理
-├── CNI連携
-├── CSI連携
-└── FiberLB/FlashDNS連携
-```
-
-**Nix-NOSの役割:**
-
-k8shostはすでにKubernetesのパチモンとして機能している。Nix-NOSは:
-
-1. **k8shostを使う場合**: k8shostクラスタ自体のデプロイをNix-NOSで管理
-2. **Pure NixOS(K8sなし)**: より軽量な選択肢として、Systemd + Nix-NOSでサービス管理
-
-```
-┌─────────────────────────────────────────────────────────────┐
-│ Orchestration Options │
-├─────────────────────────────────────────────────────────────┤
-│ Option A: k8shost (K8s-like) │
-│ ┌─────────────────────────────────────────────────────┐ │
-│ │ Nix-NOS manages: cluster topology, network, certs │ │
-│ │ k8shost manages: pods, services, scaling │ │
-│ └─────────────────────────────────────────────────────┘ │
-│ │
-│ Option B: Pure NixOS (K8s-free) │
-│ ┌─────────────────────────────────────────────────────┐ │
-│ │ Nix-NOS manages: everything │ │
-│ │ systemd + containers, static service discovery │ │
-│ │ Use case: クラウド基盤自体の管理 │ │
-│ └─────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────┘
-```
-
-**重要な洞察:**
-
-> 「クラウドの基盤そのものを作るのにKubernetesは使いたくない」
-
-これは正しいアプローチ。PlasmaCloudのコアサービス(ChainFire, FlareDB, IAM等)は:
-- K8sの上で動くのではなく、K8sを提供する側
-- Pure NixOS + Systemdで管理されるべき
-- Nix-NOSはこのレイヤーを担当
-
----
-
-## 3. 具体的な統合計画
-
-### Phase 1: Baremetal Provisioning統合
-
-**目標:** first-boot-automationをNix-NOSのtopology.nixと連携
-
-```nix
-# nix/modules/first-boot-automation.nix への追加
-{ config, lib, ... }:
-let
- # Nix-NOSのトポロジーから設定を生成
- clusterConfig =
- if config.nix-nos.cluster != null then
- config.nix-nos.cluster.generateClusterConfig {
- hostname = config.networking.hostName;
- }
- else
- # 従来のcluster-config.json読み込み
- builtins.fromJSON (builtins.readFile /etc/nixos/secrets/cluster-config.json);
-in {
- # 既存のfirst-boot-automationロジックはそのまま
- # ただし設定ソースをNix-NOSに切り替え可能に
-}
-```
-
-### Phase 2: BGP/Network統合
-
-**目標:** FiberLBのBGP連携(T055.S3)をNix-NOSで宣言的に管理
-
-```nix
-# nix/modules/fiberlb-bgp-nixnos.nix
-{ config, lib, pkgs, ... }:
-let
- fiberlbCfg = config.services.fiberlb;
- nixnosBgp = config.nix-nos.network.bgp;
-in {
- config = lib.mkIf (fiberlbCfg.enable && nixnosBgp.enable) {
- # GoBGP設定をNix-NOSから生成
- services.gobgpd = {
- enable = true;
- configFile = pkgs.writeText "gobgp.yaml" (
- nixnosBgp.generateGobgpConfig {
- localAs = nixnosBgp.getLocalAs config.networking.hostName;
- routerId = nixnosBgp.getRouterId config.networking.hostName;
- neighbors = nixnosBgp.getPeers config.networking.hostName;
- }
- );
- };
-
- # FiberLBにGoBGPアドレスを注入
- services.fiberlb.bgp = {
- gobgpAddress = "127.0.0.1:50051";
- };
- };
-}
-```
-
-### Phase 3: Deployer実装
-
-**目標:** Phone Home + Push型デプロイメントコントローラー
-
-```
-plasmacloud/
-├── deployer/ # 新規追加
-│ ├── src/
-│ │ ├── api.rs # Phone Home API
-│ │ ├── orchestrator.rs # デプロイワークフロー
-│ │ ├── state.rs # ノード状態管理(ChainFire連携)
-│ │ └── iso_generator.rs # ISO自動生成
-│ └── Cargo.toml
-└── nix/
- └── modules/
- └── deployer.nix # NixOSモジュール
-```
-
-**ChainFireとの連携:**
-
-DeployerはChainFireを状態ストアとして使用:
-
-```rust
-// deployer/src/state.rs
-struct NodeState {
- hostname: String,
- status: NodeStatus, // Pending, Provisioning, Active, Failed
- bootstrap_key_hash: Option,
- ssh_pubkey: Option,
- last_seen: DateTime,
-}
-
-impl DeployerState {
- async fn register_node(&self, node: &NodeState) -> Result<()> {
- // ChainFireに保存
- self.chainfire_client
- .put(format!("deployer/nodes/{}", node.hostname), node.to_json())
- .await
- }
-}
-```
-
----
-
-## 4. アーキテクチャ全体図
-
-```
-┌─────────────────────────────────────────────────────────────────────┐
-│ Nix-NOS Layer │
-│ ┌─────────────────────────────────────────────────────────────┐ │
-│ │ topology.nix │ │
-│ │ - ノード定義 │ │
-│ │ - ネットワークトポロジー │ │
-│ │ - サービス配置 │ │
-│ └─────────────────────────────────────────────────────────────┘ │
-│ │ │
-│ generates │ │
-│ ▼ │
-│ ┌──────────────┬──────────────┬──────────────┬──────────────┐ │
-│ │ NixOS Config │ BIRD Config │ GoBGP Config │ cluster- │ │
-│ │ (systemd) │ (BGP) │ (FiberLB) │ config.json │ │
-│ └──────────────┴──────────────┴──────────────┴──────────────┘ │
-└─────────────────────────────────────────────────────────────────────┘
- │
- ▼
-┌─────────────────────────────────────────────────────────────────────┐
-│ PlasmaCloud Services │
-│ ┌───────────────────────────────────────────────────────────────┐ │
-│ │ Control Plane │ │
-│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
-│ │ │ChainFire │ │ FlareDB │ │ IAM │ │ Deployer │ │ │
-│ │ │(Raft KV) │ │ (SQL) │ │(AuthN/Z) │ │ (新規) │ │ │
-│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
-│ └───────────────────────────────────────────────────────────────┘ │
-│ │
-│ ┌───────────────────────────────────────────────────────────────┐ │
-│ │ Network Plane │ │
-│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
-│ │ │ PrismNET │ │ FiberLB │ │ FlashDNS │ │ BIRD2 │ │ │
-│ │ │ (OVN) │ │(LB+BGP) │ │ (DNS) │ │(Nix-NOS) │ │ │
-│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
-│ └───────────────────────────────────────────────────────────────┘ │
-│ │
-│ ┌───────────────────────────────────────────────────────────────┐ │
-│ │ Compute Plane │ │
-│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
-│ │ │PlasmaVMC │ │ k8shost │ │Lightning │ │ │
-│ │ │(VM/FC) │ │(K8s-like)│ │ STOR │ │ │
-│ │ └──────────┘ └──────────┘ └──────────┘ │ │
-│ └───────────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────────────┘
-```
-
----
-
-## 5. 優先度と実装順序
-
-| 優先度 | 機能 | 依存関係 | 工数 |
-|--------|------|----------|------|
-| **P0** | topology.nix → cluster-config.json生成 | なし | 1週間 |
-| **P0** | BGPモジュール(BIRD2設定生成) | なし | 2週間 |
-| **P1** | FiberLB BGP連携(GoBGP) | T055.S3完了 | 2週間 |
-| **P1** | Deployer基本実装 | ChainFire | 3週間 |
-| **P2** | OpenWrt設定生成 | BGPモジュール | 2週間 |
-| **P2** | ISO自動生成パイプライン | Deployer完了後 | 1週間 |
-| **P2** | 各サービスの設定をNixで管理可能なように | なし | 適当 |
-
----
-
-## 6. 結論
-
-PlasmaCloud/PhotonCloudプロジェクトは、Nix-NOSの構想を実装するための**理想的な基盤**:
-
-1. **すでにNixOSモジュール化されている** → Nix-NOSモジュールとの統合が容易
-2. **first-boot-automationが存在** → Deployerの基礎として活用可能
-3. **FiberLBにBGP設計がある** → Nix-NOSのBGPモジュールと自然に統合
-4. **ChainFireが状態ストア** → Deployer状態管理に利用可能
-5. **k8shostが存在するがK8sではない** → 「K8sパチモン」の哲学と一致
-
-**次のアクション:**
-1. Nix-NOSモジュールをPlasmaCloudリポジトリに追加
-2. topology.nix → cluster-config.json生成の実装
-3. BGPモジュール(BIRD2)の実装とFiberLB連携
diff --git a/PROJECT.md b/PROJECT.md
deleted file mode 100644
index 48233de..0000000
--- a/PROJECT.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Project Overview
-これは、日本発のクラウド基盤を作るためのプロジェクトです。
-OpenStackなどの既存の使いにくいクラウド基板の代替となり、ついでに基礎技術を各種ソフトウェアに転用できるようにする。
-
-# Principal
-Peer Aへ:**自分で戦略を**決めて良い!好きにやれ!
-
-# Current Priorities
-一通り実装を終わらせ、使いやすいプラットフォームと仕様が完成することを目標とする。
-実装すべきもの:
-1. クラスター管理用KVS(chainfire)
- - これは、ライブラリとして作ることにする。単体でとりあえずKVSとして簡易的にも使えるという想定。
- - Raft+Gossip。
-2. IAM基盤(aegisという名前にしたい。)
- - 様々な認証方法に対応しておいてほしい。
- - あと、サービス感の認証もうまくやる必要がある。mTLSでやることになるだろう。IAMとしてやるのが正解かどうかはわからないが。
-3. DBaaSのための高速KVS(FlareDB)
- - そこそこクエリ効率の良いKVSを作り、その上にSQL互換レイヤーなどが乗れるようにする。
- - 超高速である必要がある。
- - 結果整合性モードと強整合性モードを両方載せられるようにしたい。
- - Tsurugiのような高速なDBが参考になるかも知れない。
- - DBaaSのためでもあるが、高速分散KVSということで、他のもののメタデータストアとして使えるべき。
- - Chainfireとの棲み分けとしては、Chainfireは単体で使う時用と、大規模な場合はクラスター管理に集中させ、メタデータのストア(特に、サービ ス感の連携をするような場合は他のサービスのメタデータにアクセスしたくなるだろう。その時に、このKVSから読めれば良い。)はFlareDBにすると良 さそう。
-4. VM基盤(PlasmaVMC)
- - ちゃんとした抽象化をすることで、様々なVMを扱えるようにしたい(KVM,FireCracker,mvisorなどなど)
-5. オブジェクトストレージ基盤(LightningSTOR)
- - この基盤の標準的な感じの(ある程度共通化されており、使いやすい)APIと、S3互換なAPIがあると良いかも
- - メタデータストアにFlareDBが使えるように当然なっているべき
-6. DNS(FlashDNS)
- - PowerDNSを100%完全に代替可能なようにしてほしい。
- - Route53のようなサービスが作れるようにしたい。
- - BINDも使いたくない。
- - 逆引きDNSをやるためにとんでもない行数のBINDのファイルを書くというのがあり、バカバカしすぎるのでサブネットマスクみたいなものに対応すると良い。
- - DNS All-Rounderという感じにしたい。
-7. ロードバランサー(FiberLB)
- - 超高速なロードバランサーとは名ばかりで、実体としてはBGPでやるので良いような気がしている。
- - AWS ELBみたいなことをできるようにしたい。
- - MaglevによるL4ロードバランシング
- - BGP AnycastによるL2ロードバランシング
- - L7ロードバランシング
- - これらをいい感じにできると良い(既存のソフトウェアでできるかも?これは要確認。)
-8. Kubernetesクラスタをいい感じにホストできるもの?
- - k0sとかk3sとかが参考になるかも知れない。
-9. これらをNixOS上で動くようにパッケージ化をしたりすると良い(Flake化?)。
- - あと、Nixで設定できると良い。まあ設定ファイルを生成するだけなのでそれはできると思うが
-10. Nixによるベアメタルプロビジョニング(Deployer)
- - Phone Home + Push型のデプロイメントコントローラー
- - topology.nix からクラスタ設定を自動生成
- - ChainFireを状態ストアとして使用
- - ISO自動生成パイプライン対応
-11. オーバーレイネットワーク
- - マルチテナントでもうまく動くためには、ユーザーの中でアクセスできるネットワークなど、考えなければいけないことが山ほどある。これを処理 するものも必要。
- - とりあえずネットワーク部分自体の実装はOVNとかで良い。
-12. オブザーバビリティコンポーネント(NightLight)
- - メトリクスストアが必要
- - VictoriaMetricsはmTLSが有料なので、作る必要がある
- - 完全オープンソースでやりたいからね
- - 最低限、Prometheus互換(PromQL)とスケーラビリティ、Push型というのは必須になる
- - メトリクスのデータをどこに置くかは良く良く考えないといけない。スケーラビリティを考えるとS3互換ストレージの上に載せたいが…?
- - あと、圧縮するかどうかなど
-13. クレジット・クオータ管理(CreditService)
- - プロジェクトごとのリソース使用量と課金を管理する「銀行」のようなサービス
- - 各サービス(PlasmaVMCなど)からのリソース作成リクエストをインターセプトして残高確認(Admission Control)を行う
- - NightLightから使用量メトリクスを収集して定期的に残高を引き落とす(Billing Batch)
-
-# Recent Changes (2025-12-11)
-- **Renaming**:
- - `Nightlight` -> `NightLight` (監視・メトリクス)
- - `PrismNET` -> `PrismNET` (ネットワーク)
- - `PlasmaCloud` -> `PhotonCloud` (プロジェクト全体コードネーム)
-- **Architecture Decision**:
- - IAMにクオータ管理を持たせず、専用の `CreditService` を新設することを決定。
- - `NightLight` を使用量計測のバックエンドとして活用する方針を策定。
-
-# Next Steps
-1. **CreditServiceの実装**:
- - プロジェクトごとのWallet管理、残高管理機能
- - gRPC APIによるAdmission Controlの実装
-2. **NightLightの実装完了**:
- - 永続化層とクエリエンジンの完成
- - `CreditService` へのデータ提供機能の実装
-3. **PlasmaVMCの改修**:
- - `CreditService` と連携したリソース作成時のチェック処理追加
- - プロジェクト単位のリソース総量制限の実装
-
-# 守るべき事柄
-1. Rustで書く。
-2. 全部のソフトウェアにおいて、コードベースの構造や依存ライブラリ、仕様や使い方を揃えて、統一感があるようにする。
-3. テスト可能なように作る。また、テストをちゃんと書く。スケーラブルかどうかや、実際に動くかどうかもテスト可能なように良く考えたうえで作る。
-4. スケーラビリティに気をつけて書く。ボトルネックになる箇所はないか?と常に確認する。
-5. 統一感ある仕様をちゃんと考える。(specificationsの中にmdで書いていってほしい。1ソフトウェアごとにフォルダを作り、その中に仕様を書く。 )
-6. 設定ファイルについても統一感ある仕様が必要。
-7. マルチテナントに関して最初から考慮したうえで設計する(次の年にAWSやGCPでそのまま採用されてもおかしくないような性能や使いやすさが必要)。
-8. ホームラボ用途も満たすようにしたい。
-9. NixのFlakeで環境を作ったり固定したりすると良い。
-10. 前方互換性は気にする必要がない(すでにある実装に縛られる必要はなく、両方を変更して良い)。v2とかv3とかそういうふうにバージョンを増やしていくのはやめてほしい。そうではなく、完璧な一つの実装を作ることに専念してほしい。
-11. ライブラリは可能な限り最新版を使う。この先も長くメンテナンスされることを想定したい。
-
-# 実戦テスト
-全ての作ったコンポーネントについて、実践的なテストを作ってバグや仕様の悪い点を洗い出し、修正する。
-NixやVM、コンテナなどあらゆるものを活用してよい。
-これにより、実用レベルまで持っていくことが期待される。
-実用的なアプリケーションを作ってみるとか、パフォーマンスを実際に高負荷な試験で確認するとか、そのレベルのものが求められている。
-また、各コンポーネントごとのテストも行うべきだが、様々なものを組み合わせるテストも行うべきである。これも含まれる。
-また、設定のやり方がちゃんと統一されているかなど、細かい点まで気を配ってやる必要がある。
diff --git a/README.md b/README.md
index 046d72d..577c535 100644
--- a/README.md
+++ b/README.md
@@ -1,507 +1,50 @@
-# PhotonCloud (旧 PlasmaCloud)
+# PhotonCloud
-**A modern, multi-tenant cloud infrastructure platform built in Rust**
+PhotonCloud is a Nix-first cloud platform workspace that assembles a small control plane, network services, VM hosting, shared storage, object storage, and gateway services into one reproducible repository.
-> NOTE: プロジェクトコードネームを PlasmaCloud から PhotonCloud に改称。コンポーネント名も Nightlight → NightLight へ統一済み(詳細は `PROJECT.md` の Recent Changes を参照)。
-> 併存する「PlasmaCloud」表記は旧コードネームを指します。PhotonCloud と読み替えてください。
+The canonical local proof path is the six-node VM cluster under [`nix/test-cluster`](/home/centra/cloud/nix/test-cluster/README.md). It builds all guest images on the host, boots them as hardware-like QEMU nodes, and validates real multi-node behavior.
-PhotonCloud provides a complete cloud computing stack with strong tenant isolation, role-based access control (RBAC), and seamless integration between compute, networking, and storage services.
+## Components
-## MVP-Beta Status: COMPLETE ✅
-
-The MVP-Beta milestone validates end-to-end tenant isolation and core infrastructure provisioning:
-
-- ✅ **IAM**: User authentication, RBAC, multi-tenant isolation
-- ✅ **PrismNET**: VPC overlay networking with tenant boundaries
-- ✅ **PlasmaVMC**: VM provisioning with network attachment
-- ✅ **Integration**: E2E tests validate complete tenant path
-
-**Test Results**: 8/8 integration tests passing
-- IAM: 6/6 tenant path tests
-- Network+VM: 2/2 integration tests
+- `chainfire`: replicated coordination store
+- `flaredb`: replicated KV and metadata store
+- `iam`: identity, token issuance, and authorization
+- `prismnet`: tenant networking control plane
+- `flashdns`: authoritative DNS service
+- `fiberlb`: load balancer control plane and dataplane
+- `plasmavmc`: VM control plane and worker agents
+- `coronafs`: shared filesystem for mutable VM volumes
+- `lightningstor`: object storage and VM image backing
+- `k8shost`: Kubernetes-style hosting control plane
+- `apigateway`: external API and proxy surface
+- `nightlight`: metrics ingestion and query service
+- `creditservice`: minimal reference quota/credit service
+- `deployer`: bootstrap and phone-home deployment service
+- `fleet-scheduler`: non-Kubernetes service scheduler for bare-metal cluster services
## Quick Start
-### Get Started in 3 Steps
-
-1. **Deploy the Platform**
- ```bash
- # Start IAM service
- cd iam && cargo run --bin iam-server -- --port 50080
-
- # Start PrismNET service
- cd prismnet && cargo run --bin prismnet-server -- --port 50081
-
- # Start PlasmaVMC service
- cd plasmavmc && cargo run --bin plasmavmc-server -- --port 50082
- ```
-
-2. **Onboard Your First Tenant**
- ```bash
- # Create user, provision network, deploy VM
- # See detailed guide below
- ```
-
-3. **Verify End-to-End**
- ```bash
- # Run integration tests
- cd iam && cargo test --test tenant_path_integration
- cd plasmavmc && cargo test --test prismnet_integration -- --ignored
- ```
-
-**For detailed instructions**: [Tenant Onboarding Guide](docs/getting-started/tenant-onboarding.md)
-
-## Architecture Overview
-
-```
-┌─────────────────────────────────────────────────────────────┐
-│ User / API Client │
-└─────────────────────────────────────────────────────────────┘
- │
- ↓
-┌─────────────────────────────────────────────────────────────┐
-│ IAM (Identity & Access Management) │
-│ • User authentication & JWT tokens │
-│ • RBAC with hierarchical scopes (Org → Project) │
-│ • Cross-tenant access denial │
-└─────────────────────────────────────────────────────────────┘
- │
- ┌─────────────┴─────────────┐
- ↓ ↓
-┌──────────────────────┐ ┌──────────────────────┐
-│ PrismNET │ │ PlasmaVMC │
-│ • VPC overlay │────▶│ • VM provisioning │
-│ • Subnets + DHCP │ │ • Hypervisor mgmt │
-│ • Ports (IP/MAC) │ │ • Network attach │
-│ • Security Groups │ │ • KVM, Firecracker │
-└──────────────────────┘ └──────────────────────┘
-```
-
-**Full Architecture**: [MVP-Beta Tenant Path Architecture](docs/architecture/mvp-beta-tenant-path.md)
-
-## Core Components
-
-### IAM (Identity & Access Management)
-
-**Location**: `/iam`
-
-Multi-tenant identity and access management with comprehensive RBAC.
-
-**Features**:
-- User and service account management
-- Hierarchical scopes: System → Organization → Project
-- Custom role creation with fine-grained permissions
-- Policy evaluation with conditional logic
-- JWT token issuance with tenant claims
-
-**Services**:
-- `IamAdminService`: User, role, and policy management
-- `IamAuthzService`: Authorization and permission checks
-- `IamTokenService`: Token issuance and validation
-
-**Quick Start**:
```bash
-cd iam
-cargo build --release
-cargo run --bin iam-server -- --port 50080
+nix develop
+nix run ./nix/test-cluster#cluster -- fresh-smoke
```
-### PrismNET (Network Virtualization)
+## Main Entrypoints
-**Location**: `/prismnet`
+- workspace flake: [flake.nix](/home/centra/cloud/flake.nix)
+- VM validation harness: [nix/test-cluster/README.md](/home/centra/cloud/nix/test-cluster/README.md)
+- shared volume notes: [coronafs/README.md](/home/centra/cloud/coronafs/README.md)
+- minimal quota-service rationale: [creditservice/README.md](/home/centra/cloud/creditservice/README.md)
+- archived manual VM launch scripts: [baremetal/vm-cluster/README.md](/home/centra/cloud/baremetal/vm-cluster/README.md)
-VPC-based overlay networking with tenant isolation.
+## Repository Guide
-**Features**:
-- Virtual Private Cloud (VPC) provisioning
-- Subnet management with CIDR allocation
-- Port allocation with IP/MAC assignment
-- DHCP server integration
-- Security group enforcement
-- OVN integration for production networking
+- [docs/README.md](/home/centra/cloud/docs/README.md): documentation entrypoint
+- [docs/testing.md](/home/centra/cloud/docs/testing.md): validation path summary
+- [docs/component-matrix.md](/home/centra/cloud/docs/component-matrix.md): supported multi-component compositions
+- [docs/storage-benchmarks.md](/home/centra/cloud/docs/storage-benchmarks.md): latest CoronaFS and LightningStor lab numbers
+- `plans/`: design notes and exploration documents
-**Services**:
-- `VpcService`: VPC lifecycle management
-- `SubnetService`: Subnet CRUD operations
-- `PortService`: Port allocation and attachment
-- `SecurityGroupService`: Firewall rule management
+## Scope
-**Quick Start**:
-```bash
-cd prismnet
-export IAM_ENDPOINT=http://localhost:50080
-cargo build --release
-cargo run --bin prismnet-server -- --port 50081
-```
-
-### PlasmaVMC (VM Provisioning & Management)
-
-**Location**: `/plasmavmc`
-
-Virtual machine lifecycle management with hypervisor abstraction.
-
-**Features**:
-- VM provisioning with tenant scoping
-- Hypervisor abstraction (KVM, Firecracker)
-- Network attachment via PrismNET ports
-- CPU, memory, and disk configuration
-- VM metadata persistence (ChainFire)
-- Live migration support (planned)
-
-**Services**:
-- `VmService`: VM lifecycle (create, start, stop, delete)
-
-**Quick Start**:
-```bash
-cd plasmavmc
-export NOVANET_ENDPOINT=http://localhost:50081
-export IAM_ENDPOINT=http://localhost:50080
-cargo build --release
-cargo run --bin plasmavmc-server -- --port 50082
-```
-
-## Future Components (Roadmap)
-
-### FlashDNS (DNS Service)
-
-**Status**: Planned for next milestone
-
-DNS resolution within tenant VPCs with automatic record creation.
-
-**Features** (Planned):
-- Tenant-scoped DNS zones
-- Automatic hostname assignment for VMs
-- DNS record lifecycle tied to resources
-- Integration with PrismNET for VPC resolution
-
-### FiberLB (Load Balancing)
-
-**Status**: Planned for next milestone
-
-Layer 4/7 load balancing with tenant isolation.
-
-**Features** (Planned):
-- Load balancer provisioning within VPCs
-- Backend pool management (VM targets)
-- VIP allocation from tenant subnets
-- Health checks and failover
-
-### LightningStor (Block Storage)
-
-**Status**: Planned for next milestone
-
-Distributed block storage with snapshot support.
-
-**Features** (Planned):
-- Volume creation and attachment to VMs
-- Snapshot lifecycle management
-- Replication and high availability
-- Integration with ChainFire for immutable logs
-
-## Testing
-
-### Integration Test Suite
-
-PlasmaCloud includes comprehensive integration tests validating the complete E2E tenant path.
-
-**IAM Tests** (6 tests, 778 LOC):
-```bash
-cd iam
-cargo test --test tenant_path_integration
-
-# Tests:
-# ✅ test_tenant_setup_flow
-# ✅ test_cross_tenant_denial
-# ✅ test_rbac_project_scope
-# ✅ test_hierarchical_scope_inheritance
-# ✅ test_custom_role_fine_grained_permissions
-# ✅ test_multiple_role_bindings
-```
-
-**Network + VM Tests** (2 tests, 570 LOC):
-```bash
-cd plasmavmc
-cargo test --test prismnet_integration -- --ignored
-
-# Tests:
-# ✅ prismnet_port_attachment_lifecycle
-# ✅ test_network_tenant_isolation
-```
-
-**Coverage**: 8/8 tests passing (100% success rate)
-
-See [E2E Test Documentation](docs/por/T023-e2e-tenant-path/e2e_test.md) for detailed test descriptions.
-
-## Documentation
-
-### Getting Started
-
-- **[Tenant Onboarding Guide](docs/getting-started/tenant-onboarding.md)**: Complete walkthrough of deploying your first tenant
-
-### Architecture
-
-- **[MVP-Beta Tenant Path](docs/architecture/mvp-beta-tenant-path.md)**: Complete system architecture with diagrams
-- **[Component Integration](docs/architecture/mvp-beta-tenant-path.md#component-boundaries)**: How services communicate
-
-### Testing & Validation
-
-- **[E2E Test Documentation](docs/por/T023-e2e-tenant-path/e2e_test.md)**: Comprehensive test suite description
-- **[T023 Summary](docs/por/T023-e2e-tenant-path/SUMMARY.md)**: MVP-Beta deliverables and test results
-
-### Component Specifications
-
-- [IAM Specification](specifications/iam.md)
-- [PrismNET Specification](specifications/prismnet.md)
-- [PlasmaVMC Specification](specifications/plasmavmc.md)
-
-## Tenant Isolation Model
-
-PlasmaCloud enforces tenant isolation at three layers:
-
-### Layer 1: IAM Policy Enforcement
-
-Every API call is validated against the user's JWT token:
-- Token includes `org_id` and `project_id` claims
-- Resources are scoped as: `org/{org_id}/project/{project_id}/{resource_type}/{id}`
-- RBAC policies enforce: `resource.org_id == token.org_id`
-- Cross-tenant access results in 403 Forbidden
-
-### Layer 2: Network VPC Isolation
-
-Each VPC provides a logical network boundary:
-- VPC scoped to an `org_id`
-- OVN overlay ensures traffic isolation between VPCs
-- Different tenants can use the same CIDR without collision
-- Security groups provide intra-VPC firewall rules
-
-### Layer 3: VM Scoping
-
-Virtual machines are scoped to tenant organizations:
-- VM metadata includes `org_id` and `project_id`
-- VMs can only attach to ports in their tenant's VPC
-- VM operations filter by token scope
-- Hypervisor isolation ensures compute boundary
-
-**Validation**: All three layers tested in [cross-tenant denial tests](docs/por/T023-e2e-tenant-path/e2e_test.md#test-scenario-2-cross-tenant-denial).
-
-## Example Workflow
-
-### Create a Tenant with Network and VM
-
-```bash
-# 1. Authenticate and get token
-grpcurl -plaintext -d '{
- "principal_id": "alice",
- "org_id": "acme-corp",
- "project_id": "project-alpha"
-}' localhost:50080 iam.v1.IamTokenService/IssueToken
-
-export TOKEN=""
-
-# 2. Create VPC
-grpcurl -plaintext -H "Authorization: Bearer $TOKEN" -d '{
- "org_id": "acme-corp",
- "project_id": "project-alpha",
- "name": "main-vpc",
- "cidr": "10.0.0.0/16"
-}' localhost:50081 prismnet.v1.VpcService/CreateVpc
-
-export VPC_ID=""
-
-# 3. Create Subnet
-grpcurl -plaintext -H "Authorization: Bearer $TOKEN" -d '{
- "org_id": "acme-corp",
- "project_id": "project-alpha",
- "vpc_id": "'$VPC_ID'",
- "name": "web-subnet",
- "cidr": "10.0.1.0/24",
- "gateway": "10.0.1.1",
- "dhcp_enabled": true
-}' localhost:50081 prismnet.v1.SubnetService/CreateSubnet
-
-export SUBNET_ID=""
-
-# 4. Create Port
-grpcurl -plaintext -H "Authorization: Bearer $TOKEN" -d '{
- "org_id": "acme-corp",
- "project_id": "project-alpha",
- "subnet_id": "'$SUBNET_ID'",
- "name": "vm-port",
- "ip_address": "10.0.1.10"
-}' localhost:50081 prismnet.v1.PortService/CreatePort
-
-export PORT_ID=""
-
-# 5. Create VM with Network
-grpcurl -plaintext -H "Authorization: Bearer $TOKEN" -d '{
- "name": "web-server-1",
- "org_id": "acme-corp",
- "project_id": "project-alpha",
- "spec": {
- "network": [{
- "id": "eth0",
- "port_id": "'$PORT_ID'"
- }]
- }
-}' localhost:50082 plasmavmc.v1.VmService/CreateVm
-```
-
-**Full walkthrough**: See [Tenant Onboarding Guide](docs/getting-started/tenant-onboarding.md)
-
-## Development
-
-### Prerequisites
-
-- Rust 1.70+ with Cargo
-- Protocol Buffers compiler (protoc)
-- Optional: KVM for real VM execution
-- Optional: OVN for production networking
-
-### Build from Source
-
-```bash
-# Clone repository
-git clone https://github.com/your-org/plasmacloud.git
-cd cloud
-
-# Initialize submodules
-git submodule update --init --recursive
-
-# Build all components
-cd iam && cargo build --release
-cd ../prismnet && cargo build --release
-cd ../plasmavmc && cargo build --release
-```
-
-### Run Tests
-
-```bash
-# IAM tests
-cd iam && cargo test --test tenant_path_integration
-
-# Network + VM tests
-cd plasmavmc && cargo test --test prismnet_integration -- --ignored
-
-# Unit tests (all components)
-cargo test
-```
-
-### Project Structure
-
-```
-cloud/
-├── iam/ # Identity & Access Management
-│ ├── crates/
-│ │ ├── iam-api/ # gRPC services
-│ │ ├── iam-authz/ # Authorization engine
-│ │ ├── iam-store/ # Data persistence
-│ │ └── iam-types/ # Core types
-│ └── tests/
-│ └── tenant_path_integration.rs # E2E tests
-│
-├── prismnet/ # Network Virtualization
-│ ├── crates/
-│ │ ├── prismnet-server/ # gRPC services
-│ │ ├── prismnet-api/ # Protocol buffers
-│ │ ├── prismnet-metadata/ # Metadata store
-│ │ └── prismnet-ovn/ # OVN integration
-│ └── proto/
-│
-├── plasmavmc/ # VM Provisioning
-│ ├── crates/
-│ │ ├── plasmavmc-server/ # VM service
-│ │ ├── plasmavmc-api/ # Protocol buffers
-│ │ ├── plasmavmc-hypervisor/ # Hypervisor abstraction
-│ │ ├── plasmavmc-kvm/ # KVM backend
-│ │ └── plasmavmc-firecracker/ # Firecracker backend
-│ └── tests/
-│ └── prismnet_integration.rs # E2E tests
-│
-├── flashdns/ # DNS Service (planned)
-├── fiberlb/ # Load Balancing (planned)
-├── lightningstor/ # Block Storage (planned)
-│
-├── chainfire/ # Immutable event log (submodule)
-├── flaredb/ # Distributed metadata store (submodule)
-│
-├── docs/
-│ ├── architecture/ # Architecture docs
-│ ├── getting-started/ # Onboarding guides
-│ └── por/ # Plan of Record (POR) docs
-│ └── T023-e2e-tenant-path/ # MVP-Beta deliverables
-│
-├── specifications/ # Component specifications
-└── README.md # This file
-```
-
-## Contributing
-
-We welcome contributions! Please follow these guidelines:
-
-1. **Fork the repository** and create a feature branch
-2. **Write tests** for new functionality
-3. **Update documentation** as needed
-4. **Run tests** before submitting PR: `cargo test`
-5. **Follow Rust style**: Use `cargo fmt` and `cargo clippy`
-
-### Code Review Process
-
-1. All PRs require at least one approval
-2. CI must pass (tests, formatting, lints)
-3. Documentation must be updated for user-facing changes
-4. Integration tests required for new features
-
-## License
-
-PlasmaCloud is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for details.
-
-## Support & Community
-
-- **GitHub Issues**: Report bugs or request features
-- **Documentation**: See [docs/](docs/) for detailed guides
-- **Architecture**: Review [architecture docs](docs/architecture/mvp-beta-tenant-path.md) for design decisions
-
-## Roadmap
-
-### Completed (MVP-Beta) ✅
-
-- [x] IAM with RBAC and tenant scoping
-- [x] PrismNET VPC overlay networking
-- [x] PlasmaVMC VM provisioning
-- [x] End-to-end integration tests
-- [x] Comprehensive documentation
-
-### In Progress
-
-- [ ] FlashDNS integration (S3)
-- [ ] FiberLB integration (S4)
-- [ ] LightningStor integration (S5)
-
-### Planned
-
-- [ ] FlareDB persistence for production
-- [ ] ChainFire integration for VM metadata
-- [ ] OVN production deployment
-- [ ] Kubernetes integration
-- [ ] Terraform provider
-- [ ] Web UI / Dashboard
-
-## Acknowledgments
-
-PlasmaCloud builds upon:
-- **ChainFire**: Immutable event log for audit trails
-- **FlareDB**: Distributed metadata store
-- **OVN (Open Virtual Network)**: Production-grade overlay networking
-- **gRPC**: High-performance RPC framework
-- **Rust**: Safe, concurrent systems programming
-
----
-
-**Status**: MVP-Beta Complete ✅
-**Last Updated**: 2025-12-09
-**Next Milestone**: FlashDNS, FiberLB, LightningStor integration
-
-For detailed information, see:
-- [Tenant Onboarding Guide](docs/getting-started/tenant-onboarding.md)
-- [Architecture Documentation](docs/architecture/mvp-beta-tenant-path.md)
-- [Test Documentation](docs/por/T023-e2e-tenant-path/e2e_test.md)
+PhotonCloud is centered on reproducible infrastructure behavior rather than polished end-user product surfaces. Some services, such as `creditservice`, are intentionally minimal reference implementations that prove integration points rather than full products.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..342f309
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,13 @@
+# Security Policy
+
+Do not report sensitive vulnerabilities through public issues.
+
+Use the repository security advisory workflow or a private maintainer contact channel when this repository is published.
+
+When reporting, include:
+
+- affected component
+- impact summary
+- reproduction steps
+- configuration assumptions
+- any suggested mitigation or patch direction
diff --git a/T003-architectural-gap-analysis.md b/T003-architectural-gap-analysis.md
deleted file mode 100644
index b165157..0000000
--- a/T003-architectural-gap-analysis.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Architectural Gap Analysis: Compute & Core
-
-**Date:** 2025-12-08
-**Scope:** Core Infrastructure (Chainfire, IAM, FlareDB) & Application Services (FlashDNS, PlasmaVMC)
-
-## Executive Summary
-
-The platform's core infrastructure ("Data" and "Identity" pillars) is in excellent shape, with implementation matching specifications closely. However, the "Compute" pillar (PlasmaVMC) exhibits a significant architectural deviation from its specification, currently existing as a monolithic prototype rather than the specified distributed control plane/agent model.
-
-## Component Status Matrix
-
-| Component | Role | Specification Status | Implementation Status | Alignment |
-|-----------|------|----------------------|-----------------------|-----------|
-| **Chainfire** | Cluster KVS | High | High | ✅ Strong |
-| **Aegis (IAM)** | Identity | High | High | ✅ Strong |
-| **FlareDB** | DBaaS KVS | High | High | ✅ Strong |
-| **FlashDNS** | DNS Service | High | High | ✅ Strong |
-| **PlasmaVMC** | VM Platform | High | **Low / Prototype** | ❌ **Mismatch** |
-
-## Detailed Findings
-
-### 1. Core Infrastructure (Chainfire, Aegis, FlareDB)
-* **Chainfire:** Fully implemented crate structure. Detailed feature gap analysis exists (`chainfire_t003_gap_analysis.md`).
-* **Aegis:** Correctly structured with `iam-server`, `iam-authn`, `iam-authz`, etc. Integration with Chainfire/FlareDB backends is present in `main.rs`.
-* **FlareDB:** Correctly structured with `flaredb-pd`, `flaredb-server` (Multi-Raft), and reserved namespaces for IAM/Metrics.
-
-### 2. Application Services (FlashDNS)
-* **Status:** Excellent.
-* **Evidence:** Crate structure matches spec. Integration with Chainfire (storage) and Aegis (auth) is visible in configuration and code.
-
-### 3. Compute Platform (PlasmaVMC) - The Gap
-* **Specification:** Describes a distributed system with:
- * **Control Plane:** API, Scheduler, Image management.
- * **Agent:** Runs on compute nodes, manages local hypervisors.
- * **Communication:** gRPC between Control Plane and Agent.
-* **Current Implementation:** Monolithic `plasmavmc-server`.
- * The `server` binary directly initializes `HypervisorRegistry` and registers `KvmBackend`/`FireCrackerBackend`.
- * **Missing Crates:**
- * `plasmavmc-agent` (Critical)
- * `plasmavmc-client`
- * `plasmavmc-core` (Scheduler logic)
- * **Implication:** The current code cannot support multi-node deployment or scheduling. It effectively runs the control plane *on* the hypervisor node.
-
-## Recommendations
-
-1. **Prioritize PlasmaVMC Refactoring:** The immediate engineering focus should be to split `plasmavmc-server` into:
- * `plasmavmc-server` (Control Plane, Scheduler, API)
- * `plasmavmc-agent` (Node status, Hypervisor control)
-2. **Implement Agent Protocol:** Define the gRPC interface between Server and Agent (`agent.proto` mentioned in spec but possibly missing or unused).
-3. **Leverage Existing Foundation:** The `plasmavmc-hypervisor` trait is solid. The `agent` implementation should simply wrap this existing trait, making the refactor straightforward.
-
-## Conclusion
-
-The project foundation is solid. The "Data" and "Identity" layers are ready for higher-level integration. The "Compute" layer requires architectural realignment to meet the distributed design goals.
diff --git a/TOAGENT.md b/TOAGENT.md
deleted file mode 100644
index 05cf3a1..0000000
--- a/TOAGENT.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Peer Aへ:
-/a あなたはpeerAです。戦略決定と計画立案に特化してください。実際の作業は、peerBへ依頼してください。PROJECT.mdは度々更新されることがあるので、PORに内容を追加したり、適切にMVPを設定・到達状況を確認するなどもあなたの仕事です。ともかく、終える前に確実にタスクをpeerBに渡すことを考えてください。
-
-Peer Bへ:
-/b peerAからの実装依頼に基づいて実装や実験などの作業を行い、終わったあとは必ずpeerAに結果を(to_peer.mdで)報告してください。高品質に作業を行うことに集中してください。
diff --git a/advice.md b/advice.md
deleted file mode 100644
index 005a665..0000000
--- a/advice.md
+++ /dev/null
@@ -1,5094 +0,0 @@
-## You asked:
-
-repomix-output.xml
-
-ファイル
-
-このソースコードたちについて、良く見てこのChainfire(クラスター管理用分散KV)とFlareDB(分散高性能DB)の実用性とさらなる高みを目指す場合の展望などを教えてほしいです。
-
----
-
-## ChatGPT Replied:
-
-Thought for 12m 48s
-
-ざっくり結論
-
-* **Chainfire**は、Raft+RocksDB+gRPC+Gossip(SWIM/foca)で「etcd 風の分散KV+Watch」を狙う設計。Rust のワークスペース分割もきれいで、API/ストレージ/ウォッチ/ゴシップ/ラフトがモジュール化されている。ただし\*\*Raft の対外RPCがまだ未配線(in‑memory/ダミー)\*\*で、本当の多ノードクラスタとしては未完成。単一ノードやプロセス内検証には十分使える段階。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-* **FlareDB**は、PD(Placement Driver)+TSO(単調増加タイムスタンプ)+KV(Raw/CAS)+Raftサービス+リージョン/マルチラフトの下地+Merkle(整合性検査の雛形)まで手が入っており、**実験用の分散ストレージ最小系**としてよくまとまっている。CI/テスト項目・Quickstart・検証スクリプトもあり、開発者体験が良い。実運用には、マルチラフトの完成度・レプリケーション/再配置・フォロワリード/線形化リード・トランザクションなど**次の一歩**が必要。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-
-* * *
-
-Chainfire:何ができていて、どこが足りないか
---------------------------
-
-**できていること(コードから確認できる実体)**
-
-* Rust Workspace でAPI/サーバ/ストレージ/ラフト/ゴシップ/ウォッチが分離。依存は `openraft`(Raft)・`foca`(SWIM Gossip)・`rocksdb`・`tonic/prost`(gRPC)に整理済み。
-
- repomix-output
-
-* Raft 設定は OpenRaft の典型値で初期化(心拍/選挙タイムアウト/スナップショット方針等)し、ユニットテストもあり。
-
- repomix-output
-
-* gRPC の **KV / Watch / Cluster / (内部)Raft** サービスを一つのTonicサーバに束ねて起動する作り。
-
- repomix-output
-
-* **Watch** は双方向ストリームで、内部のWatchRegistryとつながるちゃんとした実装。クライアント側の受信ハンドルも用意済み。
-
- repomix-output
-
- repomix-output
-
-* RocksDB をCF分割で利用。スナップショットのビルド/適用テストあり(データ転送の下地)。
-
- repomix-output
-
- repomix-output
-
-
-**詰めが甘い/未完成な点(現状の制約)**
-
-* **Raft RPCが未配線**:`RaftRpcClient` は “gRPC実装を後で差す” 前提のトレイトのまま。ノード生成時も **Dummy/In‑memory のクライアント**が使われており、実ノード間通信になっていない。これだと**単一プロセス内での検証**はできるが、別プロセス/別ホストにまたぐクラスタは動かない。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-* **Raft用ポートの扱い**:ログには Raft用アドレスを出しているが、実際のTonicサーバは **APIアドレスでまとめて** `RaftService` も公開している。ポート分離・セキュリティ/ネットワーク設計が未整理。
-
- repomix-output
-
-* クラスタメンバーシップ変更(joint consensus)や、線形化読み取り(ReadIndex)、スナップショット転送の堅牢化など、Raft運用の“本番ポイント”は未記述/未配線に見える(設計としてはOpenRaftが担保可能)。
-
-
-**今の実用性(どこで役に立つ?)**
-
-* **研究/検証・単一ノードのメタデータKV**としては十分。“etcd互換風のAPI+Watch”の感触を掴むには良い。
-
-* **本番クラスタ**やフェイルオーバを求める用途では、**Raft RPC配線とメンバーシップ管理**が入るまで待ちが必要。
-
-
-**短期で刺さる改善(着手順)**
-
-1. **RaftのgRPCクライアント**を `internal_proto` に基づいて実装し、`RaftRpcClient` に差し込む。
-
- repomix-output
-
-2. **Raft用ポート分離**:`api_addr` と `raft_addr` を別サーバで起動し、TLS/認証の下地も確保。
-
- repomix-output
-
-3. **Gossip⇔Raft連携**:focaでの生存監視をトリガに、メンバー自動追加/離脱をRaftのjoint‑consensusに流す。依存は既にワークスペースにある。
-
- repomix-output
-
-4. **線形化Read/ReadIndex**実装、**フォロワリード**(許容するなら条件付き)を整理。
-
-5. **ウォッチの厳密な順序/Revision**保証をStateMachineの適用と一体化(watch\_txの結線)。
-
- repomix-output
-
-6. **スナップショット転送の実戦投入**(チャンク/再送/検証)。テストは下地あり。
-
- repomix-output
-
-7. **メトリクス/トレース**(Prometheus/OpenTelemetry)と**障害注入テスト**。
-
-8. Docker/Helm/Flakeの梱包をCIに載せる。
-
- repomix-output
-
-
-* * *
-
-FlareDB:何ができていて、どこが足りないか
-------------------------
-
-**できていること(コードから確認できる実体)**
-
-* **PD+TSO** の独立プロセス。**Quickstart**に起動順とCLI操作(TSO/Raw Put/Get/CAS)が書かれており、User StoryのチェックリストにもTSO達成が明記。
-
- repomix-output
-
- repomix-output
-
-* **サーバ側サービス**:`KvRaw`/`KvCas`/`RaftService` を同一 gRPC サーバで提供。
-
- repomix-output
-
-* **PD連携のハートビート/再接続・リージョン更新ループ**の骨格がある(起動後に定期HB→失敗時は再接続、リージョン情報を同期)。
-
- repomix-output
-
- repomix-output
-
-* **Merkle**(領域ハッシュの雛形)で後々のアンチエントロピー/整合性検査を意識。
-
- repomix-output
-
-* **テストと仕様フォルダが豊富**:レプリケーション/マルチリージョン/スプリット/整合性などのテスト群、spec・scripts で動作確認の導線がある。
-
- repomix-output
-
- repomix-output
-
-
-**詰めが甘い/未完成な点(現状の制約)**
-
-* **マルチラフトの完成度**:リージョン分割・再配置・投票者/ラーナ/学習者の遷移、PDのスケジューリング(リバランス/ホットキー対策)の“運用アルゴリズム”はこれから。ディレクトリやspecはあるが、本番相当の道具立ては未完成。
-
- repomix-output
-
- repomix-output
-
-* **リードパスの整理**:強整合/フォロワリード/ReadIndexの選択や遅延観測の制御が未整備に見える。
-
-* **トランザクション(MVCC)**:TSOはあるが、二相コミットや悲観/楽観制御、ロールバック/ロック解放の実働コードはこれから(CASはある)。
-
- repomix-output
-
-* **障害時挙動と耐久性**:スナップショット/ログの回復・リージョンマージ・アンチエントロピー(Merkle駆動)のバックグラウンドジョブは雛形段階。
-
-
-**今の実用性**
-
-* 研究用途・PoC として\*\*単一~少数ノードのKV(Raw/CAS)\*\*を回し、PD/TSO連携やリージョンの概念を試すには充分。
-
-* フル機能の分散トランザクショナルKV/SQL バックエンドを**本番投入**するには、マルチラフト/リージョン管理/トランザクション/可観測性などの整備が必要。
-
-
-**短期で刺さる改善(着手順)**
-
-1. **マルチラフトの完成**:リージョンスプリットのトリガ(サイズ/負荷)→新リージョンのRaft起動→PDのメタ更新→クライアントのRegion Cache更新をE2Eでつなぐ。テスト骨子は既にある。
-
- repomix-output
-
-2. **フォロワリード/線形化Read**の切替を導入(読み取りSLAと一貫性を両立)。
-
-3. **MVCC+2PC**:TSO を commit\_ts/read\_ts に使い、Prewrite/Commit(TiKV流) or OCC を追加。Quickstart のCASを土台に昇華。
-
- repomix-output
-
-4. **Merkleベースのアンチエントロピー**:バックグラウンドでリージョンのMerkle葉を比較し、差分レンジを修復。
-
- repomix-output
-
-5. **PDのスケジューラ**:移動コスト・ホットキー・障害隔離を考慮した配置。
-
-6. **メトリクス/トレース/プロファイリング**と**YCSB/Jepsen系テスト**で性能と安全性を可視化。
-
-
-* * *
-
-さらに高みへ(共通の設計指針)
----------------
-
-1. **制御面(Chainfire)×データ面(FlareDB)の分業を明確化**
- Chainfire を“クラスタ制御の中枢”(ノードメタ/アロケーション/設定/ウォッチ)に、FlareDB を“データ平面”に寄せる。Gossipの生存情報→ChainfireのKV→FlareDB PDへの反映という**単一路**を敷くと運用が楽になる。
-
- repomix-output
-
-2. **アドレス解決とメンバーシップの一元管理**
- ChainfireのCluster APIに Raft peer の `BasicNode` 情報を登録/取得する経路を作り、`NetworkFactory` がそこから**動的にダイヤル**できるようにする。現状はトレイトとFactoryが揃っているので配線だけで前進する。
-
- repomix-output
-
- repomix-output
-
-3. **明示的なポート分離とゼロトラスト前提**
- Client API(KV/Watch)と Peer RPC(Raft)を分離配信し、mTLS+認可を段階導入。今は一つのTonicサーバに同居している。
-
- repomix-output
-
-4. **線形化の“契約”をドキュメント化**
- Watch の順序/Revision と Read の一貫性(ReadIndex/フォロワ/リーダ)をモード化して明示する。API層は既に独立しているので拡張しやすい。
-
- repomix-output
-
-5. **スナップショットと再構築の運用設計**
- 既存のスナップショット構造を基に**chunked streaming/再送/検証**を実装し、ローリングアップグレードと迅速なリカバリを可能に。
-
- repomix-output
-
-6. **MVCC+TSOで“トランザクション対応のFlareDB”へ**
- まずは単一リージョンで2PC/OCCを成立させ、その後リージョンを跨ぐ分散トランザクションへ。Quickstart とタスク表に沿って前進できる。
-
- repomix-output
-
-7. **可観測性と安全性**
- すべてのRaft RPC・適用・スナップショット・Gossipイベントに**トレースID**を通し、Prometheus でSLOを監視。障害注入テスト(ネット分断/ディスク遅延)を回す。
-
-
-* * *
-
-小さく始めるチェックリスト(1–2スプリント)
------------------------
-
-**Chainfire**
-
-* `RaftRpcClient` の gRPC 実装を追加(`internal_proto` をクライアント化)し、`Dummy` を置き換え。
-
- repomix-output
-
- repomix-output
-
-* `api_addr` と `raft_addr` を別 `Server` で `serve`。ログ出力と一致させる。
-
- repomix-output
-
-* Gossip からメンバーの up/down を拾い、Cluster API経由でRaft構成変更に反映。
-
- repomix-output
-
-
-**FlareDB**
-
-* `verify-multiraft.sh` とテスト群に合わせ、リージョンスプリット→新ラフト起動→PD更新→クライアントRegion Cache更新の一連をE2E化。
-
- repomix-output
-
- repomix-output
-
-* フォロワリード/線形化Readの切替をサービスに実装。
-
-* TSO を使った MVCC の最小実装(単一リージョン)を追加してから、2PCへ拡張。
-
- repomix-output
-
-
-* * *
-
-まとめ(現実的な採用ライン)
---------------
-
-* **今すぐの実用**:Chainfire はシングルノードの構成管理KV+Watchに、FlareDB は PD/TSO を含む実験用KV に向く。
-
-* **クラスタ本番**:Chainfire は **Raft RPC 配線+メンバーシップ**実装が最初の関門。FlareDB は **マルチラフト/リージョン運用+MVCC/2PC** が到達点。
-
-* 設計の方向性はどちらも筋が良い。エンジンは積んだ、あとは\*\*配線と路面(運用)\*\*を敷けば走れる、という状態だ。
-
-
-> 補足:この評価はアップロードされたリポジトリのソース構成・実装・Spec/Quickstart に基づいています(抜粋例:依存関係・OpenRaft設定・サーバ起動配線・Dummy/In‑memory RPC・PD/TSO・テスト/スクリプトなど)。必要なら、具体ファイル/行も辿れるように示しました。
->
-> repomix-output
->
-> repomix-output
->
-> repomix-output
->
-> repomix-output
->
-> repomix-output
-
-この先、どのユースケース(たとえばK8sのコントロールプレーン用KV/大規模Key-Valueの裏側/学術実験)を主眼にするかで実装の優先度は変わります。用途を教えてくれれば、必要機能の優先順位表まで落とし込みます。
-
----
-
-## You asked:
-
-repomix-output.xml
-
-ファイル
-
-このようになりました。どうでしょうか?
-
----
-
-## ChatGPT Replied:
-
-Thought for 13m 24s
-
-率直に言って、かなり良いところまで来ています。Raft の内外の配線、Watch の双方向ストリーミング、PD/TSO など「分散KVSとしての背骨」がだいぶ整ってきました。一方で、\*\*“単一ノードでは動くが、複数ノードで本当に回るか?”\*\*に直結するラストワンマイルの配線がまだ少し甘いので、そこを締めれば一気に“触れる分散KV/DB”になります。
-
-以下、\*\*Chainfire(分散KV/クラスタ管理)**と**FlareDB(分散高性能DB)\*\*を分けて、できている点/実用化に向けた詰めポイント/さらに高みを目指す展望を整理します。
-
-* * *
-
-Chainfire(クラスタ管理用分散KV)
-----------------------
-
-### できている点(実装の進捗がはっきり見えるところ)
-
-* **内部Raft RPCサーバ**が `Vote` / `AppendEntries` / `InstallSnapshot` まで実装され、OpenRaft 型へ正しく変換してからノードへ委譲できています。投票リクエストの変換と委譲、AppendEntries のエントリ変換、スナップショットの受信〜インストールまで見えています。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-* **ストレージ側のスナップショット実装**(ビルダー、インストール、取得)が形になっており、OpenRaft のメタ(last\_log\_id/membership)も保持しています。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-* **Watch サービス**は双方向ストリーミングで、内部の `WatchRegistry` と `WatchStream` をうまく繋いでいます。受信側で内部レスポンス→proto変換して送り返す構造になっていて、拡張もしやすい。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-* **クライアントの Watch** も create→BidiStream→イベント受信までワンセットで呼べる形。
-
- repomix-output
-
- repomix-output
-
-* **OpenRaft の基本設定**(ハートビート、選挙タイムアウト、スナップショット方針など)を専用関数で切り出して管理。
-
- repomix-output
-
-
-### 実用化に向けた「詰めポイント」(ここをやると“複数ノード”に跳ねる)
-
-1. **Raft RPC の“配線ミス”を修正**
- `Server` が **Raft 内部サービスを API ポートに混載**して起動しており、ログ上は `raft_addr` を出しているのに **実バインドは `api_addr` のみ**です。集群内の他ノードが `raft_addr` へ接続する前提なら、**Raft 用に別ポートを実際にリッスン**させる必要があります。
-
- repomix-output
-
- repomix-output
-
-
- 具体的には、こんな感じで **2つの gRPC サーバ**を並走させるのが簡明です(概念例):
-
- let api = TonicServer::builder()
- .add_service(KvServer::new(kv))
- .add_service(WatchServer::new(watch))
- .add_service(ClusterServer::new(cluster))
- .serve(api_addr);
-
- let raft_only = TonicServer::builder()
- .add_service(RaftServiceServer::new(raft))
- .serve(raft_addr);
-
- tokio::try_join!(api, raft_only)?;
-
-
-2. **Raft のネットワーククライアント差し替え**
- `RaftNode::new(...)` に **DummyRpcClient** が刺さったままなので、**gRPC 実装(`GrpcRaftClient`)に切り替え**、初期メンバーの `node_id -> raft_addr` マップを読み込んで `NetworkFactory` に登録してください。今は明示的に Dummy 実装が使われ、テスト用にしかならない状態です。
-
- repomix-output
-
- repomix-output
-
-3. **InstallSnapshot の実装を“逐次処理”寄りに**
- 受信側でチャンクを**全部メモリに集めてから**適用していますが、長大スナップショットでメモリ圧迫の恐れ。**Chunk→StateMachine へストリーム適用**できる構造にしておくと堅いです。
-
- repomix-output
-
-4. **AppendEntries のデコード失敗時の扱い**
- `bincode` 失敗を **空ペイロード(Blank)にフォールバック**していますが、ここは **ログ破損/互換不一致の早期検知**のためエラーに倒す方が本番では安心。
-
- repomix-output
-
-5. **ヘッダの `term` 未設定**
- `KvServiceImpl::make_header` の `term` が TODO=0 のまま。リーダのターム反映で**クライアント側の線形化判断**(将来のReadIndex等)にも効きます。
-
- repomix-output
-
-
-### “ここまでできれば使える”最小構成
-
-* `raft_addr` を実ポートとして起動し(上の分離案)、`GrpcRaftClient` に差し替え。
-
-* 単純な3ノード構成で `Put/Range/Watch` を一通り叩く。
-
-* スナップショットが切れるサイズでデータを入れ、再起動や遅延ノードを交えて整合を確認。
-
-
-* * *
-
-FlareDB(分散高性能DB)
-----------------
-
-### できている点(良い骨格)
-
-* **PD/TSO(Timestamp Oracle)** が実装され、単調増加性のテストも入っています。TSO は上位16bitを論理カウンタとしてアトミックに更新する方針。CLI からの TSO 取得ハンドラもあります。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-* **リージョン分割(Region Split)とルーティング**がテストで検証されており、キー範囲に応じた適切なリージョン選択ができています。オーバーラップの検出や PD からの配信を想定した `refresh_regions` も見えます。
-
- repomix-output
-
- repomix-output
-
-* **RaftNetwork(OpenRaft)** を gRPC クライアントで実装する `flaredb-raft` があり、**マルチRaftの土台**ができています。
-
- repomix-output
-
-* **Consistency モードやアンチエントロピー構想**(Namespaceごとの strong/eventual、Merkle 取得など)をプロトコルが先導。将来の“強い整合/最終的整合の両刀”へ布石が見えます。
-
- repomix-output
-
- repomix-output
-
-
-### 実用化に向けた詰めポイント
-
-1. **PD と各 Store(リージョン)の“実時間連携”**
- `report_leader`, `get_region_for_key`, `init_default_region` は揃っているので、**選挙結果をPDに上げる・クライアント側はPDのリージョン/リーダ情報をキャッシュ**という基本ループを堅くしましょう。
-
- repomix-output
-
- repomix-output
-
-2. **強整合(Strong)パスの完成度を上げる**
- いまは CAS/Raw を中心に進んでいます。**MVCC(Multi-Version Concurrency Control)+ロックテーブル**を導入すると、2相コミットや楽観ロック、フォロワ読み(リーダリース)などの高度機能へ進めます。CAS のテストは下地として良いので、これを\*\*MVCC の write/lock/default 3CF(TiKV 流)\*\*へ延ばすのが王道。
-
- repomix-output
-
-3. **マルチRaftの“運用上のツメ”**
- スナップショット/ログ圧縮、リージョンの再配置(peer追加/削除)、Raftの backpressure を入れる。Raft RPC のエラーパスと再送戦略(指数バックオフ)も詰める。
-
-4. **エンドツーエンド・ベンチ**
- Raw/CAS/Range について **単シャード・マルチシャードの QPS/レイテンシ**を CI で回し、リージョンスプリットやスナップショットの閾値を可視化・自動化する。
-
-
-* * *
-
-さらに高みへ(具体ロードマップ)
-----------------
-
-**短期(実用化直前の仕上げ)**
-
-* Chainfire
-
- * Raft を **別ポートで実サーバ起動**し、`GrpcRaftClient` に差し替え。
-
- repomix-output
-
- repomix-output
-
- * AppendEntries のデコード失敗は **エラー返し**に変更。
-
- repomix-output
-
- * InstallSnapshot を **ストリームで適用**(メモリフットプリント削減)。
-
- repomix-output
-
- * `make_header` に **現在term**を反映。
-
- repomix-output
-
-* FlareDB
-
- * PD と Store の **リーダ報告/取得の定期フロー**をサービス化。
-
- repomix-output
-
- * Raft ネットワークの **切断/再接続**と **スナップショット伝送**の堅牢化。
-
- repomix-output
-
- * 強整合パスの **MVCC 基盤**(3CF + トランザクションAPIの雛形)。
-
-
-**中期(性能と機能の拡張)**
-
-* **Follower Read(ReadIndex)** と **Leader Lease** で読みのレイテンシを削減。
-
-* **Async Commit / 1PC(条件成立時)** でライトのP99を短縮。
-
-* **Anti-entropy**(Merkleレンジの実装&同期プロトコル)で最終的整合モードの信頼性を底上げ。
-
- repomix-output
-
-* **観測性の充実**(Raft/Storage/PD のメトリクス、トレース)と **障害注入テスト**。
-
-
-**長期(プロダクション要件)**
-
-* **TLS/mTLS**、**ローリングアップグレード**、**ディスク/ネットワーク障害に対する耐性試験**。
-
-* **オンラインリージョンスプリット/マージ** と **自動バランシング**(PDがホットレンジを検知して指示)。
-
-
-* * *
-
-総評(今の実用性)
----------
-
-* **Chainfire**は、\*\*Raft内外の配線を仕上げれば“実際に3ノードで回る分散KV”\*\*になります。Watch/Cluster/KV のAPIも揃っているので、**クラスタ管理の中核**として十分育ちます。
-
- repomix-output
-
- repomix-output
-
-* **FlareDB**は、**PD/TSOとリージョン分割の骨格**があり、\*\*マルチRaftと一緒に“スケールする高性能KV/DB”\*\*の方向へ素直に伸びます。MVCC/Tx を入れれば“フル装備の分散トランザクションDB”へ踏み込めます。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-
-このフェーズなら、**「まずは3ノードのChainfireクラスタ+FlareDB単リージョン」を立ち上げ**、`Put/Range/Watch` と **リージョンスプリット→PD更新→クライアントのルーティング**の一連を回す“スモークテスト”を作るのが最短距離です。そこまで通ったら、性能ベンチとMVCCへフェーズアップしていきましょう。
-
----
-
-## You asked:
-
-repomix-output.xml
-
-ファイル
-
-更に機能を追加しましたが、どうでしょうか?
-
----
-
-## ChatGPT Replied:
-
-Thought for 8m 34s
-
-良い伸び方してます。新しく入った実装を“何がもう実用レベルか/どこがまだ骨組みか”で切り分けて、次の登り方の提案までまとめます。
-
-* * *
-
-いま入った機能の読み取り(Chainfire)
------------------------
-
-**gRPC Raft RPCの道が通りました。**
-
-* 生成されたRaftのgRPCには `Vote` / `AppendEntries` に加えて **`InstallSnapshot`(ストリーミング受信)** まで生えています。クライアント側は `client_streaming` を要求し、サーバ側は `ClientStreamingService` として受ける形です。
-
- repomix-output
-
- repomix-output
-
-* `chainfire-server` のCLIは **API/RAFT/Gossip の各アドレスを別々に指定**でき、起動時にそれぞれをログに出すように。サーバ側はAPIとRaftを**別サーバで立てる準備**が進んでいます(実装箇所はserver側・生成コード側の両方で確認)。
-
- repomix-output
-
- repomix-output
-
-* Raftノード構築は **外部注入のRPCクライアントを渡す設計**になり、初期メンバーを gRPC クライアントへ登録するフローも入りました。
-
- repomix-output
-
- repomix-output
-
-
-**ストレージとRaft設定も“実戦設定寄り”。**
-
-* OpenRaft設定ではスナップショットのチャンク上限を **3MB** に、スナップショット方針は **“最後のスナップショット以後のログが5000件たまったら”** と定義。実運用値の雰囲気が出てきました。
-
- repomix-output
-
-* RocksDBを背にした **統合Storage(ログ+状態機械+スナップショットビルダ)** が実装済み。OpenRaftのトレイトをまとめて受ける“合体ストレージ”の形です。
-
- repomix-output
-
- repomix-output
-
-
-> **実用度(Chainfire)**
-> ローカル〜少数ノードで **Raft RPCが往復してログ適用まで**の道筋は見えています。API/RAFTポート分離の方向性、Storageまわりも本格的。次節の「足りないところ」を詰めれば、**実験クラスタ〜小規模常時稼働**は現実的です。
-
-* * *
-
-いま入った機能の読み取り(FlareDB)
----------------------
-
-**PD(Placement Driver)・TSO・リージョン分割の“分散の芯”が入った。**
-
-* PDは **Store登録とRegionメタ管理**を持ち、ブートストラップ用の自動リージョン生成の雛形まで入っています(MVPではpeersの表現がまだ粗く、リーダーID単体を使う設計メモ付き)。
-
- repomix-output
-
- repomix-output
-
-* サーバは **PDに繋がらない場合のスタンドアロン起動**と、接続できたら `refresh_regions` でメタを更新するコードパスを実装。
-
- repomix-output
-
- repomix-output
-
-* **TSO(Timestamp Oracle)** は“物理ミリ秒<<16 | 論理16bit”構成で単調性を多スレッドで検証済み。
-
- repomix-output
-
- repomix-output
-
-* **リージョン分割(split)** はStore APIでの分割・経路表更新・重複検出・無効キー拒否などのテストが入っています。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-* **CASの整合性**(競合で現在値を返す)がクライアントE2Eテストで確認できます。
-
- repomix-output
-
-* クライアントには **RegionCache** が生え、`[start, end)` の範囲でルーティングする前提の形に。CLIも Raw/CAS/TSO を一通り叩けます。
-
- repomix-output
-
- repomix-output
-
-
-> **実用度(FlareDB)**
-> 単一ノード〜少数ノードの**キー空間分割・ルーティング・CAS・TSO**は試せる段階。PDを介したメタ配布やリージョン更新のワークフローが光っています。**高スループット×強整合**の本番運用には、Raftの複数グループ化・フォロワリード・フェイルオーバの詰めが必要、という立ち位置。
-
-* * *
-
-ここから“実戦投入”へ詰めるべきポイント
---------------------
-
-**Chainfire(分散KV/クラスタ基盤)**
-
-1. **Raft RPCの再接続・タイムアウト・バックオフ**
- いまは接続表の導入やポート分離の地ならしまで。トランスポート層での**失敗時リトライ/指数バックオフ/締切時間(deadline)**は早めに入れると事故が減ります。`InstallSnapshot` はgRPCの**クライアントストリーミング**を使える形なので、**チャンク分割+進捗再送**を設計してください。
-
- repomix-output
-
-2. **監視・計測(Prometheus/OpenTelemetry)**
- 選挙回数・遅延分布・`append`/`apply`レイテンシ、スナップショットサイズ等のメトリクスがあると、クラスタの“体温”が見えます。
-
-3. **メンバーシップ変更の安全化**
- Learner追加→昇格の手順と、`remove-node` の安全手順。OpenRaft側の手当と合わせてE2Eで落とし込みを。
-
-4. **ディスク耐障害性の検証**
- RocksDBのオプション(WAL・圧縮・fsync頻度)と、**クラッシュ直後再起動**の再現テストを。“ログ先→スナップショット再構築”の導線は既にあります。
-
- repomix-output
-
-
-**FlareDB(分散高性能DB)**
-
-1. **マルチRaft(リージョンごとRaftグループ)**
- いまの分割ロジックは鍵空間の管理が中心。次は**RegionごとにRaftノードを束ねる**実体化を。PDのRegionメタ返却に**PeersとLeader**を明示で含め、クライアントのRegionCacheも**Follower/Leader識別**へ拡張。
-
- repomix-output
-
- repomix-output
-
-2. **フォロワリード(ReadIndex/Lease read)**
- 強整合モードでも読み取りのホットスポット緩和に効きます。
-
- * Leader lease内はLeader直読
-
- * それ以外は `ReadIndex` 経由でFollower読みに落とす
- Namespaceモード切替のプロトが既にあるので(`strong`/`eventual`)、ここに**read pathの分岐**を繋げると綺麗にハマります。
-
- repomix-output
-
-3. **リージョンスプリットの自動化**
- 現状は手動分割のテストが充実。**サイズ基準やキー分布のヒストグラム**で自動スプリットのトリガを入れると、PD→Store→Raftの**分割オーケストレーション**の通し試験に移れます。
-
- repomix-output
-
-4. **Merkle+レンジFetchでの最終一致検証**
- Merkle木と範囲フェッチのRPCが用意されているので、**レプリカ間の差分検査→差分取り寄せ**の“棚卸し”プロトコルを入れると、イベント駆動レプリケーションの堅牢さが増します。
-
- repomix-output
-
- repomix-output
-
-5. **トランザクション拡張(MVCC/2PC/Async Commit)**
- まずは **MVCCのread\_ts/commit\_ts** と **ロックCF** を切るところから。既に **TSO** があるので時刻配布は土台が整っています。
-
- repomix-output
-
-6. **クライアントのリージョン再解決**
- ルーティングミス時(`NotLeader`や`RegionNotFound`)に**PD問い合わせ→RegionCache更新→リトライ**の共通パスを。エラー型は既に定義済み。
-
- repomix-output
-
-
-* * *
-
-すぐ試せる“実験レシピ”
-------------
-
-* **単ノードのCAS/TSO/E2E**:いまのクライアントCLIで既に叩けます。`cas` の競合動作はテストでも確認済み。
-
- repomix-output
-
- repomix-output
-
-* **リージョン分割のルーティング確認**:`split_region` 後に `[a]` と `[z]` のキーで別リージョンにルーティングされることを確認。
-
- repomix-output
-
-* **PDダウン→スタンドアロン起動→再接続**:スタンドアロンで1リージョンをブート後、PD復帰で `refresh_regions` が走る経路をトレース。
-
- repomix-output
-
-
-* * *
-
-まとめの見立て
--------
-
-* **Chainfire** は「**クラスタ管理の土台(Raft通信・ストレージ・ポート分離)」が実用域へ近づいた段階**。失敗時制御と可観測性を入れれば、検証環境を越えて**小〜中規模の常時稼働**に十分届きます。
-
- repomix-output
-
- repomix-output
-
-* **FlareDB** は「**分散の芯(PD/TSO/リージョン分割)」が揃い、CAS中心の**小さな一貫性ドメイン**をきれいに動かす所まで来ました。次は**マルチRaft+フォロワリード+自動スプリット**を繋げて**高スループット×低レイテンシ\*\*の世界に持ち上げるターンです。
-
- repomix-output
-
- repomix-output
-
-
-この先は、**“落ちるところを先に計測し、計測できるところを先に高速化”** の順で攻めると開発速度も信頼度も両立しやすいです。具体的には、Raft RPCの締切/再接続、メトリクス導入、PD連携の負荷試験、リージョン数増加時のキャッシュヒット率と再解決コスト、を数値で可視化してから最適化に入るのが王道。数字は嘘をつかない、ついでにボトルネックも隠れてくれません。
-
----
-
-## You asked:
-
-実は、OpenStackの代替を作ろうとしています。そのために、クラスターをうまく管理できる必要があると思います。設定の書き方が大事だと思いますが、どうすべきだと思われますか?
-
----
-
-## ChatGPT Replied:
-
-Thought for 4m 22s
-
-狙いが “OpenStackの代替” なら、\*\*設定(Configuration)は“運用の言語”\*\*です。読めて、差分が取れて、段階的に反映できて、ロールバックできることが最重要。いまのChainfire/FlareDBの実装断片から読み取れる前提に乗っかりつつ、\*\*静的(ブートストラップ)**と**動的(ランタイム)\*\*をきれいに分けた二層設計をおすすめします。
-
-* * *
-
-まず現状の把握(コードから見える事実)
--------------------
-
-* **Chainfire** は API/Watch/Cluster/内部RaftのgRPCを同一プロセスでホストしていて、`api_addr` と `raft_addr` をログ出ししています(=ネットワーク周りはすでに分離設計)。
- CLI引数で `api_addr/raft_addr/gossip_addr` などを**設定ファイル値に上書き**できるようになっている(=運用フレンドリーの素地)。
- また `cluster.bootstrap` が有効なら初期化(Split-brain回避には扱い注意)。
-
-* **初期メンバー**はRaft RPCクライアントに `id` と `raft_addr` で登録している(=設定で`initial_members`にID+アドレスを持たせればよい)。
-
-* **Watchサービス**を提供しており、設定の動的反映に向く通知路がもうあります。ワークスペース依存にも `chainfire-watch` が入っています。
-
-* **FlareDB** は「名前空間(namespace)ごとに一貫性モード(Strong/Eventual)を持つ」`ServerConfig` を用意(デフォルトnamespace “default” は必ずid=1で用意)。
- さらに **モード取得/更新/List** のRPC契約があり(`GetMode/UpdateNamespaceMode/ListNamespaceModes`)、運用API化の道筋が見えます。
-
-* \*\*リージョン(範囲分割)\*\*は、「重なり検出でエラー」「PDメタからのリフレッシュで置き換え」「分割後に正しくルーティング」という流れのテストが通っており、**設定適用時にバリデーションを必須にすべき**ことが見て取れます。
- 検証スクリプトも `rdb-server --addr ... --pd-addr ...` のCLIを前提に動きます。
-
-
-* * *
-
-原則(OpenStack代替の“運用の言語”にするための7か条)
---------------------------------
-
-1. **二層化**:
-
- * **静的設定(ブートストラップ)**=“ノードが起動できる最低限”だけをTOML/JSONに。例:ノードID、役割、リッスンアドレス、データディレクトリ、初期クラスタメンバー。
-
- * **動的設定(ランタイム)**=“運用でいじるもの”は**ChainfireのKVに置き、Watchで反映**。例:メンバーシップ変更、名前空間の一貫性モード、レプリカ数、移動/分割ポリシー。
-
-2. **不変と可変の境界**を明示:起動に必要な不変情報(`raft_addr` など)と、後から変えたい情報(NSのモード等)を違うレイヤに。
-
-3. **スキーマと検証**:適用前に**バリデーション**(重複リージョン禁止等)を必須化。FlareDBの重なり検出テスト相当をサーバ側“Apply”時に実行。
-
-4. **宣言的&差分適用**:Configを“望ましい状態”として宣言→Raft提案→Watch経由で各ノードが**Idempotent**に収束。CAS更新や“世代番号”で競合抑止(CASはクライアント側テストもあり)。
-
-5. **段階的ロールアウト**:`staged → canary → rolling → commit`。失敗時は**自動ロールバック**。
-
-6. **監査可能性**:適用トランザクションをイベントログ化(誰がいつ何を設定したか)。
-
-7. **ローカル上書き(CLI/ENV)≧ファイル≧KVの優先順位**を明記。現状のCLI上書き機構はそのまま活かせる。
-
-
-* * *
-
-推奨:設定の“二層設計”
-------------
-
-### ① 静的(ノード)設定:`chainfire.toml`
-
-Chainfireは `api_addr / raft_addr / gossip_addr` を個別に持っているので、そのまま**ノードファイル**に寄せるのが素直です。
-
- # /etc/chainfire/chainfire.toml
- [node]
- id = 3
- name = "cf-node-3"
- role = "control_plane" # or "worker"
-
- [cluster]
- id = 42
- bootstrap = false
- # 初回だけseedノードでbootstrap=true。他はfalseにする。
- initial_members = [
- { id = 1, raft_addr = "10.0.0.1:24001" },
- { id = 2, raft_addr = "10.0.0.2:24001" }
- ]
-
- [network]
- api_addr = "0.0.0.0:23001"
- raft_addr = "0.0.0.0:24001"
- gossip_addr = "0.0.0.0:25001"
-
- [storage]
- data_dir = "/var/lib/chainfire"
-
-
-* **only 1ノードだけ** `bootstrap=true` にする設計ルール:複数ノードが同時bootstrapしないよう運用規約で固定。
-
-* **CLI上書き**(例: `--api-addr`)は既存実装の通り活かす。
-
-
-### ② 動的(クラスタ)設定:**Chainfire KV** に集約
-
-* 例:
-
- * `/cluster/members/ = {"raft_addr": "...", "role": "worker"}`(追加/退役をRaft提案で)
-
- * `/flaredb/namespaces/ = {"id": 1, "mode": "strong"}`(Strong/Eventual切替をロールアウト)
-
- * `/flaredb/placement/regions/ = {start,end,replicas...}`(適用前に重複検証)
-
-* これらのキーを**Watch**で購読し、各ノードが**安全な順序**で反映(サービスが `WatchServer` を持っているのを利用)。
-
-
-> FlareDBは名前空間のモード管理が型で切られていて(Strong/Eventual, default NS=1)、API契約も定義済み。\*\*モード変更を“KV→RPC適用”\*\*で繋ぐのが筋が良いです。
-
-* * *
-
-具体策:適用フロー(安全第一)
----------------
-
-1. **提案(Propose)**: オペレータは「ClusterConfig v42」をKVに**CAS**で作成(`/cluster/pending/v42`)。
-
-2. **検証(Validate)**: コントロールプレーン(Chainfire側)がサーバ内ロジックで**リージョン重複・不正キー**などを検証。FlareDBテストでやっている“重複検出/分割後ルーティング正常”をそのままサーバ適用前バリデーションに移植。
-
-3. **カナリア(Canary)**: `region ≤ N` / `namespace subset` / `read-only` など絞って適用。遅延やエラー率を監視。
-
-4. **ローリング(Rolling)**: 世代番号 `generation` を増やしながら段階的に反映(各ノードは `generation` 比較で冪等apply)。
-
-5. **コミット/公開(Commit)**: 合格したら `/cluster/current` を v42 にAtomically切替。
-
-6. **ロールバック**: 監視メトリクスがしきい値超過なら `/cluster/current` を直前世代に戻す。
-
-
-※ CASと“現在値の世代確認”は既にクライアントのCASテストがあるので概念的に馴染むはずです。
-
-* * *
-
-どう“書く”と運用しやすいか(書式・スキーマ)
------------------------
-
-* **ファイルはTOML(静的)**:人が手で直すので読みやすさ重視。`clap` でCLI上書き、`serde`でロード、`schemars`等で**JSON Schema自動生成**→Lint可能。
-
-* **KVはJSON(動的)**:差分と監査、`curl`/`grpcurl`で触りやすい。
-
-* **スキーマ厳格化**:
-
- * アドレス衝突チェック(`api_addr ≠ raft_addr ≠ gossip_addr`)
-
- * `initial_members`は `id + raft_addr` を必須(コードがそう使っている)
-
- * FlareDBの `namespace.mode ∈ {strong,eventual}`(型ですでに担保)
-
- * リージョンは`[start,end)`半開区間、重なり禁止(テスト準拠)。
-
-
-* * *
-
-サンプル:FlareDBの動的設定(KV側)
-----------------------
-
- // /config/flaredb/namespaces/default
- { "id": 1, "mode": "strong" }
-
- // /config/flaredb/namespaces/logs
- { "mode": "eventual" } // 未指定ならサーバ側defaultでid払い出し
-
- // /config/flaredb/placement/regions/1
- { "start": "", "end": "m", "replicas": [1,2,3] }
-
- // /config/flaredb/placement/regions/2
- { "start": "m", "end": "", "replicas": [2,3,4] }
-
-
-* 反映器(オーケストレータ)は、KVの変更をWatchで購読→FlareDB RPC `UpdateNamespaceMode` 等に橋渡し。
-
-* 適用前に**リージョン重複バリデーション**を必ず実行(テストのロジック準拠)。
-
-
-* * *
-
-運用の“落とし穴”と対策
-------------
-
-* **二重Bootstrap**:`bootstrap=true` ノードが複数存在しないよう**起動時ガード**。起動時にクラスタ状態を観測し、既に`current`があれば拒否。
-
-* **設定ドリフト**:各ノードは定期的に`/cluster/current`世代とローカル反映世代を比較し、**差分検知**をエラーログ&メトリクスに出す。
-
-* **NSモード不一致**:`diff_modes` 的な比較APIを揃えて「ノード間でのモード相違」を発見次第、警告を出す(テストが既に存在)。
-
-* **秘密情報**:KVに生で置かない。`sops`/KMS等で暗号化→ノードではENVで復号、またはSecret専用ストアを別に。
-
-
-* * *
-
-直近の実装TODO(効果が大きい順)
-------------------
-
-1. **ServerConfigバリデータ**(Chainfire)
-
- * アドレス重複や`initial_members`の整合性チェックを起動前に。
-
-2. **KV側の“世代付きClusterConfig”スキーマ確定**
-
- * `generation`, `created_by`, `validated`, `rollout_policy` 等を定義。
-
-3. **適用オーケストレータ**
-
- * KV Watch → 検証 → カナリア → ローリング → Commit → ロールバック の一連を実装。
-
-4. **FlareDBモード連携**
-
- * KVの`/flaredb/namespaces/*`変更を`UpdateNamespaceMode`に橋渡し。デフォルトNS(id=1)保証ロジックを踏襲。
-
-5. **テレメトリ**
-
- * 反映世代、失敗理由、リージョン重複検出、モード不一致をメトリクス化(ダッシュボード前提)。
-
-
-* * *
-
-まとめ
----
-
-* **静的はノードの身元と入口だけ、動的は全部KV**。
-
-* **適用は検証つき宣言的ロールアウト**。
-
-* 既存コードの資産(Watch、CLI上書き、NSモードAPI、リージョン重複テスト)が**そのまま強い設計基盤**になります。
-
-
-次のステップとして、上の`chainfire.toml`テンプレとKVキー階層(`/config/...`)を最小セットで刻み、\*\*“世代付きの安全な適用ループ”\*\*を一気に通してみるのが近道。そこまで行けば、Nova/Neutron/Cinder的な上位エージェントは「Watchして実行して状態を返す」薄い作りで量産できます。
-
----
-
-## You asked:
-
-あと、OpenStackの代替をするにあたって「何が必要か(IAM?VPC?DNS?)」について教えてほしいです。現時点で次に何に取り組むべきかがわかっていません。
-
----
-
-## ChatGPT Replied:
-
-Thought for 3m 55s
-
-狙いが「OpenStackの代替」なら、まず“クラウドの最小構成(Minimum Viable Cloud)”を定義してから、Chainfire/FlareDBの強み(分散KV+Watch、名前空間の一貫性モード、リージョン分割、PD/TSO 風のコントロールプレーン)に合わせて落とし込むとハマります。下は**何が要るか**と**次に何を作るか**の地図です。
-
-* * *
-
-1) 必要なコンポーネント(OpenStackに相当する面)
-------------------------------
-
-### A. アイデンティティ & マルチテナンシ(IAM)
-
-* **ユーザ/プロジェクト(テナント)/ロール**、**サービスアカウント**、**トークン発行**(JWT/OIDC連携でも可)。
-
-* **RBAC**と**クォータ**(プロジェクト単位のインスタンス数、vCPU、RAM、ボリューム容量、Floating IP 等)。
-
-* Chainfire の「KV+Watch」を\*\*単一の真実の所在(SSOT)\*\*にして、変更は Watch で各エージェントへ配信する構成が自然。Chainfire は gRPC で KV/Watch/Cluster を API サーバに載せ、Raft 用サーバを分離できるので、**外部APIと内部複製の経路分離**がデフォルトでできます。
-
-* Watch は**双方向 gRPC ストリーム**で、クライアント側から Create/Cancel/Progress を流し、サーバはイベントをプッシュ可能(Controller→Agent の通知に最適)。
-
-
-### B. ネットワーク(VPC)
-
-* **VPC / サブネット / ルータ / ルートテーブル / NAT**、**セキュリティグループ**、**Floating IP**、最初はL3中心でOK(L2は後回し)。
-
-* **IPAM**(アドレス管理)と**DNS**(プロジェクト内ゾーン、インスタンス名解決、メタデータ域の逆引き)が要点。
-
-* \*\*L4ロードバランサ(VIP)\*\*は後追いでも良いが、北向きAPIは先に定義。
-
-* ネットワーク状態は Chainfire の Keyspace を**リソース毎のプレフィクス**でモデリングし、FlareDB の**リージョン分割**(prefix のレンジ分割)でスケールさせると良い。重複レンジを弾き、PD 相当が配列を刷新してもルーティングが正しく入れ替わるテストが揃ってます。
-
-
-### C. コンピュート(Nova 相当)
-
-* **イメージからの起動/停止/削除/リサイズ**、**NIC/VIF のアタッチ**、**メタデータ & cloud-init**(169.254.169.254)。
-
-* 最初は **KVM/QEMU or Firecracker** のどれか1本に絞る。**Scheduler** は“重み付きビンパッキング(vCPU/RAM/NUMA/ラベル)”のシンプル版で十分。
-
-
-### D. ストレージ(Cinder/Swift 相当)
-
-* \*\*ブロック(Volume/Snapshot/Attach/Detach)\*\*を先行、**オブジェクト**は後回しでも実用に届きます。
-
-* まずはローカルLVM等の“プール1種・可用性は低め”から始め、のちにネットワーク分散(レプリカ/Erasure)へ拡張。
-
-
-### E. 監視・課金・イベント
-
-* **メトリクス/ログ/イベント**、**使用量メータリング**、**アラート**。
-
-* Chainfire の Watch と Gossip を使えば、**コントローラ→エージェントの宣言的配信**と**エージェント→コントローラの状態伝搬**が素直に噛み合います。
-
- repomix-output
-
-
-* * *
-
-2) “設定の書き方”の指針(単一の真実をKey-Valueに)
---------------------------------
-
-あなたのコードは、**API/RAFT/Gossip の三つの経路**を設定ファイルで独立指定できる構造です(`api_addr`/`raft_addr`/`gossip_addr`)。**外部のクライアント**は API を叩き、**内部の複製や会員管理**は Raft/Gossip を使うという分離前提で設計・デプロイができます。
-
-**推奨:宣言的/二層構造の設定**
-
-* **層1: 静的ノード設定**(起動前に読む)
- `node.id/name/role`、`network.api_addr/raft_addr/gossip_addr`、`storage.data_dir`、`cluster.initial_members` 等。
-
-* **層2: クラスタの動的リソース**(KVに保存/Watch配信)
-
- * `/iam/users/*`, `/iam/projects/*`, `/iam/roles/*`
-
- * `/net/vpcs/*`, `/net/subnets/*`, `/net/routers/*`, `/net/secgroups/*`, `/net/fips/*`
-
- * `/compute/instances/*`, `/compute/images/*`
-
- * `/storage/volumes/*`
- これらは\*\*「spec」「status」二本立て\*\*(所望状態と現在状態)。Controller が spec を見て reconcile、Agent は status を上げる。**差分イベント**は Watch の双方向ストリームで配信。クライアント側 Watch 実装も既にあります。
-
-
-**一貫性の設計(強い/最終的)**
-FlareDB は**名前空間(namespace)単位で “strong / eventual” を切り替える API**を持っています。**IAMや課金・クォータ**は strong、**メトリクスや一部キャッシュ**は eventual、と用途別に切り分ける方針が取りやすいです。
-
-**シャーディング/ルーティング**
-Keyspace をリソース種別ごとにプレフィクスで分け、FlareDB の**リージョン分割**(split/refresh)でホットレンジを切る。重複検知や再配置の振る舞いはテストでカバーされています。
-
-**順序づけ(TSO/ID発番)**
-分散トランザクションを避けつつ“全体順序”が要る場面では、PD/TSO 風の**単調増加タイムスタンプ**を使うと設計が簡単になります(物理ビット+論理カウンタ形式の TSO 定義あり)。
-
-repomix-output
-
-* * *
-
-3) 次に作るべきもの(6–8週間の打順)
----------------------
-
-### フェーズ0:制御面の背骨を固める(1–2週間)
-
-* **コアAPI の型定義**(gRPC/HTTP)と**リソースモデル**:Project/VPC/Subnet/Router/SecGroup/FloatingIP/Instance/Volume/Image(spec/status)。
-
-* **Controller/Agent 方式**のスケルトン:
-
- * `net-controller`(IPAM, ルーティング, NAT, SG)
-
- * `compute-controller`(スケジューリング、起動指示)
-
- * `volume-controller`
-
- * 各ノードに `compute-agent`/`net-agent`/`volume-agent`。
-
-* **強い整合性が要る Keyspace は “strong” 名前空間に**、監視系は “eventual” に分離。
-
- repomix-output
-
-
-### フェーズ1:最小IAM + 認証(1–2週間)
-
-* Users/Projects/Roles/RoleBindings、トークン発行(JWT)を**Chainfire KV**で管理し、**Watch でキャッシュ更新**。
-
-* API サーバは mTLS or JWT 検証。**Cluster/Watch/KV を同居**させる現行構造で開始。
-
- repomix-output
-
-
-### フェーズ2:VPCのMVP(2週間)
-
-* **VPC/サブネット/ルーティング/NAT/SG**の CRUD と IPAM。
-
-* `net-agent` は WireGuard/OVS/iptables 等のどれか**1手**に絞る(最初は L3 NAT 中心でOK)。
-
-* **Floating IP** と **プロジェクト内DNS**(A/AAAA だけ)を用意。
-
-* Keyspace を prefix で区切り、**リージョン split**でスケール観点を実験。
-
- repomix-output
-
-
-### フェーズ3:ComputeのMVP(2週間)
-
-* **イメージ登録→インスタンス起動**のフロー:`compute-controller` が spec を Watch、`compute-agent` が起動し status を報告(Gossip/Watch)。
-
-* Scheduler は**最小の重み付き**(vCPU/RAM/アフィニティ)で良い。
-
-* **メタデータサービス**と cloud-init を先に通すと実用性が一気に上がる。
-
-* 変更イベントの配信は**双方向 Watch**を使用。
-
- repomix-output
-
-
-* * *
-
-4) 具体的な設定/キー設計の雛形
------------------
-
-**静的ファイル(例:`chainfire.toml`)**
-
- [node]
- id = 101
- name = "worker-01"
- role = "worker"
-
- [network]
- api_addr = "10.0.0.10:2379"
- raft_addr = "10.0.0.10:2380"
- gossip_addr= "10.0.0.10:2381"
-
- [cluster]
- id = 1
- bootstrap = false
- initial_members = [{ id=1, raft_addr="10.0.0.1:2380" }]
-
-
-この分離(APIとRaftとGossip)はあなたのサーバ実装がそのまま受け入れてくれます。
-
-repomix-output
-
-**KV階層(例)**
-
- /iam/projects/{prj}
- /iam/users/{user}
- /iam/roles/{role}
-
- /net/vpcs/{vpc}
- /net/subnets/{subnet}
- /net/routers/{router}
- /net/secgroups/{sg}
- /net/fips/{fip}
-
- /compute/images/{img}
- /compute/instances/{vm}
-
- /storage/volumes/{vol}
-
-
-各キーの値は `{spec: {...}, status: {...}}`。Controller は spec から reconcile、Agent は status を更新。Diff は Watch で配る(双方向ストリーム実装あり)。
-
-repomix-output
-
-**一貫性モードの割当**
-
-* `iam/*`, `net/*`(制御メタ)、`compute/instances/*` の **spec** → **strong**
-
-* `*/status` と `metrics/*` → **eventual**
- モードの CRUD は FlareDB の **Get/Update/ListNamespaceMode** で行えます。
-
- repomix-output
-
-
-**ID/順序**
-
-* 重要操作の ID/リビジョンは **TSO** 由来の単調増加値を使う(`physical<<16 | logical` 形式の定義あり)。これで“重複作成の排除・ソート・監査”が楽になります。
-
- repomix-output
-
-
-* * *
-
-5) 技術的に“効く”設計の肝
----------------
-
-* **宣言的コントロールプレーン**:すべての Desired State を KV に、**差分は Watch で**。Raft/Gossip/Watch の土台が既に実装されているので、Controller/Agent を載せるだけでスケールするコアになります。
-
-* **名前空間で整合性を切る**:強い整合性が必要な部分だけ strong。他は eventual。可用性とレイテンシを稼げます。
-
- repomix-output
-
-* **レンジ分割でホットスポット回避**:プレフィクス設計+リージョン split/refresh をコントローラから駆動。
-
- repomix-output
-
-* **API/RAFT/Gossip の経路分離**:障害ドメインを分け、外部公開面の堅牢性を上げる。
-
- repomix-output
-
-
-* * *
-
-### まとめ
-
-* **必須パーツ**:IAM、VPC(+IPAM/DNS/SG/NAT)、Compute、Block Storage、Image、メタデータ、監視/課金。
-
-* **設定の流儀**:静的ノード設定はファイル、**動的リソースはKV+Watch**。一貫性は**namespace単位で strong/eventual** を切り替える。
-
-* **次やること**:①リソースモデルとAPIの確定 → ②IAM最小実装 → ③VPC L3(IPAM/DNS/SG/NAT) → ④Compute起動までのE2E。
-
-
-この順で走れば、「OpenStackっぽい“全部入り”」を目指しつつも、土台(Chainfire/FlareDB)の良さ=**宣言的&イベント駆動**を活かした、軽量で理解しやすいクラウドに仕上がります。次の段で、各リソースの具体的な proto/JSON スキーマ(spec/status のフィールド)も一気に叩き台を出せます。
-
----
-
-## You asked:
-
-IAMの権限系をどうやって設計するかに困っています。
-
----
-
-## ChatGPT Replied:
-
-Thought for 3m 57s
-
-狙いが明確でよいです。OpenStack 代替を本気でやるなら、IAM は「後付け ACL」ではなく**クラスタの“制御面 API”そのもの**として設計するのが成功パターンです。以下は、あなたの Chainfire(分散 KV)と FlareDB(分散 DB/TSO)を前提にした、**実装可能な IAM 設計**と当面の道筋です。
-
-* * *
-
-要点(TL;DR)
----------
-
-* **スコープ階層**:`system > org(domain) > project(tenant) > resource`。評価は**最も狭いスコープ優先**、デフォルト拒否(deny-by-default)。
-
-* **モデル**:RBAC(ロール)を土台に、必要箇所だけ ABAC 条件(owner、project、node、time など)を混ぜる**ハイブリッド**。
-
-* **格納**:IAM の実体(ユーザ/ロール/バインディング/境界)は**Chainfire の「強整合」ネームスペース**に保存(弱整合は不可)。Namespace モードは API で操作できる前提(`GetMode / UpdateNamespaceMode / ListNamespaceModes`)。
-
- repomix-output
-
- repomix-output
-
-* **配布**:各サービスの PEP(Policy Enforcement Point)は**ウォッチでポリシーを購読・キャッシュ**し、変更は**双方向 gRPC ストリーム**で即時反映。
-
- repomix-output
-
- repomix-output
-
-* **更新の整合**:ポリシー更新は **CAS(Compare-And-Swap)** で衝突解決。FlareDB の CAS/バージョン設計に乗る。
-
- repomix-output
-
-* **トークン**:認証は OIDC/JWT(外部 IdP 可)。権限は**一時セッショントークン**で発行し、`iat`/`exp` は **TSO(物理48+論理16)** の単調増加タイムスタンプで刻印(クロックスキュー防止)。
-
- repomix-output
-
- repomix-output
-
- repomix-output
-
-* **最小ロール**:`SystemAdmin / OrgAdmin / ProjectAdmin / ProjectMember(標準) / ReadOnly / ServiceRole-*` を先に固定配布。
-
-
-* * *
-
-1) スコープとエンティティ
---------------
-
-**エンティティ**
-
-* **Principal**: `User` / `ServiceAccount`
-
-* **Group**: 任意(大規模化したら導入)
-
-* **Project**(= tenant)/ **Org**(= ドメイン)
-
-* **Role**: `Action` の集合
-
-* **PolicyBinding**: `principal(or group) × role × scope × 条件`
-
-
-**スコープ**
-
-* `system`(クラスタ全体・コントロールプレーン)
-
-* `org`(組織/ドメイン)
-
-* `project`(テナント)
-
-* `resource`(個別リソース:VM、Volume、VPC、LB、Image、DNS Zone 等)
-
-
-評価順は**最狭→最広**でマージ、**明示 Deny 優先**、最終的に 1 つでも Allow がヒットすれば許可(ただし境界で打ち止め後述)。
-
-> Chainfire は API / Raft のエンドポイントが分離されており(`api_addr / raft_addr / gossip_addr`)、IAM の PEP を**API 側**に据えやすい構造です。
->
-> repomix-output
-
-* * *
-
-2) ポリシーモデル(RBAC + 条件)
----------------------
-
-### アクション命名
-
-`::[verb]` 例:
-
-* `compute:instances:create|read|update|delete|start|stop|attachVolume|detachVolume`
-
-* `network:vpc:create|delete`
-
-* `block:volumes:create|attach|detach|delete`
-
-* `iam:*`(自己管理系を最小限)
-
-
-### 条件(ABAC)キー例
-
-* `principal.org`, `principal.project`, `principal.uid`, `principal.groups[]`
-
-* `resource.project`, `resource.owner`, `resource.node`, `resource.region`, `resource.tags[]`
-
-* `request.ip`, `request.time`, `request.auth_level`(MFA など)
-
-
-### 権限の境界(Permission Boundary)
-
-* **ServiceAccount** には**最大許可境界**を付与(例:`compute-agent` は `resource.node == self` のものに限る)。
-
-* ユーザにも**セッション境界**をサポート(AssumeRole 時にさらに絞る)。
-
-
-* * *
-
-3) データモデル(Chainfire/FlareDB に素直に乗せる)
-------------------------------------
-
-**強整合ネームスペース**(例:`iam`)にキーを設計。Namespace の強/弱は API で設定・列挙可能(`UpdateNamespaceMode/ListNamespaceModes`)。IAM は**強**で固定してください。
-
-repomix-output
-
-repomix-output
-
- /iam/users/ -> { uid, name, org, projects[], oidc_sub, keys[] }
- /iam/service-accounts/ -> { id, org, project, node?, boundary_policy_ref }
- /iam/projects/ -> { id, org, owners[], ... }
- /iam/roles/ -> { scope: "system|org|project|resource",
- permissions: [ {action, resource, condition?} ] }
- /iam/bindings///
- -> { principalRef, roleRef, condition?, createdAt(ver) }
- /iam/policies/ -> policy doc(境界/共有用)
- /iam/indices/... -> 逆引き用(principal→bindings、project→users)
-
-
-* **更新**は CAS。FlareDB の CAS API で version を進め、失敗したら現行版でリトライ。
-
- repomix-output
-
-* **監査**は別ネームスペース `audit`(強整合)に Append。後で Watch でストリーム配信。
-
-
-* * *
-
-4) 配布とキャッシュ(PEP/PDP)
---------------------
-
-* **PDP**(Policy Decision Point)= IAM サービス(API 内 or サイドカー)。評価エンジンをここに。
-
-* **PEP**(Enforcement)= 各マイクロサービスの gRPC エンドポイント前段。すべてのリクエストで `principal + action + resource` を PDP に照会。
-
-* **Watch**:PEP 側キャッシュは Chainfire の Watch を使って**差分購読**。実装は既に双方向ストリームがあるので(`watch()` ハンドラの双方向処理と内部 WatchStream)、これを流用。
-
- repomix-output
-
- repomix-output
-
-
-> この構成だと、**強整合ストア**からのポリシー更新→**Watch で即時配布**→**各 PEP の LRU キャッシュ更新**、という流れにできます。
-
-* * *
-
-5) 認証とトークン(STS + TSO)
----------------------
-
-* 外部 IdP(OIDC)で `sub` を受け取り、**AssumeRole** で**短命セッショントークン**を IAM が発行。
-
-* トークンには `iss, aud, sub, org, project, roles[], boundary_id, iat, exp`。`iat/exp` は **TSO** で単調増加(「物理<<16 | 論理」)を使えば、クラスタクロックずれに強い。
-
- repomix-output
-
- repomix-output
-
-* FlareDB の **TSO サービス**は既に定義・実装の体裁があり(`Tso.GetTimestamp`、サーバ側 `TsoServiceImpl`)、ここを呼び出すだけでよい。
-
- repomix-output
-
- repomix-output
-
-
-* * *
-
-6) 権限評価アルゴリズム(擬似コード)
---------------------
-
-1. **コンテキスト生成**:`principal`(IdP/JWT + SA)、`resource`(パス/タグ/オーナ)、`request`(action、IP、時刻)
-
-2. **収集**:対象スコープの Binding を集め、ロール → 権限を展開
-
-3. **境界適用**:ServiceAccount の **permission boundary** と `session policy` を**積集合**で適用
-
-4. **明示 Deny** を先に評価(1 ヒットで拒否)
-
-5. 条件(ABAC)を評価(owner, project, node, time …)
-
-6. 1 つでも Allow がヒット→許可、なければ拒否
-
-
-* * *
-
-7) ロールセット(最小版)
---------------
-
-* `SystemAdmin`:system スコープの全権(ブレークグラス)
-
-* `OrgAdmin`:自組織の project/user 管理
-
-* `ProjectAdmin`:自プロジェクトの全リソース管理
-
-* `ProjectMember`:自分が owner のリソース作成・操作、読取は project 内
-
-* `ReadOnly`:監査・可観測系のみ
-
-* `ServiceRole-ComputeAgent`:`compute:*` の一部(条件 `resource.node == self`)
-
-* `ServiceRole-NetworkAgent`:`network:*` の一部(条件 `resource.region == self.region`)
-
-
-* * *
-
-8) ポリシー例(JSON)
---------------
-
-**Role 定義**(例:ProjectMember)
-
- {
- "role": "ProjectMember",
- "scope": "project",
- "permissions": [
- { "action": "compute:instances:create", "resource": "project/${project}/instances/*" },
- { "action": "compute:instances:start", "resource": "project/${project}/instances/*",
- "condition": { "StringEquals": { "resource.owner": "${principal.uid}" } } },
- { "action": "compute:instances:read", "resource": "project/${project}/instances/*" }
- ]
- }
-
-
-**Binding**(ユーザ U を P に結びつけ)
-
- {
- "principal": "user:U",
- "roleRef": "roles/ProjectMember",
- "scope": { "type": "project", "id": "P" }
- }
-
-
-**ServiceAccount 境界**(ComputeAgent は自ノードだけ)
-
- {
- "policyId": "boundary/compute-agent",
- "statement": [
- { "effect": "Allow", "action": ["compute:instances:*"],
- "resource": "project/*/instances/*",
- "condition": { "StringEquals": { "resource.node": "${principal.node}" } } }
- ]
- }
-
-
-* * *
-
-9) 監査と可観測性
-----------
-
-* すべての PEP で**決定ログ**(who/what/why/allow?)を `audit` に書き込み。
-
-* 監査ビューアは Chainfire の **Merkle/Range** で検証や範囲取得も可能(将来の整合監査に有用)。
-
- repomix-output
-
- repomix-output
-
-
-* * *
-
-10) 実装の当面ロードマップ(2–3 スプリント)
---------------------------
-
-**M0: 最小動作**
-
-1. `iam` ネームスペースを **強整合**に設定(起動時に明示)。
-
- repomix-output
-
-2. `roles/`, `bindings/`, `users/` の KV スキーマを確定し、**CAS で更新**。
-
- repomix-output
-
-3. PDP(単体バイナリ or API 内モジュール)で**評価エンジン**実装。
-
-4. 各サービスの gRPC に**PEP フィルタ**を挿入(メタデータから JWT を取り出し評価)。
-
-5. **Watch ストリーム購読**による PEP キャッシュ更新。
-
- repomix-output
-
-
-**M1: 運用性**
-
-1. STS(AssumeRole)で**短命トークン発行**(TSO で `iat/exp`)を実装。
-
- repomix-output
-
-2. ServiceAccount + **permission boundary** 実装(Compute/Network Agent 用)。
-
-3. 監査ログの**付帯情報**(該当 Binding/Role、一致条件)を保存。
-
-
-**M2: 多テナント強化**
-
-1. Org/Project 間の委任(プロジェクト間共有は resource-based policy を追加)。
-
-2. ロールテンプレートと UI/CLI(`list-roles`, `bind-role`, `whoami`, `explain`)。
-
-
-* * *
-
-11) なぜこの形があなたの基盤にハマるか
----------------------
-
-* **Namespace 強/弱の切替**を既に持っており(`UpdateNamespaceMode` など)、IAM を**強整合**に寄せられる。可用性が要る監査等は強整合、ログ配送や診断メトリクスは弱整合に分離できる。
-
- repomix-output
-
- repomix-output
-
-* **Watch ベースの即時配布**が実装済みで、PEP キャッシュの設計がシンプルになる。
-
- repomix-output
-
-* **TSO** があるので、**セッションの有効期限や監査の順序付け**が一貫する。
-
- repomix-output
-
-
-* * *
-
-12) 失敗しがちな落とし穴と対策
------------------
-
-* **ポリシーが肥大化**:先に**固定ロール**を用意し、カスタムは後回し。`explain` コマンドで可視化支援。
-
-* **弱整合に IAM を置く**:禁止。**強整合**ネームスペースに限定。
-
-* **サービスアカウントの過剰権限**:必ず **permission boundary** を使い、`node/region` 条件で縛る。
-
-* **評価のホットパス化**:PEP キャッシュと**ウォームアップ**、Binding の逆引きインデックスで 1 クエリ完結に。
-
-
-* * *
-
-必要なら、この設計に合わせた **キー配置(/iam/...)の具体 YAML/TOML**、および **PEP ミドルウェア(tonic の interceptor)雛形**もまとめます。
-次は **M0 の “強整合 iam NS + CAS 更新 + Watch 配布 + 最小ロール”** を一気に通すのが最短距離です。
-
----
-
-## You asked:
-
-namespaceごとの切り替えが実装されているのはchainfireではなくflaredbなはずです。
-
----
-
-## ChatGPT Replied:
-
-Thought for 5m 28s
-
-そう、それ!完全にその通りです。
-**namespace ごとの strong/eventual 切り替えを持っているのは FlareDB 側で、Chainfire ではない**です。前の説明でそこをごちゃっとさせてしまいました、すみません。
-
-コード的にも:
-
-* `flaredb-server` の `RaftService` が
- `GetMode / UpdateNamespaceMode / ListNamespaceModes` を持っていて、
- `ConsistencyMode::Strong / ::Eventual` に変換しています。
-
- repomix-output
-
-* proto の方も `NamespaceMode { namespace, id, mode("strong"/"eventual"), from_default }` になっていて、完全に FlareDB の世界の話。
-
- repomix-output
-
-* docs でも「Quickstart: Namespace Consistency Modes」として、FlareDB クラスタを `logs=eventual` みたいに起動する例が載ってます。
-
- repomix-output
-
-
-* * *
-
-### じゃあ IAM 設計はどう解釈し直すか?
-
-やりたいこと自体は変わりませんが、**こう整理し直すのが正確**です:
-
-* IAM のユーザ / ロール / バインディング / ポリシーなどの**権限情報そのもの**は
- → **FlareDB の「強整合 namespace」**(例: `iam`)に載せる
- → `UpdateNamespaceMode(namespace="iam", mode="strong")` で固定しておくイメージ。
-
- repomix-output
-
-* メトリクスや一部ログなど「落ちても後で整合すればいい」ものは
- → FlareDB の別 namespace(例: `metrics`)を `eventual` にする。
-
- repomix-output
-
-* **Chainfire** はあくまで
-
- * クラスタメンバーシップ
-
- * gossip / watch / 分散 KV(強整合だが「namespace モード」はない)
- を担う「コントロールプレーン用の KV・合意レイヤ」として使う、という整理にするときれいです。
-
- repomix-output
-
-
-なので、前に話した
-
-> 「IAM は強整合 namespace に置き、監視系は eventual にして…」
-
-という設計の\*\*“どのプロジェクトがそれを持っているか”\*\*だけを修正すると:
-
-* ✅ **FlareDB**
-
- * データ平面 & メタデータ本体
-
- * `namespace -> strong/eventual` の切り替え
-
- * TSO(セッションの `iat/exp` や監査ログの順序付けに使える)
-
-* ✅ **Chainfire**
-
- * クラスタ構成 / ノード情報 / 各種コントローラの設定・watch 配信
-
- * IAM ポリシーそのものは持たない(置いても良いけど「モード切り替え」はここには無い)
-
-
-としておくのが正確な構図です。
-
-* * *
-
-IAM の権限モデル(ロール/バインディング/境界ポリシー/PEP・PDP構成)そのものは、そのまま FlareDB 上に移せば OK なので、
-\*\*「Chainfire の namespace モードを使う」→「FlareDB の namespace モードを使う」\*\*に読み替えてください。
-
-このあと詰めるなら、
-
-* FlareDB の `iam` namespace を strong に固定
-
-* `metrics` / `audit_logs` などを eventual にする
-
-* Chainfire には「どの FlareDB namespace をどのサービスが使うか」という“配線情報”だけ載せる
-
-
-みたいなレベルまで落とし込んでいくと、だいぶ設計がクリアになります。
-
----
-
-## You asked:
-
-そして、各々のこのクラスタ上のソフトウェアのAPIゲートウェイがFlareDBを見に行って権限が正しいか確認しながらこなすという感じでしょうか?この辺を実際のクラウド基盤ではどのように実装しているのか良くわからないのですが…
-
----
-
-## ChatGPT Replied:
-
-Thought for 5m 12s
-
-いいところに気づいてます。
-
-ざっくり言うと、
-
-> 「各サービスの API ゲートウェイ(or API サーバ)が FlareDB に聞きに行って “権限OK?” を毎回チェックする」
-
-というイメージは**半分正しい**んですが、
-実際のクラウド基盤だと、
-
-* **毎リクエストで生 DB を直叩きはしない**
-
-* どこかに\*\*“権限を決める役(PDP)”**と**“実際に止める役(PEP)”\*\*を分ける
-
-* ポリシーは DB から**キャッシュ or Watch で同期**して、評価をローカルでやる
-
-
-という構成になっていることが多いです。
-あなたの Chainfire/FlareDB だと、それをかなり綺麗に組める構造になっています。
-
-repomix-output
-
-* * *
-
-現実のクラウドはどうやってるかざっくり
--------------------
-
-### パターン1: OpenStack / Kubernetes 型(分散 PEP)
-
-* OpenStack:
-
- * 認証: Keystone がトークン発行
-
- * 各サービス(Nova, Neutron, Cinder…)はトークンを Keystone で検証 or ローカル検証
-
- * 認可: 各サービスが **ローカルの policy.yaml/json** をロードして、**プロセス内で評価**
-
- * → 毎回 Keystone や DB に聞かない。**設定ファイル+リロード**で反映
-
-* Kubernetes:
-
- * 認証: API Server が cert/token を検証
-
- * 認可: RBAC/ABAC ルールは etcd に入っているが、API Server が **watch で同期してメモリにキャッシュ**
-
- * → リクエスト時は**メモリ上の RBAC ルールで即評価**(etcd に毎回聞かない)
-
-
-### パターン2: AWS / GCP 型(中央 IAM +キャッシュ)
-
-* IAM のポリシーは中央サービスにあるけど、
-
- * 各サービスのフロントエンドが **署名/トークンを検証**して、
-
- * ポリシーは**ローカルキャッシュ or 内部評価ライブラリ**で解決
-
-* ポリシーアップデートは、
-
- * 配信システム(S3 / 内部ストレージ + watch 的なもの)で反映
-
- * 再起動/定期リロード/push など
-
-
-共通しているのは:
-
-> 「**オンラインのDBに毎回問い合わせるより、ローカルキャッシュして評価**する」
-
-という点です。
-
-* * *
-
-あなたの基盤でのおすすめ構成
---------------
-
-### 役割の整理
-
-* **FlareDB**:
-
- * IAM のユーザ/ロール/バインディング/ポリシーを**強整合 namespace**に格納
-
- * namespace 切り替え API (`GetMode/UpdateNamespaceMode/ListNamespaceModes`) は FlareDB 側にあるので、`iam` namespace を `strong` で固定しておくイメージ
-
-* **Chainfire**:
-
- * クラスタ構成とサービスディスカバリ、設定、ノード情報 etc のメタ
-
- * IAM の実データは持たなくてもよい(持つなら参照用)
-
-
-ここに、
-
-* **PDP(Policy Decision Point) = iam-service**
-
-* **PEP(Policy Enforcement Point) = 各 API ゲートウェイ / サービスのミドルウェア**
-
-
-を置くと綺麗です。
-
-### ざっくりデータフロー
-
-1. **ポリシーの真実の所在**
-
- * FlareDB `iam` namespace に、
- `users/`, `roles/`, `bindings/`, `policies/` などを CRUD する。
-
-2. **iam-service(PDP)が FlareDB を watch**
-
- * FlareDB から `iam/*` を **strong モードで読む**。
-
- * 変更は FlareDB の watch / Range で拾って、**メモリ上のポリシーキャッシュ**に反映。
-
-3. **各 API(PEP)が iam-service に問い合わせ**
-
- * API Gateway や各マイクロサービスの gRPC/HTTP handler の前段にミドルウェアを置く:
-
- 1. 認証: JWT / mTLS で principal を確定
-
- 2. 認可: `iam-service.Authorize(principal, action, resource)` を gRPC で呼ぶ
- → iam-service は**自分のキャッシュ**だけを見て判定
-
- * これなら、**リクエストごとに FlareDB を直叩きしない**。
-
-
-### 「FlareDB 直叩き」と「PDP経由」の比較
-
-* FlareDB を **毎回直叩き**:
-
- * 実装はシンプルだけど、
-
- * QPS が上がると FlareDB が**ボトルネック& SPOF**になりがち
-
- * ネットワーク遅延がそのまま P99 に乗る
-
-* **iam-service でキャッシュ & watch**:
-
- * 初期実装は少しだけ重いけど、
-
- * FlareDB への負荷を限定できる
-
- * 「IAM 落ちたら全部死ぬ」を避けるために、PDP を複数レプリカにできる
-
-
-**現実クラウドはほぼ後者寄り**です。AWS も GCP も K8s も、「オンライン DB を直接叩いてる」というより、
-**どこかで“コンパイルされたポリシー”をメモリに抱えて評価**しています。
-
-* * *
-
-API ゲートウェイ側のイメージ(擬似コード)
------------------------
-
-Rust っぽく書くとこんな感じ:
-
- async fn handle_request(req: Request) -> Result {
- // 1. 認証(JWT / mTLS)
- let principal = authn::authenticate(&req)?;
-
- // 2. アクション・リソースを決定
- let action = Action::from_http(&req); // e.g. "compute:instances:start"
- let resource = Resource::from_path(&req); // e.g. "projects/p1/instances/vm-123"
-
- // 3. 認可 (PDPへ)
- iam_client
- .authorize(principal, action, resource)
- .await
- .map_err(|_| Error::Forbidden)?;
-
- // 4. 実処理
- do_business_logic(req).await
- }
-
-
-`iam_client.authorize` の中で FlareDB に行くのではなく、**iam-service のメモリキャッシュ**を使う、という構造。
-
-* * *
-
-じゃあ FlareDB / Chainfire のどこを使うか
--------------------------------
-
-* **FlareDB**
-
- * `iam` namespace(strong)に IAM 情報を格納
-
- * 別 namespace(`metrics`, `audit` など)は eventual にしてもよい
-
- * TSO(単調タイムスタンプ)で
-
- * ポリシーの `created_at` / `version`
-
- * セッショントークンの `iat/exp`
- を管理すると気持ちいい
-
-* **Chainfire**
-
- * `iam-service` 自体の配置情報や設定(どの FlareDB に接続するか、どの namespace を使うか)を持つ
-
- * Gossip / Watch で「どのノードにどのサービスがいるか」を配信
-
- * 将来的には「どの API ゲートウェイがどの PDP を見るか」もここで管理できる
-
-
-* * *
-
-まとめると
------
-
-* あなたのイメージどおり「API を受けるところが FlareDB に基づいて権限チェックする」のは方向性として正しい。
-
-* ただし \*\*「毎回 FlareDB を叩く」より「PDP(iam-service)が FlareDB を watch してキャッシュ、API 側は PDP に問い合わせ」\*\*という 2 段構成にすると、実クラウドの設計にかなり近づきます。
-
-* OpenStack は「各サービスがローカル policy ファイルを読む」、Kubernetes は「etcd を watch して API server がメモリに持つ」、AWS/GCP は「中央 IAM + キャッシュ」の変種、という理解で OK。
-
-
-次の一歩としては:
-
-1. FlareDB 上の `iam` namespace のモデル(users/roles/bindings)を決める
-
-2. 小さい `iam-service`(PDP)を作って FlareDB を watch しつつメモリにロード
-
-3. どれか 1 サービス(例: compute API)に PEP ミドルウェアを入れて `Authorize` を噛ませる
-
-
-ここまで通ると、「このクラスタ上のソフトウェアが全部同じ IAM ルールで動く」世界が一気にリアルになります。
-
----
-
-## You asked:
-
-repomix-output.xml
-
-ファイル
-
-そういえば、これに関してFlareDBのAPIゲートウェイなどを変更する必要はあるでしょうか?一応、FlareDBに関しては様々な形のクエリをサポート可能なように、SDKを定義するという形で考えていた気がします。例えば、SQLっぽいクエリも取ることができるということだったと思います。このような場合、IAM側はSQLなどの良くあるもので書いてFlareDBがなくても最悪Postgreなどでもできるようにするということも考えていたのですが、どう思いますか?
-
----
-
-## ChatGPT Replied:
-
-Thought for 6m 2s
-
-ざっくり結論からいくと:
-
-* **IAM を実装するために FlareDB の「APIゲートウェイ」(=gRPC/kvrpc レイヤ)を大きく変える必要はほぼ無い**です。
-
-* むしろ FlareDB は「分散KVS+Raft+TSO」のシンプルな顔のままにして、
- その上に **IAM サービス(+各サービスの API Gateway)を乗せる**構成にした方がキレイで差し替えも効きます。
-
-* 「SQL っぽいクエリを SDK 経由で投げられるようにしておく」のはアリですが、
- **IAM のポリシー言語そのものを SQL にしてしまうのはあまりオススメしない**です。
- 代わりに「IAM ストレージ層」を抽象化して FlareDB 版 / PostgreSQL 版を差し替えられるようにするのが筋がいい。
-
-
-* * *
-
-1\. 今の FlareDB の立ち位置を整理
------------------------
-
-リポジトリを見ると、FlareDB はこんな構造になってます:
-
-repomix-output
-
-* `flaredb-proto` に gRPC サービス定義(`kvrpc.proto`, `pdpb.proto`, `raft_server.proto` …)
-
-* `flaredb-server` がそれを実装(Raft, RocksDB をラップ)
-
- repomix-output
-
-* クライアントは `flaredb-client::RdbClient` から RawPut / RawGet / CAS / TSO を呼ぶ
-
- repomix-output
-
-* KVS 側は namespace や consistency mode などを gRPC で操作可能(`GetMode`, `ListNamespaceModes`, `FetchRange` など)
-
- repomix-output
-
-
-つまり、今の FlareDB の「ゲートウェイ」は
-
-> 「名前空間付きの分散 KVS と Raft 系 APIを提供する低レベルストレージ」
-
-という役割で完結していて、ここに IAM ロジックを混ぜると**責務がごちゃっとする**危険ゾーンです。
-
-* * *
-
-2\. 「各サービスの API Gateway が FlareDB を見に行って権限チェック」はどう設計するか
--------------------------------------------------------
-
-あなたがイメージしている:
-
-> 「各クラスタ上のソフトウェアの API ゲートウェイが FlareDB を見に行って権限が正しいかを確認する」
-
-というのは、多くのクラウド基盤でも似た構造で、
-
-* 各サービスの Gateway / Frontend は
-
- * 認証済みトークン(OIDC/JWT など)を受け取り
-
- * **IAM の権限判定 API** を叩く
-
-* IAM サービスが
-
- * FlareDB(or PostgreSQL)に保存されたポリシーとメタデータを読んで
-
- * 「許可 / 拒否」を返す
-
-
-という 3 層モデルに分解するのがわかりやすいです:
-
-1. **Storage 層**
-
- * FlareDB(本番向け分散ストレージ)
-
- * PostgreSQL(ローカル・最悪の fallback)
-
-2. **IAM Core 層(PDP: Policy Decision Point)**
-
- * Policy / Role / Binding / Condition の評価ロジック
-
-3. **サービスごとの API Gateway(PEP: Policy Enforcement Point)**
-
- * HTTP/gRPC の入口。IAM Core に「このリクエスト、OK?」と聞く。
-
-
-この構成にすると、
-
-* FlareDB のゲートウェイは「ただの KVS API」のままでいい
-
-* IAM Core が Storage 抽象を持てば
-
- * FlareDB バックエンド
-
- * PostgreSQL バックエンド
- を差し替え可能
-
-
-になります。
-
-* * *
-
-3\. FlareDB の API ゲートウェイを変える必要があるケース / ないケース
---------------------------------------------
-
-### 変えなくていいケース(多分いまはこっち)
-
-* FlareDB は **クラスタ内の「管理用 DB」** としてのみ使う
- (ユーザーやテナントが直接 FlareDB にアクセスしない)
-
-* クラスタの他サービス(Compute, Network, IAM など)が
- 内部ネットワークから FlareDB に gRPC でアクセスするだけ
-
-
-この場合は、FlareDB 側に「ユーザーごとの権限」なんて一切いりません。
-クラスタ内のマイクロサービス同士は mTLS やネットワーク ACL で守る世界です。
-
-**この前提なら、FlareDB の gRPC API を IAM のために変更する必要はほぼゼロです。**
-
-### 変えたくなるかもしれないケース
-
-* 「FlareDB をユーザー向け DB サービスとしても公開する」
- (例:Managed KVS / 時系列 DB として直接叩かせたい)
-
-* 「テナントごとに namespace を分けているので、FlareDB 自身に namespace 単位の ACL を持たせたい」
-
-
-この場合は、例えば:
-
-* gRPC に軽い認証情報(mTLS の CN ベース / JWT / API Key)を足す
-
-* namespace 単位に「どの service/account が触れるか」のメタを持つ
-
-
-といった機能を FlareDB 側に足す意味が出てきますが、
-**IAM の実装とはほぼ別問題**(DB サービスのテナント分離の話)です。
-
-* * *
-
-4\. 「IAM を SQL で書いておいて、最悪 PostgreSQL に逃がす」案について
------------------------------------------------
-
-ここが一番おもしろいポイント。
-
-あなたの案は:
-
-* FlareDB 側は SDK 経由で SQLっぽいクエリも投げられるようにする(内部で KV に変換)
-
-* IAM のポリシーやロール定義を「SQL などのよくあるもので表現」
-
-* そうすれば、FlareDB がなくても PostgreSQL に乗り換え可能
-
-
-というものですよね。
-
-ここで気をつけたいのは、
-
-> 「**外部 API / ポリシー言語** を SQL にする」のか
-> 「**内部のストレージアクセス** を SQL にする」のか
-
-をちゃんと分けることです。
-
-### やってはいけない方
-
-* サービスや Gateway に「SQL テンプレ」を埋め込んで、
- 「ユーザーが来たらこの SQL を実行して許可判定する」みたいな形にする
-
-
-理由:
-
-* SQL が外部 API レベルに漏れると
-
- * FlareDB のクエリ仕様に縛られる
-
- * PostgreSQL に変えるときに**全サービスを書き換え**になる
-
-* セキュリティ的にも
-
- * インジェクション対策やクエリ制限が必要になる
-
- * ポリシーのキャッシュや評価のチューニングが難しい
-
-
-### おすすめの形
-
-**外部から見ると:**
-
-* IAM API は以下みたいな gRPC/HTTP で固定する:
-
- * `Authorize(principal, action, resource, context) -> ALLOW/DENY`
-
- * `ListRoles(project_id)`
-
- * `AttachRole(principal, role, scope)`
-
- * etc…
-
-
-**内部では:**
-
-* IAM のストレージ層を Trait で抽象化:
-
-
- // ざっくりイメージ
- #[async_trait]
- pub trait PolicyStore {
- async fn get_bindings_for_principal(
- &self,
- principal_id: &PrincipalId,
- ) -> Result>;
-
- async fn get_policies_for_resource(
- &self,
- resource: &ResourceId,
- ) -> Result>;
-
- // ほか create/update 系もここに
- }
-
-
-* `FlareDbPolicyStore` と `PostgresPolicyStore` の 2 実装を作る:
-
- * FlareDB 版:
-
- * key レイアウト例:`iam/policy/{policy_id}` → JSON ドキュメント
-
- * `FetchRange` で prefix スキャンする
-
- repomix-output
-
- * PostgreSQL 版:
-
- * `policies` テーブルに `id` + `doc JSONB` を保存
-
- * シンプルな `SELECT doc FROM policies WHERE resource_id = $1` などを発行
-
-* **Authorize ロジックはメモリ内で JSON を評価する**
- (SQL に判定ロジックを埋めない)
-
-
-こうしておくと、
-
-* FlareDB を PostgreSQL に差し替えたいときは `PolicyStore` 実装を変えるだけ
-
-* IAM の API やポリシー表現(JSON/YAML)はそのまま
-
-* 「SQLっぽい」クエリはあくまで **ストレージ層の実装ディテール** として閉じ込められる
-
-
-という状態になります。
-
-* * *
-
-5\. 「SDK で SQLっぽいクエリをサポートする」こと自体はどうか
-------------------------------------
-
-これは **FlareDB を汎用 DB サービスとしても使うかどうか**の話です。
-
-* FlareDB 自体のクライアント SDKで
-
- * RawPut/RawGet/CAS の他に
-
- * 「SQLライク AST」を受け取って KV 操作にコンパイルする
-
-* これは将来的に
-
- * 「ユーザー向けに SQL っぽいものを提供したい」
-
- * 「クエリ最適化 layer を作りたい」
-
-
-といった理由で、**別レイヤとして作るのはアリ**です。
-
-ただし IAM だけを考えるなら、
-
-* わざわざ汎用クエリエンジンを FlareDB 上に作らなくても
-
-* 「IAM 用の固定のアクセスパターン(principal から binding を引く、resource からポリシーを引く)」に最適化したキー設計+インデックスで十分間に合います。
-
-
-なので、優先度としては:
-
-1. まずは **IAM サービス + PolicyStore 抽象 + FlareDB バックエンド** を作る
-
-2. 余裕が出たら
- 「FlareDB 汎用クエリ(SQLライク)レイヤ」を追加
- (IAM 以外の用途にも使える)
-
-
-くらいの順番がよさそうです。
-
-* * *
-
-6\. まとめ
--------
-
-* **FlareDB の API ゲートウェイを IAM 用にいじる必要は基本なし**
-
- * いまの gRPC KVS + namespace + consistency mode のままで OK
-
- repomix-output
-
-* IAM は
-
- * 独立したサービス(PDP)として実装し
-
- * 内部で FlareDB / PostgreSQL を差し替え可能な PolicyStore 抽象を持つ
-
-* 「SQL っぽいクエリを SDK でサポート」は
-
- * FlareDB を汎用 DB として進化させるための**別レイヤ**
-
- * ただし IAM のポリシー言語そのものを SQL にするのは避けた方が安全
-
-
-今の構成だと、FlareDB は「分散 RocksDB+Raft のごっついストレージ・エンジン」、
-Chainfire は「クラスター管理用 KV」、
-その上に「IAM / Compute / Network サービス」が乗る三層くらいになるので、
-そのレイヤリングを崩さないように設計していくと OpenStack 代替としてもだいぶ育てやすくなります。
-
----
-
-## You asked:
-
-あと、chainfireのクラスター設定に関しても質問があります。100台くらいの規模のクラスタに関して、initial\_membersというのを決めると思いますが、これは本当に最初だけ使うという感じになりますか?具体的には、Raftのメンバーが障害などでいなくなることを考えており、initial\_membersがいなくなったらどうするのだろうと思っていました。
-
----
-
-## ChatGPT Replied:
-
-Thought for 9m 42s
-
-結論からいうと:
-
-* \*\*Raft 的には `initial_members` は「最初だけ使うもの」\*\*で合っています。
-
-* その後のクラスタ構成は **Raft のログ & スナップショットの中が正** であって、設定ファイルの `initial_members` はほぼ無視される世界になります。
-
-* 「`initial_members` に書いてあったノードが全部死んだらどうする?」という不安は、設計をちゃんと切り分ければだいたい解消できます。
-
-
-で、ここから「一般的な Raft の話」と「あなたの Chainfire 実装の現状」の両方を整理します。
-
-* * *
-
-1\. 今の Chainfire の実装、実は `initial_members` まだ使ってない
--------------------------------------------------
-
-まず事実確認。
-
-`ServerConfig` に `cluster.initial_members` と `bootstrap` が定義されています:
-
-repomix-output
-
- pub struct ClusterConfig {
- pub id: u64,
- pub initial_members: Vec,
- pub bootstrap: bool,
- }
-
-
-一方で、サーバ起動時のブートストラップは `Node::maybe_bootstrap` でこうなっています:
-
-repomix-output
-
- pub async fn maybe_bootstrap(&self) -> Result<()> {
- if self.config.cluster.bootstrap {
- info!("Bootstrapping new cluster");
- self.raft.initialize().await?;
- }
- Ok(())
- }
-
-
-ここで呼んでいる `RaftNode::initialize()` は「自分1台だけの single-node クラスタを初期化」するだけです:
-
-repomix-output
-
- pub async fn initialize(&self) -> Result<(), RaftError> {
- let mut nodes = BTreeMap::new();
- nodes.insert(self.id, BasicNode::default());
- self.raft.initialize(nodes).await?;
- ...
- }
-
-
-マルチノード初期化用の `initialize_cluster(...)` も一応用意されていますが:
-
-repomix-output
-
- pub async fn initialize_cluster(
- &self,
- members: BTreeMap,
- ) -> Result<(), RaftError> {
- self.raft.initialize(members).await?;
- ...
- }
-
-
-**`Server` / `Node` 側からはまだ呼ばれていません。**
-つまり現状のコードでは:
-
-* `bootstrap = true` → 「このノード1台で Raft クラスタを初期化」
-
-* `initial_members` → **まだどこからも参照されてないプレースホルダー**
-
-
-という状態です。
-
-* * *
-
-2\. Raft の世界観:`initial_members` の正しい役割
---------------------------------------
-
-Raft(OpenRaft含む)でのクラスタ構成のライフサイクルはざっくりこうです:
-
-1. **ブートストラップ(initialize / initialize\_cluster)**
-
- * ログが空の状態で **一度だけ** 呼ぶ。
-
- * ここで渡したノード集合(members)が「初期メンバー」として Raft のログに永続化される。
-
-2. **通常運転**
-
- * メンバー追加:`add_learner` → `change_membership`
-
- * メンバー削除:`change_membership`
-
- * あなたのコードだと `ClusterServiceImpl::member_add / member_remove` でまさにそれをやっている:
-
- repomix-output
-
-
- 要するに、**クラスタ構成は Raft クラスタ自身が持つメタデータ**になる。
-
-3. **再起動**
-
- * ノードはローカルストレージからログ・スナップショットを読む。
-
- * そこに最新のメンバーシップが入っているので、**設定ファイルを見なくても自分の世界が再構築できる**。
-
-
-なので本来の設計としては、
-
-* `initial_members` は「**ログが空のときに一度だけ使う、初期メンバー表**」
-
-* それ以降は **Cluster API 経由(member\_add / remove)でしか構成を変えない**
-
- repomix-output
-
-
-というのが自然です。
-
-* * *
-
-3\. 100台クラスタでの考え方:Raft メンバーはごく少数でいい
------------------------------------
-
-「100台規模のクラスタ」と言っていますが、Raft の世界では以下を強く推奨します:
-
-* **Raft の voter(投票権を持つノード)は 3〜5 台くらいに抑える**
-
-* 残りの多くのノードは:
-
- * Chainfire/FlareDB のクライアントとして動く worker
-
- * もしくは別のシャード・別の Raft グループ
-
-
-etcd や TiKV もみんなそうです。
-100台全部を一つの Raft グループの voter にすると:
-
-* レプリケーションのレイテンシが O(N) で増える
-
-* フェイル時の再構成が地獄
-
-* ネットワーク分断時にすぐクォーラムが壊れる
-
-
-ので、\*\*「少数の control-plane ノード + 大量の worker」\*\*という構造にするのが現実的です。
-あなたの `ServerConfig.node.role` にもすでに `control_plane` / `worker` の区別がありますね
-
-repomix-output
-
-
-→ これはまさにその構造に対応できる布石です。
-
-* * *
-
-4\. 「initial\_members が死んだらどうするの?」問題
-------------------------------------
-
-ここが本題。
-
-### 4-1. 普通のケース:一部だけ死ぬ
-
-Raft クラスタは、「**現在のメンバーのうち過半数が生きていれば**」動き続けます。
-
-* たとえば初期メンバーが `[1,2,3]` だとして
-
- * 1 が死んでも 2,3 が生きていれば OK
-
- * 新ノード 4 を追加 → `member_add` で learner → `change_membership` で voter に昇格
-
- repomix-output
-
- * その後 `member_remove` で 1 を構成から外す
-
-
-この時点で、「**初期メンバー 1 はもはや何の特別扱いでもない**」です。
-単なる「昔いたメンバーの一人」に過ぎません。
-
-### 4-2. かなり悪いケース:初期メンバーが全部死ぬ
-
-ここをもう少し細かく分けます:
-
-1. **でもクラスタの他メンバー(後から追加した voter)がまだ過半数生きている**
-
- * 例:初期 `[1,2,3]` に後から `[4,5]` を追加して、今の voter が `[2,3,4,5]` みたいな状態。
-
- * この場合は「初期メンバー」という概念は本質的ではなく、Raft は普通に動き続ける。
-
-2. **本当に voter が過半数壊れてクォーラム喪失**
-
- * これは etcd でも Consul でも「**人間が手でリカバリするやつ**」です。
-
- * 代表的なパターン:
-
- * どこか1ノードだけは最新ログが残ってる → それを seed に「強制 new-cluster」ブートストラップ
-
- * 最悪、ログごと失ってる → もう新しいクラスタとして作り直し(データはあきらめる)
-
-
-ここは「OpenStack の代替を作る」という目標からすると SRE/運用設計の領域になります。
-
-* * *
-
-5\. あなたの設計に落とし込むなら
-------------------
-
-**(1) `initial_members` の使い方をちゃんとコードに反映する**
-
-今の `maybe_bootstrap()` は single-node で `initialize()` するだけなので、
-`cluster.initial_members` を使うならざっくりこんなイメージになります:
-
-* `bootstrap = true` かつ `initial_members` が埋まっているノードだけが
-
- * `BTreeMap` を組み立てて
-
- * `RaftNode::initialize_cluster(members)` を一度だけ実行
-
-* 他のノードは `bootstrap = false` で起動し、
-
- * 既存クラスタに対して `Cluster.member_add` を投げて参加する(Raft 的には learner → voter)
-
-
-**(2)「設定ファイルの initial\_members はブートストラップ専用」と割り切る**
-
-* クラスタ起動後の構成変更はすべて Cluster API 経由
-
-* 設定ファイルを後から書き換えても Raft メンバーは変わらない
- (etcd の `--initial-cluster` も同じ発想です)
-
-
-**(3) 100台スケールのときのパターン**
-
-* Chainfire(etcd 相当)は control-plane ノード 3〜5 台だけ Raft voter にする。
-
-* コンピュートノード / ストレージノード / VM エージェント達は:
-
- * Chainfire/FlareDB を読むだけ(クライアント)
-
- * 状態は Gossip + Watch で流す(あなたのアーキテクチャのまま)
-
-
-こうしておくと、「初期メンバーが死んだらどうするの?」は:
-
-* 事実上「control-plane ノードの過半数が死んだらどうするの?」という問題に還元される
-
-* それは etcd/Consul/TiKV と同じ議論になり、既存の運用パターンを真似できる
-
-
-* * *
-
-6\. まとめ
--------
-
-* `initial_members` は **本質的には「ブートストラップ一回用の種データ」**。
-
-* それ以降のクラスタ構成は **Raft のログと Cluster API (`member_add` / `member_remove`) が真実**。
-
-* あなたの現状コードでは `initial_members` はまだ使われておらず、常に single-node で bootstrap している。
-
-* 100台クラスタを考えるときは、「Raft voter は 3〜5 台だけ」「他はクライアント or 別クラスタ」と割り切ると壊れにくく、実装もシンプルになります。
-
-
-ここまでを前提に、次のステップとしては:
-
-* `ClusterConfig.initial_members` を `RaftNode::initialize_cluster` に実際に結線する
-
-* Cluster API での `member_add / remove` の UX(CLI や管理 API)を整える
-
-
-あたりを触ると、一気に「OpenStack 代替の中枢メタストア」として形になってきます。
-
----
-
-## You asked:
-
-あと、複数のサービス(VM基盤や、これから作るS3互換ストレージサーバなど)が動くことを考えるときに、(FlareDBは一応マネージドDBaaSの基盤となることを想定して作ったので)chainfireが動いているサーバー全てでFlareDB/VM基盤/S3互換ストレージサーバが動くという想定はあまりしていません。要求されるスペックが違いすぎると思います。そこで、chainfireは全てのサーバーで動いているが、その中でも特定のサービスがそれぞれのサーバーで動いているというような想定をしています。どうでしょうか?
-
----
-
-## ChatGPT Replied:
-
-Thought for 6m 51s
-
-発想としてはめちゃくちゃアリです。
-ただし「chainfire が全サーバーで _どういう役割で_ 動いているか」をきちんと分けておくと、100台規模でも破綻しない設計になります。
-
-* * *
-
-結論だけ先に
-------
-
-* 「**全ノードに共通のコントロールプレーンのエージェント**(=chainfire のクライアント+gossip)」を入れる
-
-* 「\*\*Raft でレプリケーションする KVS 本体(chainfire-server)」はごく少数のコントロールプレーンノードだけ
-
-* VM/S3/FlareDB ノードは、このエージェント経由で chainfire の KVS を読んだり watch したりするだけ
-
-
-という形にすると、今考えている
-
-> chainfire は全てのサーバーで動いているが、その中でも特定のサービスがそれぞれのサーバーで動いている
-
-というイメージときれいに両立します。
-
-* * *
-
-いまの実装がやっていること
--------------
-
-`chainfire-server` の `Node` を見ると、**どのノードでも必ず Raft ノードと RocksDB を立ち上げる**ようになっています。
-
-repomix-output
-
- pub struct Node {
- config: ServerConfig,
- raft: Arc,
- watch_registry: Arc,
- gossip: Option,
- // ...
- }
-
- pub async fn new(config: ServerConfig) -> Result {
- // RocksDB store
- let store = RocksStore::new(&config.storage.data_dir)?;
- // Raft node
- let raft = Arc::new(
- RaftNode::new(config.node.id, store, Arc::new(DummyRpcClient))
- .await?,
- );
- // Gossip agent (role は ControlPlane/Worker を見るが、Raft 側は常に起動)
- let role = match config.node.role.as_str() {
- "control_plane" => NodeRole::ControlPlane,
- _ => NodeRole::Worker,
- };
- let gossip_id = GossipId::new(config.node.id, config.network.gossip_addr, role);
- let gossip = Some(GossipAgent::new(gossip_id, ...).await?);
- // ...
- }
-
-
-`NodeRole` は gossip の identity には使われているけれど、Raft の voter/learner/非メンバーの切り替えにはまだ使っていません。
-
-repomix-output
-
-なので **現状のまま「全ノードで chainfire-server を起動」すると、100ノード Raft クラスタ**になり、これはさすがに重い&レイテンシも悪くなります。
-
-一方で `chainfire-client` クレートは「ただの gRPC クライアント」として使えるようになっています。
-
-repomix-output
-
- //! This crate provides a client for interacting with Chainfire clusters.
-
- pub use client::Client;
-
-
-ここを活かすと、
-
-* **コントロールプレーンノード**: `chainfire-server`(Raft + Gossip + Watch)、FlareDB のメタ系サービスなど
-
-* **ワーカーノード(VM/S3/FlareDB データノード)**: `chainfire-client` + `chainfire-gossip` だけを使った薄い「node agent」
-
-
-という二段構成に分けるのが自然です。
-
-* * *
-
-オススメ構成:Chainfire = 「全ノードエージェント」+「少数 Raft クラスタ」
-----------------------------------------------
-
-### 1\. 役割の分離
-
-**役割レベルでこう分けると整理しやすいです:**
-
-1. **Chainfire Core(少数ノード)**
-
- * `chainfire-server` を動かす
-
- * Raft voter(3〜5台)として KVS をレプリケーション
-
- * Cluster のメタデータ・IAM 情報・ノードのラベルなどを保存
-
-2. **Node Agent(全ノード)**
-
- * `chainfire-client` で Core に接続
-
- * `chainfire-gossip` で CPU/メモリ/ストレージなどの**実際の状態**をブロードキャスト
-
- * 必要なら特定の prefix(例:`/scheduling/vm//...`)を Watch して「このノードに割り当てられたタスク」を見て動く
- → これはあなたが以前書いていた
-
- > 「Watchして、VMを起動して、Gossipでステータスを返すエージェント」
- >
- > repomix-output
- >
- >
- > そのままの世界観です。
-
-3. **サービスプロセス(VM/S3/FlareDB)**
-
- * Node Agent と同じノードで動く
-
- * Agent から「今このノードで起動すべき VM/S3 shard/DB インスタンス」を教えてもらって起動/停止
-
- * あるいは自分で直接 `chainfire-client` を叩いてもいい(ただしエントリポイントを agent に寄せた方が設計が綺麗)
-
-
-### 2\. 設定から見たイメージ
-
-* `chainfire-server` の `ServerConfig` に、たとえば
-
- * `raft_role = "voter" | "learner" | "none"`
-
-
- を追加して、
-
- * Core ノード: `raft_role = "voter"`
-
- * その他: `raft_role = "none"`(もしくは server 自体立てず、agent だけ)
-
-
- にするのが次の一歩かなと思います。
-
-* Node Agent 用には別バイナリ(例: `chainfire-agent`)を作って、
-
- * `chainfire-gossip` でクラスタに参加
-
- * `chainfire-client::Client` で Core に接続
-
- * prefix 単位で watch して VM/S3/DB の命令をもらう
-
-
- というミニデーモンにすると、「全ノードで chainfire が動いている」という感覚にも合います。
-
-
-* * *
-
-異なるスペックのノードと複数サービスの共存
----------------------
-
-VM・S3・FlareDB で必要スペックが違うのはまさにその通りなので、\*\*「サービスごとのロールとキャパシティを chainfire KVS に載せる」\*\*のが王道です。
-
-例えば、KVS 上のキー設計をこんな感じにしておく:
-
-* `/nodes//roles = ["vm_host", "s3_storage", "flaredb_data"]`
-
-* `/nodes//capacity/cpu = 32`
-
-* `/nodes//capacity/memory_gb = 128`
-
-* `/nodes//labels/zone = "az1"`
-
-
-これを scheduler(将来の「OpenStack 代替の中枢」)が読んで
-
-* 「flaredb\_data ロールを持ったノードの中で、ディスク IO が空いているやつ」に DB shard を追加
-
-* 「vm\_host ロールで CPU が空いているノード」に新しい VM を置く
-
-
-みたいな判定をします。
-
-各ノード側では、
-
-* 自ノードの ID を知っている
-
-* `/scheduling/vm//...` とか `/scheduling/s3//...` を watch する
-
-* 新しい指示が来たらローカルサービス(QEMU, MinIO っぽいもの, FlareDB プロセス)を起動
-
-* 状態を gossip でばらまく(`ActualState` や `MembershipState` はもう実装済み)
-
- repomix-output
-
-
-という流れになります。
-
-* * *
-
-他のクラウドとの対応関係でいうと…
------------------
-
-* etcd + Kubernetes:
-
- * etcd クラスタ = 今の chainfire Core
-
- * kube-apiserver/scheduler/controller = あなたがこれから作る「クラウドコントロールプレーン」
-
- * kubelet + 各種エージェント = Node Agent
-
-* OpenStack:
-
- * central DB + message queue = chainfire + FlareDB(+将来の MQ)
-
- * nova-compute / cinder-volume / neutron-agt = VM/S3/DB のエージェント
-
-
-なので、あなたの
-
-> chainfire は全てのサーバーで動いているが、その中でも特定のサービスがそれぞれのサーバーで動いている
-
-という構想は、「全ノードに kubelet を入れて、Pod はロールごとに配置する」という Kubernetes 的なアプローチとかなり近いです。方向性としてだいぶ健全。
-
-* * *
-
-まとめと「次にやると良さそうなこと」
-------------------
-
-1. **chainfire-server の役割を分ける**
-
- * Raft voter をやるノード(control\_plane)と、そうでないノードを設定で明示
-
- * できれば worker 側は `chainfire-server` を使わず「agent + client」に寄せる
-
-2. **Node Agent バイナリを作る**
-
- * gossip 参加
-
- * chainfire-client で Core に接続
-
- * prefix で watch して VM/S3/FlareDB の指示を受ける
-
-3. **KVS 上のノードメタデータ設計**
-
- * roles / capacity / labels をどう持つか、キー命名をサクッと決める
-
-
-ここまでできると、「VM 基盤」「S3 互換ストレージ」「FlareDB as DBaaS」は全部
-
-> 「Chainfire に向かって watch し、指示通りにローカルリソースをいじるエージェント」
-
-として同じパターンで実装できるようになります。
-一度この “型” が決まると、後からどんなサービスを追加しても同じノリで増やせるので、かなり気持ちいい設計になります。
-
----
-
-## You asked:
-
-了解しました。これらをもとに、(とりあえず、chainfire/flaredbについて加える変更点や、機能増強、さらなる実装について)コーディングエージェント用の指示を書いてください。
-
----
-
-## You asked:
-
-repomix-output.xml
-
-ファイル
-
-了解しました。これまでの会話と現状のコードを踏まえて、(とりあえず、chainfire/flaredbについて加える変更点や、機能増強、さらなる実装について)コーディングエージェント用の指示を書いてください。
-
----
-
-## ChatGPT Replied:
-
-Thought for 6m 3s
-
-いいね、ここまででだいぶ「設計の山」は越えてるので、あとは「コーディングエージェント向けの登山ルート」を書き下せばOKです。
-以下は **chainfire / flaredb に対して今後やってほしい変更・機能追加を、直接エージェントに渡せる形の指示書**です。
-
-repomix-output
-
-* * *
-
-全体コンテキスト(エージェント向けメモ)
---------------------
-
-* リポジトリ構成は `chainfire/` と `flaredb/` の二つが並ぶモノリポ。どちらも Rust。
-
- repomix-output
-
-* chainfire は「クラスタ管理用分散KV(Raft + RocksDB + Gossip + Watch)」
-
-* flaredb は「分散高性能 DB(マルチ Raft・namespace ごとの strong/eventual モード・TSO etc)」
-
-* 将来的には:
-
- * chainfire = **クラスタ全体のメタストア & スケジューラの土台**
-
- * flaredb = **DBaaS / IAM データストア / 各種サービスの強整合ストア**
-
-* 今回のタスクでは **この2つの基盤そのものの強化・整理だけ** を対象とし、上位の「IAM サービス」や「VM/S3サービス」は登場人物としてだけ意識する。
-
-
-* * *
-
-1\. chainfire 側の変更・機能追加
-=======================
-
-### 1-0. 触ることになる主なクレート
-
-* `crates/chainfire-server/`(ServerConfig, Node, main エントリ)
-
-* `crates/chainfire-raft/`(RaftNode, network, config)
-
-* `crates/chainfire-gossip/`(Agent, Membership)
-
-* `chainfire-client/`(クラスタと話すためのクライアント)
-
-
-* * *
-
-### 1-1. Raft ブートストラップの整理(`initial_members` をちゃんと使う)
-
-**目的**
-
-* `ServerConfig.cluster.initial_members` を実際に使って、**マルチノードブートストラップ**をできるようにする。
-
-* 現状は `bootstrap = true` で起動したノードが `RaftNode::initialize()` を呼び、**単一ノードクラスタ**として初期化しているが、将来の100台規模運用を考えると「初期メンバー指定」方式に寄せたい。
-
-
-**仕様**
-
-1. `ServerConfig` にはすでに `ClusterConfig { id, initial_members, bootstrap }` がいるのでそれを利用する。
-
- repomix-output
-
-2. `Node::maybe_bootstrap()` の実装を以下の方針で変更:
-
- * ログ・スナップショットが空で、
-
- * `cluster.bootstrap == true`
-
- * かつ `cluster.initial_members` が非空
- の場合は **`RaftNode::initialize_cluster(members)` を呼ぶ**。
- `members: BTreeMap` は `initial_members` から生成する。
-
- * `initial_members` が空なら、従来通り「自ノード1台だけの initialize」でもよい(が、将来的にはエラー扱いでもOK)。
-
-3. `bootstrap = true` なノードは**クラスタ全体で1台だけ**にする想定。「複数台が同時に bootstrap を試みた場合」の挙動は、今は undefined でよいが、ログ/エラーで警告は出す。
-
-
-**完了条件**
-
-* `chainfire-server` の起動テストを追加:
-
- * `initial_members = [ {id:1}, {id:2} ]` の config ファイルを2つ用意し、どちらか一方だけ `bootstrap=true` で起動 → もう一方は既存クラスタに `member_add` で参加する形で正常に接続できる。
-
-* ドキュメント(`advice.md` など)に「bootstrap ノードは1台だけ」「initial\_members はブートストラップ専用」という注意書きを追加。
-
-
-* * *
-
-### 1-2. コントロールプレーンとワーカの役割分離(Raft voter を絞る)
-
-**目的**
-
-* 100台規模クラスタで「全ノードが Raft voter」になるのを避け、**3〜5台の control-plane ノードだけが Raft クラスタを構成**するようにする。
-
-* 他のノードは `chainfire-client` だけを使う「Node Agent」として振る舞う。
-
-
-**仕様案**
-
-1. `ServerConfig.node` に新フィールド追加(例):
-
- pub enum RaftRole {
- Voter,
- Learner,
- None,
- }
-
-
- * TOML では `raft_role = "voter" | "learner" | "none"` などの文字列。
-
-2. `Node::new()` 内での Raft 初期化ロジックを変更:
-
- * `RaftRole::None` の場合は **RaftNode を起動しない**。
-
- * 代わりに、このプロセスは「将来の agent 用」に使うか、あるいはそもそも `chainfire-server` を使わず `chainfire-agent` を別バイナリで作る(後述)。
-
- * `RaftRole::Learner` は(後の拡張用に)受け入れるが、現フェーズでは `Voter` だけあればよい。
-
-3. コマンドライン引数側でも `--raft-role` 的なオプションを足して TOML の値を上書きできるようにする。
-
-
-**完了条件**
-
-* `RaftRole::Voter` / `None` を混在させた構成で integration test 追加。
-
-* `RaftRole::None` ノードから `chainfire-client` を使って KV API にアクセスできることを確認。
-
-
-* * *
-
-### 1-3. Node Agent バイナリの追加(全ノードで常駐する薄いエージェント)
-
-**目的**
-
-* chainfire の「全ノードにいるやつ」と「Raft voter のやつ」を分離。
-
-* 全ノードで動く常駐プロセスを `chainfire-agent` として切り出す。
-
-
-**仕様**
-
-1. 新バイナリ `crates/chainfire-agent/` を追加(または `chainfire-server` の `mode=agent`)。
-
-2. このバイナリは:
-
- * `chainfire-gossip` でクラスタに参加
-
- * `chainfire-client::Client` で control-plane(`chainfire-server`)に接続
-
- * 自ノード ID を `ServerConfig` か CLI 引数で受け取り、
-
- * `/nodes//...` プレフィクスを定期更新(capacity, labels, health)
-
- * `/scheduling/*` プレフィクスを watch して「このノードに割り当てられた work item(VM起動、S3 shard 起動など)」を取得
-
- * 実際の VM 起動などはまだ実装しなくてよい。今回は **watch が動き、ログに “仮のタスク” を表示する程度** まででOK。
-
-3. `chainfire-watch` の API(registry / matcher / stream)に沿って、agent 側の watch クライアント実装を追加。
-
- repomix-output
-
-
-**完了条件**
-
-* `chainfire-server`(voter)1台 + `chainfire-agent` 1台の構成で、
-
- * `/scheduling/demo//task-1` に値を書き込むと agent が watch 経由で検知し、ログに出す E2E テスト。
-
-
-* * *
-
-### 1-4. ノードメタデータの KVS スキーマと Helper API
-
-**目的**
-
-* VM 基盤 / S3 / FlareDB などのスケジューリングに必要なメタデータを、chainfire 上のキーとして標準化しておく。
-
-
-**仕様**
-
-1. KVS 上のキー設計(最低限)
-
- * `/nodes//roles` : `["vm_host", "s3_storage", "flaredb_data", ...]`
-
- * `/nodes//capacity/cpu` : integer
-
- * `/nodes//capacity/memory_gb` : integer
-
- * `/nodes//labels/` : string (例: `zone=az1`, `rack=r1`)
-
-2. `chainfire-api` に helper メソッド(クライアント SDK)を追加:
-
- * `Client::register_node(NodeInfo)`
-
- * `Client::list_nodes(filter)`
-
-3. chainfire-agent は起動時にこれらのキーを埋める(フル自動じゃなくていい。設定ファイルから読み込んでもOK)。
-
-
-**完了条件**
-
-* 単体テスト & ちいさな integration テスト(ノード情報を書き、`list_nodes` 相当で読める)。
-
-
-* * *
-
-### 1-5. Raft トランスポートの堅牢化(タイムアウト/再接続)
-
-**目的**
-
-* 100台規模クラスタを見据えて、Raft RPC の失敗時挙動をきちんと定義する。
-
-
-**仕様(第一段階)**
-
-1. `chainfire-raft::network` の gRPC クライアントに対し:
-
- * リクエストごとの timeout を設定(config から注入できる形)
-
- * 接続エラー時に指数バックオフ(最大待ち時間あり)
-
-2. InstallSnapshot 等のストリーミング RPC について:
-
- * 現状のインタフェースを確認しつつ、失敗時に「どこまで送れたか」をログ出力(再開プロトコルは次フェーズでもOK)。
-
-
-**完了条件**
-
-* 意図的に Raft peer のポートを塞いだ状態でも、retry/backoff が走り続けることをテストで確認(panic しない)。
-
-
-* * *
-
-2\. flaredb 側の変更・機能追加
-=====================
-
-### 2-0. 触ることになる主な場所
-
-* `flaredb-server/`(TSO, PD, Region 管理, KVRPC 実装)
-
-* `flaredb-proto/`(`pdpb.proto`, `kvrpc.proto`, namespace mode 関連)
-
-* `flaredb-client/` 相当(あれば)
-
-
-* * *
-
-### 2-1. Namespace モードまわりの整理(IAM 用 strong namespace の前提作り)
-
-**目的**
-
-* 今後 IAM サービスなどが `iam` namespace を **strong consistency 固定** で使えるように、namespace 周りを整理。
-
-
-**仕様**
-
-1. flaredb の namespace config に「Reserved namespace 名」を追加(コード or config で `["iam", "metrics", ...]` のように定義してもよい)。
-
-2. `iam` namespace は:
-
- * サーバ起動時に自動作成(既に存在する場合は何もしない)
-
- * mode は強制的に `strong` をセット(`UpdateNamespaceMode` での変更を拒否、もしくは無視)
-
-3. もしまだであれば、`ListNamespaceModes` で reserved フラグを返せるようにする(optional)。
-
-
-**完了条件**
-
-* `iam` namespace が存在しない状態からサーバ起動 → `ListNamespaceModes` で `iam` が `strong` として返るテスト。
-
-* `UpdateNamespaceMode(namespace="iam", mode="eventual")` を投げても、`strong` のまま、もしくはエラーになることを確認。
-
-
-* * *
-
-### 2-2. TSO(Timestamp Oracle)の API/実装を IAM から使いやすくする
-
-**目的**
-
-* IAM セッションやポリシー version の `iat/exp` に FlareDB の TSO を使えるようにする。
-
-
-**仕様**
-
-1. 現状の TSO gRPC(`Tso.GetTimestamp` 的なもの)があれば、そのまま使う前提で OK。なければ:
-
- * 単純な API を追加:
-
- * `rpc GetTimestamp(GetTimestampRequest) returns (GetTimestampResponse)`
-
- * レスポンスは `physical: u64` / `logical: u16` などの構造体。
-
-2. サーバ実装は:
-
- * 単一ノード or 単一リージョンで TSO を提供(分散 TSO は次フェーズ)。
-
- * 物理時刻(ミリ秒)と論理カウンタで単調増加を保証。
-
-3. 将来のために:
-
- * `GetTimestamp` はバッチ(N個の連番)要求も受け付けられるよう設計だけ考えておく(実装は単一でもよい)。
-
-
-**完了条件**
-
-* 単体テストで:
-
- * 複数スレッドから同時に `GetTimestamp` を叩いても単調増加すること。
-
- * 物理時刻が巻き戻っても論理ビットで単調性が守られること。
-
-
-* * *
-
-### 2-3. IAM 用の「ポリシーストア」として使いやすくするための Range API の確認
-
-**目的**
-
-* IAM サービスが FlareDB を「key-value な PolicyStore」として使うために最低限必要な API を確認/整理する。
-
-
-**仕様**
-
-1. 以下が揃っていることを確認し、不足があれば追加:
-
- * prefix / range でのスキャン(例: `/iam/users/` プレフィクス)
-
- * 単一 key の get/put/CAS
-
- * (将来)Merkle + RangeFetch を使った整合性チェックの土台
-
-2. API 名は既存の `kvrpc` を踏襲。新規追加が必要なら:
-
- * `Scan` 的な RPC:`start_key`, `end_key`, `limit`, `include_values` を指定できるもの。
-
-3. SDK から見て、IAM サービスは FlareDB に対して:
-
- * `put_policy(policy_id, doc)`
-
- * `list_policies_by_principal(principal_id)`
-
- * `list_bindings_by_resource(resource_id)`
- を実装できればよい。
-
-
-**完了条件**
-
-* flaredb のサンプル/テストで、`/iam/users/*` に複数エントリを入れ、prefix スキャンで取得するテストを追加。
-
-
-* * *
-
-### 2-4. (オプション)`iam` namespace 専用の小さなクライアントヘルパ
-
-**目的**
-
-* 後で IAM サービスを書く人が flaredb-client の素の API に触れなくても済むように、**超薄い wrapper** を用意しておく(時間があれば)。
-
-
-**仕様簡略**
-
-* `IamStore` 的な struct を flaredb 側 or 別 crate に追加:
-
- * `fn put_doc(&self, key: &str, value: &Json)` → `namespace="iam"` で `Put`
-
- * `fn get_doc(&self, key: &str)` → `Get`
-
- * `fn scan_prefix(&self, prefix: &str)` → Range
-
-* 内部で使う namespace 名 `iam` は固定文字列でOK。
-
-
-**完了条件**
-
-* 最低1つの単体テスト(`put_doc` → `get_doc` → `scan_prefix`)が通ること。
-
-
-* * *
-
-3\. 実装順序(エージェントへの提案)
-====================
-
-**優先度: 高**
-
-1. chainfire: `initial_members` を用いたマルチノード bootstrap 実装(1-1)
-
-2. chainfire: RaftRole 導入 & voter / none の分離(1-2)
-
-3. chainfire: Node Agent バイナリの骨組み(gossip + client + watch のみ)(1-3)
-
-
-**優先度: 中**
-
-4. chainfire: ノードメタデータ KVS スキーマ & helper API(1-4)
-
-5. flaredb: `iam` namespace の strong 固定 & reserved namespace ロジック(2-1)
-
-6. flaredb: TSO の API/実装確認&テスト拡充(2-2)
-
-
-**優先度: 低(時間があれば)**
-
-7. chainfire: Raft RPC の timeout / backoff(1-5)
-
-8. flaredb: IAM 用 Range API のテスト追加(2-3)
-
-9. flaredb: `IamStore` 的ヘルパの追加(2-4)
-
-
-* * *
-
-こんな感じの指示をそのまま「コードを書くエージェント」に渡せば、だいぶ筋の良い実装タスクリストになります。
-ここまでできると、上に載せる IAM / VM / S3 のサービスは全部「chainfire の KVS と watch をしゃぶるエージェント」として同じ型で作れるので、将来の拡張もかなり楽になります。
-
----
-
-## You asked:
-
-chainfire-agent について、別バイナリ (`crates/chainfire-agent/`) として作成するか、それとも `chainfire-server --mode=agent` のようなモード切り替えで対応しますか? ❯ 1. 別バイナリ 新規クレート `chainfire-agent/` を作成。シンプルで軽量なバイナリになる 2. モード切り替え `chainfire-server` に `--mode=agent` オプションを追加。既存コードを再利用しやすい 3. Type something. このような質問が来ています。私としては、そもそもRaftのどれかのノードが死んでも過半数のRaftノードが生きていればLearnerを抽選か何かで選んで昇格させることを考えていたのでバイナリを分離することは結構予想外でしたし、ちょっと違うと思っています。設定でRaftのノードにしない(不安定だったり、リソースが少なかったりする場合に)ということはできるようにすると良いと思います(Raftノードにならなければそこまでリソース消費もデカくないはず)が、現状コードベースが複雑になるだけでそこまでアシンクロナスな環境を想定する必要があるとも思えないです。どうでしょうか?
-
----
-
-## ChatGPT Replied:
-
-Thought for 9m 32s
-
-いい視点だと思います、その違和感はかなり筋がいいです。
-
-* * *
-
-まず結論
-----
-
-* **今の段階なら「別バイナリ」じゃなくて、単一バイナリ+設定で Raft をオン/オフする方針で全然OK**。
-
-* つまり選択肢で言うと **「2. モード切り替え」寄り**(ただし `--mode=agent` というより、`raft.enabled` みたいなフラグで制御するイメージ)。
-
-* 「Raft voter が死んだら Learner を昇格させる」という設計とも、**単一バイナリ構成は綺麗に両立**します。
-
-
-なので、コーディングエージェントには:
-
-> **2\. モード切り替え(単一バイナリ)で進める。
-> ただし mode は CLI の文字列ではなく、設定で `raft` の有効/無効や voter/learner を制御する形にしてほしい。**
-
-と答えておくのが良さそうです。
-
-* * *
-
-なぜ別バイナリじゃなくていいのか
-----------------
-
-今の `chainfire-server` の Node を見ると、こんな構成になっています:
-
-repomix-output
-
- pub struct Node {
- config: ServerConfig,
- raft: Arc,
- watch_registry: Arc,
- gossip: Option,
- shutdown_tx: broadcast::Sender<()>,
- }
-
-
-* つまり **必ず RaftNode が起動する前提**。
-
-* `NodeRole` は `control_plane` / `worker` を gossip に伝えるためだけに使っていて、Raft の voter/learner とは関係がない。
-
-
-ここに別バイナリを足すと、
-
-* `chainfire-server`(フル機能:Raft + Gossip + API)
-
-* `chainfire-agent`(Gossip + client + watch)
-
-
-という2パターンが生まれて、`ServerConfig`/起動コードの分岐が増えるうえ、
-
-* デプロイのたびに「どっち入れるんだっけ?」問題が出る
-
-* まだ VM/S3 サービス側のエージェントも実装されていない状態でやると、設計だけ先に複雑になる
-
-
-ので、「**とりあえず全部1バイナリでいいじゃん**」という感覚はかなり妥当です。
-
-将来、
-「もうプロダクションで1000ノードだし、agent と server を分けたいね」
-となってからでも、**そこまで大きな破壊的変更なしに分離できます**。
-
-* * *
-
-どう作るとキレイか(単一バイナリ案の中身)
----------------------
-
-### 1\. `ServerConfig` に Raft の役割フラグを追加
-
-今の config は `node.role = "control_plane" | "worker"` しかないですが、ここにもう少し具体的な Raft 設定を足すイメージです。
-
-例:
-
- [node]
- id = 1
- role = "control_plane" # これは gossip 用のメタ的なロール
-
- [raft]
- enabled = true # false にすると RaftNode 自体を持たない
- voter = true # enabled = true のときだけ意味がある
-
-
-あるいは:
-
- [raft]
- role = "voter" | "learner" | "none"
-
-
-みたいな enum でもOK。
-
-### 2\. `Node` の `raft` を `Option>` にする
-
- pub struct Node {
- config: ServerConfig,
- raft: Option>,
- watch_registry: Arc,
- gossip: Option,
- // ...
- }
-
-
-`Node::new` で:
-
- let raft = if config.raft.enabled {
- Some(Arc::new(RaftNode::new(...).await?))
- } else {
- None
- };
-
-
-みたいにする。
-
-* Raft を持たないノードは、単に gossip + watch だけ動く「薄いノード」として振る舞う。
-
-* もしそのノードがローカルから KVS を叩く必要があれば、**`chainfire-client` でリモートの Raft クラスタに繋ぐ**ことができます(すでに API は揃っている)。
-
- repomix-output
-
-
-これなら「全ノードで chainfire が動いている」という感覚は維持しつつ、
-**どのノードが Raft メンバーかは設定だけで切り替え可能**になります。
-
-> 「不安定なマシンやリソースの細いマシンは Raft メンバーにしない」という要件にもピッタリ。
-
-### 3\. Learner 昇格ロジックは「クラスタサービス」に閉じ込める
-
-あなたが言っていた:
-
-> Raft のどれかのノードが死んでも過半数の Raft ノードが生きていれば
-> Learner を抽選か何かで選んで昇格させたい
-
-これは **バイナリ分割とはまったく独立した話**で、
-
-* gossip から「ノードの liveness / health」を取る
-
-* `chainfire-api` にクラスタ管理用の RPC(`add_learner`, `change_membership` を wrap)を生やす
-
-* 「voter が N 台未満になったら、`raft.role = learner` でかつ healthy なノードを昇格する」
-
-
-というコントロールプレーンのロジックをどこか1箇所に書けば実現できます。
-
-そのロジックは `control_plane` ロールのノードのどれか 1 台で動かせばよいし、
-それが `chainfire-server` と同じバイナリか、将来分離したバイナリかは関係ないです。
-
-* * *
-
-「そこまでアシンクロナスな環境を想定する必要がある?」問題
------------------------------
-
-ここで言っている「agent を別バイナリにするか」は、
-実は「アシンクロナスかどうか」というよりは **運用と責務分離の話**なんですよね。
-
-* 今:
-
- * Raft + gRPC + Gossip + Watch が全部 `chainfire-server` の Node に押し込まれている
-
- repomix-output
-
-* 将来:
-
- * これを「KVSサーバー」と「クラスタエージェント」に分けて、
- どこに何を入れるかをもっときれいに整理できると嬉しいかもね、という話。
-
-
-ただ、
-
-* まだサービス群(VM/S3/FlareDB データノード)の実装がこれから
-
-* ノード数もとりあえず 100 台規模想定
-
-* コードベースをこれ以上分岐だらけにしたくない
-
-
-という現在地を考えると、
-
-> ● とりあえず単一バイナリで実装しつつ
-> ● Raft の有効/無効、voter/learner を **設定で切れるようにしておく**
-
-というところまでで十分です。
-
-そのうえで、将来「VM/S3 エージェントをもっと綺麗にしたい」「起動オプションを減らしたい」となったら、
-そのときに **`chainfire-server --mode=agent` を追加したり、別バイナリに分ける**のがちょうどいいタイミングです。
-
-* * *
-
-コーディングエージェントへの返答テンプレ(そのまま投げてOKなやつ)
-----------------------------------
-
-質問への返答としては、こんな感じで答えておくと意図が伝わりやすいと思います:
-
-> **2\. モード切り替えでお願いします。**
-> ただし、新しいバイナリ `chainfire-agent` は作らず、既存の `chainfire-server` に
-> 「Raft を有効にするかどうか」「voter/learner/none の役割」を設定で切り替えられるようにしてください。
->
-> 具体的には:
->
-> * `ServerConfig` に `[raft]` セクションを追加して、`role = "voter" | "learner" | "none"` を持たせる
->
-> * `Node` の `raft` フィールドを `Option>` にして、`role = "none"` のときは RaftNode を起動しない
->
-> * gossip は全ノードで起動し、`node.role`(control\_plane / worker)は従来通り gossip 上のロールとして使う
->
-> * 将来的に、Raft voter が減ったときに learner を昇格させる機能(`change_membership` を呼ぶコントローラ)を実装する前提で、
-> その土台になる `raft.role` の情報が KVS から取得できるようにしておいてください。
->
-
-こんな方針をベースに進めると、
-
-* あなたの「全ノード chainfire が動きつつ、一部だけ Raft メンバー」という前提
-
-* Learner 昇格での自動回復
-
-* そして「今はコードベースを無駄に複雑にしたくない」という現実
-
-
-この3つがうまく同時に満たせます。
-
-クラスタ基盤って、最初は「シンプルさ>超キレイな責務分離」の方が開発速度も理解も早いので、今の判断はかなり良いバランスだと思います。
-
----
-
-## You asked:
-
-FlareDB の Range/Scan API は、どの gRPC サービスに追加しますか? ❯ 1. KvRaw に追加 既存の KvRaw サービスに `RawScan` を追加 2. 新サービス 新規 `KvScan` サービスを作成 3. 両方に追加 KvRaw と KvCas 両方に Scan を追加(consistency mode別) 4. Type something. これはどうしますか?
-
----
-
-## ChatGPT Replied:
-
-Thought for 5m 39s
-
-自分なら **選択肢 3(KvRaw と KvCas 両方に追加)一択**にします。
-
-理由をちゃんと分解して話します。
-
-* * *
-
-なぜ「両方に追加」か
-----------
-
-今の gRPC 契約を改めて見ると:
-
-* `KvRaw` = **Raw(eventual consistency)用のAPI**
-
-* `KvCas` = **CAS + version 付きの strong consistency API**
-
- repomix-output
-
-
-さらに、FlareDB は namespace ごとに `strong | eventual` モードを持つ、という設計になってますよね。
-
-repomix-output
-
-つまり世界観としては:
-
-* eventual なログやメトリクス系 → `KvRaw`
-
-* IAM など強い整合性が欲しい設定系 → `KvCas`
-
-
-という役割分担になっているはずです。
-
-### Range/Scan のニーズをそれにマッピングすると…
-
-* **IAM 用(強整合)スキャン**
-
- * 「この namespace (`iam/*`) 配下の policy を全部列挙」みたいなユースケース
-
- * version 情報も欲しい(楽観ロックや監査に使える)
-
- * → **KvCas 側に Scan が必要**
-
-* **ログ・メトリクス・キャッシュ的な eventual スキャン**
-
- * 「最近のイベントを key prefix でザッと読む」みたいなやつ
-
- * 多少の遅延・ズレは OK
-
- * → **KvRaw 側に RawScan があると便利**
-
-
-なので、**「整合性モードごとに別サービス」という既存の分離をそのまま Range にも引き継ぐ**のが一番きれいです。
-結果として、選択肢 3 の
-
-> KvRaw と KvCas 両方に Scan を追加(consistency mode 別)
-
-が自然な落としどころになります。
-
-* * *
-
-具体的な形のイメージ
-----------
-
-命名はこんな感じが良さそうです:
-
-* `KvRaw` に **`RawScan`**
-
-* `KvCas` に **`Scan`**(もしくは `CasScan`)
-
-
-### proto のイメージ
-
-※ざっくりイメージレベルです。細かいフィールドは後で詰めればOK。
-
- // Raw (eventual) scan
- service KvRaw {
- rpc RawPut(RawPutRequest) returns (RawPutResponse);
- rpc RawGet(RawGetRequest) returns (RawGetResponse);
- rpc RawScan(RawScanRequest) returns (RawScanResponse);
- }
-
- message RawScanRequest {
- string namespace = 1;
- bytes start_key = 2; // inclusive
- bytes end_key = 3; // exclusive (or empty = no upper bound)
- uint32 limit = 4; // paging 用
- }
-
- message RawScanResponse {
- repeated RawKvPair pairs = 1;
- bool has_more = 2;
- }
-
- message RawKvPair {
- bytes key = 1;
- bytes value = 2;
- }
-
-
- // Strong (CAS) scan
- service KvCas {
- rpc CompareAndSwap(CasRequest) returns (CasResponse);
- rpc Get(GetRequest) returns (GetResponse);
- rpc Scan(ScanRequest) returns (ScanResponse);
- }
-
- message ScanRequest {
- string namespace = 1;
- bytes start_key = 2;
- bytes end_key = 3;
- uint32 limit = 4;
- }
-
- message ScanResponse {
- repeated VersionedKvPair pairs = 1;
- bool has_more = 2;
- }
-
- message VersionedKvPair {
- bytes key = 1;
- bytes value = 2;
- uint64 version = 3;
- }
-
-
-実装側では内部的に
-
-* 共通の `RangeScan` トレイト/関数(`fn scan(range, namespace, mode)`)
-
-* それを呼ぶ gRPC handler が `KvRaw` / `KvCas` に 2 つあるだけ
-
-
-という感じにすれば、ロジックはほぼ共有できます。proto レベルでは分かれているけど、中身は共通、という構造。
-
-* * *
-
-なぜ「KvRawだけ」や「新サービス」にしないのか
--------------------------
-
-### 1\. KvRaw だけに追加する案
-
-* strong consistency が欲しい IAM 側からすると、
-
- * 「なぜ single Get は KvCas なのに、Range だけ eventual 側に行くの?」という気持ち悪さ
-
- * 将来 Txn/SQL っぽいレイヤを乗せるときに、「strong namespace の Range がない」という歪みが出る
-
-
-**→ IAM ユースケースを考えると、KvCas 側に Scan が無いのはかなりつらい。**
-
-### 2\. 新サービス `KvScan` を作る案
-
-* `KvScan` の中で `mode=strong|eventual` みたいなフラグを出すか、namespace モードで切り替えることになる
-
-* ところが、既にサービスレベルで strong と eventual を分けている世界観と **二重構造**になってしまう
-
-* クライアントから見たときに、
-
- * 単一キー → KvRaw / KvCas
-
- * Range → KvScan(ただし中で strong/eventual がまた分岐)
-
- * という API の形が不自然
-
-
-**→ せっかくサービス名でモードを分けている設計を壊してしまうだけなので、やめておいた方が素直。**
-
-* * *
-
-まとめ:回答としてはこう返すのがおすすめ
---------------------
-
-コーディングエージェントの質問への返答としては:
-
-> **「3. KvRaw と KvCas 両方に追加」**
->
-> * `KvRaw` に `RawScan` を追加(eventual consistency range)
->
-> * `KvCas` に `Scan` を追加(strong consistency + version 付き range)
->
-> * request/response メッセージはできるだけ共通の形を保ちつつ、CAS では `version` を返す
->
-
-と答えておくと、そのままきれいに進められると思います。
-
-このあとのステップとしては、
-
-1. `rdb-proto/src/kvrpc.proto` に上記メソッド&メッセージを追加
-
-2. tonic/prost 再生成
-
-3. `rdb-server` 側で stub 実装(単 shard / 単 replica の簡易実装から)
-
-4. 既存の `verify-sharding.sh` みたいな感じで、Range をまたぐテストスクリプトを追加
-
-
-という順で攻めると、壊さずに徐々に拡張できます。ここまでできると IAM 側から「strong namespace + Scan」を素直に使えるようになるはず。
-
----
-
-## You asked:
-
-● 計画ファイルを作成しました。内容の概要: Phase 1(依存なし): - Raft RPC タイムアウト/バックオフ追加 - FlareDB reserved namespace (iam を strong 固定) - TSO ドキュメント追加 Phase 2(Chainfire コア): - RaftRole enum (voter/learner/none) 導入 - Node.raft を Option> に変更 - initial\_members を使ったマルチノード bootstrap - Agent モード(role=none で Raft なし、gossip + client のみ) - ノードメタデータ KVS スキーマ & ヘルパー API Phase 3(FlareDB Range API): - KvRaw.RawScan + KvCas.Scan 追加(ページネーション対応) - IamStore ヘルパー(optional) 実装は優先度順に9タスク。別バイナリは作らず、既存の chainfire-server に設定で役割を切り替える方式です。 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Ready to code? Here is Claude's plan: ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ Chainfire & FlareDB 分散システム強化計画 概要 chainfire(Raft+Gossip KVS)と flaredb(分散DB)の基盤強化。9タスクを3フェーズで実装。 --- Phase 1: 基盤整備(依存なし) 1-5. Raft RPC タイムアウト/バックオフ ファイル: chainfire/crates/chainfire-api/src/raft\_client.rs // 追加: RetryConfig 構造体 pub struct RetryConfig { pub initial\_timeout: Duration, // 500ms pub max\_timeout: Duration, // 30s pub max\_retries: u32, // 3 pub backoff\_multiplier: f64, // 2.0 } // GrpcRaftClient に with\_retry メソッド追加 // vote, append\_entries, install\_snapshot を retry ラッパーで包む // InstallSnapshot 失敗時は error! ログ出力 2-1. Reserved Namespace (IAM用 strong 固定) ファイル: flaredb/crates/flaredb-server/src/config/mod.rs // 追加: 予約済み namespace リスト pub const RESERVED\_NAMESPACES: &\[&str\] = &\["iam", "metrics", "\_system"\]; // ServerConfig::new() で自動作成 (mode=Strong) // set\_namespace\_mode() で予約済みの mode 変更をブロック → Err 返却 2-2. TSO ドキュメント追加 ファイル: flaredb/crates/flaredb-pd/src/tso.rs - モジュールドキュメント追加(フォーマット説明: upper 48bit = physical, lower 16bit = logical) - physical\_time(ts), logical\_counter(ts) ヘルパー追加 - バッチ割り当てテスト追加 --- Phase 2: Chainfire コア変更 1-2. RaftRole 分離 (voter/learner/none) ファイル: - chainfire/crates/chainfire-types/src/node.rs — RaftRole enum 追加 - chainfire/crates/chainfire-server/src/config.rs — RaftConfig セクション追加 - chainfire/crates/chainfire-server/src/node.rs — Node 構造体変更 // chainfire-types/src/node.rs #\[derive(Default)\] pub enum RaftRole { #\[default\] Voter, Learner, None, } // chainfire-server/src/config.rs pub struct RaftConfig { pub role: RaftRole, // TOML: \[raft\] role = "voter" | "learner" | "none" } // chainfire-server/src/node.rs pub struct Node { raft: Option>, // None when role=none // gossip は全ノードで起動 } 1-1. Multi-node Bootstrap ファイル: chainfire/crates/chainfire-server/src/node.rs pub async fn maybe\_bootstrap(&self) -> Result<()> { let Some(raft) = &self.raft else { return Ok(()); }; match self.config.raft.role { RaftRole::Voter if self.config.cluster.bootstrap => { if self.config.cluster.initial\_members.is\_empty() { raft.initialize().await?; // 単一ノード } else { let members = initial\_members\_to\_btreemap(&self.config.cluster.initial\_members); raft.initialize\_cluster(members).await?; // マルチノード } } RaftRole::Learner => { info!("Learner ready, waiting to join"); } \_ => {} } self.store\_raft\_role\_metadata().await?; // KVS に role 記録 Ok(()) } 1-3. Agent モード (role=none) ファイル: chainfire/crates/chainfire-server/src/node.rs - role=none 時は RaftNode を起動しない - chainfire-client で control-plane に接続 - watch subscription 可能 let client = if !config.raft.role.participates\_in\_raft() { // initial\_members から control-plane アドレス取得して接続 Some(Client::connect(&control\_plane\_addr).await?) } else { None }; 1-4. ノードメタデータ KVS スキーマ ファイル: chainfire/chainfire-client/src/node.rs (新規) KVS キー設計: /nodes//roles → {"raft\_role": "voter", "gossip\_role": "control\_plane"} /nodes//capacity/cpu → u32 /nodes//capacity/memory\_gb → u32 /nodes//labels/ → string /nodes//api\_addr → string pub struct NodeMetadata { id, name, raft\_role, gossip\_role, capacity, labels, ... } pub async fn register\_node(client: &mut Client, meta: &NodeMetadata) -> Result<()> pub async fn list\_nodes(client: &mut Client, filter: &NodeFilter) -> Result> --- Phase 3: FlareDB Range API 2-3. KvRaw/KvCas に Scan 追加 ファイル: - flaredb/crates/flaredb-proto/src/kvrpc.proto - flaredb/crates/flaredb-server/src/service.rs // kvrpc.proto service KvRaw { rpc RawScan(RawScanRequest) returns (RawScanResponse); } message RawScanRequest { bytes start\_key = 1; // inclusive bytes end\_key = 2; // exclusive uint32 limit = 3; string namespace = 4; } message RawScanResponse { repeated bytes keys = 1; repeated bytes values = 2; bool has\_more = 3; bytes next\_key = 4; // pagination用 } service KvCas { rpc Scan(ScanRequest) returns (ScanResponse); } message VersionedKV { bytes key = 1; bytes value = 2; uint64 version = 3; } message ScanResponse { repeated VersionedKV entries = 1; bool has\_more = 2; bytes next\_key = 3; } 2-4. IamStore ヘルパー (Optional) ファイル: flaredb/crates/flaredb-client/src/iam\_store.rs (新規) pub struct IamStore { client: RdbClient } impl IamStore { pub async fn put\_doc(&mut self, prefix: &str, id: &str, doc: &T) -> Result pub async fn get\_doc(&mut self, prefix: &str, id: &str) -> Result