@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,260 @@
|
|
|
1
|
+
// Knowledge-library promotion (w-021).
|
|
2
|
+
//
|
|
3
|
+
// On `research mark done <id>` for a NORMAL or DEEP session, promote the
|
|
4
|
+
// session's verbatim `answer.md` into the operator knowledge library as a
|
|
5
|
+
// first-class queryable doc under `operator/knowledge/research/`, so
|
|
6
|
+
// `pa knowledge` surfaces it alongside every other operator doc.
|
|
7
|
+
//
|
|
8
|
+
// Operator directive (2026-07-07):
|
|
9
|
+
// - normal + deep → auto-promote.
|
|
10
|
+
// - light → NEVER promote (hard rule; `--promote` on light is a
|
|
11
|
+
// usage error, enforced in mark.mjs before we get here).
|
|
12
|
+
// - `--no-promote` → normal/deep skip with a one-line note (status still done).
|
|
13
|
+
// - aborted → never promoted (mark aborted never calls this).
|
|
14
|
+
//
|
|
15
|
+
// This module is the ONE place that writes to `operator/knowledge/`. Session
|
|
16
|
+
// reads fan out through the store (tooling standard §7: reads may scatter,
|
|
17
|
+
// writes may not). `knowledgeDir` is injectable so tests bind a temp dir —
|
|
18
|
+
// same posture as the store's `makeStore(dir)`.
|
|
19
|
+
//
|
|
20
|
+
// Graph shape the promoted doc must satisfy (discovered from
|
|
21
|
+
// @stravica-ai/engineering-pa-core .../knowledge/retrieval/graph-builder.mjs +
|
|
22
|
+
// the `pa knowledge` CLI graph.mjs — NEITHER reads front-matter):
|
|
23
|
+
// - node `title` = the first `# ` heading in the file → we prepend `# <question>`.
|
|
24
|
+
// - node `domain` = path segment under operator/knowledge → `research/` gives it.
|
|
25
|
+
// - edges = `[[wiki]]` + `[md](rel.md)` links + .backlinks.json → we add
|
|
26
|
+
// a provenance footer linking `./README.md` so `related` is non-empty.
|
|
27
|
+
// The rich front-matter block below is honoured by no builder today; it is
|
|
28
|
+
// human/Librarian metadata and forward-compat for a schema-aware builder.
|
|
29
|
+
|
|
30
|
+
import { mkdir, writeFile, readFile } from 'node:fs/promises';
|
|
31
|
+
import { existsSync } from 'node:fs';
|
|
32
|
+
import { join } from 'node:path';
|
|
33
|
+
|
|
34
|
+
import { getRepoRoot } from '../pa/repo-root.mjs';
|
|
35
|
+
|
|
36
|
+
// Where promoted answers land inside the operator repo. Historical shape: when
|
|
37
|
+
// the tool lived at `operator/extensions/tools/research/`, this constant was
|
|
38
|
+
// computed with `fileURLToPath(new URL('../../../../../', import.meta.url))` —
|
|
39
|
+
// a fixed five-`../` walk that only worked at that anchor. Under
|
|
40
|
+
// `@stravica-ai/digital-operator-pa`, the source lives inside `node_modules/`, so the
|
|
41
|
+
// walk lands in the wrong tree. Instead we resolve the operator repo root the
|
|
42
|
+
// same way `pa knowledge` / `pa work` do (env-var override, else walk up for
|
|
43
|
+
// `.git`) and join `operator/knowledge/` under it. Async because getRepoRoot is.
|
|
44
|
+
export const KNOWLEDGE_SUBPATH = 'operator/knowledge';
|
|
45
|
+
export const RESEARCH_DOMAIN = 'research';
|
|
46
|
+
|
|
47
|
+
export async function defaultKnowledgeDir() {
|
|
48
|
+
return join(await getRepoRoot(), KNOWLEDGE_SUBPATH);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ── pure helpers ──────────────────────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
// Kebab-case slug from the question. Deterministic (same question → same slug →
|
|
54
|
+
// same filename → idempotent promotion). Bounded length keeps filenames sane.
|
|
55
|
+
export function slugify(text, maxLen = 60) {
|
|
56
|
+
const slug = String(text ?? '')
|
|
57
|
+
.toLowerCase()
|
|
58
|
+
.normalize('NFKD').replace(/[\u0300-\u036f]/g, '') // strip accents
|
|
59
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
60
|
+
.replace(/^-+|-+$/g, '')
|
|
61
|
+
.slice(0, maxLen)
|
|
62
|
+
.replace(/-+$/g, '');
|
|
63
|
+
return slug || 'session';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// The promoted doc's filename: `<sessionId>-<slug>.md`. sessionId is unique and
|
|
67
|
+
// stable, so the target path is deterministic — the basis for idempotency.
|
|
68
|
+
export function promotedFileName(sessionId, question) {
|
|
69
|
+
return `${sessionId}-${slugify(question)}.md`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Derive counts the frontmatter records. manifest.json is FROZEN and carries
|
|
73
|
+
// none of these — everything is derived from the session's other artifacts
|
|
74
|
+
// (brief §5). A finding is the unit of "claim":
|
|
75
|
+
// refuted — any verification vote refuted it.
|
|
76
|
+
// verified — else, any vote confirmed it.
|
|
77
|
+
// unverified — else (only unverified-infra votes, or none, e.g. light mode).
|
|
78
|
+
// gatedCount counts UNRESOLVED gates (pending/retrying) — the ones still owed a
|
|
79
|
+
// human sweep; resolved/failed are closed out.
|
|
80
|
+
export function deriveCounts({ sources, findings, gates }) {
|
|
81
|
+
const sourceCount = sources?.items?.length ?? 0;
|
|
82
|
+
let verifiedCount = 0;
|
|
83
|
+
let refutedCount = 0;
|
|
84
|
+
let unverifiedCount = 0;
|
|
85
|
+
for (const f of findings ?? []) {
|
|
86
|
+
const outcomes = (f.verificationVotes ?? []).map((v) => v.outcome);
|
|
87
|
+
if (outcomes.includes('refuted')) refutedCount++;
|
|
88
|
+
else if (outcomes.includes('confirmed')) verifiedCount++;
|
|
89
|
+
else unverifiedCount++;
|
|
90
|
+
}
|
|
91
|
+
const gatedCount = (gates?.queue ?? []).filter(
|
|
92
|
+
(g) => g.status === 'pending' || g.status === 'retrying',
|
|
93
|
+
).length;
|
|
94
|
+
return { sourceCount, verifiedCount, refutedCount, unverifiedCount, gatedCount };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// First substantive paragraph of the answer body → doc description. Skips
|
|
98
|
+
// front-matter, headings, blank lines, block markers and horizontal rules;
|
|
99
|
+
// collapses whitespace; truncates. Falls back to the question when the answer
|
|
100
|
+
// has no prose (e.g. a `structured` answer that is one JSON block).
|
|
101
|
+
export function firstParagraph(answer, fallback, maxLen = 240) {
|
|
102
|
+
const body = stripFrontMatter(String(answer ?? ''));
|
|
103
|
+
const para = [];
|
|
104
|
+
let inFence = false;
|
|
105
|
+
for (const raw of body.split(/\r?\n/)) {
|
|
106
|
+
const line = raw.trim();
|
|
107
|
+
if (line.startsWith('```')) {
|
|
108
|
+
// A fence before any prose → skip the whole block; after prose → stop.
|
|
109
|
+
if (para.length) break;
|
|
110
|
+
inFence = !inFence;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (inFence) continue; // skip fenced content entirely
|
|
114
|
+
if (line === '') { if (para.length) break; else continue; }
|
|
115
|
+
if (line.startsWith('#')) { if (para.length) break; else continue; }
|
|
116
|
+
if (line === '---' || line.startsWith('|')) { if (para.length) break; else continue; }
|
|
117
|
+
para.push(line);
|
|
118
|
+
}
|
|
119
|
+
const text = para.join(' ').replace(/\s+/g, ' ').trim();
|
|
120
|
+
const chosen = text || String(fallback ?? '').replace(/\s+/g, ' ').trim();
|
|
121
|
+
return chosen.length > maxLen ? chosen.slice(0, maxLen - 1).trimEnd() + '…' : chosen;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function stripFrontMatter(content) {
|
|
125
|
+
if (!content.startsWith('---')) return content;
|
|
126
|
+
const lines = content.split(/\r?\n/);
|
|
127
|
+
if (lines[0].trim() !== '---') return content;
|
|
128
|
+
for (let i = 1; i < lines.length; i++) {
|
|
129
|
+
if (lines[i].trim() === '---') return lines.slice(i + 1).join('\n');
|
|
130
|
+
}
|
|
131
|
+
return content;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// YAML-ish scalar escaping for the flat `key: value` front-matter we emit.
|
|
135
|
+
// Double-quote and escape when the value could be misread (colons, leading
|
|
136
|
+
// specials, quotes). Numbers pass through bare.
|
|
137
|
+
function yamlScalar(value) {
|
|
138
|
+
if (typeof value === 'number') return String(value);
|
|
139
|
+
const s = String(value ?? '');
|
|
140
|
+
if (s === '') return '""';
|
|
141
|
+
if (/^[A-Za-z0-9][\w .\-/]*$/.test(s) && !/^\d/.test(s)) return s;
|
|
142
|
+
return `"${s.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Assemble the promoted document: front-matter + `# <question>` H1 (so the
|
|
146
|
+
// graph builder titles the node with the question) + the VERBATIM answer body
|
|
147
|
+
// + a provenance footer that links `./README.md` (a real graph edge, so
|
|
148
|
+
// `pa knowledge related` is non-empty). The answer body itself is untouched.
|
|
149
|
+
export function buildDocument({ manifest, counts, slug, date, description, answer }) {
|
|
150
|
+
const fm = [
|
|
151
|
+
'---',
|
|
152
|
+
`name: ${yamlScalar(slug)}`,
|
|
153
|
+
`title: ${yamlScalar(manifest.question)}`,
|
|
154
|
+
`description: ${yamlScalar(description)}`,
|
|
155
|
+
`domain: ${yamlScalar(RESEARCH_DOMAIN)}`,
|
|
156
|
+
`type: ${yamlScalar('research-session')}`,
|
|
157
|
+
`mode: ${yamlScalar(manifest.mode)}`,
|
|
158
|
+
`sessionId: ${yamlScalar(manifest.sessionId)}`,
|
|
159
|
+
`date: ${yamlScalar(date)}`,
|
|
160
|
+
`sourceCount: ${yamlScalar(counts.sourceCount)}`,
|
|
161
|
+
`verifiedCount: ${yamlScalar(counts.verifiedCount)}`,
|
|
162
|
+
`refutedCount: ${yamlScalar(counts.refutedCount)}`,
|
|
163
|
+
`unverifiedCount: ${yamlScalar(counts.unverifiedCount)}`,
|
|
164
|
+
`gatedCount: ${yamlScalar(counts.gatedCount)}`,
|
|
165
|
+
`question: ${yamlScalar(manifest.question)}`,
|
|
166
|
+
'---',
|
|
167
|
+
].join('\n');
|
|
168
|
+
|
|
169
|
+
const footer = `*Promoted from research session \`${manifest.sessionId}\` (\`${manifest.mode}\` mode, ${date}). ` +
|
|
170
|
+
`Part of the [research knowledge library](./README.md).*`;
|
|
171
|
+
|
|
172
|
+
const body = String(answer ?? '').replace(/\s+$/, '');
|
|
173
|
+
return `${fm}\n\n# ${manifest.question}\n\n${body}\n\n---\n\n${footer}\n`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ── the write chokepoint ────────────────────────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
// Promote a session's answer.md into the knowledge library. Reads via the
|
|
179
|
+
// injected `store`; writes exactly one file under `knowledgeDir/research/`.
|
|
180
|
+
//
|
|
181
|
+
// Returns a result object; NEVER throws for expected skips (missing answer,
|
|
182
|
+
// already promoted) so `mark done` still succeeds. `date` defaults to the
|
|
183
|
+
// manifest's updatedAt date (the mark-done timestamp).
|
|
184
|
+
//
|
|
185
|
+
// Callers guarantee: only invoked for status===done, mode in {normal,deep},
|
|
186
|
+
// and not when --no-promote / light (those decisions live in decidePromotion).
|
|
187
|
+
export async function promoteSession(id, { store, knowledgeDir } = {}) {
|
|
188
|
+
// Resolve the write target lazily: if the caller didn't inject one, walk
|
|
189
|
+
// to the operator repo root and land under operator/knowledge/. The same
|
|
190
|
+
// resolver `pa knowledge` uses — `$DAVE_REPO_ROOT` / `$PA_REPO_ROOT` /
|
|
191
|
+
// walk-up-for-`.git`.
|
|
192
|
+
if (!knowledgeDir) knowledgeDir = await defaultKnowledgeDir();
|
|
193
|
+
const manifest = await store.readManifest(id);
|
|
194
|
+
|
|
195
|
+
const answer = await store.readAnswer(id);
|
|
196
|
+
if (answer == null) {
|
|
197
|
+
return { status: 'skipped-no-answer', reason: `session ${id} has no answer.md — nothing to promote` };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const domainDir = join(knowledgeDir, RESEARCH_DOMAIN);
|
|
201
|
+
const fileName = promotedFileName(id, manifest.question);
|
|
202
|
+
const relPath = `operator/knowledge/${RESEARCH_DOMAIN}/${fileName}`;
|
|
203
|
+
const absPath = join(domainDir, fileName);
|
|
204
|
+
|
|
205
|
+
// Idempotency, derived from filesystem state (no manifest field — schema is
|
|
206
|
+
// frozen). Same session → same deterministic filename; if it already exists
|
|
207
|
+
// we do not re-write, so a re-promotion is a no-op.
|
|
208
|
+
if (existsSync(absPath)) {
|
|
209
|
+
return { status: 'already-promoted', path: relPath };
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const sources = await store.readSources(id);
|
|
213
|
+
const gates = await store.readGates(id);
|
|
214
|
+
const findings = await store.listFindings(id);
|
|
215
|
+
const counts = deriveCounts({ sources, findings, gates });
|
|
216
|
+
|
|
217
|
+
const date = (manifest.updatedAt || manifest.createdAt || '').slice(0, 10);
|
|
218
|
+
const slug = slugify(manifest.question);
|
|
219
|
+
const description = firstParagraph(answer, manifest.question);
|
|
220
|
+
const doc = buildDocument({ manifest, counts, slug, date, description, answer });
|
|
221
|
+
|
|
222
|
+
await mkdir(domainDir, { recursive: true });
|
|
223
|
+
await writeFile(absPath, doc, 'utf8');
|
|
224
|
+
|
|
225
|
+
return { status: 'promoted', path: relPath, counts };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// ── promotion decision (pure) ───────────────────────────────────────────────────
|
|
229
|
+
|
|
230
|
+
// Decide what to do given the terminal transition + flags. Kept pure so the
|
|
231
|
+
// mark command is thin glue and the rules are unit-testable in isolation.
|
|
232
|
+
// light + promote → throw usage error (exit 1): light is NEVER promoted.
|
|
233
|
+
// light → skip-silent (the point of light is quiet lookups).
|
|
234
|
+
// normal/deep + noPromote → skip-note (log one line, still success).
|
|
235
|
+
// normal/deep → promote.
|
|
236
|
+
// status !== done → skip-silent (aborted et al. never promote).
|
|
237
|
+
export function decidePromotion({ mode, status, noPromote = false, promote = false }) {
|
|
238
|
+
if (mode === 'light') {
|
|
239
|
+
if (promote) {
|
|
240
|
+
throw Object.assign(
|
|
241
|
+
new Error('light-mode sessions are never promoted to the knowledge library (operator directive); --promote is not allowed on light mode'),
|
|
242
|
+
{ exitCode: 1 },
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
return { action: 'skip-silent' };
|
|
246
|
+
}
|
|
247
|
+
if (status !== 'done') return { action: 'skip-silent' };
|
|
248
|
+
if (noPromote) return { action: 'skip-note' };
|
|
249
|
+
return { action: 'promote' };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// The one-line hint printed after a successful promotion. The knowledge graph
|
|
253
|
+
// is rebuilt by a 6-hourly reindex job (see the `Knowledge reindex` cron); it
|
|
254
|
+
// re-reads every doc in operator/knowledge/, so we do NOT shell into the
|
|
255
|
+
// version-pinned builder from here (brief §5: global side effects → hint, don't
|
|
256
|
+
// auto-run). There is no stable `pa knowledge rebuild` verb to call.
|
|
257
|
+
export function refreshHint(relPath) {
|
|
258
|
+
return `promoted to ${relPath} — rebuild the knowledge graph (knowledge-reindex cron, ` +
|
|
259
|
+
`or run the graph/index builders) so \`pa knowledge search\`/\`related\` surface it`;
|
|
260
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "ai.stravica.knowledge.research/finding.schema.json",
|
|
4
|
+
"title": "Research finding",
|
|
5
|
+
"description": "One finding per sub-question, written by workers at sessions/<sessionId>/findings/sq-<id>.json. We read/validate them, workers write them. Validator: src/store/findings.mjs.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["subQuestionId", "summary", "quotes", "sources", "confidence", "verificationVotes", "unsourced"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"subQuestionId": { "type": "string", "minLength": 1 },
|
|
11
|
+
"summary": { "type": "string", "description": "Synthesised answer to the sub-question." },
|
|
12
|
+
"quotes": {
|
|
13
|
+
"type": "array",
|
|
14
|
+
"description": "Direct supporting quotes, each tied to a source ref (build-spec §5 quote-grounded extraction).",
|
|
15
|
+
"items": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"required": ["text", "sourceId"],
|
|
19
|
+
"properties": {
|
|
20
|
+
"text": { "type": "string", "minLength": 1 },
|
|
21
|
+
"sourceId": { "type": "string", "minLength": 1, "description": "References sources.json items[].id." },
|
|
22
|
+
"importance": { "type": "string", "enum": ["central", "supporting", "incidental"] }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"sources": {
|
|
27
|
+
"type": "array",
|
|
28
|
+
"items": { "type": "string" },
|
|
29
|
+
"description": "Source ids (sources.json items[].id) this finding draws on."
|
|
30
|
+
},
|
|
31
|
+
"confidence": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"enum": ["low", "medium", "high"],
|
|
34
|
+
"description": "Bucketed confidence. Buckets chosen over a 0..1 float — LLM self-scored floats are false precision."
|
|
35
|
+
},
|
|
36
|
+
"verificationVotes": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"description": "Verify outcomes (build-spec §4/§5). Empty in light mode. Three outcomes per vote.",
|
|
39
|
+
"items": {
|
|
40
|
+
"type": "object",
|
|
41
|
+
"additionalProperties": false,
|
|
42
|
+
"required": ["outcome"],
|
|
43
|
+
"properties": {
|
|
44
|
+
"outcome": { "type": "string", "enum": ["confirmed", "refuted", "unverified-infra"] },
|
|
45
|
+
"lens": { "type": "string", "description": "Verifier lens (deep diverse-lens: quote-support | contradiction-search | recency-source-fit)." },
|
|
46
|
+
"note": { "type": "string" }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"unsourced": {
|
|
51
|
+
"type": "boolean",
|
|
52
|
+
"description": "True if the finding carries claims without a supporting quote (build-spec §8 unsourced-claim counter)."
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "ai.stravica.knowledge.research/gates.schema.json",
|
|
4
|
+
"title": "Research human-gate queue",
|
|
5
|
+
"description": "gates.json at sessions/<sessionId>/gates.json — the retry queue for human-gated fetches (build-spec §6). Merges brief §3 status-tracking fields with spec §6 descriptive fields. Validator: src/store/gates.mjs.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["queue"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"queue": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"items": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"required": ["id", "url", "gateType", "whatIsNeeded", "status", "blockedAt"],
|
|
16
|
+
"properties": {
|
|
17
|
+
"id": { "type": "string", "minLength": 1, "description": "Gate record id (unique within the session)." },
|
|
18
|
+
"url": { "type": "string", "minLength": 1, "description": "The gated URL." },
|
|
19
|
+
"gateType": { "type": "string", "description": "e.g. cloudflare, captcha, auth, paywall." },
|
|
20
|
+
"subQuestionId": { "type": "string", "description": "Which sub-question was blocked, if known." },
|
|
21
|
+
"whatIsNeeded": { "type": "string", "description": "Human-readable what-is-needed-to-clear (spec §6). Also the brief's `reason`." },
|
|
22
|
+
"status": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"enum": ["pending", "retrying", "resolved", "failed"],
|
|
25
|
+
"description": "pending → retrying (marked eligible by `gates --retry`) → resolved/failed."
|
|
26
|
+
},
|
|
27
|
+
"blockedAt": { "type": "string", "description": "ISO 8601 UTC when the gate was hit (spec's loggedAt)." },
|
|
28
|
+
"resolution": { "type": "string", "description": "Note or outcome once resolved/failed." },
|
|
29
|
+
"artifactPath": { "type": "string", "description": "Path to the saved page content (sessions/<id>/gated/<hash>.md, spec §6.4)." }
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "ai.stravica.knowledge.research/manifest.schema.json",
|
|
4
|
+
"title": "Research session manifest",
|
|
5
|
+
"description": "Root manifest.json for a research session, at sessions/<sessionId>/manifest.json. Hand-rolled validator: src/store/manifest.mjs. camelCase throughout.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"sessionId",
|
|
10
|
+
"mode",
|
|
11
|
+
"question",
|
|
12
|
+
"gatePolicy",
|
|
13
|
+
"status",
|
|
14
|
+
"outputMode",
|
|
15
|
+
"budget",
|
|
16
|
+
"assumptions",
|
|
17
|
+
"createdAt",
|
|
18
|
+
"updatedAt"
|
|
19
|
+
],
|
|
20
|
+
"properties": {
|
|
21
|
+
"sessionId": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "ULID-like 26-char Crockford base32 id: 10-char ms timestamp + 16-char entropy. Lexicographically sortable by creation time.",
|
|
24
|
+
"pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
|
|
25
|
+
},
|
|
26
|
+
"mode": { "type": "string", "enum": ["light", "normal", "deep"] },
|
|
27
|
+
"question": { "type": "string", "minLength": 1, "description": "Raw operator question." },
|
|
28
|
+
"intent": { "type": "string", "description": "Clarified intent, if the caller passed one." },
|
|
29
|
+
"gatePolicy": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"enum": ["operatorPresent", "background", "worker"],
|
|
32
|
+
"description": "Human-gate execution posture (build-spec §6)."
|
|
33
|
+
},
|
|
34
|
+
"status": { "type": "string", "enum": ["draft", "in-progress", "done", "aborted"] },
|
|
35
|
+
"outputMode": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"enum": ["shortAnswer", "article", "structured"],
|
|
38
|
+
"description": "Synthesis render target. Defaults to shortAnswer."
|
|
39
|
+
},
|
|
40
|
+
"budget": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"description": "Records what the run was scoped to. Not enforced by the CLI.",
|
|
43
|
+
"additionalProperties": false,
|
|
44
|
+
"required": ["maxSubQuestions", "maxDeepeningRounds", "wallClockMinutes"],
|
|
45
|
+
"properties": {
|
|
46
|
+
"maxSubQuestions": { "type": "integer", "minimum": 0 },
|
|
47
|
+
"maxDeepeningRounds": { "type": "integer", "minimum": 0 },
|
|
48
|
+
"wallClockMinutes": { "type": "integer", "minimum": 0 }
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"assumptions": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"items": { "type": "string" },
|
|
54
|
+
"description": "Scope-narrowing assumptions recorded when a background run cannot clarify (build-spec §4)."
|
|
55
|
+
},
|
|
56
|
+
"createdAt": { "type": "string", "description": "ISO 8601 UTC." },
|
|
57
|
+
"updatedAt": { "type": "string", "description": "ISO 8601 UTC." }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "ai.stravica.knowledge.research/plan.schema.json",
|
|
4
|
+
"title": "Research plan",
|
|
5
|
+
"description": "plan.json at sessions/<sessionId>/plan.json. `run` writes a skeleton (empty subQuestions, mode-derived rounds/tier); the workflow (w-017) fills subQuestions. Validator: src/store/plan.mjs.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["subQuestions", "deepeningRounds", "verificationTier"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"subQuestions": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"description": "Dependency-classified decomposition (build-spec §4). Empty until the planner fills it.",
|
|
13
|
+
"items": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"additionalProperties": false,
|
|
16
|
+
"required": ["id", "text", "kind", "dependsOn"],
|
|
17
|
+
"properties": {
|
|
18
|
+
"id": { "type": "string", "minLength": 1 },
|
|
19
|
+
"text": { "type": "string", "minLength": 1 },
|
|
20
|
+
"kind": { "type": "string", "enum": ["independent", "dependent"] },
|
|
21
|
+
"dependsOn": {
|
|
22
|
+
"type": "array",
|
|
23
|
+
"items": { "type": "string" },
|
|
24
|
+
"description": "Sub-question ids this one depends on. Empty for independent facets."
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"deepeningRounds": {
|
|
30
|
+
"type": "integer",
|
|
31
|
+
"minimum": 0,
|
|
32
|
+
"maximum": 3,
|
|
33
|
+
"description": "0 for light, 1 for normal, up to 3 for deep."
|
|
34
|
+
},
|
|
35
|
+
"verificationTier": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"enum": ["none", "central-3vote", "diverse-lens-3vote"],
|
|
38
|
+
"description": "none (light), central-3vote (normal), diverse-lens-3vote (deep)."
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "ai.stravica.knowledge.research/sources.schema.json",
|
|
4
|
+
"title": "Research sources",
|
|
5
|
+
"description": "Aggregated source registry at sessions/<sessionId>/sources.json. One entry per fetched source; finding.sources[] and quote.sourceId reference items[].id. Validator: src/store/sources.mjs.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["items"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"items": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"items": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"required": ["id", "kind"],
|
|
16
|
+
"properties": {
|
|
17
|
+
"id": { "type": "string", "minLength": 1, "description": "Stable id referenced by findings." },
|
|
18
|
+
"kind": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"enum": ["web", "playwright", "kb", "codebase", "prior-session"],
|
|
21
|
+
"description": "Source capability (build-spec §2/§3)."
|
|
22
|
+
},
|
|
23
|
+
"url": { "type": "string" },
|
|
24
|
+
"title": { "type": "string" },
|
|
25
|
+
"fetchedAt": { "type": "string", "description": "ISO 8601 UTC." },
|
|
26
|
+
"checksum": { "type": "string", "description": "Optional content hash for dedup/change-detection." }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// finding.json schema + validator (build-spec §5). Zero-dep, hand-rolled.
|
|
2
|
+
// Workers write findings/sq-<id>.json; we read + validate them. We never write findings.
|
|
3
|
+
// Schema doc: src/schema/finding.schema.json.
|
|
4
|
+
import {
|
|
5
|
+
parseJson, requireObject, requireFields, noExtraFields,
|
|
6
|
+
requireString, optionalString, requireEnum, optionalEnum, requireArray, requireBoolean, fail,
|
|
7
|
+
} from './validate.mjs';
|
|
8
|
+
|
|
9
|
+
export const CONFIDENCE = ['low', 'medium', 'high'];
|
|
10
|
+
export const IMPORTANCE = ['central', 'supporting', 'incidental'];
|
|
11
|
+
export const VOTE_OUTCOMES = ['confirmed', 'refuted', 'unverified-infra'];
|
|
12
|
+
|
|
13
|
+
const TOP = ['subQuestionId', 'summary', 'quotes', 'sources', 'confidence', 'verificationVotes', 'unsourced'];
|
|
14
|
+
const QUOTE_FIELDS = ['text', 'sourceId', 'importance'];
|
|
15
|
+
const QUOTE_REQUIRED = ['text', 'sourceId'];
|
|
16
|
+
const VOTE_FIELDS = ['outcome', 'lens', 'note'];
|
|
17
|
+
|
|
18
|
+
export function loadFinding(text, where = 'finding') {
|
|
19
|
+
return validateFinding(parseJson(text, where), where);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function validateFinding(f, where = 'finding') {
|
|
23
|
+
requireObject(f, where);
|
|
24
|
+
requireFields(f, TOP, where);
|
|
25
|
+
noExtraFields(f, TOP, where);
|
|
26
|
+
|
|
27
|
+
requireString(f, 'subQuestionId', where);
|
|
28
|
+
requireString(f, 'summary', where, { nonEmpty: false });
|
|
29
|
+
|
|
30
|
+
const quotes = requireArray(f, 'quotes', where);
|
|
31
|
+
quotes.forEach((q, i) => {
|
|
32
|
+
const w = `${where}.quotes[${i}]`;
|
|
33
|
+
requireObject(q, w);
|
|
34
|
+
requireFields(q, QUOTE_REQUIRED, w);
|
|
35
|
+
noExtraFields(q, QUOTE_FIELDS, w);
|
|
36
|
+
requireString(q, 'text', w);
|
|
37
|
+
requireString(q, 'sourceId', w);
|
|
38
|
+
optionalEnum(q, 'importance', IMPORTANCE, w);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const sources = requireArray(f, 'sources', where);
|
|
42
|
+
sources.forEach((s, i) => {
|
|
43
|
+
if (typeof s !== 'string') fail(`sources[${i}] must be a string (source id)`, where);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
requireEnum(f, 'confidence', CONFIDENCE, where);
|
|
47
|
+
|
|
48
|
+
const votes = requireArray(f, 'verificationVotes', where);
|
|
49
|
+
votes.forEach((v, i) => {
|
|
50
|
+
const w = `${where}.verificationVotes[${i}]`;
|
|
51
|
+
requireObject(v, w);
|
|
52
|
+
requireFields(v, ['outcome'], w);
|
|
53
|
+
noExtraFields(v, VOTE_FIELDS, w);
|
|
54
|
+
requireEnum(v, 'outcome', VOTE_OUTCOMES, w);
|
|
55
|
+
optionalString(v, 'lens', w);
|
|
56
|
+
optionalString(v, 'note', w);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
requireBoolean(f, 'unsourced', where);
|
|
60
|
+
return f;
|
|
61
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// gates.json schema + validator + pure queue transforms (build-spec §6). Zero-dep.
|
|
2
|
+
// Schema doc: src/schema/gates.schema.json.
|
|
3
|
+
//
|
|
4
|
+
// Disk persistence for gates lives in store/index.mjs (the write chokepoint).
|
|
5
|
+
// This module owns the schema, validation, and PURE transforms only — nothing
|
|
6
|
+
// here touches the filesystem, so `gates --retry` composes read (index) →
|
|
7
|
+
// transform (here) → write (index).
|
|
8
|
+
import {
|
|
9
|
+
parseJson, requireObject, requireFields, noExtraFields,
|
|
10
|
+
requireString, optionalString, requireEnum, requireArray, fail,
|
|
11
|
+
} from './validate.mjs';
|
|
12
|
+
|
|
13
|
+
export const GATE_STATUSES = ['pending', 'retrying', 'resolved', 'failed'];
|
|
14
|
+
|
|
15
|
+
const TOP = ['queue'];
|
|
16
|
+
const ITEM_FIELDS = ['id', 'url', 'gateType', 'subQuestionId', 'whatIsNeeded', 'status', 'blockedAt', 'resolution', 'artifactPath'];
|
|
17
|
+
const ITEM_REQUIRED = ['id', 'url', 'gateType', 'whatIsNeeded', 'status', 'blockedAt'];
|
|
18
|
+
|
|
19
|
+
export function emptyGates() {
|
|
20
|
+
return { queue: [] };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function loadGates(text, where = 'gates') {
|
|
24
|
+
return validateGates(parseJson(text, where), where);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function validateGates(g, where = 'gates') {
|
|
28
|
+
requireObject(g, where);
|
|
29
|
+
requireFields(g, TOP, where);
|
|
30
|
+
noExtraFields(g, TOP, where);
|
|
31
|
+
|
|
32
|
+
const queue = requireArray(g, 'queue', where);
|
|
33
|
+
const seen = new Set();
|
|
34
|
+
queue.forEach((it, i) => {
|
|
35
|
+
const w = `${where}.queue[${i}]`;
|
|
36
|
+
requireObject(it, w);
|
|
37
|
+
requireFields(it, ITEM_REQUIRED, w);
|
|
38
|
+
noExtraFields(it, ITEM_FIELDS, w);
|
|
39
|
+
const id = requireString(it, 'id', w);
|
|
40
|
+
if (seen.has(id)) fail(`duplicate gate id "${id}"`, w);
|
|
41
|
+
seen.add(id);
|
|
42
|
+
requireString(it, 'url', w);
|
|
43
|
+
requireString(it, 'gateType', w);
|
|
44
|
+
optionalString(it, 'subQuestionId', w);
|
|
45
|
+
requireString(it, 'whatIsNeeded', w);
|
|
46
|
+
requireEnum(it, 'status', GATE_STATUSES, w);
|
|
47
|
+
requireString(it, 'blockedAt', w);
|
|
48
|
+
optionalString(it, 'resolution', w);
|
|
49
|
+
optionalString(it, 'artifactPath', w);
|
|
50
|
+
});
|
|
51
|
+
return g;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// A gate item is eligible for retry when it is still pending or already retrying
|
|
55
|
+
// (idempotent re-mark). Resolved/failed items are terminal and left untouched.
|
|
56
|
+
export function isRetryEligible(item) {
|
|
57
|
+
return item.status === 'pending' || item.status === 'retrying';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// PURE: return a new gates object with all eligible items marked `retrying`,
|
|
61
|
+
// plus the list of items that were (re)marked. Does not mutate the input.
|
|
62
|
+
export function markEligibleForRetry(gates) {
|
|
63
|
+
const marked = [];
|
|
64
|
+
const queue = gates.queue.map((it) => {
|
|
65
|
+
if (isRetryEligible(it)) {
|
|
66
|
+
const next = { ...it, status: 'retrying' };
|
|
67
|
+
marked.push(next);
|
|
68
|
+
return next;
|
|
69
|
+
}
|
|
70
|
+
return it;
|
|
71
|
+
});
|
|
72
|
+
return { gates: { ...gates, queue }, marked };
|
|
73
|
+
}
|