agents-city 0.3.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +16 -0
- package/LICENSE +202 -0
- package/NOTICE +5 -0
- package/README.es.md +2021 -0
- package/README.md +1999 -0
- package/benchmarks/committee/README.md +39 -0
- package/benchmarks/committee/metrics.py +51 -0
- package/benchmarks/committee/run.py +64 -0
- package/benchmarks/committee/traces/01-single.json +8 -0
- package/benchmarks/committee/traces/02-mesh.json +16 -0
- package/benchmarks/committee/traces/03-chair.json +15 -0
- package/benchmarks/latency/README.md +35 -0
- package/benchmarks/latency/fake-claude-cli.mjs +119 -0
- package/benchmarks/latency/fake-native-server.mjs +340 -0
- package/benchmarks/latency/fake-tui.py +91 -0
- package/benchmarks/latency/live.py +380 -0
- package/benchmarks/stress/README.md +20 -0
- package/benchmarks/stress/run.py +487 -0
- package/bin/agents +4 -0
- package/bin/agents-city.js +116 -0
- package/bin/benchmark +17 -0
- package/bin/bus +6 -0
- package/bin/cities +3 -0
- package/bin/city +86 -0
- package/bin/committee +6 -0
- package/bin/demo +200 -0
- package/bin/exit +5 -0
- package/bin/hall +73 -0
- package/bin/hall.html +426 -0
- package/bin/logs +3 -0
- package/bin/report.py +14 -0
- package/bin/reset +3 -0
- package/bin/road +3 -0
- package/bin/seat +10 -0
- package/bin/serve.py +1428 -0
- package/bin/setup.py +753 -0
- package/bin/skills +3 -0
- package/bin/test +131 -0
- package/bin/test-adapter.py +183 -0
- package/bin/test-admision.py +99 -0
- package/bin/test-avatar.py +58 -0
- package/bin/test-benchmark.py +40 -0
- package/bin/test-broker.py +334 -0
- package/bin/test-cage.py +206 -0
- package/bin/test-card.py +402 -0
- package/bin/test-channel.py +379 -0
- package/bin/test-cities.py +453 -0
- package/bin/test-claude-runtime.py +252 -0
- package/bin/test-committee.py +340 -0
- package/bin/test-contracts.py +544 -0
- package/bin/test-crecimiento.py +164 -0
- package/bin/test-demo.py +308 -0
- package/bin/test-doctor.py +106 -0
- package/bin/test-domains.py +151 -0
- package/bin/test-evidencia.py +50 -0
- package/bin/test-exit.py +128 -0
- package/bin/test-hall-protocol.py +93 -0
- package/bin/test-launch.py +169 -0
- package/bin/test-live-feed.py +508 -0
- package/bin/test-pairing.py +99 -0
- package/bin/test-parcels.py +283 -0
- package/bin/test-runtime-failures.py +252 -0
- package/bin/test-runtime-ui.py +488 -0
- package/bin/test-runtime.py +268 -0
- package/bin/test-rutas.py +80 -0
- package/bin/test-seat.py +1386 -0
- package/bin/test-security.py +150 -0
- package/bin/test-serve.py +1057 -0
- package/bin/test-stress.py +64 -0
- package/bin/test-widgets.py +143 -0
- package/bin/test-workspace.py +188 -0
- package/bin/testlib.py +95 -0
- package/bin/tokens.py +14 -0
- package/bus/scripts/deploy.sh +60 -0
- package/bus/scripts/mint-token.sh +68 -0
- package/bus/scripts/setup-dev.sh +79 -0
- package/bus/scripts/test-channel.ts +8 -0
- package/bus/scripts/test-hub.ts +266 -0
- package/bus/scripts/test-local.sh +40 -0
- package/bus/scripts/test-queue.ts +132 -0
- package/bus/worker/package-lock.json +1971 -0
- package/bus/worker/package.json +17 -0
- package/bus/worker/src/index.ts +485 -0
- package/bus/worker/tsconfig.json +13 -0
- package/bus/worker/wrangler.toml +32 -0
- package/city/oven/README.md +59 -0
- package/city/oven/collect.py +43 -0
- package/city/oven/oven.html +4 -0
- package/city/scripts/history.py +120 -0
- package/city/scripts/seed.py +442 -0
- package/city/web/assets/modelos/License.txt +28 -0
- package/city/web/assets/modelos/PROCEDENCIA.txt +3 -0
- package/city/web/assets/modelos/building-a.glb +0 -0
- package/city/web/assets/modelos/building-b.glb +0 -0
- package/city/web/assets/modelos/building-c.glb +0 -0
- package/city/web/assets/modelos/building-d.glb +0 -0
- package/city/web/assets/modelos/building-e.glb +0 -0
- package/city/web/assets/modelos/building-f.glb +0 -0
- package/city/web/assets/modelos/building-g.glb +0 -0
- package/city/web/assets/modelos/building-h.glb +0 -0
- package/city/web/assets/sprites/building-a.png +0 -0
- package/city/web/assets/sprites/building-b.png +0 -0
- package/city/web/assets/sprites/building-c.png +0 -0
- package/city/web/assets/sprites/building-d.png +0 -0
- package/city/web/assets/sprites/building-e.png +0 -0
- package/city/web/assets/sprites/building-f.png +0 -0
- package/city/web/assets/sprites/building-g.png +0 -0
- package/city/web/assets/sprites/building-h.png +0 -0
- package/city/web/assets/sprites/building-i.png +0 -0
- package/city/web/assets/sprites/building-j.png +0 -0
- package/city/web/assets/sprites/building-k.png +0 -0
- package/city/web/assets/sprites/building-l.png +0 -0
- package/city/web/assets/sprites/building-m.png +0 -0
- package/city/web/assets/sprites/building-n.png +0 -0
- package/city/web/assets/sprites/building-skyscraper-a.png +0 -0
- package/city/web/assets/sprites/building-skyscraper-b.png +0 -0
- package/city/web/assets/sprites/building-skyscraper-c.png +0 -0
- package/city/web/assets/sprites/building-skyscraper-d.png +0 -0
- package/city/web/assets/sprites/building-skyscraper-e.png +0 -0
- package/city/web/assets/sprites/catalogo.json +47 -0
- package/city/web/assets/sprites/detail-awning-wide.png +0 -0
- package/city/web/assets/sprites/detail-awning.png +0 -0
- package/city/web/assets/sprites/detail-overhang-wide.png +0 -0
- package/city/web/assets/sprites/detail-overhang.png +0 -0
- package/city/web/assets/sprites/detail-parasol-a.png +0 -0
- package/city/web/assets/sprites/detail-parasol-b.png +0 -0
- package/city/web/assets/sprites/low-detail-building-a.png +0 -0
- package/city/web/assets/sprites/low-detail-building-b.png +0 -0
- package/city/web/assets/sprites/low-detail-building-c.png +0 -0
- package/city/web/assets/sprites/low-detail-building-d.png +0 -0
- package/city/web/assets/sprites/low-detail-building-e.png +0 -0
- package/city/web/assets/sprites/low-detail-building-f.png +0 -0
- package/city/web/assets/sprites/low-detail-building-g.png +0 -0
- package/city/web/assets/sprites/low-detail-building-h.png +0 -0
- package/city/web/assets/sprites/low-detail-building-i.png +0 -0
- package/city/web/assets/sprites/low-detail-building-j.png +0 -0
- package/city/web/assets/sprites/low-detail-building-k.png +0 -0
- package/city/web/assets/sprites/low-detail-building-l.png +0 -0
- package/city/web/assets/sprites/low-detail-building-m.png +0 -0
- package/city/web/assets/sprites/low-detail-building-n.png +0 -0
- package/city/web/assets/sprites/low-detail-building-wide-a.png +0 -0
- package/city/web/assets/sprites/low-detail-building-wide-b.png +0 -0
- package/city/web/assets/sprites/medidas.json +248 -0
- package/city/web/dist/city.js +939 -0
- package/city/web/dist/index.html +294 -0
- package/city/web/dist/modelos/License.txt +28 -0
- package/city/web/dist/modelos/PROCEDENCIA.txt +3 -0
- package/city/web/dist/modelos/building-a.glb +0 -0
- package/city/web/dist/modelos/building-b.glb +0 -0
- package/city/web/dist/modelos/building-c.glb +0 -0
- package/city/web/dist/modelos/building-d.glb +0 -0
- package/city/web/dist/modelos/building-e.glb +0 -0
- package/city/web/dist/modelos/building-f.glb +0 -0
- package/city/web/dist/modelos/building-g.glb +0 -0
- package/city/web/dist/modelos/building-h.glb +0 -0
- package/city/web/dist/sprites/building-a.png +0 -0
- package/city/web/dist/sprites/building-b.png +0 -0
- package/city/web/dist/sprites/building-c.png +0 -0
- package/city/web/dist/sprites/building-d.png +0 -0
- package/city/web/dist/sprites/building-e.png +0 -0
- package/city/web/dist/sprites/building-f.png +0 -0
- package/city/web/dist/sprites/building-g.png +0 -0
- package/city/web/dist/sprites/building-h.png +0 -0
- package/city/web/dist/sprites/building-i.png +0 -0
- package/city/web/dist/sprites/building-j.png +0 -0
- package/city/web/dist/sprites/building-k.png +0 -0
- package/city/web/dist/sprites/building-l.png +0 -0
- package/city/web/dist/sprites/building-m.png +0 -0
- package/city/web/dist/sprites/building-n.png +0 -0
- package/city/web/dist/sprites/building-skyscraper-a.png +0 -0
- package/city/web/dist/sprites/building-skyscraper-b.png +0 -0
- package/city/web/dist/sprites/building-skyscraper-c.png +0 -0
- package/city/web/dist/sprites/building-skyscraper-d.png +0 -0
- package/city/web/dist/sprites/building-skyscraper-e.png +0 -0
- package/city/web/dist/sprites/catalogo.json +47 -0
- package/city/web/dist/sprites/detail-awning-wide.png +0 -0
- package/city/web/dist/sprites/detail-awning.png +0 -0
- package/city/web/dist/sprites/detail-overhang-wide.png +0 -0
- package/city/web/dist/sprites/detail-overhang.png +0 -0
- package/city/web/dist/sprites/detail-parasol-a.png +0 -0
- package/city/web/dist/sprites/detail-parasol-b.png +0 -0
- package/city/web/dist/sprites/low-detail-building-a.png +0 -0
- package/city/web/dist/sprites/low-detail-building-b.png +0 -0
- package/city/web/dist/sprites/low-detail-building-c.png +0 -0
- package/city/web/dist/sprites/low-detail-building-d.png +0 -0
- package/city/web/dist/sprites/low-detail-building-e.png +0 -0
- package/city/web/dist/sprites/low-detail-building-f.png +0 -0
- package/city/web/dist/sprites/low-detail-building-g.png +0 -0
- package/city/web/dist/sprites/low-detail-building-h.png +0 -0
- package/city/web/dist/sprites/low-detail-building-i.png +0 -0
- package/city/web/dist/sprites/low-detail-building-j.png +0 -0
- package/city/web/dist/sprites/low-detail-building-k.png +0 -0
- package/city/web/dist/sprites/low-detail-building-l.png +0 -0
- package/city/web/dist/sprites/low-detail-building-m.png +0 -0
- package/city/web/dist/sprites/low-detail-building-n.png +0 -0
- package/city/web/dist/sprites/low-detail-building-wide-a.png +0 -0
- package/city/web/dist/sprites/low-detail-building-wide-b.png +0 -0
- package/city/web/dist/sprites/medidas.json +248 -0
- package/city/web/dist-hall/hall.js +264 -0
- package/city/web/index.html +294 -0
- package/city/web/package.json +18 -0
- package/city/web/sella.py +21 -0
- package/city/web/src/activity-actors.ts +47 -0
- package/city/web/src/activity.ts +172 -0
- package/city/web/src/ayuntamiento.ts +580 -0
- package/city/web/src/draw.ts +640 -0
- package/city/web/src/game-speech.ts +79 -0
- package/city/web/src/hall.ts +1867 -0
- package/city/web/src/main.ts +2225 -0
- package/city/web/src/oven.ts +124 -0
- package/city/web/src/people.ts +244 -0
- package/city/web/src/presencia.ts +193 -0
- package/city/web/src/puertas.ts +180 -0
- package/city/web/src/repo-roles.ts +59 -0
- package/city/worker/package.json +16 -0
- package/city/worker/schema.sql +117 -0
- package/city/worker/src/index.ts +702 -0
- package/city/worker/src/square.ts +218 -0
- package/city/worker/wrangler.toml +58 -0
- package/demo/ada.md +50 -0
- package/demo/bruno.md +62 -0
- package/demo/camila.md +56 -0
- package/demo/city/ada.md +40 -0
- package/demo/city/city.yml +8 -0
- package/demo/city/parcels.yml +15 -0
- package/demo/city/roads.json +4 -0
- package/demo/city/units.yml +10 -0
- package/demo/clinica/city.yml +8 -0
- package/demo/clinica/parcels.yml +15 -0
- package/demo/clinica/roads.json +4 -0
- package/demo/clinica/units.yml +9 -0
- package/demo/clinica/vera.md +46 -0
- package/demo/dante.md +54 -0
- package/demo/despacho/city.yml +8 -0
- package/demo/despacho/marta.md +46 -0
- package/demo/despacho/parcels.yml +15 -0
- package/demo/despacho/roads.json +4 -0
- package/demo/despacho/units.yml +9 -0
- package/demo/elsa.md +50 -0
- package/demo/farid.md +52 -0
- package/demo/greta.md +50 -0
- package/demo/hugo.md +49 -0
- package/demo/iris.md +49 -0
- package/demo/jonas.md +51 -0
- package/demo/kira.md +51 -0
- package/demo/luca.md +49 -0
- package/demo/parcels.yml +92 -0
- package/demo/seed.py +20 -0
- package/demo/show.py +161 -0
- package/demo/stories.py +824 -0
- package/demo/units.yml +33 -0
- package/docs/agents-first.md +99 -0
- package/docs/glossary.md +55 -0
- package/docs/map-live-layers.md +73 -0
- package/docs/security.md +231 -0
- package/docs/self-host.md +151 -0
- package/docs/testing.md +205 -0
- package/package.json +73 -0
- package/plugin/.claude-plugin/plugin.json +62 -0
- package/plugin/.mcp.json +15 -0
- package/plugin/channel/activity-cli.ts +16 -0
- package/plugin/channel/adapter-prompts.ts +113 -0
- package/plugin/channel/adapter.js +4292 -0
- package/plugin/channel/adapter.ts +133 -0
- package/plugin/channel/bus.js +20188 -0
- package/plugin/channel/bus.ts +131 -0
- package/plugin/channel/city-config.ts +125 -0
- package/plugin/channel/claude-channel.ts +58 -0
- package/plugin/channel/cli-args.ts +75 -0
- package/plugin/channel/client.js +4200 -0
- package/plugin/channel/client.ts +38 -0
- package/plugin/channel/committee/activity.ts +256 -0
- package/plugin/channel/committee/collection.ts +154 -0
- package/plugin/channel/committee/decision.ts +175 -0
- package/plugin/channel/committee/floor.ts +135 -0
- package/plugin/channel/committee/guards.ts +30 -0
- package/plugin/channel/committee/history.ts +38 -0
- package/plugin/channel/committee/render.ts +102 -0
- package/plugin/channel/committee/service.ts +72 -0
- package/plugin/channel/committee/storage.ts +92 -0
- package/plugin/channel/committee/types.ts +163 -0
- package/plugin/channel/committee/view.ts +63 -0
- package/plugin/channel/committee-cli.ts +109 -0
- package/plugin/channel/delivery-metrics.ts +61 -0
- package/plugin/channel/delivery-queue.ts +118 -0
- package/plugin/channel/hub/activity-controller.ts +72 -0
- package/plugin/channel/hub/activity-feed.ts +169 -0
- package/plugin/channel/hub/committee-controller.ts +60 -0
- package/plugin/channel/hub/connections.ts +48 -0
- package/plugin/channel/hub/diagnostics.ts +67 -0
- package/plugin/channel/hub/envelope-validity.ts +109 -0
- package/plugin/channel/hub/envelopes.ts +66 -0
- package/plugin/channel/hub/lifecycle.ts +91 -0
- package/plugin/channel/hub/local-roads.ts +89 -0
- package/plugin/channel/hub/remote-roads.ts +165 -0
- package/plugin/channel/hub/road-controller.ts +99 -0
- package/plugin/channel/hub-client.ts +149 -0
- package/plugin/channel/local-hub.js +5995 -0
- package/plugin/channel/local-hub.ts +349 -0
- package/plugin/channel/map-reporter.ts +48 -0
- package/plugin/channel/package-lock.json +1731 -0
- package/plugin/channel/package.json +19 -0
- package/plugin/channel/protocol.ts +98 -0
- package/plugin/channel/road-cli.ts +18 -0
- package/plugin/channel/run.sh +15 -0
- package/plugin/channel/runtime/claude.ts +458 -0
- package/plugin/channel/runtime/codex-config.ts +77 -0
- package/plugin/channel/runtime/codex.ts +669 -0
- package/plugin/channel/runtime/command.ts +62 -0
- package/plugin/channel/runtime/factory.ts +15 -0
- package/plugin/channel/runtime/json-rpc.ts +154 -0
- package/plugin/channel/runtime/kimi.ts +277 -0
- package/plugin/channel/runtime/opencode.ts +248 -0
- package/plugin/channel/runtime/process.ts +84 -0
- package/plugin/channel/runtime/types.ts +45 -0
- package/plugin/channel/runtime-files.ts +73 -0
- package/plugin/channel/runtime-gateway.js +6396 -0
- package/plugin/channel/runtime-gateway.ts +358 -0
- package/plugin/channel/runtime-metrics.ts +52 -0
- package/plugin/channel/runtime-subscription.ts +180 -0
- package/plugin/channel/terminal-delivery.ts +131 -0
- package/plugin/channel/untrusted.ts +60 -0
- package/plugin/commands/committee.md +31 -0
- package/plugin/commands/exit.md +32 -0
- package/plugin/commands/goals.md +20 -0
- package/plugin/commands/join.md +18 -0
- package/plugin/commands/notice.md +20 -0
- package/plugin/commands/propose.md +19 -0
- package/plugin/commands/round.md +17 -0
- package/plugin/commands/session.md +22 -0
- package/plugin/commands/settings.md +25 -0
- package/plugin/commands/setup.md +21 -0
- package/plugin/commands/team.md +23 -0
- package/plugin/domains/custom.md +27 -0
- package/plugin/domains/finance.md +31 -0
- package/plugin/domains/healthcare.md +34 -0
- package/plugin/domains/legal.md +31 -0
- package/plugin/domains/marketing.md +33 -0
- package/plugin/domains/operations.md +31 -0
- package/plugin/domains/research.md +32 -0
- package/plugin/domains/sales.md +30 -0
- package/plugin/domains/software.md +37 -0
- package/plugin/hooks/activity.sh +6 -0
- package/plugin/hooks/digging.sh +68 -0
- package/plugin/hooks/growth.sh +42 -0
- package/plugin/hooks/hooks.json +106 -0
- package/plugin/hooks/notice-on-pr.sh +35 -0
- package/plugin/hooks/notice-on-stop.sh +80 -0
- package/plugin/hooks/notice-pending.sh +58 -0
- package/plugin/hooks/solo-en-ciudad.sh +23 -0
- package/plugin/hooks/tokens.sh +47 -0
- package/plugin/roles/examples/account-executive.md +25 -0
- package/plugin/roles/examples/ai-manager.md +34 -0
- package/plugin/roles/examples/associate.md +24 -0
- package/plugin/roles/examples/brand-lead.md +20 -0
- package/plugin/roles/examples/cfo.md +20 -0
- package/plugin/roles/examples/city-lead.md +25 -0
- package/plugin/roles/examples/clinical-director.md +26 -0
- package/plugin/roles/examples/clinical-ops.md +25 -0
- package/plugin/roles/examples/clinician.md +25 -0
- package/plugin/roles/examples/compliance.md +27 -0
- package/plugin/roles/examples/content.md +24 -0
- package/plugin/roles/examples/controller.md +27 -0
- package/plugin/roles/examples/cpto.md +41 -0
- package/plugin/roles/examples/customer-success.md +25 -0
- package/plugin/roles/examples/data-engineer.md +37 -0
- package/plugin/roles/examples/data.md +60 -0
- package/plugin/roles/examples/dev.md +37 -0
- package/plugin/roles/examples/devops.md +39 -0
- package/plugin/roles/examples/enablement.md +24 -0
- package/plugin/roles/examples/ethics.md +24 -0
- package/plugin/roles/examples/fin-analytics.md +27 -0
- package/plugin/roles/examples/health-compliance.md +25 -0
- package/plugin/roles/examples/health-data.md +26 -0
- package/plugin/roles/examples/knowledge.md +25 -0
- package/plugin/roles/examples/lifecycle.md +26 -0
- package/plugin/roles/examples/llm-engineer.md +34 -0
- package/plugin/roles/examples/managing-partner.md +20 -0
- package/plugin/roles/examples/methods.md +23 -0
- package/plugin/roles/examples/operations-lead.md +23 -0
- package/plugin/roles/examples/ops.md +24 -0
- package/plugin/roles/examples/patient-safety.md +26 -0
- package/plugin/roles/examples/performance.md +27 -0
- package/plugin/roles/examples/po.md +36 -0
- package/plugin/roles/examples/process-owner.md +23 -0
- package/plugin/roles/examples/product-design.md +39 -0
- package/plugin/roles/examples/program-manager.md +24 -0
- package/plugin/roles/examples/quality.md +25 -0
- package/plugin/roles/examples/research-director.md +24 -0
- package/plugin/roles/examples/research-ops.md +25 -0
- package/plugin/roles/examples/researcher.md +25 -0
- package/plugin/roles/examples/revenue-lead.md +25 -0
- package/plugin/roles/examples/revops.md +26 -0
- package/plugin/roles/examples/seo.md +27 -0
- package/plugin/roles/examples/specialist.md +24 -0
- package/plugin/scripts/admision.py +165 -0
- package/plugin/scripts/apaga.py +232 -0
- package/plugin/scripts/avatar.py +211 -0
- package/plugin/scripts/broker.py +531 -0
- package/plugin/scripts/cage.py +252 -0
- package/plugin/scripts/capabilities.py +197 -0
- package/plugin/scripts/card.py +312 -0
- package/plugin/scripts/cities.py +520 -0
- package/plugin/scripts/city-env.sh +90 -0
- package/plugin/scripts/city-runtime.sh +87 -0
- package/plugin/scripts/city-session.sh +526 -0
- package/plugin/scripts/city_env.py +67 -0
- package/plugin/scripts/crecimiento.py +140 -0
- package/plugin/scripts/deliberations.py +48 -0
- package/plugin/scripts/doctor.py +172 -0
- package/plugin/scripts/domains.py +201 -0
- package/plugin/scripts/evidencia.py +64 -0
- package/plugin/scripts/find-repos.sh +111 -0
- package/plugin/scripts/gh.py +159 -0
- package/plugin/scripts/hall_protocol.py +147 -0
- package/plugin/scripts/hook_activity.py +139 -0
- package/plugin/scripts/launch.py +94 -0
- package/plugin/scripts/logs.py +98 -0
- package/plugin/scripts/pairing.py +185 -0
- package/plugin/scripts/parcels.py +132 -0
- package/plugin/scripts/read-card.py +51 -0
- package/plugin/scripts/report.py +201 -0
- package/plugin/scripts/reset.py +180 -0
- package/plugin/scripts/roads.py +230 -0
- package/plugin/scripts/roles.py +274 -0
- package/plugin/scripts/runtime_log.py +69 -0
- package/plugin/scripts/runtime_processes.py +132 -0
- package/plugin/scripts/rutas.py +83 -0
- package/plugin/scripts/seat.py +1349 -0
- package/plugin/scripts/tokens.py +194 -0
- package/plugin/scripts/trust-repos.py +59 -0
- package/plugin/scripts/ui.py +280 -0
- package/plugin/scripts/units.py +80 -0
- package/plugin/scripts/workspace.py +364 -0
- package/plugin/skills/city/SKILL.md +191 -0
- package/templates/blank.md +39 -0
- package/templates/finance.md +44 -0
- package/templates/legal.md +45 -0
- package/templates/marketing.md +48 -0
- package/templates/product.md +45 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Square — the *now* of the city.
|
|
3
|
+
*
|
|
4
|
+
* One Durable Object for the whole city: it holds the spectator WebSockets with
|
|
5
|
+
* hibernation, keeps the live state (who has a light on, who is digging where,
|
|
6
|
+
* the latest notices) and fans out every change.
|
|
7
|
+
*
|
|
8
|
+
* Spectators CANNOT send anything. That is a decision, not an omission: the web
|
|
9
|
+
* is a mirror, not a control panel. If a round could be launched on somebody
|
|
10
|
+
* else's machine from here, the whole thing dies of mistrust.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export interface Light {
|
|
14
|
+
agent: string;
|
|
15
|
+
user: string;
|
|
16
|
+
since: string;
|
|
17
|
+
digging?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A worker is ONE window of ONE person digging in ONE parcel.
|
|
22
|
+
* A person has several: the seat window, one per repo, and one per worktree —
|
|
23
|
+
* same repo, different branches, different workers. They are identified by
|
|
24
|
+
* (user, window), and the user is set by the token, not claimed by the client.
|
|
25
|
+
*/
|
|
26
|
+
export interface Worker {
|
|
27
|
+
id: string; // user/window
|
|
28
|
+
user: string;
|
|
29
|
+
window: string;
|
|
30
|
+
parcel: string;
|
|
31
|
+
since: number;
|
|
32
|
+
last: number; // last heartbeat; without heartbeats they go home
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface Notice {
|
|
36
|
+
ts: string;
|
|
37
|
+
from: string;
|
|
38
|
+
to: string;
|
|
39
|
+
tag: string;
|
|
40
|
+
text: string;
|
|
41
|
+
read: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class Square {
|
|
45
|
+
state: DurableObjectState;
|
|
46
|
+
lights = new Map<string, Light>();
|
|
47
|
+
workers = new Map<string, Worker>();
|
|
48
|
+
notices: Notice[] = [];
|
|
49
|
+
|
|
50
|
+
constructor(state: DurableObjectState) {
|
|
51
|
+
this.state = state;
|
|
52
|
+
this.state.blockConcurrencyWhile(async () => {
|
|
53
|
+
this.notices = (await this.state.storage.get<Notice[]>('notices')) ?? [];
|
|
54
|
+
this.lights = new Map((await this.state.storage.get<[string, Light][]>('lights')) ?? []);
|
|
55
|
+
this.workers = new Map((await this.state.storage.get<[string, Worker][]>('workers')) ?? []);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Per-sender throttle. A leaked valid token — or a window in a loop — can push
|
|
61
|
+
* thousands of events a minute and swamp the fan-out to every spectator. 120 a
|
|
62
|
+
* minute is ten times what somebody actually working needs.
|
|
63
|
+
*/
|
|
64
|
+
brakes = new Map<string, { n: number; until: number }>();
|
|
65
|
+
allowed(who: string): boolean {
|
|
66
|
+
const now = Date.now();
|
|
67
|
+
const b = this.brakes.get(who);
|
|
68
|
+
if (!b || b.until < now) {
|
|
69
|
+
this.brakes.set(who, { n: 1, until: now + 60_000 });
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
if (b.n >= 120) return false;
|
|
73
|
+
b.n++;
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async fetch(req: Request): Promise<Response> {
|
|
78
|
+
const url = new URL(req.url);
|
|
79
|
+
|
|
80
|
+
// Spectator: subscribes and only receives.
|
|
81
|
+
if (url.pathname === '/ws') {
|
|
82
|
+
if (req.headers.get('Upgrade') !== 'websocket')
|
|
83
|
+
return new Response('expected websocket', { status: 426 });
|
|
84
|
+
const pair = new WebSocketPair();
|
|
85
|
+
// Hibernation: the DO can be evicted from memory without closing sockets.
|
|
86
|
+
this.state.acceptWebSocket(pair[1]);
|
|
87
|
+
pair[1].send(
|
|
88
|
+
JSON.stringify({
|
|
89
|
+
t: 'state',
|
|
90
|
+
lights: [...this.lights.values()],
|
|
91
|
+
workers: this.alive(),
|
|
92
|
+
notices: this.notices.slice(0, 40),
|
|
93
|
+
}),
|
|
94
|
+
);
|
|
95
|
+
return new Response(null, { status: 101, webSocket: pair[0] });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Event intake: only from inside (the Worker already checked the secret).
|
|
99
|
+
if (url.pathname === '/ingest' && req.method === 'POST') {
|
|
100
|
+
const ev = await req.json<any>();
|
|
101
|
+
const who = String(ev.user ?? ev.from ?? ev.agent ?? 'anonymous');
|
|
102
|
+
if (!this.allowed(who)) return new Response('too many events', { status: 429 });
|
|
103
|
+
await this.apply(ev);
|
|
104
|
+
return Response.json({ ok: true });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (url.pathname === '/state') {
|
|
108
|
+
return Response.json({
|
|
109
|
+
lights: [...this.lights.values()],
|
|
110
|
+
workers: this.alive(),
|
|
111
|
+
notices: this.notices.slice(0, 40),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return new Response('no', { status: 404 });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** A worker with no heartbeat for three minutes has left: nobody digs alone. */
|
|
119
|
+
alive(): Worker[] {
|
|
120
|
+
const cut = Date.now() - 3 * 60_000;
|
|
121
|
+
let changed = false;
|
|
122
|
+
for (const [k, w] of this.workers)
|
|
123
|
+
if (w.last < cut) {
|
|
124
|
+
this.workers.delete(k);
|
|
125
|
+
changed = true;
|
|
126
|
+
}
|
|
127
|
+
if (changed) this.state.storage.put('workers', [...this.workers.entries()]);
|
|
128
|
+
return [...this.workers.values()];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async apply(ev: any) {
|
|
132
|
+
if (ev.t === 'worker') {
|
|
133
|
+
const id = `${ev.user}/${ev.window}`;
|
|
134
|
+
const before = this.workers.get(id);
|
|
135
|
+
if (ev.stopped) {
|
|
136
|
+
this.workers.delete(id);
|
|
137
|
+
} else {
|
|
138
|
+
this.workers.set(id, {
|
|
139
|
+
id,
|
|
140
|
+
user: ev.user,
|
|
141
|
+
window: ev.window,
|
|
142
|
+
parcel: ev.parcel,
|
|
143
|
+
since: before && before.parcel === ev.parcel ? before.since : Date.now(),
|
|
144
|
+
last: Date.now(),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
await this.state.storage.put('workers', [...this.workers.entries()]);
|
|
148
|
+
// Only fan out on a move: a heartbeat every 30 s is not news.
|
|
149
|
+
if (!before || before.parcel !== ev.parcel || ev.stopped) this.fanOut({ ...ev, t: 'worker' });
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (ev.t === 'attempt') return; // only needed to pass through the throttle
|
|
153
|
+
if (ev.t === 'light') {
|
|
154
|
+
if (ev.on) {
|
|
155
|
+
this.lights.set(ev.agent, {
|
|
156
|
+
agent: ev.agent,
|
|
157
|
+
user: String(ev.agent).split('/')[0],
|
|
158
|
+
since: new Date().toISOString(),
|
|
159
|
+
digging: ev.digging,
|
|
160
|
+
});
|
|
161
|
+
} else {
|
|
162
|
+
this.lights.delete(ev.agent);
|
|
163
|
+
}
|
|
164
|
+
await this.state.storage.put('lights', [...this.lights.entries()]);
|
|
165
|
+
} else if (ev.t === 'notice') {
|
|
166
|
+
this.notices.unshift({
|
|
167
|
+
ts: new Date().toISOString(),
|
|
168
|
+
from: ev.from,
|
|
169
|
+
to: ev.to,
|
|
170
|
+
tag: ev.tag ?? 'notice',
|
|
171
|
+
text: ev.text ?? '',
|
|
172
|
+
read: false,
|
|
173
|
+
});
|
|
174
|
+
this.notices = this.notices.slice(0, 200);
|
|
175
|
+
await this.state.storage.put('notices', this.notices);
|
|
176
|
+
} else if (ev.t === 'read') {
|
|
177
|
+
const n = this.notices.find((x) => x.ts === ev.ts);
|
|
178
|
+
if (n) {
|
|
179
|
+
n.read = true;
|
|
180
|
+
await this.state.storage.put('notices', this.notices);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
this.fanOut(ev);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
fanOut(ev: any) {
|
|
187
|
+
const msg = JSON.stringify({ t: 'change', ev });
|
|
188
|
+
for (const ws of this.state.getWebSockets()) {
|
|
189
|
+
try {
|
|
190
|
+
ws.send(msg);
|
|
191
|
+
} catch {
|
|
192
|
+
/* a spectator who left is not a problem */
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// With hibernation these two handlers are required so the runtime knows what
|
|
198
|
+
// to do on wake-up.
|
|
199
|
+
/** Sockets already told they are spectators. Lost on hibernation, which only
|
|
200
|
+
* means somebody gets told twice. */
|
|
201
|
+
avisados = new WeakSet<WebSocket>();
|
|
202
|
+
|
|
203
|
+
async webSocketMessage(ws: WebSocket) {
|
|
204
|
+
// Spectators do not send. Say so once, then ignore them: answering every
|
|
205
|
+
// message would let a client in a loop make this object work for nothing.
|
|
206
|
+
if (this.avisados.has(ws)) return;
|
|
207
|
+
this.avisados.add(ws);
|
|
208
|
+
ws.send(
|
|
209
|
+
JSON.stringify({
|
|
210
|
+
t: 'info',
|
|
211
|
+
text: 'spectator mode: this connection does not accept messages',
|
|
212
|
+
}),
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
async webSocketClose() {
|
|
216
|
+
/* nothing to clean: getWebSockets() drops it */
|
|
217
|
+
}
|
|
218
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name = "city"
|
|
2
|
+
main = "src/index.ts"
|
|
3
|
+
compatibility_date = "2026-08-01"
|
|
4
|
+
# The same Cloudflare account as the bus.
|
|
5
|
+
account_id = "<YOUR_CLOUDFLARE_ACCOUNT_ID>"
|
|
6
|
+
|
|
7
|
+
# The front end is served by the Worker itself: one origin, no CORS, no separate
|
|
8
|
+
# CDN. run_worker_first is about security and not performance: without it the
|
|
9
|
+
# static files are served BEFORE the Worker runs, so the Access door covered
|
|
10
|
+
# neither the HTML nor the JS nor the sprites.
|
|
11
|
+
[assets]
|
|
12
|
+
directory = "../web/dist"
|
|
13
|
+
binding = "ASSETS"
|
|
14
|
+
run_worker_first = true
|
|
15
|
+
|
|
16
|
+
# In production: turn these off and route a custom domain instead. A workers.dev
|
|
17
|
+
# URL cannot sit behind an identity proxy, so leaving it on is a permanent back
|
|
18
|
+
# door. Left on here so `wrangler dev` and a first deploy just work.
|
|
19
|
+
# workers_dev = false
|
|
20
|
+
# preview_urls = false
|
|
21
|
+
#
|
|
22
|
+
# [[routes]]
|
|
23
|
+
# pattern = "city.example.com"
|
|
24
|
+
# custom_domain = true
|
|
25
|
+
|
|
26
|
+
# The square: live state, and fan-out to the spectators.
|
|
27
|
+
[[durable_objects.bindings]]
|
|
28
|
+
name = "SQUARE"
|
|
29
|
+
class_name = "Square"
|
|
30
|
+
|
|
31
|
+
[[migrations]]
|
|
32
|
+
tag = "v1"
|
|
33
|
+
new_sqlite_classes = ["Square"]
|
|
34
|
+
|
|
35
|
+
# The history: what has been built, which does not fit in memory and is queried.
|
|
36
|
+
[[d1_databases]]
|
|
37
|
+
binding = "DB"
|
|
38
|
+
database_name = "city"
|
|
39
|
+
database_id = "<YOUR_D1_DATABASE_ID>"
|
|
40
|
+
|
|
41
|
+
# The bus's own token KV: a worker identifies itself with its own token.
|
|
42
|
+
[[kv_namespaces]]
|
|
43
|
+
binding = "TOKENS"
|
|
44
|
+
id = "<YOUR_KV_NAMESPACE_ID>"
|
|
45
|
+
|
|
46
|
+
[triggers]
|
|
47
|
+
crons = ["*/5 * * * *"] # batches of 6 repos: the whole org about every 2h
|
|
48
|
+
|
|
49
|
+
[vars]
|
|
50
|
+
GITHUB_ORG = "your-org"
|
|
51
|
+
# Closed in production, open when you clone it. With "1", nothing is served
|
|
52
|
+
# without the header your identity proxy sets — the static HTML included. Leave
|
|
53
|
+
# it at "0" for local development and set it to "1" before you deploy: see
|
|
54
|
+
# docs/install.md, "Closing the door".
|
|
55
|
+
REQUIRE_ACCESS = "0"
|
|
56
|
+
|
|
57
|
+
[observability]
|
|
58
|
+
enabled = true
|
package/demo/ada.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
user: ada
|
|
3
|
+
name: Ada Fontán
|
|
4
|
+
role: cpto
|
|
5
|
+
agent: ada/lead
|
|
6
|
+
repos: []
|
|
7
|
+
covers: [all]
|
|
8
|
+
goals_defined: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Ada Fontán
|
|
12
|
+
|
|
13
|
+
Role: **cpto** — in the city, the **architect**. The domain is in `roles/cpto.md`.
|
|
14
|
+
|
|
15
|
+
## Repos
|
|
16
|
+
|
|
17
|
+
No repos of their own: cross-cutting roles do not own any, they answer for one property of all of them.
|
|
18
|
+
|
|
19
|
+
## Current goals
|
|
20
|
+
|
|
21
|
+
### O1 — Every parcel has an owner who answers for it
|
|
22
|
+
- **What**: Every parcel has an owner who answers for it.
|
|
23
|
+
- **How it is measured**: 34 parcels, 9 with no owner on the card
|
|
24
|
+
- **Measure**: `grep -c 'dueno' parcels.yml`
|
|
25
|
+
- **Baseline**: 9 without an owner (2026-06-01)
|
|
26
|
+
- **Target**: 0
|
|
27
|
+
- **By when**: Q4 2026
|
|
28
|
+
- **State**: in progress
|
|
29
|
+
|
|
30
|
+
<!-- Format, one block per goal:
|
|
31
|
+
|
|
32
|
+
### O1 — <short title>
|
|
33
|
+
- **What**: what has to be achieved, in one sentence.
|
|
34
|
+
- **How it is measured**: the concrete signal that says whether it is going well.
|
|
35
|
+
- **Measure**: the command or query returning that signal, runnable as written.
|
|
36
|
+
If the signal is a judgement and not a number: `manual — <who looks at what, and
|
|
37
|
+
how often>`.
|
|
38
|
+
- **Baseline**: what the measure returned the day it was agreed, with the date.
|
|
39
|
+
- **Target**: the value to reach.
|
|
40
|
+
- **By when**: a date or a quarter.
|
|
41
|
+
- **State**: not started | in progress | at risk | done
|
|
42
|
+
|
|
43
|
+
The measure gets run before the goal is agreed: if it does not work, what is
|
|
44
|
+
missing is building it, and that is work. See /city:goals.
|
|
45
|
+
|
|
46
|
+
-->
|
|
47
|
+
|
|
48
|
+
## Round history
|
|
49
|
+
|
|
50
|
+
Rounds leave their summary here, most recent first.
|
package/demo/bruno.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
user: bruno
|
|
3
|
+
name: Bruno Castel
|
|
4
|
+
role: devops
|
|
5
|
+
agent: bruno/ops
|
|
6
|
+
repos: [consent-kit, infrastructure, ci-templates]
|
|
7
|
+
covers: [all]
|
|
8
|
+
also: [data]
|
|
9
|
+
goals_defined: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Bruno Castel
|
|
13
|
+
|
|
14
|
+
Role: **devops** — in the city, the **surveyor**. The domain is in `roles/devops.md`.
|
|
15
|
+
|
|
16
|
+
## Repos
|
|
17
|
+
|
|
18
|
+
Answers for: `consent-kit`, `infrastructure`, `ci-templates`.
|
|
19
|
+
|
|
20
|
+
## Current goals
|
|
21
|
+
|
|
22
|
+
### O1 — Launcher start-up drops from 4.2 s to 2 s
|
|
23
|
+
- **What**: Launcher start-up drops from 4.2 s to 2 s.
|
|
24
|
+
- **How it is measured**: time to the game-select screen on the reference machine.
|
|
25
|
+
- **Measure**: `npm run bench:launcher --silent | tail -1`
|
|
26
|
+
- **Baseline**: 4.2 s (2026-01-08)
|
|
27
|
+
- **Target**: 2.0 s
|
|
28
|
+
- **By when**: Q1 2026
|
|
29
|
+
- **State**: in progress
|
|
30
|
+
|
|
31
|
+
### O2 — No open work sits for more than 14 days
|
|
32
|
+
- **What**: No open work sits for more than 14 days.
|
|
33
|
+
- **How it is measured**: PRs open for over two weeks across the whole org.
|
|
34
|
+
- **Measure**: `gh search prs --owner your-org --state open --created '<2026-01-01' --json number --jq 'length'`
|
|
35
|
+
- **Baseline**: 38 (2026-01-08)
|
|
36
|
+
- **Target**: 0
|
|
37
|
+
- **By when**: Q2 2026
|
|
38
|
+
- **State**: at risk
|
|
39
|
+
|
|
40
|
+
_Last edited: 2026-02-14 by ada._
|
|
41
|
+
|
|
42
|
+
<!-- Format, one block per goal:
|
|
43
|
+
|
|
44
|
+
### O1 — <short title>
|
|
45
|
+
- **What**: what has to be achieved, in one sentence.
|
|
46
|
+
- **How it is measured**: the concrete signal that says whether it is going well.
|
|
47
|
+
- **Measure**: the command or query returning that signal, runnable as written.
|
|
48
|
+
If the signal is a judgement and not a number: `manual — <who looks at what, and
|
|
49
|
+
how often>`.
|
|
50
|
+
- **Baseline**: what the measure returned the day it was agreed, with the date.
|
|
51
|
+
- **Target**: the value to reach.
|
|
52
|
+
- **By when**: a date or a quarter.
|
|
53
|
+
- **State**: not started | in progress | at risk | done
|
|
54
|
+
|
|
55
|
+
The measure gets run before the goal is agreed: if it does not work, what is
|
|
56
|
+
missing is building it, and that is work. See /city:goals.
|
|
57
|
+
|
|
58
|
+
-->
|
|
59
|
+
|
|
60
|
+
## Round history
|
|
61
|
+
|
|
62
|
+
Rounds leave their summary here, most recent first.
|
package/demo/camila.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
user: camila
|
|
3
|
+
name: Camila Ruiz
|
|
4
|
+
role: product-design
|
|
5
|
+
agent: camila/design
|
|
6
|
+
repos: []
|
|
7
|
+
covers: [mobile, arcade]
|
|
8
|
+
goals_defined: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Camila Ruiz
|
|
12
|
+
|
|
13
|
+
Role: **product-design** — in the city, the **interior designer**. The domain is in `roles/product-design.md`.
|
|
14
|
+
|
|
15
|
+
## Repos
|
|
16
|
+
|
|
17
|
+
No repos of their own: cross-cutting roles do not own any, they answer for one property of all of them.
|
|
18
|
+
|
|
19
|
+
## What they cover
|
|
20
|
+
|
|
21
|
+
Units: **Mobile Games**, **Arcade Cabinets**. The map of which repo and which path belongs to each unit is in `parcels.yml`.
|
|
22
|
+
|
|
23
|
+
## Current goals
|
|
24
|
+
|
|
25
|
+
### O1 — No interface component outside the design system
|
|
26
|
+
- **What**: No interface component outside the design system.
|
|
27
|
+
- **How it is measured**: components in nova/packages/ui with no system token.
|
|
28
|
+
- **Measure**: `manual — Camila reviews packages/ui every two weeks`
|
|
29
|
+
- **Baseline**: 9 outside (2026-01-10)
|
|
30
|
+
- **Target**: 0
|
|
31
|
+
- **By when**: Q2 2026
|
|
32
|
+
- **State**: in progress
|
|
33
|
+
|
|
34
|
+
_Last edited: 2026-02-14 by ada._
|
|
35
|
+
|
|
36
|
+
<!-- Format, one block per goal:
|
|
37
|
+
|
|
38
|
+
### O1 — <short title>
|
|
39
|
+
- **What**: what has to be achieved, in one sentence.
|
|
40
|
+
- **How it is measured**: the concrete signal that says whether it is going well.
|
|
41
|
+
- **Measure**: the command or query returning that signal, runnable as written.
|
|
42
|
+
If the signal is a judgement and not a number: `manual — <who looks at what, and
|
|
43
|
+
how often>`.
|
|
44
|
+
- **Baseline**: what the measure returned the day it was agreed, with the date.
|
|
45
|
+
- **Target**: the value to reach.
|
|
46
|
+
- **By when**: a date or a quarter.
|
|
47
|
+
- **State**: not started | in progress | at risk | done
|
|
48
|
+
|
|
49
|
+
The measure gets run before the goal is agreed: if it does not work, what is
|
|
50
|
+
missing is building it, and that is work. See /city:goals.
|
|
51
|
+
|
|
52
|
+
-->
|
|
53
|
+
|
|
54
|
+
## Round history
|
|
55
|
+
|
|
56
|
+
Rounds leave their summary here, most recent first.
|
package/demo/city/ada.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
user: ada
|
|
3
|
+
name: Ada Fontán
|
|
4
|
+
role: cpto
|
|
5
|
+
agent: ada/seat
|
|
6
|
+
repos: [nova, store-service, telemetry-collector, engine-core, launcher]
|
|
7
|
+
role.nova: po
|
|
8
|
+
role.store-service: security
|
|
9
|
+
role.telemetry-collector: data-engineer
|
|
10
|
+
role.engine-core: dev
|
|
11
|
+
role.launcher: product-design
|
|
12
|
+
runs.seat: claude
|
|
13
|
+
runs.nova: claude
|
|
14
|
+
runs.store-service: codex
|
|
15
|
+
runs.telemetry-collector: opencode
|
|
16
|
+
runs.engine-core: kimi
|
|
17
|
+
runs.launcher: codex
|
|
18
|
+
goals_defined: true
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Ada Fontán — Aurora Games chair
|
|
22
|
+
|
|
23
|
+
Ada is the chair. The five repositories are private support agents with their
|
|
24
|
+
own operating roles and mixed runtimes; the demo does not start paid models.
|
|
25
|
+
|
|
26
|
+
## Current goal
|
|
27
|
+
|
|
28
|
+
### O1 — Release cross-save without losing player progress
|
|
29
|
+
- **What**: Ship cross-save through a reversible rollout shared by every game.
|
|
30
|
+
- **How it is measured**: verified restores, conflict rate and rollback time.
|
|
31
|
+
- **Measure**: `demo — scripted evidence over the local WebSocket committee`
|
|
32
|
+
- **Baseline**: one game, no shared rollback contract
|
|
33
|
+
- **Target**: canary verified before portfolio rollout
|
|
34
|
+
- **By when**: demo day
|
|
35
|
+
- **State**: in progress
|
|
36
|
+
|
|
37
|
+
## Round history
|
|
38
|
+
|
|
39
|
+
The guided committee writes its complete act here at runtime. The packaged
|
|
40
|
+
fixture is copied to a temporary directory first, so this file stays untouched.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Five repo agents, five visible houses. The scripted committee deliberately
|
|
2
|
+
# invites only three, so abstention and bounded participation remain believable.
|
|
3
|
+
repos:
|
|
4
|
+
nova:
|
|
5
|
+
- ruta: "" ; unidad: games ; nombre: "Nova games"
|
|
6
|
+
store-service:
|
|
7
|
+
- ruta: "" ; unidad: platform ; nombre: "Player store"
|
|
8
|
+
telemetry-collector:
|
|
9
|
+
- ruta: "" ; unidad: data ; nombre: "Telemetry"
|
|
10
|
+
engine-core:
|
|
11
|
+
- ruta: "" ; unidad: platform ; nombre: "Engine core"
|
|
12
|
+
launcher:
|
|
13
|
+
- ruta: "" ; unidad: games ; nombre: "Game launcher"
|
|
14
|
+
|
|
15
|
+
lab: []
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# A compact city: enough variety to understand districts without turning the
|
|
2
|
+
# first screen into a wall of houses.
|
|
3
|
+
units:
|
|
4
|
+
- id: games ; name: Player Games ; color: 3fb8a0 ; order: 1
|
|
5
|
+
- id: platform ; name: Shared Platform ; color: 8f7ae6 ; order: 2
|
|
6
|
+
- id: data ; name: Player Data ; color: e2604f ; order: 3
|
|
7
|
+
|
|
8
|
+
special:
|
|
9
|
+
- id: lab ; name: Lab ; color: 8fb8c9 ; order: 90
|
|
10
|
+
- id: none ; name: Shared ; color: c8b48a ; order: 99
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Five agents, five houses. The scripted committee invites only three, so
|
|
2
|
+
# abstention and bounded participation remain believable — same as Aurora.
|
|
3
|
+
repos:
|
|
4
|
+
urgencias:
|
|
5
|
+
- ruta: "" ; unidad: atencion ; nombre: "Urgencias"
|
|
6
|
+
laboratorio:
|
|
7
|
+
- ruta: "" ; unidad: diagnostico ; nombre: "Laboratorio"
|
|
8
|
+
farmacia:
|
|
9
|
+
- ruta: "" ; unidad: atencion ; nombre: "Farmacia"
|
|
10
|
+
archivo-historias:
|
|
11
|
+
- ruta: "" ; unidad: gestion ; nombre: "Archivo de historias"
|
|
12
|
+
admision:
|
|
13
|
+
- ruta: "" ; unidad: gestion ; nombre: "Admisión"
|
|
14
|
+
|
|
15
|
+
lab: []
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# A small clinic: three districts anyone can read at a glance.
|
|
2
|
+
units:
|
|
3
|
+
- id: atencion ; name: Atención al Paciente ; color: 3fb8a0 ; order: 1
|
|
4
|
+
- id: diagnostico ; name: Diagnóstico ; color: 4a9ede ; order: 2
|
|
5
|
+
- id: gestion ; name: Gestión ; color: 8f7ae6 ; order: 3
|
|
6
|
+
|
|
7
|
+
special:
|
|
8
|
+
- id: lab ; name: Lab ; color: 8fb8c9 ; order: 90
|
|
9
|
+
- id: none ; name: Shared ; color: c8b48a ; order: 99
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
user: vera
|
|
3
|
+
name: Vera Salas
|
|
4
|
+
role: cpto
|
|
5
|
+
agent: vera/seat
|
|
6
|
+
agents: [urgencias, laboratorio, farmacia, archivo-historias, admision]
|
|
7
|
+
kind.urgencias: coordinator
|
|
8
|
+
kind.laboratorio: knowledge
|
|
9
|
+
kind.farmacia: knowledge
|
|
10
|
+
kind.archivo-historias: knowledge
|
|
11
|
+
kind.admision: coordinator
|
|
12
|
+
role.urgencias: triaje
|
|
13
|
+
role.laboratorio: analisis
|
|
14
|
+
role.farmacia: recetas
|
|
15
|
+
role.archivo-historias: historias
|
|
16
|
+
role.admision: citas
|
|
17
|
+
runs.seat: claude
|
|
18
|
+
runs.urgencias: claude
|
|
19
|
+
runs.laboratorio: claude
|
|
20
|
+
runs.farmacia: claude
|
|
21
|
+
runs.archivo-historias: claude
|
|
22
|
+
runs.admision: claude
|
|
23
|
+
goals_defined: true
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Vera Salas — Clínica Alba, dirección
|
|
27
|
+
|
|
28
|
+
Vera chairs the clinic. No agent here is a repository: they are knowledge and
|
|
29
|
+
coordination agents — the agents-first model, where a repo is just one thing an
|
|
30
|
+
agent may mount and none of these mounts one.
|
|
31
|
+
|
|
32
|
+
## Current goal
|
|
33
|
+
|
|
34
|
+
### O1 — Nadie sale de la sala de espera sin un camino
|
|
35
|
+
- **What**: Que cada persona que entra salga atendida o con cita real en mano.
|
|
36
|
+
- **How it is measured**: sala bajo aforo y reprogramaciones con día y hora.
|
|
37
|
+
- **Measure**: `demo — scripted evidence over the local WebSocket committee`
|
|
38
|
+
- **Baseline**: mañanas de caos cuando el sistema de citas falla
|
|
39
|
+
- **Target**: caos absorbido sin cerrar la puerta
|
|
40
|
+
- **By when**: demo day
|
|
41
|
+
- **State**: in progress
|
|
42
|
+
|
|
43
|
+
## Round history
|
|
44
|
+
|
|
45
|
+
The guided committee writes its complete act here at runtime. The packaged
|
|
46
|
+
fixture is copied to a temporary directory first, so this file stays untouched.
|
package/demo/dante.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
user: dante
|
|
3
|
+
name: Dante Oliveira
|
|
4
|
+
role: product-design
|
|
5
|
+
agent: dante/design
|
|
6
|
+
repos: []
|
|
7
|
+
covers: [console, school]
|
|
8
|
+
goals_defined: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Dante Oliveira
|
|
12
|
+
|
|
13
|
+
Role: **product-design** — in the city, the **interior designer**. The domain is in `roles/product-design.md`.
|
|
14
|
+
|
|
15
|
+
## Repos
|
|
16
|
+
|
|
17
|
+
No repos of their own: cross-cutting roles do not own any, they answer for one property of all of them.
|
|
18
|
+
|
|
19
|
+
## What they cover
|
|
20
|
+
|
|
21
|
+
Units: **Console Games**, **School Editions**. The map of which repo and which path belongs to each unit is in `parcels.yml`.
|
|
22
|
+
|
|
23
|
+
## Current goals
|
|
24
|
+
|
|
25
|
+
### O1 — The design system is what ships, not a reference
|
|
26
|
+
- **What**: The design system is what ships, not a reference.
|
|
27
|
+
- **How it is measured**: Screens built from components rather than one-off styles
|
|
28
|
+
- **Measure**: `rg -l 'StyleSheet.create' apps | wc -l`
|
|
29
|
+
- **Baseline**: 38 files (2026-06-20)
|
|
30
|
+
- **Target**: under 10
|
|
31
|
+
- **By when**: Q1 2027
|
|
32
|
+
- **State**: at risk
|
|
33
|
+
|
|
34
|
+
<!-- Format, one block per goal:
|
|
35
|
+
|
|
36
|
+
### O1 — <short title>
|
|
37
|
+
- **What**: what has to be achieved, in one sentence.
|
|
38
|
+
- **How it is measured**: the concrete signal that says whether it is going well.
|
|
39
|
+
- **Measure**: the command or query returning that signal, runnable as written.
|
|
40
|
+
If the signal is a judgement and not a number: `manual — <who looks at what, and
|
|
41
|
+
how often>`.
|
|
42
|
+
- **Baseline**: what the measure returned the day it was agreed, with the date.
|
|
43
|
+
- **Target**: the value to reach.
|
|
44
|
+
- **By when**: a date or a quarter.
|
|
45
|
+
- **State**: not started | in progress | at risk | done
|
|
46
|
+
|
|
47
|
+
The measure gets run before the goal is agreed: if it does not work, what is
|
|
48
|
+
missing is building it, and that is work. See /city:goals.
|
|
49
|
+
|
|
50
|
+
-->
|
|
51
|
+
|
|
52
|
+
## Round history
|
|
53
|
+
|
|
54
|
+
Rounds leave their summary here, most recent first.
|