@stravica-ai/digital-operator-pa 0.1.0
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/LICENSE +21 -0
- package/README.md +170 -0
- package/bin/desk +9 -0
- package/bin/distill +2 -0
- package/bin/estate-sync +2 -0
- package/bin/launch +2 -0
- package/bin/memory-sync +2 -0
- package/bin/migrate-inspect +2 -0
- package/bin/pa +2 -0
- package/bin/pa-coordinator-hook +2 -0
- package/bin/pa-init +2 -0
- package/bin/research +2 -0
- package/bin/scheduler +2 -0
- package/bin/secrets +2 -0
- package/bin/slice +2 -0
- package/bin/smoke +9 -0
- package/bin/sync +2 -0
- package/dist/engineering-pa-cli/README.md +205 -0
- package/dist/engineering-pa-cli/bin/estate-sync +2 -0
- package/dist/engineering-pa-cli/bin/launch +2 -0
- package/dist/engineering-pa-cli/bin/pa +2 -0
- package/dist/engineering-pa-cli/bin/pa-coordinator-hook +12 -0
- package/dist/engineering-pa-cli/bin/research +2 -0
- package/dist/engineering-pa-cli/bin/scheduler +2 -0
- package/dist/engineering-pa-cli/bin/secrets +2 -0
- package/dist/engineering-pa-cli/bin/smoke +9 -0
- package/dist/engineering-pa-cli/bin/sync +2 -0
- package/dist/engineering-pa-cli/config/coordinator-allowlist.json +118 -0
- package/dist/engineering-pa-cli/docs/coordinator-hook.md +211 -0
- package/dist/engineering-pa-cli/docs/estate-sync.md +412 -0
- package/dist/engineering-pa-cli/docs/gsc.md +175 -0
- package/dist/engineering-pa-cli/docs/lint-linkedin.md +139 -0
- package/dist/engineering-pa-cli/docs/secrets.md +221 -0
- package/dist/engineering-pa-cli/docs/smoke.md +113 -0
- package/dist/engineering-pa-cli/docs/staging-alias.md +114 -0
- package/dist/engineering-pa-cli/index.mjs +17 -0
- package/dist/engineering-pa-cli/package.json +37 -0
- package/dist/engineering-pa-cli/src/autonomy/cli.mjs +329 -0
- package/dist/engineering-pa-cli/src/autonomy/envelope.mjs +301 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/cli.mjs +140 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/config.mjs +134 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/message.mjs +47 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/policy.mjs +211 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/repo-root.mjs +44 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/self.mjs +30 -0
- package/dist/engineering-pa-cli/src/environment/cli.mjs +287 -0
- package/dist/engineering-pa-cli/src/environment/probes.mjs +302 -0
- package/dist/engineering-pa-cli/src/gsc/auth.mjs +148 -0
- package/dist/engineering-pa-cli/src/gsc/cli.mjs +93 -0
- package/dist/engineering-pa-cli/src/gsc/cloudflare.mjs +318 -0
- package/dist/engineering-pa-cli/src/gsc/commands/add-property.mjs +70 -0
- package/dist/engineering-pa-cli/src/gsc/commands/list-properties.mjs +33 -0
- package/dist/engineering-pa-cli/src/gsc/commands/pull-analytics.mjs +130 -0
- package/dist/engineering-pa-cli/src/gsc/commands/submit-sitemap.mjs +41 -0
- package/dist/engineering-pa-cli/src/gsc/commands/verify-via-cf-dns.mjs +189 -0
- package/dist/engineering-pa-cli/src/knowledge/call-log.mjs +59 -0
- package/dist/engineering-pa-cli/src/knowledge/cli.mjs +242 -0
- package/dist/engineering-pa-cli/src/knowledge/eval.mjs +446 -0
- package/dist/engineering-pa-cli/src/knowledge/formatters.mjs +331 -0
- package/dist/engineering-pa-cli/src/knowledge/graph.mjs +710 -0
- package/dist/engineering-pa-cli/src/launch/README.md +214 -0
- package/dist/engineering-pa-cli/src/launch/cli.mjs +51 -0
- package/dist/engineering-pa-cli/src/launch/commands/launch.mjs +106 -0
- package/dist/engineering-pa-cli/src/launch/identity.mjs +43 -0
- package/dist/engineering-pa-cli/src/launch/planner.mjs +44 -0
- package/dist/engineering-pa-cli/src/launch/repo-root.mjs +53 -0
- package/dist/engineering-pa-cli/src/launch/runner.mjs +147 -0
- package/dist/engineering-pa-cli/src/launch/task-loader.mjs +85 -0
- package/dist/engineering-pa-cli/src/lint/cli.mjs +61 -0
- package/dist/engineering-pa-cli/src/lint/commands/linkedin.mjs +133 -0
- package/dist/engineering-pa-cli/src/lint/detectors.mjs +90 -0
- package/dist/engineering-pa-cli/src/lint/linter.mjs +69 -0
- package/dist/engineering-pa-cli/src/lint/reporter.mjs +32 -0
- package/dist/engineering-pa-cli/src/lint/rules.mjs +132 -0
- package/dist/engineering-pa-cli/src/pa/cli.mjs +369 -0
- package/dist/engineering-pa-cli/src/pa/doc-groups.mjs +164 -0
- package/dist/engineering-pa-cli/src/pa/io.mjs +80 -0
- package/dist/engineering-pa-cli/src/pa/project-cli.mjs +385 -0
- package/dist/engineering-pa-cli/src/pa/projects.mjs +352 -0
- package/dist/engineering-pa-cli/src/pa/repo-root.mjs +64 -0
- package/dist/engineering-pa-cli/src/pa/session.mjs +254 -0
- package/dist/engineering-pa-cli/src/pa/work-cli.mjs +164 -0
- package/dist/engineering-pa-cli/src/pa/work.mjs +196 -0
- package/dist/engineering-pa-cli/src/pa/workstreams.mjs +201 -0
- package/dist/engineering-pa-cli/src/research/README.md +360 -0
- package/dist/engineering-pa-cli/src/research/briefs/extractor.md +103 -0
- package/dist/engineering-pa-cli/src/research/briefs/searcher.md +113 -0
- package/dist/engineering-pa-cli/src/research/briefs/synthesizer.md +124 -0
- package/dist/engineering-pa-cli/src/research/briefs/verifier.md +86 -0
- package/dist/engineering-pa-cli/src/research/cli.mjs +141 -0
- package/dist/engineering-pa-cli/src/research/commands/gates.mjs +176 -0
- package/dist/engineering-pa-cli/src/research/commands/list.mjs +56 -0
- package/dist/engineering-pa-cli/src/research/commands/mark.mjs +97 -0
- package/dist/engineering-pa-cli/src/research/commands/paths.mjs +69 -0
- package/dist/engineering-pa-cli/src/research/commands/prune.mjs +86 -0
- package/dist/engineering-pa-cli/src/research/commands/run.mjs +94 -0
- package/dist/engineering-pa-cli/src/research/commands/show.mjs +43 -0
- package/dist/engineering-pa-cli/src/research/docs/operator-present-flow.md +120 -0
- package/dist/engineering-pa-cli/src/research/format.mjs +59 -0
- package/dist/engineering-pa-cli/src/research/promote.mjs +260 -0
- package/dist/engineering-pa-cli/src/research/schema/finding.schema.json +55 -0
- package/dist/engineering-pa-cli/src/research/schema/gates.schema.json +34 -0
- package/dist/engineering-pa-cli/src/research/schema/manifest.schema.json +59 -0
- package/dist/engineering-pa-cli/src/research/schema/plan.schema.json +41 -0
- package/dist/engineering-pa-cli/src/research/schema/sources.schema.json +31 -0
- package/dist/engineering-pa-cli/src/research/store/findings.mjs +61 -0
- package/dist/engineering-pa-cli/src/research/store/gates.mjs +73 -0
- package/dist/engineering-pa-cli/src/research/store/index.mjs +312 -0
- package/dist/engineering-pa-cli/src/research/store/manifest.mjs +56 -0
- package/dist/engineering-pa-cli/src/research/store/plan.mjs +59 -0
- package/dist/engineering-pa-cli/src/research/store/sources.mjs +44 -0
- package/dist/engineering-pa-cli/src/research/store/validate.mjs +92 -0
- package/dist/engineering-pa-cli/src/research/workflows/research-normal.js +573 -0
- package/dist/engineering-pa-cli/src/scheduler/cli.mjs +197 -0
- package/dist/engineering-pa-cli/src/secrets/cli.mjs +254 -0
- package/dist/engineering-pa-cli/src/secrets/commands/backup-template.mjs +67 -0
- package/dist/engineering-pa-cli/src/secrets/commands/backup.mjs +85 -0
- package/dist/engineering-pa-cli/src/secrets/commands/delete.mjs +58 -0
- package/dist/engineering-pa-cli/src/secrets/commands/find.mjs +36 -0
- package/dist/engineering-pa-cli/src/secrets/commands/get.mjs +49 -0
- package/dist/engineering-pa-cli/src/secrets/commands/init.mjs +69 -0
- package/dist/engineering-pa-cli/src/secrets/commands/list.mjs +37 -0
- package/dist/engineering-pa-cli/src/secrets/commands/rotate.mjs +46 -0
- package/dist/engineering-pa-cli/src/secrets/commands/set.mjs +123 -0
- package/dist/engineering-pa-cli/src/secrets/commands/status.mjs +146 -0
- package/dist/engineering-pa-cli/src/secrets/commands/vaults.mjs +57 -0
- package/dist/engineering-pa-cli/src/secrets/commands/verify.mjs +143 -0
- package/dist/engineering-pa-cli/src/secrets/vault.mjs +766 -0
- package/dist/engineering-pa-cli/src/smoke/checks.mjs +199 -0
- package/dist/engineering-pa-cli/src/smoke/cli.mjs +108 -0
- package/dist/engineering-pa-cli/src/smoke/commands/run.mjs +237 -0
- package/dist/engineering-pa-cli/src/smoke/runner.mjs +191 -0
- package/dist/engineering-pa-cli/src/staging-alias/cli.mjs +91 -0
- package/dist/engineering-pa-cli/src/staging-alias/cloudflare.mjs +380 -0
- package/dist/engineering-pa-cli/src/staging-alias/commands/list.mjs +36 -0
- package/dist/engineering-pa-cli/src/staging-alias/commands/set.mjs +188 -0
- package/dist/engineering-pa-cli/src/staging-alias/commands/status.mjs +113 -0
- package/dist/engineering-pa-cli/src/staging-alias/commands/unset.mjs +95 -0
- package/dist/engineering-pa-cli/src/staging-alias/sites.mjs +105 -0
- package/dist/engineering-pa-cli/src/sync/cli.mjs +151 -0
- package/dist/engineering-pa-cli/src/sync/git.mjs +149 -0
- package/dist/engineering-pa-cli/src/sync/lock.mjs +30 -0
- package/dist/engineering-pa-cli/src/sync/regenerated-artifacts.mjs +114 -0
- package/dist/engineering-pa-cli/src/sync/registry-scope.mjs +260 -0
- package/dist/engineering-pa-cli/src/sync/run.mjs +531 -0
- package/dist/engineering-pa-cli/src/sync/runner.mjs +62 -0
- package/dist/engineering-pa-cli/src/sync/runs-digest.mjs +138 -0
- package/dist/engineering-pa-core/README.md +60 -0
- package/dist/engineering-pa-core/bin/desk +9 -0
- package/dist/engineering-pa-core/bin/distill +2 -0
- package/dist/engineering-pa-core/bin/memory-sync +2 -0
- package/dist/engineering-pa-core/bin/slice +2 -0
- package/dist/engineering-pa-core/docs/autonomy-envelope-tracker.md +111 -0
- package/dist/engineering-pa-core/docs/blueprints/README.md +45 -0
- package/dist/engineering-pa-core/docs/blueprints/docker-services/blueprint.md +168 -0
- package/dist/engineering-pa-core/docs/blueprints/git-identity/blueprint.md +116 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/custom-workspace-views.md +9 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/knowledge-domain-patterns.md +15 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/office-integration.md +11 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/team-scaling.md +9 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/work-personal-separation.md +9 -0
- package/dist/engineering-pa-core/docs/blueprints/scheduled-distillation/blueprint.md +129 -0
- package/dist/engineering-pa-core/docs/blueprints/tool-integration/blueprint.md +110 -0
- package/dist/engineering-pa-core/docs/commands/init.md +159 -0
- package/dist/engineering-pa-core/docs/commands/schedule.md +98 -0
- package/dist/engineering-pa-core/docs/commands/upgrade.md +67 -0
- package/dist/engineering-pa-core/docs/entity-location-map.md +93 -0
- package/dist/engineering-pa-core/docs/knowledge-scaffold.md +121 -0
- package/dist/engineering-pa-core/docs/lock.md +155 -0
- package/dist/engineering-pa-core/docs/memory-sync.md +28 -0
- package/dist/engineering-pa-core/docs/pa-operating-model.md +457 -0
- package/dist/engineering-pa-core/docs/scheduling.md +35 -0
- package/dist/engineering-pa-core/docs/standards/README.md +24 -0
- package/dist/engineering-pa-core/docs/standards/briefing-contract.md +161 -0
- package/dist/engineering-pa-core/docs/standards/tooling.md +240 -0
- package/dist/engineering-pa-core/docs/tools/distill.md +230 -0
- package/dist/engineering-pa-core/docs/tools/memory-sync.md +98 -0
- package/dist/engineering-pa-core/docs/tools/scheduler.md +243 -0
- package/dist/engineering-pa-core/docs/tools/slice.md +150 -0
- package/dist/engineering-pa-core/docs/upstream-issue-filing.md +88 -0
- package/dist/engineering-pa-core/docs/working-directory.md +29 -0
- package/dist/engineering-pa-core/docs/workspace-operations.md +46 -0
- package/dist/engineering-pa-core/index.mjs +21 -0
- package/dist/engineering-pa-core/knowledge/README.md +53 -0
- package/dist/engineering-pa-core/knowledge/canonical/.gitkeep +0 -0
- package/dist/engineering-pa-core/knowledge/content-voice/README.md +64 -0
- package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-baseline.md +133 -0
- package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-shape.md +58 -0
- package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-taxonomy.md +33 -0
- package/dist/engineering-pa-core/knowledge/content-voice/content-pipeline-routing.md +58 -0
- package/dist/engineering-pa-core/knowledge/content-voice/new-tell-capture-procedure.md +40 -0
- package/dist/engineering-pa-core/knowledge/content-voice/voice-guide-shape.md +43 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/README.md +34 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/briefing-contract.md +77 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/delegation-modes.md +84 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/dispatch-envelope.md +238 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/task-groups-and-orchestrators.md +62 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/team-improvement-loop.md +48 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/tool-development-policy.md +48 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/README.md +33 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/blast-radius-and-safety.md +50 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/investigate-root-causes.md +48 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/role-ladder.md +57 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/verify-runtime-behaviour.md +53 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/worktree-isolation.md +50 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/README.md +33 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/claude-md-hygiene.md +47 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/journal-and-self-improvement.md +53 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/knowledge-retrieval-discipline.md +62 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/librarian-synthesis-mandate.md +56 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/staging-and-observations.md +58 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/README.md +32 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/communication-style.md +33 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/escalation-and-correction.md +45 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/push-back-discipline.md +42 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/session-boot-and-end.md +56 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/README.md +37 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/desk-cli-reference.md +52 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/environment-awareness.md +91 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/mcp-servers-catalogue.md +52 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/pa-cli-reference.md +55 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/scheduling-and-launchd.md +56 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/tool-discovery-discipline.md +49 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/working-directory-vs-project-root.md +43 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/workspace-server.md +51 -0
- package/dist/engineering-pa-core/knowledge/raw/.gitkeep +0 -0
- package/dist/engineering-pa-core/knowledge/scaffold/domains.json +5 -0
- package/dist/engineering-pa-core/knowledge/schema/.gitkeep +0 -0
- package/dist/engineering-pa-core/knowledge/work-management/README.md +33 -0
- package/dist/engineering-pa-core/knowledge/work-management/desk-cli.md +84 -0
- package/dist/engineering-pa-core/knowledge/work-management/progress-md.md +48 -0
- package/dist/engineering-pa-core/knowledge/work-management/projects.md +64 -0
- package/dist/engineering-pa-core/knowledge/work-management/spawn-log.md +48 -0
- package/dist/engineering-pa-core/knowledge/work-management/work-items.md +67 -0
- package/dist/engineering-pa-core/package.json +26 -0
- package/dist/engineering-pa-core/roles/agent-ops/definition.md +79 -0
- package/dist/engineering-pa-core/roles/dispatch-briefer/definition.md +195 -0
- package/dist/engineering-pa-core/roles/librarian/definition.md +176 -0
- package/dist/engineering-pa-core/roles/pa/definition.md +93 -0
- package/dist/engineering-pa-core/roles/system-admin/definition.md +106 -0
- package/dist/engineering-pa-core/roles/tool-developer/definition.md +116 -0
- package/dist/engineering-pa-core/roles/writer/definition.md +130 -0
- package/dist/engineering-pa-core/schema/autonomy-envelope.schema.json +61 -0
- package/dist/engineering-pa-core/schema/project.json +114 -0
- package/dist/engineering-pa-core/schema/schedule.json +63 -0
- package/dist/engineering-pa-core/schema/work-item.json +92 -0
- package/dist/engineering-pa-core/src/config/pa-package-name.mjs +30 -0
- package/dist/engineering-pa-core/src/desk/cli.mjs +95 -0
- package/dist/engineering-pa-core/src/desk/commands.mjs +398 -0
- package/dist/engineering-pa-core/src/desk/format.mjs +84 -0
- package/dist/engineering-pa-core/src/desk/repo.mjs +172 -0
- package/dist/engineering-pa-core/src/desk/team-scope.mjs +142 -0
- package/dist/engineering-pa-core/src/distill/cli.mjs +112 -0
- package/dist/engineering-pa-core/src/distill/prereqs.mjs +171 -0
- package/dist/engineering-pa-core/src/distill/prompt.mjs +74 -0
- package/dist/engineering-pa-core/src/distill/run.mjs +230 -0
- package/dist/engineering-pa-core/src/distill/runner.mjs +86 -0
- package/dist/engineering-pa-core/src/distill/staging.mjs +59 -0
- package/dist/engineering-pa-core/src/knowledge/retrieval/backlink-indexer.mjs +154 -0
- package/dist/engineering-pa-core/src/knowledge/retrieval/graph-builder.mjs +186 -0
- package/dist/engineering-pa-core/src/knowledge/retrieval/index-builder.mjs +225 -0
- package/dist/engineering-pa-core/src/knowledge/retrieval/query.mjs +263 -0
- package/dist/engineering-pa-core/src/lock/lock.mjs +202 -0
- package/dist/engineering-pa-core/src/memory-sync/cli-support.mjs +12 -0
- package/dist/engineering-pa-core/src/memory-sync/cli.mjs +56 -0
- package/dist/engineering-pa-core/src/memory-sync/commands/pull.mjs +44 -0
- package/dist/engineering-pa-core/src/memory-sync/commands/push.mjs +46 -0
- package/dist/engineering-pa-core/src/memory-sync/mirror.mjs +114 -0
- package/dist/engineering-pa-core/src/memory-sync/repo.mjs +65 -0
- package/dist/engineering-pa-core/src/scheduler/detect.mjs +111 -0
- package/dist/engineering-pa-core/src/scheduler/host.mjs +38 -0
- package/dist/engineering-pa-core/src/scheduler/index.mjs +13 -0
- package/dist/engineering-pa-core/src/scheduler/install.mjs +854 -0
- package/dist/engineering-pa-core/src/scheduler/list.mjs +168 -0
- package/dist/engineering-pa-core/src/scheduler/remove.mjs +176 -0
- package/dist/engineering-pa-core/src/scheduler/verify.mjs +435 -0
- package/dist/engineering-pa-core/src/session-boot/autonomy-injection.mjs +84 -0
- package/dist/engineering-pa-core/src/slice/cli.mjs +139 -0
- package/dist/engineering-pa-core/src/slice/inputs.mjs +174 -0
- package/dist/engineering-pa-core/src/slice/prompt.mjs +94 -0
- package/dist/engineering-pa-core/src/slice/prompts/dave-boot.md +91 -0
- package/dist/engineering-pa-core/src/slice/run.mjs +334 -0
- package/dist/engineering-pa-core-extensions-atlassian/README.md +31 -0
- package/dist/engineering-pa-core-extensions-atlassian/index.mjs +9 -0
- package/dist/engineering-pa-core-extensions-atlassian/package.json +19 -0
- package/dist/engineering-pa-core-extensions-n8n/README.md +29 -0
- package/dist/engineering-pa-core-extensions-n8n/index.mjs +8 -0
- package/dist/engineering-pa-core-extensions-n8n/package.json +19 -0
- package/dist/engineering-pa-librarian/README.md +38 -0
- package/dist/engineering-pa-librarian/index.mjs +12 -0
- package/dist/engineering-pa-librarian/package.json +19 -0
- package/dist/engineering-pa-migrate-inspect/README.md +131 -0
- package/dist/engineering-pa-migrate-inspect/bin/migrate-inspect +2 -0
- package/dist/engineering-pa-migrate-inspect/package.json +21 -0
- package/dist/engineering-pa-migrate-inspect/src/age-key-migrate.mjs +83 -0
- package/dist/engineering-pa-migrate-inspect/src/cli.mjs +97 -0
- package/dist/engineering-pa-migrate-inspect/src/inspector.mjs +237 -0
- package/dist/engineering-pa-migrate-inspect/src/platforms/linux.mjs +87 -0
- package/dist/engineering-pa-migrate-inspect/src/platforms/macos.mjs +105 -0
- package/dist/engineering-pa-migrate-inspect/src/runner.mjs +87 -0
- package/dist/engineering-pa-runbook/README.md +103 -0
- package/dist/engineering-pa-runbook/package.json +18 -0
- package/dist/engineering-pa-runbook/reference/dex-template.runbook.json +66 -0
- package/dist/engineering-pa-runbook/reference/hq-dave.runbook.json +69 -0
- package/dist/engineering-pa-runbook/reference/smarthome01.runbook.json +92 -0
- package/dist/engineering-pa-runbook/schema/inspection.schema.json +113 -0
- package/dist/engineering-pa-runbook/schema/runbook.schema.json +67 -0
- package/dist/engineering-pa-runbook/src/validator.mjs +167 -0
- package/dist/engineering-pa-scaffold/README.md +164 -0
- package/dist/engineering-pa-scaffold/bin/pa-init +2 -0
- package/dist/engineering-pa-scaffold/index.mjs +42 -0
- package/dist/engineering-pa-scaffold/package.json +22 -0
- package/dist/engineering-pa-scaffold/src/cli.mjs +115 -0
- package/dist/engineering-pa-scaffold/src/commands/init.mjs +169 -0
- package/dist/engineering-pa-scaffold/src/generator.mjs +354 -0
- package/dist/engineering-pa-scaffold/src/prompts.mjs +125 -0
- package/dist/engineering-pa-scaffold/src/runner.mjs +142 -0
- package/dist/engineering-pa-scaffold/templates/CLAUDE.md.template +196 -0
- package/dist/engineering-pa-scaffold/templates/operator-README.md.template +44 -0
- package/dist/engineering-pa-types-engineering/README.md +35 -0
- package/dist/engineering-pa-types-engineering/docs/commands/product-build.md +120 -0
- package/dist/engineering-pa-types-engineering/index.mjs +9 -0
- package/dist/engineering-pa-types-engineering/package.json +19 -0
- package/dist/engineering-pa-types-engineering/roles/product-engineer/definition.md +650 -0
- package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/build-spec.md +82 -0
- package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/preflight-checklist.md +158 -0
- package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/worker-brief.md +130 -0
- package/dist/engineering-pa-workspace/README.md +197 -0
- package/dist/engineering-pa-workspace/app/assets/md.js +187 -0
- package/dist/engineering-pa-workspace/app/assets/modal.js +120 -0
- package/dist/engineering-pa-workspace/app/assets/theme.css +132 -0
- package/dist/engineering-pa-workspace/app/assets/theme.js +159 -0
- package/dist/engineering-pa-workspace/app/banner.js +320 -0
- package/dist/engineering-pa-workspace/app/delegations.html +345 -0
- package/dist/engineering-pa-workspace/app/home.html +1060 -0
- package/dist/engineering-pa-workspace/app/index.html +361 -0
- package/dist/engineering-pa-workspace/app/knowledge-map.html +163 -0
- package/dist/engineering-pa-workspace/app/knowledge.html +304 -0
- package/dist/engineering-pa-workspace/app/nav.json +75 -0
- package/dist/engineering-pa-workspace/app/notes.html +199 -0
- package/dist/engineering-pa-workspace/app/onboarding.html +592 -0
- package/dist/engineering-pa-workspace/app/profile.html +243 -0
- package/dist/engineering-pa-workspace/app/project-detail.html +432 -0
- package/dist/engineering-pa-workspace/app/projects.html +297 -0
- package/dist/engineering-pa-workspace/app/repos.html +598 -0
- package/dist/engineering-pa-workspace/app/schedules.html +486 -0
- package/dist/engineering-pa-workspace/app/secrets.html +164 -0
- package/dist/engineering-pa-workspace/app/staging.html +319 -0
- package/dist/engineering-pa-workspace/app/tasks.html +465 -0
- package/dist/engineering-pa-workspace/app/vendor/chart.umd.min.js +21 -0
- package/dist/engineering-pa-workspace/app/viewer.html +116 -0
- package/dist/engineering-pa-workspace/docs/DAEMON.md +104 -0
- package/dist/engineering-pa-workspace/docs/page-blueprint.md +286 -0
- package/dist/engineering-pa-workspace/docs/status-mon.md +168 -0
- package/dist/engineering-pa-workspace/index.mjs +12 -0
- package/dist/engineering-pa-workspace/nav.json.example +8 -0
- package/dist/engineering-pa-workspace/package.json +27 -0
- package/dist/engineering-pa-workspace/src/api.mjs +2086 -0
- package/dist/engineering-pa-workspace/src/install-daemon.mjs +573 -0
- package/dist/engineering-pa-workspace/src/nav.mjs +190 -0
- package/dist/engineering-pa-workspace/src/secrets-api.mjs +175 -0
- package/dist/engineering-pa-workspace/src/server.mjs +516 -0
- package/dist/engineering-pa-workspace/src/status-mon/poll.mjs +220 -0
- package/dist/engineering-pa-workspace/src/status-mon/poller.mjs +113 -0
- package/dist/engineering-pa-workspace/src/status-mon/run.mjs +133 -0
- package/dist/engineering-pa-workspace/src/supervisor.mjs +264 -0
- package/dist/engineering-pa-workspace/src/ws.mjs +633 -0
- package/index.mjs +60 -0
- package/package.json +58 -0
- package/templates/banned-ai-tells.md +102 -0
- package/templates/purpose.md +105 -0
- package/templates/voice-guide.md +98 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# coordinator-hook
|
|
2
|
+
|
|
3
|
+
`pa-coordinator-hook` — a Claude Code `PreToolUse` hook that mechanically
|
|
4
|
+
enforces a three-tier tool policy on interactive PA main threads: dispatch
|
|
5
|
+
primitives are always allowed, a small argument-gated set of Bash/Read/Write
|
|
6
|
+
calls are permitted for coordination-scale work, and everything else
|
|
7
|
+
(`Edit`, `Grep`, `WebFetch`, …) is blocked with a message pointing at the
|
|
8
|
+
dispatch alternative.
|
|
9
|
+
|
|
10
|
+
This exists because "handle it inline instead of dispatching" is a repeat
|
|
11
|
+
failure mode for interactive PAs — soft discipline in CLAUDE.md isn't
|
|
12
|
+
sufficient on its own. See `projects/agentic-harness/product-vision.md` §1
|
|
13
|
+
item 6 for the design rationale (operator repo, not this one).
|
|
14
|
+
|
|
15
|
+
## Status
|
|
16
|
+
|
|
17
|
+
Implemented: full three-tier decision engine, config + per-PA overlay
|
|
18
|
+
loading, `--help`. Not yet wired into any `~/.claude/settings.json` by this
|
|
19
|
+
package — that's an explicit boundary (see below), and the `pa-init`
|
|
20
|
+
scaffold does not yet emit the snippet either (tracked as a follow-up, not
|
|
21
|
+
done in the PR that introduced this doc).
|
|
22
|
+
|
|
23
|
+
## How it works
|
|
24
|
+
|
|
25
|
+
Claude Code's `PreToolUse` hook contract (verified against the current docs
|
|
26
|
+
at the time this was built —
|
|
27
|
+
[code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks)):
|
|
28
|
+
every `PreToolUse` invocation matching the configured `matcher` gets the
|
|
29
|
+
event as JSON on **stdin** (not an env var — the `TOOL_NAME` env var
|
|
30
|
+
mentioned in some older mental models of this contract does not exist in
|
|
31
|
+
the current shape):
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"tool_name": "Bash",
|
|
36
|
+
"tool_input": { "command": "npm test" },
|
|
37
|
+
"cwd": "/home/user/my-project",
|
|
38
|
+
"session_id": "...",
|
|
39
|
+
"permission_mode": "default"
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Exit codes: `0` = allow (falls through to Claude Code's normal permission
|
|
44
|
+
flow — the hook only ever *tightens*, it never auto-grants), `2` = block
|
|
45
|
+
(stderr becomes the message the model sees), anything else = non-blocking
|
|
46
|
+
error (tool call proceeds; stderr is logged to the transcript). `pa-
|
|
47
|
+
coordinator-hook` uses exit `1` for a malformed/empty stdin payload — it
|
|
48
|
+
fails OPEN on hook-input errors rather than blocking every tool call
|
|
49
|
+
estate-wide because of a hook bug.
|
|
50
|
+
|
|
51
|
+
## The three tiers
|
|
52
|
+
|
|
53
|
+
**Tier 1 — always allowed, never reaches the hook.** Dispatch + coordination
|
|
54
|
+
primitives (`Agent`, `SendMessage`, `TaskCreate`, `Skill`, …). The
|
|
55
|
+
settings.json `matcher` (below) simply never fires the hook for these tool
|
|
56
|
+
names, so there's no tier1 enforcement code — `config.tier1` in
|
|
57
|
+
`coordinator-allowlist.json` is documentation only.
|
|
58
|
+
|
|
59
|
+
**Tier 2 — argument-gated allowlist.** `Bash`, `Read`, `Write`. The hook
|
|
60
|
+
inspects `tool_input` against regex allow patterns:
|
|
61
|
+
|
|
62
|
+
- **Bash** — `command` must match one of `tier2.Bash.allowPatterns` (`pa `,
|
|
63
|
+
`desk `, `git status`, `gh api `, `ls`, …), and must NOT match
|
|
64
|
+
`hardDeny.bashPatterns` or contain a shell-chaining metacharacter
|
|
65
|
+
(`;`, `&&`, `||`, `|`, `` ` ``, `$(`) — the chain-guard exists so a command
|
|
66
|
+
like `pa knowledge search foo && rm -rf ~` can't slip through on the
|
|
67
|
+
strength of its allowed prefix.
|
|
68
|
+
- **Read** — `file_path` must match `tier2.Read.allowPathPatterns` (repo-
|
|
69
|
+
relative: `.session/`, `agents/<self>/`, `work/`, `projects/*/project.json`,
|
|
70
|
+
…) or `allowAbsolutePathPatterns` (`/tmp/`, `/private/tmp/` — scratchpad),
|
|
71
|
+
and must NOT match `blockPathPatterns` (`operator/knowledge/**` — direct
|
|
72
|
+
reads bypass the knowledge graph; use `pa knowledge` verbs instead) or
|
|
73
|
+
`hardDeny.pathPatterns` (`.ssh/`, `.vault/`, `secrets.enc.json`, `.env` —
|
|
74
|
+
credential material, never overridable by an overlay).
|
|
75
|
+
- **Write** — same shape as Read, no `blockPathPatterns` (default-deny
|
|
76
|
+
already covers "anything not explicitly staged/session/cache/scratch").
|
|
77
|
+
|
|
78
|
+
`<self>` in a path pattern is substituted at runtime: the resolved `paName`
|
|
79
|
+
(`PA_SELF_AGENT` env var, else `operator/config/preferences.json#paName`
|
|
80
|
+
read relative to the resolved repo root) when known, else `[^/]+` — the
|
|
81
|
+
documented fallback ("if unknown, allow any `agents/*/` path").
|
|
82
|
+
|
|
83
|
+
**Tier 3 — always blocked.** `Edit`, `NotebookEdit`, `Grep`, `Glob`,
|
|
84
|
+
`WebFetch`, `WebSearch`. Every invocation gets a tool-specific message
|
|
85
|
+
(`config.messages[toolName]`) pointing at the dispatch alternative — e.g.
|
|
86
|
+
Grep says "dispatch Explore for search", WebFetch says "dispatch
|
|
87
|
+
`/research`".
|
|
88
|
+
|
|
89
|
+
### Hard-deny (never overridable by an overlay)
|
|
90
|
+
|
|
91
|
+
`hardDeny` in `coordinator-allowlist.json` is checked before any allow
|
|
92
|
+
pattern, core or overlay-supplied, for both Bash commands and Read/Write
|
|
93
|
+
paths. It exists because the overlay mechanism (below) only *adds* allow
|
|
94
|
+
patterns — a careless or malicious overlay entry (e.g. an allow pattern that
|
|
95
|
+
accidentally matches `rm -rf ~` because it was written too loosely) must not
|
|
96
|
+
be able to defeat the policy's basic safety floor. Covers: `rm -rf`,
|
|
97
|
+
`curl | sh` / `wget | sh`, `git push --force`, `git reset --hard`,
|
|
98
|
+
`git clean -f`, `git branch -D`, `--no-verify`, `--no-gpg-sign`,
|
|
99
|
+
`gh repo delete` and other destructive `gh` verbs, `sudo`, `dd if=`,
|
|
100
|
+
`mkfs`, raw-disk redirects, and reads/writes of `.ssh/`, `.aws/`,
|
|
101
|
+
`.vault/`, `secrets.enc.json`, `.env`. Not a security sandbox — a
|
|
102
|
+
determined caller can still construct a bypass a naive prefix/negative-list
|
|
103
|
+
regex won't catch — just a mechanical backstop against the obviously
|
|
104
|
+
destructive cases.
|
|
105
|
+
|
|
106
|
+
## Toggle
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
PA_COORDINATOR_MODE=1 # enforce
|
|
110
|
+
# unset, or anything other than "1" → transparent no-op, exits 0 for everything
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Deliberately a different variable name from the unofficial internal
|
|
114
|
+
`CLAUDE_CODE_COORDINATOR_MODE` some environments may already use — this one
|
|
115
|
+
is owned by the pa-coordinator-hook contract specifically.
|
|
116
|
+
|
|
117
|
+
## Config
|
|
118
|
+
|
|
119
|
+
Core allowlist ships at `packages/cli/config/coordinator-allowlist.json`
|
|
120
|
+
(bundled into the published tarball at
|
|
121
|
+
`dist/engineering-pa-cli/config/coordinator-allowlist.json` — resolved via
|
|
122
|
+
`import.meta.url` at runtime, so it works identically from source and from
|
|
123
|
+
the bundled package). **This file is not the place to add a personal
|
|
124
|
+
exception** — it ships inside the package and is overwritten on every
|
|
125
|
+
`pnpm add`/upgrade.
|
|
126
|
+
|
|
127
|
+
### Per-PA overlay
|
|
128
|
+
|
|
129
|
+
Add allow-pattern exceptions at:
|
|
130
|
+
|
|
131
|
+
- `~/.claude/coordinator-overlay.json` (home — applies to every repo on the
|
|
132
|
+
machine), and/or
|
|
133
|
+
- `<repo-root-or-cwd>/.claude/coordinator-overlay.json` (workspace —
|
|
134
|
+
applies to just this operator repo; applied after the home overlay, so it
|
|
135
|
+
can extend past whatever the home overlay already added)
|
|
136
|
+
|
|
137
|
+
```jsonc
|
|
138
|
+
{
|
|
139
|
+
"tier2": {
|
|
140
|
+
"Bash": { "allowPatterns": ["^npm ls\\s"] },
|
|
141
|
+
"Read": { "allowPathPatterns": ["^docs/"] }
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Contract (enforced by `mergeOverlay` in `config.mjs`):** an overlay may
|
|
147
|
+
ONLY extend `tier2.<Bash|Read|Write>.allowPatterns` /
|
|
148
|
+
`.allowPathPatterns`. It cannot move a tool between tiers, touch
|
|
149
|
+
`tier1`/`tier3`, or touch `hardDeny` — any other key is ignored and reported
|
|
150
|
+
as a stderr warning, never silently accepted. This is deliberate: silently
|
|
151
|
+
accepting an unrecognised overlay shape is exactly how a stray key would
|
|
152
|
+
quietly widen the policy.
|
|
153
|
+
|
|
154
|
+
## Settings snippet (documentation only — not applied by this package)
|
|
155
|
+
|
|
156
|
+
Wire the hook up in your OWN `~/.claude/settings.json` (per-machine operator
|
|
157
|
+
territory — this package never writes to it):
|
|
158
|
+
|
|
159
|
+
```jsonc
|
|
160
|
+
{
|
|
161
|
+
"hooks": {
|
|
162
|
+
"PreToolUse": [
|
|
163
|
+
{
|
|
164
|
+
"matcher": "^(Bash|Read|Write|Edit|NotebookEdit|Grep|Glob|WebFetch|WebSearch)$",
|
|
165
|
+
"hooks": [
|
|
166
|
+
{
|
|
167
|
+
"type": "command",
|
|
168
|
+
"command": "pa-coordinator-hook"
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Then, per-repo or per-session:
|
|
178
|
+
|
|
179
|
+
```sh
|
|
180
|
+
export PA_COORDINATOR_MODE=1
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Verifying an install
|
|
184
|
+
|
|
185
|
+
```sh
|
|
186
|
+
pa-coordinator-hook --help # prints usage, exits 0
|
|
187
|
+
|
|
188
|
+
# allow (mode off — transparent no-op)
|
|
189
|
+
echo '{"tool_name":"Grep","tool_input":{}}' | pa-coordinator-hook; echo $? # 0
|
|
190
|
+
|
|
191
|
+
# block (mode on, tier3)
|
|
192
|
+
echo '{"tool_name":"Grep","tool_input":{}}' \
|
|
193
|
+
| PA_COORDINATOR_MODE=1 pa-coordinator-hook; echo $? # 2
|
|
194
|
+
|
|
195
|
+
# allow (mode on, tier2 Bash allow pattern)
|
|
196
|
+
echo '{"tool_name":"Bash","tool_input":{"command":"pa knowledge search foo"}}' \
|
|
197
|
+
| PA_COORDINATOR_MODE=1 pa-coordinator-hook; echo $? # 0
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Known follow-ups (not done in this package)
|
|
201
|
+
|
|
202
|
+
- **`/research` light mode** (operator-side skill, not this package) runs
|
|
203
|
+
inline `WebFetch`/`WebSearch` — under coordinator mode that path is
|
|
204
|
+
blocked. The skill needs to detect `PA_COORDINATOR_MODE=1` and switch
|
|
205
|
+
light-mode to a scoped dispatch. Tracked as a separate work item — not
|
|
206
|
+
changed here.
|
|
207
|
+
- **`pa-init` scaffold** does not yet emit the settings.json snippet or a
|
|
208
|
+
starter `.claude/coordinator-overlay.json` for new operator repos.
|
|
209
|
+
- **`gh` verb allowlist** is coarse (`gh api ` allows any subpath, `gh pr
|
|
210
|
+
{view,list,merge,close}`) — if a narrower per-repo policy is needed later,
|
|
211
|
+
extend via overlay rather than editing the core config.
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
# estate-sync
|
|
2
|
+
|
|
3
|
+
`ai.stravica.ops.estate-sync` — single-writer-per-host git sync for
|
|
4
|
+
ESTATE-NATIVE content only.
|
|
5
|
+
|
|
6
|
+
The sole git-writer on a host running HQ scheduled tools, for the paths
|
|
7
|
+
this tool actually owns. Cron tools (distill, wsd-ingest,
|
|
8
|
+
upstream-triage, …) become pure file writers; this tool is the one
|
|
9
|
+
process per host that ever `git add` / `git commit` / `git push`. That
|
|
10
|
+
structural rule eliminates the intra-host write race that previously
|
|
11
|
+
caused `fail-rebase` and `fail-dirty-tree` cron alerts.
|
|
12
|
+
|
|
13
|
+
**Renamed from `dave-sync`** (library-sync-solidification, D1). The
|
|
14
|
+
rename is not cosmetic: the rewrite that ships alongside it replaces a
|
|
15
|
+
blind `git add -A` with a REGISTRY-SCOPED commit set. Task/schedule ids
|
|
16
|
+
that reference this tool by its estate-side name (e.g.
|
|
17
|
+
`schedules/dave-sync.json`) are estate data, out of scope for this
|
|
18
|
+
package — they don't need to change for the tool to work; the bin alias
|
|
19
|
+
below covers that gap during migration.
|
|
20
|
+
|
|
21
|
+
## Status
|
|
22
|
+
|
|
23
|
+
Implemented: `run`, `run --dry-run`, `--help`.
|
|
24
|
+
|
|
25
|
+
## Install / invoke
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
estate-sync run
|
|
29
|
+
estate-sync run --dry-run
|
|
30
|
+
estate-sync --help
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`sync` is kept as a back-compat alias — identical bin, identical
|
|
34
|
+
behaviour, same entry point (`src/sync/cli.mjs`). Existing crontab /
|
|
35
|
+
schedule entries invoking `sync run` keep working unchanged; new installs
|
|
36
|
+
should prefer `estate-sync run`.
|
|
37
|
+
|
|
38
|
+
Designed to run every 30 minutes on each HQ host (smarthome01 + optional
|
|
39
|
+
macbook). The companion schedule definition is at
|
|
40
|
+
`schedules/dave-sync.json` (operator instance) — renaming that schedule
|
|
41
|
+
id/tag is estate-side work, not part of this package.
|
|
42
|
+
|
|
43
|
+
## Commands
|
|
44
|
+
|
|
45
|
+
### `estate-sync run`
|
|
46
|
+
|
|
47
|
+
1. **Acquire process lock.** A PID file at `<repoRoot>/.cache/estate-sync/.lock`
|
|
48
|
+
ensures no two sync runs overlap on a host. The lock is considered
|
|
49
|
+
stale after 10 minutes (a real run never legitimately takes that long;
|
|
50
|
+
the cron tick is 30 minutes, so a 10-minute window is safely under
|
|
51
|
+
the next-tick interval). On lock contention the run exits 0 with
|
|
52
|
+
status `noop-locked`; the next tick retries.
|
|
53
|
+
2. **`git fetch origin`.** Refresh remote-tracking refs **before** the
|
|
54
|
+
ahead/behind probe so the short-circuit in step 4 sees what origin
|
|
55
|
+
actually has. Without this, a long-idle clean clone computes
|
|
56
|
+
`behind` from whatever `origin/<branch>` happened to point at on
|
|
57
|
+
the last successful fetch — which can be days stale, and the
|
|
58
|
+
noop short-circuit then traps the clone on stale state forever.
|
|
59
|
+
Fetch failure (network / auth) is logged but **not blocking**: the
|
|
60
|
+
sync continues on stale refs for this tick, which still allows
|
|
61
|
+
local-only commits to be made and queued for push; the next tick
|
|
62
|
+
retries. Skipped under `--dry-run` to preserve the "no git commands
|
|
63
|
+
spawned" contract.
|
|
64
|
+
3. **Examine state.** `git status --porcelain` to detect a dirty working
|
|
65
|
+
tree; `git rev-list --left-right --count HEAD...@{u}` to detect local
|
|
66
|
+
commits ahead of (or behind) origin.
|
|
67
|
+
4. **Short-circuit if nothing to do.** Clean tree + 0 ahead + 0 behind
|
|
68
|
+
⇒ exit 0, status `noop-nothing-to-do`. (Accurate now that step 2
|
|
69
|
+
refreshes the refs.)
|
|
70
|
+
5. **Compose commit body + compute commit scope.** Walk
|
|
71
|
+
`.cache/*/logs/runs.jsonl` and `operator/extensions/tools/*/logs/runs.jsonl`
|
|
72
|
+
for the runs-digest section of the commit body (see `runs-digest.mjs`).
|
|
73
|
+
In parallel, compute the registry-scoped commit-scope decision (see
|
|
74
|
+
below) — cheap, at most two small JSON reads.
|
|
75
|
+
6. **Stage — registry-scoped, never a blind `git add -A`.**
|
|
76
|
+
|
|
77
|
+
When `<repoRoot>/operator/registry/{devices.json,repos.json}` both
|
|
78
|
+
exist:
|
|
79
|
+
- Resolve this device from `os.hostname()` against `devices.json`
|
|
80
|
+
(exact host match, then device-id-equals-hostname, then
|
|
81
|
+
short-name-before-first-dot — identical algorithm to
|
|
82
|
+
`operator/extensions/tools/library-sync/run.mjs`'s
|
|
83
|
+
`resolveDeviceId`, so the two tools never disagree about "which
|
|
84
|
+
device am I").
|
|
85
|
+
- Resolve the repos this device is entitled to
|
|
86
|
+
(`devices.json[deviceId].entitlements.repos`).
|
|
87
|
+
- Derive the EXCLUSION set: every entitled repo's mount `to` subtree,
|
|
88
|
+
**unconditionally** (no ownership carve-out — see
|
|
89
|
+
`registry-scope.mjs`'s module doc for why this is deliberately
|
|
90
|
+
simpler than library-sync's own down-path owner-exclusion), plus
|
|
91
|
+
`.vault/**` unconditionally.
|
|
92
|
+
- Stage ONLY the in-scope dirty paths (everything from
|
|
93
|
+
`git status --porcelain` NOT under an excluded subtree) via
|
|
94
|
+
explicit pathspecs: `git add -- <path> <path> ...`. An untracked
|
|
95
|
+
file inside an excluded subtree is never passed to `git add`, so it
|
|
96
|
+
can never be staged — the pathspec approach handles this by
|
|
97
|
+
construction, not by a follow-up filter.
|
|
98
|
+
|
|
99
|
+
When the registry is **not present** at this repo root: previous
|
|
100
|
+
(pre-rewrite) behaviour — unscoped `git add -A` — but LOUDLY flagged,
|
|
101
|
+
both in the run's stderr output and in the commit body
|
|
102
|
+
(`estate-sync: no registry found, unscoped commit`).
|
|
103
|
+
|
|
104
|
+
Either way, the commit body gets a scope-decision section reporting
|
|
105
|
+
counts: paths staged, subtrees excluded by rule (see "Commit body"
|
|
106
|
+
below).
|
|
107
|
+
7. **`git commit -m "estate-sync <ISO ts>" -m "<body>"`.** Commit
|
|
108
|
+
**before** the rebase. `git pull --rebase` refuses to run when the
|
|
109
|
+
index or working tree has uncommitted changes, so the working state
|
|
110
|
+
must be turned into a real commit first. Skipped if the tree is
|
|
111
|
+
clean (e.g. a `behind`-only state — the pull is the whole job), or if
|
|
112
|
+
every dirty path was excluded by the commit scope (nothing staged).
|
|
113
|
+
8. **`git pull --rebase origin <branch>`.** Fetch was done in step 2,
|
|
114
|
+
so this is just the rebase. Now safe because the index is clean
|
|
115
|
+
(we either committed in step 6/7 or the tree was already clean).
|
|
116
|
+
Skipped entirely if step 2's fetch failed (rebasing onto stale
|
|
117
|
+
refs is a no-op at best and a spurious failure at worst).
|
|
118
|
+
|
|
119
|
+
**Conflict handling (auto-resolve on regenerated artifacts).** When
|
|
120
|
+
the rebase conflicts, sync checks whether every conflicted path is
|
|
121
|
+
in the *regenerated-artifacts allowlist* (see below). Files in that
|
|
122
|
+
list are regenerated by distillation on every host — different byte
|
|
123
|
+
output, semantically-equivalent content — so a conflict is a race
|
|
124
|
+
between two hosts' regenerations, not a real disagreement. In that
|
|
125
|
+
case sync takes origin's version (`git checkout --ours -- <paths>`;
|
|
126
|
+
note the rebase-inversion — `--ours` refers to the branch being
|
|
127
|
+
rebased *onto*), stages the paths, `git rebase --continue`s, and
|
|
128
|
+
proceeds to push. The audit record adds
|
|
129
|
+
`autoResolved: <N>` + `autoResolvedPaths: [...]` to the `ok` line.
|
|
130
|
+
|
|
131
|
+
If **any** conflicted path is outside the allowlist,
|
|
132
|
+
`git rebase --abort` runs and sync exits 2 with status `fail-rebase`
|
|
133
|
+
as before. Real content conflicts still surface for human resolution;
|
|
134
|
+
the audit record includes `conflictedPaths: [...]` for the disallowed
|
|
135
|
+
paths so the on-call has a starting point.
|
|
136
|
+
|
|
137
|
+
### Registry-scoped commit set
|
|
138
|
+
|
|
139
|
+
Source: `src/sync/registry-scope.mjs`. Pure functions over injected
|
|
140
|
+
registry docs + `os.hostname()` — no git, no spawning, fully unit-tested
|
|
141
|
+
in isolation from `run.mjs`.
|
|
142
|
+
|
|
143
|
+
Degrade-gracefully-never-crash contract, in priority order:
|
|
144
|
+
|
|
145
|
+
1. `operator/registry/devices.json` or `repos.json` missing at this repo
|
|
146
|
+
root → `registryPresent: false` (unscoped fallback).
|
|
147
|
+
2. Either file present but unparseable JSON → `registryPresent: false`,
|
|
148
|
+
with a warning naming the parse failure (unscoped fallback).
|
|
149
|
+
3. Registry present and parseable, but this device's hostname doesn't
|
|
150
|
+
resolve to a known device id → `registryPresent: false`, warning
|
|
151
|
+
naming the hostname tried (unscoped fallback).
|
|
152
|
+
4. Otherwise → `registryPresent: true`, scoped exclusion set computed.
|
|
153
|
+
|
|
154
|
+
None of these paths ever throws out of `computeCommitScope` — a broken
|
|
155
|
+
or absent registry degrades to the pre-rewrite behaviour, never a crashed
|
|
156
|
+
30-minute cron.
|
|
157
|
+
|
|
158
|
+
### Regenerated-artifacts allowlist
|
|
159
|
+
|
|
160
|
+
Built-in defaults (in `src/sync/regenerated-artifacts.mjs`):
|
|
161
|
+
|
|
162
|
+
- `operator/knowledge/.graph.json`
|
|
163
|
+
- `operator/knowledge/.backlinks.json`
|
|
164
|
+
- `operator/knowledge/domains.json`
|
|
165
|
+
- `operator/profile/profile.md`
|
|
166
|
+
- `operator/profile/operator.json`
|
|
167
|
+
- `operator/knowledge/systems/web-properties/*.md`
|
|
168
|
+
|
|
169
|
+
Repos can extend the allowlist by adding `<repoRoot>/.sync-config.json`:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"regeneratedArtifacts": [
|
|
174
|
+
"projects/foo/generated.json",
|
|
175
|
+
"some/tool/output/**/*.json"
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Entries are additive to the defaults. Globs use POSIX-style `*`
|
|
181
|
+
(single segment) and `**` (any number of segments) via
|
|
182
|
+
`node:path.matchesGlob`. Missing / malformed config file falls back to
|
|
183
|
+
defaults with a stderr warning; the config is intentionally non-fatal
|
|
184
|
+
so an editor mistake can't wedge the cron.
|
|
185
|
+
|
|
186
|
+
9. **`git push`.** On rejection: `git fetch && git pull --rebase` and
|
|
187
|
+
retry the push once. If the retry fails, exit 2 with status
|
|
188
|
+
`fail-push` and leave the commit local (next tick will reconcile or
|
|
189
|
+
surface again).
|
|
190
|
+
10. **Append audit record** to `<repoRoot>/.cache/estate-sync/logs/runs.jsonl`.
|
|
191
|
+
|
|
192
|
+
### `estate-sync run --dry-run`
|
|
193
|
+
|
|
194
|
+
Same as steps 1–5 (lock is still taken — dry-run still serialises
|
|
195
|
+
against itself), then prints the would-be commit title, body, and scope
|
|
196
|
+
decision, and exits 0. Never spawns `git add`/`commit`/`push`, never
|
|
197
|
+
writes `runs.jsonl`.
|
|
198
|
+
|
|
199
|
+
### Commit body
|
|
200
|
+
|
|
201
|
+
Two sections, in order:
|
|
202
|
+
|
|
203
|
+
1. **Scope-decision section** — either:
|
|
204
|
+
- `estate-sync scope: registry-scoped (device=<id>)` with `staged: N
|
|
205
|
+
path(s)` and `excluded: M subtree(s) by rule (K dirty path(s)
|
|
206
|
+
matched) — <list>`, or
|
|
207
|
+
- `estate-sync: no registry found, unscoped commit` (the loud
|
|
208
|
+
unscoped-fallback flag).
|
|
209
|
+
2. **Runs-digest section** — the pre-existing per-cron-tool summary
|
|
210
|
+
(unchanged; see `runs-digest.mjs`).
|
|
211
|
+
|
|
212
|
+
### `runs.jsonl` audit-record schema
|
|
213
|
+
|
|
214
|
+
One JSON object per line, camelCase keys (§11 of the tooling standard):
|
|
215
|
+
|
|
216
|
+
| Field | Type | Description |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| `ts` | string | RFC-3339 / ISO-8601 UTC timestamp. Round-trips through `new Date()`. |
|
|
219
|
+
| `status` | string | Semantic status, closed vocabulary (see below). |
|
|
220
|
+
| `exitCode` | number | Process exit code (0 / 2 / 3). |
|
|
221
|
+
| `durationSec` | number | Seconds elapsed since start of run. |
|
|
222
|
+
| `reason` | string | Present on every non-`ok`/non-`noop-nothing-to-do` record; omitted otherwise. |
|
|
223
|
+
| `dirty` | bool | Working tree was dirty at examine-time. `noop-nothing-to-do` only. |
|
|
224
|
+
| `ahead` | number | Local commits ahead of origin. `noop-nothing-to-do` only. |
|
|
225
|
+
| `behind` | number | Origin commits the local branch is behind. `noop-nothing-to-do` only. |
|
|
226
|
+
| `committed` | bool | A commit was created this run. `ok` only. |
|
|
227
|
+
| `pushed` | bool | A push succeeded this run. `ok` only. |
|
|
228
|
+
| `retriedAfterRebase` | bool | The push needed a rebase + retry. `ok` only. |
|
|
229
|
+
| `branch` | string | The current branch name. Present on `ok` and `noop-nothing-to-do`. |
|
|
230
|
+
| `autoResolved` | number | Number of allowlisted regenerated-artifact paths auto-resolved during a rebase conflict. `ok` only, present iff > 0. |
|
|
231
|
+
| `autoResolvedPaths` | string[] | The specific paths that got the `--ours` treatment. `ok` only, paired with `autoResolved`. |
|
|
232
|
+
| `conflictedPaths` | string[] | The disallowed conflicted paths that forced the abort. `fail-rebase` only, when at least one conflict was outside the allowlist. |
|
|
233
|
+
|
|
234
|
+
Status vocabulary (closed set):
|
|
235
|
+
|
|
236
|
+
| Status | exitCode | When |
|
|
237
|
+
|---|---|---|
|
|
238
|
+
| `ok` | 0 | Commit + push (or pull-only) succeeded. |
|
|
239
|
+
| `noop-nothing-to-do` | 0 | Clean tree, no local commits ahead, up-to-date with origin. |
|
|
240
|
+
| `noop-locked` | 0 | Another sync run holds the lock. |
|
|
241
|
+
| `fail-rebase` | 2 | `git pull --rebase` conflicted; rebase aborted. Human reconciliation required. |
|
|
242
|
+
| `fail-push` | 2 | Push rejected even after one rebase-and-retry. Commit is local-only. |
|
|
243
|
+
| `fail-git` | 3 | A `git status`/`add`/`commit` command itself errored (transport or IO). |
|
|
244
|
+
| `fail-cli-bootstrap` | varies | parseArgs / import / startup failure before runSync was reached. |
|
|
245
|
+
|
|
246
|
+
Consumer contract: monitors should treat `status == 'ok'` and any
|
|
247
|
+
`noop-*` as healthy; any `fail-*` as failing.
|
|
248
|
+
|
|
249
|
+
## Exit codes
|
|
250
|
+
|
|
251
|
+
| Code | Meaning |
|
|
252
|
+
|---|---|
|
|
253
|
+
| `0` | OK — nothing to do, or sync completed and (optionally) pushed. |
|
|
254
|
+
| `1` | Usage error (unknown verb, bad flag). |
|
|
255
|
+
| `2` | Logical / operational failure (rebase conflict, push rejected after retry). |
|
|
256
|
+
| `3` | Transport / IO failure (a git command itself errored). |
|
|
257
|
+
|
|
258
|
+
## Operational discipline rules
|
|
259
|
+
|
|
260
|
+
1. **Single writer per host, for the paths it owns.** This tool is the
|
|
261
|
+
only HQ process that performs `git add` / `git commit` / `git push`
|
|
262
|
+
on the shared estate repo. It is scoped to estate-native content —
|
|
263
|
+
mount-owned paths, `agents/*` run-state, and `.vault/**` ride the
|
|
264
|
+
library pipeline instead (see the library-sync-solidification
|
|
265
|
+
architecture decision, D1/D2). Cron tools (`distill`, `wsd-ingest`,
|
|
266
|
+
`upstream-triage`) write files only. The chokepoint is the lock file
|
|
267
|
+
plus the discipline that no other tool spawns mutating git commands.
|
|
268
|
+
2. **Never a blind `git add -A` when a registry is present.** Explicit
|
|
269
|
+
pathspecs only. The no-registry fallback IS still `git add -A`, by
|
|
270
|
+
design (nothing to scope against) — but it is loud about it in both
|
|
271
|
+
the run's output and the commit body, never silent.
|
|
272
|
+
3. **No shell interpolation.** Every spawn passes arguments as an array
|
|
273
|
+
with `shell:false`. Commit message bodies (which can contain newlines
|
|
274
|
+
and quotes from runs.jsonl content) are passed through argv `-m`
|
|
275
|
+
without any escaping required.
|
|
276
|
+
4. **Chokepoint for every external effect.** `src/sync/runner.mjs` is the
|
|
277
|
+
only module that spawns processes or reads wall-clock time. Tests
|
|
278
|
+
replace it with a scripted fake. `registry-scope.mjs` is pure (file
|
|
279
|
+
reads + string logic only, no spawning) and independently testable.
|
|
280
|
+
5. **Lock-on-write.** The PID lock ensures two sync runs on the same
|
|
281
|
+
host never both reach the `git commit` step. The lock is stale-safe
|
|
282
|
+
(10 minutes) so a crashed runner does not wedge subsequent ticks.
|
|
283
|
+
6. **No stranded commits.** If push fails even after one rebase-retry,
|
|
284
|
+
exit 2 (`fail-push`). The next 30m tick will retry from the start —
|
|
285
|
+
discovering the local-only commit, pulling origin's new state,
|
|
286
|
+
rebasing on top, pushing again. Monitor on `fail-push` runs lasting
|
|
287
|
+
> 2 ticks.
|
|
288
|
+
7. **Degrade gracefully, never crash on registry state.** A missing,
|
|
289
|
+
malformed, or device-unresolvable registry falls back to the
|
|
290
|
+
pre-rewrite unscoped behaviour with a loud warning — never a thrown
|
|
291
|
+
error, never a silently-scoped-wrong commit.
|
|
292
|
+
|
|
293
|
+
## Project layout
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
packages/cli/
|
|
297
|
+
bin/
|
|
298
|
+
estate-sync Node shebang shim (canonical bin name). One line.
|
|
299
|
+
sync Same shim — back-compat alias, same entry point.
|
|
300
|
+
src/sync/
|
|
301
|
+
cli.mjs Arg parsing (node:util.parseArgs), verb routing,
|
|
302
|
+
exit-code translation.
|
|
303
|
+
run.mjs Orchestrator: lock -> examine -> compute scope ->
|
|
304
|
+
stage -> commit -> pull --rebase -> push. One
|
|
305
|
+
function per step. (Commit precedes the rebase
|
|
306
|
+
because git pull --rebase refuses to run with
|
|
307
|
+
uncommitted changes.)
|
|
308
|
+
registry-scope.mjs Registry-scoped commit-scope computation. Pure —
|
|
309
|
+
no spawning. Device resolution, mount-exclusion
|
|
310
|
+
derivation, porcelain-output filtering, scope
|
|
311
|
+
rendering for the commit body.
|
|
312
|
+
git.mjs Thin wrappers around the git commands sync invokes.
|
|
313
|
+
No spawning of its own — delegates to the runner.
|
|
314
|
+
runner.mjs Chokepoint. The only module that spawns processes
|
|
315
|
+
and reads the clock.
|
|
316
|
+
lock.mjs PID-file lock with stale-after-10m semantics.
|
|
317
|
+
Pure functions over an injectable fs.
|
|
318
|
+
runs-digest.mjs Discovers cron tool runs.jsonl files and tails the
|
|
319
|
+
last N records to compose a commit-body summary.
|
|
320
|
+
test/sync/
|
|
321
|
+
*.test.mjs node:test.
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Runtime-only (gitignored), under `<repoRoot>/.cache/estate-sync/`:
|
|
325
|
+
`.lock` (per-host PID file), `logs/runs.jsonl` (per-host audit roll-up),
|
|
326
|
+
`logs/<ts>.log` (per-run diagnostic logs, if added later).
|
|
327
|
+
|
|
328
|
+
## Tests
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
node --test packages/cli/test/sync/*.test.mjs
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Tests use dependency injection over mocking libraries. Real git, real
|
|
335
|
+
filesystem mutations (outside of `tmpdir()`) and real network never
|
|
336
|
+
appear in the suite.
|
|
337
|
+
|
|
338
|
+
Coverage:
|
|
339
|
+
|
|
340
|
+
- `lock.test.mjs` — acquire on empty path, contention with a live PID,
|
|
341
|
+
steal on a stale PID, steal on age-exceeded, release-only-if-still-ours.
|
|
342
|
+
- `runs-digest.test.mjs` — discovery (known parents, missing dirs
|
|
343
|
+
tolerated, sync's own log excluded), tail (last N, malformed JSON
|
|
344
|
+
lines skipped, empty file → empty array), body composition (header,
|
|
345
|
+
per-tool sections, footer, edge cases).
|
|
346
|
+
- `git.test.mjs` — argv shape of every git wrapper call.
|
|
347
|
+
- `registry-scope.test.mjs` — device resolution (exact host, device-id
|
|
348
|
+
match, short-name match, unresolvable), entitlement resolution (known
|
|
349
|
+
device, unknown device, repo missing from repos.json), exclude-dir
|
|
350
|
+
derivation (mount `to` union, `.vault/` always present, dedup + sort),
|
|
351
|
+
porcelain-path parsing (plain entries, renames contribute both sides,
|
|
352
|
+
short/malformed lines skipped), in-scope filtering (mount-owned dirty
|
|
353
|
+
file excluded, foreign-agent run-state excluded, `.vault` change
|
|
354
|
+
excluded, estate-native change included, untracked file inside an
|
|
355
|
+
excluded subtree never staged), no-registry / malformed-registry /
|
|
356
|
+
unknown-device fallback (all degrade to `registryPresent: false` with
|
|
357
|
+
a warning, never throw), scope-section rendering (scoped and unscoped
|
|
358
|
+
shapes).
|
|
359
|
+
- `run.test.mjs` — noop-nothing-to-do, noop-locked, dry-run no side
|
|
360
|
+
effects (asserts fetch->add->commit->pull->push ordering in the plan
|
|
361
|
+
output), dry-run on clean-but-behind tree omits add/commit, dirty
|
|
362
|
+
happy path (asserts fetch precedes add, add precedes commit, commit
|
|
363
|
+
precedes pull --rebase), regression coverage for the dirty + 0 ahead +
|
|
364
|
+
0 behind case and the clean + remote-has-new-commits case, rebase
|
|
365
|
+
conflict path (fail-rebase + audit + rebase --abort invoked), push
|
|
366
|
+
retry succeeds, push retry fails (fail-push), fetch failure during
|
|
367
|
+
pull tolerated, fetch failure during push-retry surfaces as fail-push,
|
|
368
|
+
auto-resolve on allowlisted regenerated artifacts, still fail-rebase
|
|
369
|
+
on any non-allowlisted conflict, mixed conflict fails without partial
|
|
370
|
+
resolution, `.sync-config.json` override extends the allowlist,
|
|
371
|
+
rebase --continue failure after resolution still fail-rebases,
|
|
372
|
+
**registry-scoped staging** (mount-owned dirty file not committed,
|
|
373
|
+
foreign-agent run-state not committed, `.vault` change not committed,
|
|
374
|
+
estate-native change is committed, no-registry fallback warns +
|
|
375
|
+
commits all, untracked file inside excluded subtree not staged, all
|
|
376
|
+
dirty paths excluded → no commit attempted), commit title/body reflect
|
|
377
|
+
`estate-sync` naming and the scope-decision section.
|
|
378
|
+
- `regenerated-artifacts.test.mjs` — defaults pin the known distill
|
|
379
|
+
outputs, glob semantics (exact / `*` single-segment / `**` deep),
|
|
380
|
+
classifyConflicts partitioning, config loader edge cases (missing
|
|
381
|
+
file / malformed JSON / non-array field / non-string entries).
|
|
382
|
+
- `cli.test.mjs` — `--help`, `-h`, no-args, unknown verb, unknown flag,
|
|
383
|
+
for both `estate-sync` and `sync` bins (identical behaviour).
|
|
384
|
+
|
|
385
|
+
## The tooling standard
|
|
386
|
+
|
|
387
|
+
This tool follows [`packages/core/docs/standards/tooling.md`](../../core/docs/standards/tooling.md)
|
|
388
|
+
(§1 identity, §2 Node-only, §3 zero deps, §4 structure, §5 CLI,
|
|
389
|
+
§6 exit codes, §7 chokepoint, §8 testing, §11 camelCase JSON,
|
|
390
|
+
§15 audit-record, §16 gitignored operational artefacts).
|
|
391
|
+
|
|
392
|
+
## Relationship to other tools
|
|
393
|
+
|
|
394
|
+
- **distill** writes the staging→knowledge promotion outputs. It does
|
|
395
|
+
not commit or push — sync picks those up on its next tick (if the
|
|
396
|
+
paths it wrote to are in-scope; distill's own outputs under
|
|
397
|
+
`operator/knowledge/` are canonical-owned mount content on most
|
|
398
|
+
estates and land via the library pipeline, not this tool).
|
|
399
|
+
- **library-sync** (`operator/extensions/tools/library-sync/`) owns
|
|
400
|
+
ALL mount-owned content, including `agents/*` run-state — this is
|
|
401
|
+
exactly the set estate-sync now excludes by construction.
|
|
402
|
+
- **wsd-ingest** writes per-entry markdown into `agents/dave/staging/`.
|
|
403
|
+
Under the current registry, `agents/dave/` is a mount `to` path (the
|
|
404
|
+
`stravica-library-hq` repo's `agents/barry/dave/` mount) and is
|
|
405
|
+
therefore excluded from estate-sync's commit scope — that content
|
|
406
|
+
reaches canonical exclusively via the library up-path, never via this
|
|
407
|
+
tool's git commit.
|
|
408
|
+
|
|
409
|
+
Cross-host visibility latency: estate-native outputs written by a cron
|
|
410
|
+
tool reach origin at the next sync tick (max 30 minutes behind
|
|
411
|
+
real-time). Mount-owned content's visibility latency is governed by the
|
|
412
|
+
library pipeline's own cadence instead.
|