@lsctech/polaris 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/README.md +87 -0
- package/dist/__mocks__/tool-server-linear.js +34 -0
- package/dist/cli/adopt-approve.js +60 -0
- package/dist/cli/adopt-cognition.js +199 -0
- package/dist/cli/adopt-instructions.js +143 -0
- package/dist/cli/adopt-rules.js +169 -0
- package/dist/cli/adopt-scan.js +25 -0
- package/dist/cli/adopt-smartdocs.js +192 -0
- package/dist/cli/adoption-inventory.js +350 -0
- package/dist/cli/adoption-plan.js +222 -0
- package/dist/cli/args.js +28 -0
- package/dist/cli/args.test.js +30 -0
- package/dist/cli/branding.js +41 -0
- package/dist/cli/graph.js +358 -0
- package/dist/cli/index.js +127 -0
- package/dist/cli/index.test.js +162 -0
- package/dist/cli/init-detect.js +61 -0
- package/dist/cli/init.js +492 -0
- package/dist/cli/init.test.js +259 -0
- package/dist/cli/librarian.js +32 -0
- package/dist/cli/medic.js +96 -0
- package/dist/cli/startup.test.js +23 -0
- package/dist/cli/tracker.js +130 -0
- package/dist/cli/tracker.test.js +126 -0
- package/dist/cli/version.js +10 -0
- package/dist/cli/version.test.js +11 -0
- package/dist/cli/worker.js +287 -0
- package/dist/cluster-state/fixtures/test-clusters.json +19 -0
- package/dist/cluster-state/store.js +302 -0
- package/dist/cluster-state/store.test.js +145 -0
- package/dist/cluster-state/types.js +2 -0
- package/dist/cognition/archive.js +158 -0
- package/dist/cognition/closeout-librarian-types.js +161 -0
- package/dist/cognition/cognition.test.js +623 -0
- package/dist/cognition/index.js +41 -0
- package/dist/cognition/librarian-dispatch.js +391 -0
- package/dist/cognition/librarian-dispatch.test.js +247 -0
- package/dist/cognition/librarian-packet.js +313 -0
- package/dist/cognition/librarian-types.js +57 -0
- package/dist/cognition/route-cognition-delta.js +350 -0
- package/dist/cognition/summary-delta.js +279 -0
- package/dist/cognition/validate.js +162 -0
- package/dist/config/defaults.js +98 -0
- package/dist/config/doctor.js +273 -0
- package/dist/config/index.js +14 -0
- package/dist/config/loader.js +58 -0
- package/dist/config/provider-detect.js +60 -0
- package/dist/config/provider-detect.test.js +119 -0
- package/dist/config/schema.js +2 -0
- package/dist/config/show.js +44 -0
- package/dist/config/show.test.js +42 -0
- package/dist/config/validator.js +675 -0
- package/dist/config/validator.test.js +77 -0
- package/dist/docs/canon-check.js +334 -0
- package/dist/docs/canon-check.test.js +207 -0
- package/dist/docs/doctrine.js +133 -0
- package/dist/docs/doctrine.test.js +139 -0
- package/dist/docs/index.js +168 -0
- package/dist/docs/index.test.js +83 -0
- package/dist/docs/ingest.js +295 -0
- package/dist/docs/ingest.test.js +71 -0
- package/dist/docs/migrate.js +165 -0
- package/dist/docs/migrate.test.js +136 -0
- package/dist/docs/seed-instructions.js +147 -0
- package/dist/docs/seed-instructions.test.js +137 -0
- package/dist/docs/validate-instructions.js +267 -0
- package/dist/docs/validate-instructions.test.js +238 -0
- package/dist/finalize/artifact-policy.js +214 -0
- package/dist/finalize/artifact-policy.test.js +84 -0
- package/dist/finalize/delivery-integrity.js +141 -0
- package/dist/finalize/finalize.test.js +210 -0
- package/dist/finalize/github.js +41 -0
- package/dist/finalize/index.js +474 -0
- package/dist/finalize/linear.js +213 -0
- package/dist/finalize/run-report.js +47 -0
- package/dist/finalize/steps/01-map-update.js +11 -0
- package/dist/finalize/steps/02-map-validate.js +11 -0
- package/dist/finalize/steps/03-schema-validate.js +11 -0
- package/dist/finalize/steps/04-run-checks.js +118 -0
- package/dist/finalize/steps/05-generate-report.js +14 -0
- package/dist/finalize/steps/06-commit.js +39 -0
- package/dist/finalize/steps/07-push.js +10 -0
- package/dist/finalize/steps/08-create-pr.js +9 -0
- package/dist/finalize/steps/09-update-state.js +9 -0
- package/dist/finalize/steps/10-append-jsonl.js +23 -0
- package/dist/finalize/steps/11-update-linear.js +22 -0
- package/dist/finalize/steps/12-archive.js +21 -0
- package/dist/graph/adapter/c/adapter.js +45 -0
- package/dist/graph/adapter/c/extract.js +135 -0
- package/dist/graph/adapter/c/index.js +10 -0
- package/dist/graph/adapter/c/runtime.js +67 -0
- package/dist/graph/adapter/cpp/adapter.js +45 -0
- package/dist/graph/adapter/cpp/extract.js +159 -0
- package/dist/graph/adapter/cpp/index.js +10 -0
- package/dist/graph/adapter/cpp/runtime.js +61 -0
- package/dist/graph/adapter/csharp/adapter.js +45 -0
- package/dist/graph/adapter/csharp/extract.js +127 -0
- package/dist/graph/adapter/csharp/index.js +10 -0
- package/dist/graph/adapter/csharp/runtime.js +61 -0
- package/dist/graph/adapter/dart/adapter.js +56 -0
- package/dist/graph/adapter/dart/extract.js +130 -0
- package/dist/graph/adapter/dart/index.js +10 -0
- package/dist/graph/adapter/dart/runtime.js +61 -0
- package/dist/graph/adapter/go/adapter.js +45 -0
- package/dist/graph/adapter/go/extract.js +112 -0
- package/dist/graph/adapter/go/index.js +10 -0
- package/dist/graph/adapter/go/runtime.js +58 -0
- package/dist/graph/adapter/kotlin-java/extract-common.js +83 -0
- package/dist/graph/adapter/kotlin-java/index.js +15 -0
- package/dist/graph/adapter/kotlin-java/java-adapter.js +45 -0
- package/dist/graph/adapter/kotlin-java/java-extract.js +42 -0
- package/dist/graph/adapter/kotlin-java/kotlin-adapter.js +48 -0
- package/dist/graph/adapter/kotlin-java/kotlin-extract.js +58 -0
- package/dist/graph/adapter/kotlin-java/runtime.js +75 -0
- package/dist/graph/adapter/python/adapter.js +45 -0
- package/dist/graph/adapter/python/extract.js +121 -0
- package/dist/graph/adapter/python/index.js +10 -0
- package/dist/graph/adapter/python/runtime.js +70 -0
- package/dist/graph/adapter/registry.js +82 -0
- package/dist/graph/adapter/rust/adapter.js +45 -0
- package/dist/graph/adapter/rust/extract.js +110 -0
- package/dist/graph/adapter/rust/index.js +10 -0
- package/dist/graph/adapter/rust/runtime.js +74 -0
- package/dist/graph/adapter/shell/adapter.js +34 -0
- package/dist/graph/adapter/shell/extract.js +98 -0
- package/dist/graph/adapter/shell/index.js +8 -0
- package/dist/graph/adapter/svelte/adapter.js +91 -0
- package/dist/graph/adapter/svelte/extract.js +41 -0
- package/dist/graph/adapter/svelte/index.js +8 -0
- package/dist/graph/adapter/swift/adapter.js +45 -0
- package/dist/graph/adapter/swift/extract.js +120 -0
- package/dist/graph/adapter/swift/index.js +10 -0
- package/dist/graph/adapter/swift/runtime.js +70 -0
- package/dist/graph/adapter/types.js +2 -0
- package/dist/graph/adapter/typescript-javascript/adapter.js +72 -0
- package/dist/graph/adapter/typescript-javascript/extract.js +115 -0
- package/dist/graph/adapter/typescript-javascript/index.js +10 -0
- package/dist/graph/adapter/typescript-javascript/runtime.js +97 -0
- package/dist/graph/capability/index.js +105 -0
- package/dist/graph/governance.js +104 -0
- package/dist/graph/parser/extract.js +5 -0
- package/dist/graph/parser/loader.js +2 -0
- package/dist/graph/parser/pipeline.js +194 -0
- package/dist/graph/query/index.js +277 -0
- package/dist/graph/query/types.js +5 -0
- package/dist/graph/resolver/build-edges.js +211 -0
- package/dist/graph/resolver/index.js +23 -0
- package/dist/graph/resolver/resolve-imports.js +168 -0
- package/dist/graph/store/adapter.js +132 -0
- package/dist/graph/store/queries.js +124 -0
- package/dist/graph/store/types.js +4 -0
- package/dist/ignore/defaults.js +41 -0
- package/dist/ignore/parser.js +39 -0
- package/dist/lint/map-reference-validator.js +72 -0
- package/dist/loop/abort.js +188 -0
- package/dist/loop/abort.test.js +151 -0
- package/dist/loop/adapters/__tests__/terminal-cli.test.js +92 -0
- package/dist/loop/adapters/agent-subtask.js +137 -0
- package/dist/loop/adapters/agent-subtask.test.js +151 -0
- package/dist/loop/adapters/cli-subtask-bridge.js +108 -0
- package/dist/loop/adapters/index.js +9 -0
- package/dist/loop/adapters/registry.js +17 -0
- package/dist/loop/adapters/terminal-cli.js +403 -0
- package/dist/loop/adapters/types.js +2 -0
- package/dist/loop/adapters/worker-instructions.js +85 -0
- package/dist/loop/body-parser.js +226 -0
- package/dist/loop/bootstrap-packet.js +97 -0
- package/dist/loop/bootstrap-packet.test.js +171 -0
- package/dist/loop/branch-governance.js +54 -0
- package/dist/loop/budget.js +63 -0
- package/dist/loop/budget.test.js +163 -0
- package/dist/loop/checkpoint.js +325 -0
- package/dist/loop/compact-return.js +59 -0
- package/dist/loop/continue.js +645 -0
- package/dist/loop/continue.test.js +337 -0
- package/dist/loop/dispatch-boundary.js +335 -0
- package/dist/loop/dispatch-state.js +223 -0
- package/dist/loop/dispatch-state.test.js +186 -0
- package/dist/loop/dispatch.js +1236 -0
- package/dist/loop/dispatch.test.js +499 -0
- package/dist/loop/ephemeral-smoke.test.js +160 -0
- package/dist/loop/evidence-backfill.js +216 -0
- package/dist/loop/execution-adapter.js +141 -0
- package/dist/loop/execution-adapter.test.js +66 -0
- package/dist/loop/finalize-evidence.js +169 -0
- package/dist/loop/git-custody.js +250 -0
- package/dist/loop/impl-packet-input.js +38 -0
- package/dist/loop/index.js +270 -0
- package/dist/loop/ledger.js +49 -0
- package/dist/loop/ledger.test.js +127 -0
- package/dist/loop/lifecycle-dispatch.js +348 -0
- package/dist/loop/lifecycle-dispatch.test.js +318 -0
- package/dist/loop/lifecycle.js +93 -0
- package/dist/loop/lifecycle.test.js +150 -0
- package/dist/loop/orphan-recovery.js +276 -0
- package/dist/loop/orphan-recovery.test.js +236 -0
- package/dist/loop/parent.js +1566 -0
- package/dist/loop/parent.test.js +738 -0
- package/dist/loop/provider-sealed-packet.test.js +164 -0
- package/dist/loop/resume.js +295 -0
- package/dist/loop/resume.test.js +172 -0
- package/dist/loop/run-bootstrap.js +234 -0
- package/dist/loop/run-preflight.js +203 -0
- package/dist/loop/status.js +665 -0
- package/dist/loop/status.test.js +235 -0
- package/dist/loop/wait.js +86 -0
- package/dist/loop/worker-packet.js +406 -0
- package/dist/loop/worker-packet.test.js +243 -0
- package/dist/loop/worker-prompt.js +260 -0
- package/dist/loop/worker-prompt.test.js +247 -0
- package/dist/loop/worker.js +498 -0
- package/dist/loop/worker.test.js +372 -0
- package/dist/map/atlas.js +77 -0
- package/dist/map/backfill.js +171 -0
- package/dist/map/backfill.test.js +120 -0
- package/dist/map/index.js +255 -0
- package/dist/map/inference.js +73 -0
- package/dist/map/inference.test.js +35 -0
- package/dist/map/query.js +157 -0
- package/dist/map/query.test.js +174 -0
- package/dist/map/update.js +355 -0
- package/dist/map/update.test.js +67 -0
- package/dist/map/validate.js +153 -0
- package/dist/map/validate.test.js +90 -0
- package/dist/map/welfare.js +86 -0
- package/dist/mcp/lib/invoke.js +35 -0
- package/dist/mcp/lib/redact.js +24 -0
- package/dist/mcp/lib/redact.test.js +112 -0
- package/dist/mcp/lib/root.js +41 -0
- package/dist/mcp/lib/root.test.js +114 -0
- package/dist/mcp/server.js +15 -0
- package/dist/mcp/tools/claim-child.js +119 -0
- package/dist/mcp/tools/claim-child.test.js +69 -0
- package/dist/mcp/tools/current-state.js +73 -0
- package/dist/mcp/tools/current-state.test.js +114 -0
- package/dist/mcp/tools/dispatch-result.js +186 -0
- package/dist/mcp/tools/dispatch-result.test.js +109 -0
- package/dist/mcp/tools/index.js +222 -0
- package/dist/mcp/tools/index.test.js +172 -0
- package/dist/mcp/tools/linear.js +74 -0
- package/dist/mcp/tools/loop-continue.js +159 -0
- package/dist/mcp/tools/loop-continue.test.js +186 -0
- package/dist/mcp/tools/loop-dry-run.js +15 -0
- package/dist/mcp/tools/status.js +65 -0
- package/dist/medic/chart-id.js +75 -0
- package/dist/medic/chart-schema.js +139 -0
- package/dist/runs/index.js +119 -0
- package/dist/runs/index.test.js +184 -0
- package/dist/runs/ledger-tail.js +15 -0
- package/dist/runs/list.js +29 -0
- package/dist/runs/reconcile.js +74 -0
- package/dist/runs/show.js +10 -0
- package/dist/runtime/audit/logger.js +15 -0
- package/dist/runtime/audit/reader.js +42 -0
- package/dist/runtime/checkpoint.js +89 -0
- package/dist/runtime/continuation/confirmed.js +225 -0
- package/dist/runtime/continuation/confirmed.test.js +421 -0
- package/dist/runtime/continuation/dry-run.js +74 -0
- package/dist/runtime/execution-window.js +106 -0
- package/dist/runtime/scheduling/child-selector.js +16 -0
- package/dist/runtime/state.js +43 -0
- package/dist/runtime/status.js +46 -0
- package/dist/runtime/verification/envelope.js +80 -0
- package/dist/runtime/verification/fingerprint.js +26 -0
- package/dist/skill-packet/cli.test.js +105 -0
- package/dist/skill-packet/generator.js +225 -0
- package/dist/skill-packet/generator.test.js +159 -0
- package/dist/skill-packet/index.js +49 -0
- package/dist/skill-packet/types.js +2 -0
- package/dist/smartdocs-engine/audit.js +194 -0
- package/dist/smartdocs-engine/audit.test.js +122 -0
- package/dist/smartdocs-engine/canon-check.js +340 -0
- package/dist/smartdocs-engine/canon-check.test.js +234 -0
- package/dist/smartdocs-engine/doctrine.js +633 -0
- package/dist/smartdocs-engine/doctrine.test.js +374 -0
- package/dist/smartdocs-engine/index.js +456 -0
- package/dist/smartdocs-engine/index.test.js +82 -0
- package/dist/smartdocs-engine/ingest.js +495 -0
- package/dist/smartdocs-engine/ingest.test.js +163 -0
- package/dist/smartdocs-engine/migrate.js +217 -0
- package/dist/smartdocs-engine/migrate.test.js +200 -0
- package/dist/smartdocs-engine/seed-instructions.js +335 -0
- package/dist/smartdocs-engine/seed-instructions.test.js +275 -0
- package/dist/smartdocs-engine/smartdoc-ignore.js +258 -0
- package/dist/smartdocs-engine/smartdoc-ignore.test.js +146 -0
- package/dist/smartdocs-engine/validate-instructions.js +366 -0
- package/dist/smartdocs-engine/validate-instructions.test.js +283 -0
- package/dist/tracker/adapters/github/index.js +305 -0
- package/dist/tracker/adapters/jira/index.js +293 -0
- package/dist/tracker/adapters/linear/http-errors.test.js +51 -0
- package/dist/tracker/adapters/linear/index.js +621 -0
- package/dist/tracker/adapters/linear/index.test.js +238 -0
- package/dist/tracker/adapters/linear.js +50 -0
- package/dist/tracker/adapters/local/index.js +10 -0
- package/dist/tracker/adapters/local-file/index.js +159 -0
- package/dist/tracker/adapters/mcp-bridge.js +158 -0
- package/dist/tracker/adapters/mcp-bridge.test.js +12 -0
- package/dist/tracker/adapters/spec/index.js +146 -0
- package/dist/tracker/capabilities.js +2 -0
- package/dist/tracker/index.js +49 -0
- package/dist/tracker/lifecycle-policy.js +139 -0
- package/dist/tracker/lifecycle-transition.js +164 -0
- package/dist/tracker/local-graph.js +98 -0
- package/dist/tracker/migration.js +56 -0
- package/dist/tracker/schema.js +86 -0
- package/dist/tracker/sync/index.js +404 -0
- package/dist/tracker/sync/queue-store.js +95 -0
- package/dist/tracker/sync/queue-store.test.js +104 -0
- package/dist/tracker/types.js +11 -0
- package/dist/types/linear.js +3 -0
- package/dist/types/result-packet.js +12 -0
- package/dist/types/runtime-state.js +2 -0
- package/dist/types/work-contract.js +2 -0
- package/dist/utils/monotonic-timestamp.js +13 -0
- package/dist/utils/monotonic-timestamp.test.js +19 -0
- package/package.json +64 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Polaris worker entry point.
|
|
4
|
+
*
|
|
5
|
+
* A worker process is spawned by the parent loop to execute exactly ONE child
|
|
6
|
+
* task. The worker:
|
|
7
|
+
* 1. Reads the bootstrap packet (from POLARIS_BOOTSTRAP_PACKET env var or
|
|
8
|
+
* --bootstrap CLI flag).
|
|
9
|
+
* 2. Executes the single child specified in the packet.
|
|
10
|
+
* 3. Updates current-state.json (child completion fields).
|
|
11
|
+
* 4. Appends telemetry JSONL events.
|
|
12
|
+
* 5. Writes a CompactReturn JSON to stdout.
|
|
13
|
+
* 6. Exits.
|
|
14
|
+
*
|
|
15
|
+
* The worker MUST NOT continue to the next child under any circumstances.
|
|
16
|
+
* Calling runWorker() will call process.exit() when done.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.readBootstrapPacket = readBootstrapPacket;
|
|
20
|
+
exports.executeOneChild = executeOneChild;
|
|
21
|
+
exports.runWorker = runWorker;
|
|
22
|
+
const node_fs_1 = require("node:fs");
|
|
23
|
+
const node_crypto_1 = require("node:crypto");
|
|
24
|
+
const node_path_1 = require("node:path");
|
|
25
|
+
const node_child_process_1 = require("node:child_process");
|
|
26
|
+
const checkpoint_js_1 = require("./checkpoint.js");
|
|
27
|
+
const monotonic_timestamp_js_1 = require("../utils/monotonic-timestamp.js");
|
|
28
|
+
const index_js_1 = require("../cognition/index.js");
|
|
29
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
30
|
+
// Bootstrap packet reading
|
|
31
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Parse CLI args looking for --bootstrap <path>.
|
|
34
|
+
*/
|
|
35
|
+
function bootstrapPathFromArgs(argv) {
|
|
36
|
+
const idx = argv.indexOf("--bootstrap");
|
|
37
|
+
if (idx !== -1 && idx + 1 < argv.length) {
|
|
38
|
+
return argv[idx + 1] ?? null;
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Read and parse the bootstrap packet.
|
|
44
|
+
* Resolution order:
|
|
45
|
+
* 1. --bootstrap <path> CLI argument
|
|
46
|
+
* 2. POLARIS_BOOTSTRAP_PACKET env var (path to file)
|
|
47
|
+
* 3. POLARIS_PACKET_FILE env var (path to file)
|
|
48
|
+
* 4. POLARIS_PACKET_JSON env var (raw JSON)
|
|
49
|
+
*/
|
|
50
|
+
function readBootstrapPacket(argv = process.argv) {
|
|
51
|
+
// 1. CLI arg
|
|
52
|
+
const cliPath = bootstrapPathFromArgs(argv);
|
|
53
|
+
if (cliPath) {
|
|
54
|
+
return JSON.parse((0, node_fs_1.readFileSync)(cliPath, "utf-8"));
|
|
55
|
+
}
|
|
56
|
+
// 2. POLARIS_BOOTSTRAP_PACKET env var (file path)
|
|
57
|
+
const envPath = process.env["POLARIS_BOOTSTRAP_PACKET"];
|
|
58
|
+
if (envPath) {
|
|
59
|
+
return JSON.parse((0, node_fs_1.readFileSync)(envPath, "utf-8"));
|
|
60
|
+
}
|
|
61
|
+
// 3. POLARIS_PACKET_FILE env var (file path)
|
|
62
|
+
const packetFile = process.env["POLARIS_PACKET_FILE"];
|
|
63
|
+
if (packetFile) {
|
|
64
|
+
return JSON.parse((0, node_fs_1.readFileSync)(packetFile, "utf-8"));
|
|
65
|
+
}
|
|
66
|
+
// 4. POLARIS_PACKET_JSON env var (raw JSON string)
|
|
67
|
+
const packetJson = process.env["POLARIS_PACKET_JSON"];
|
|
68
|
+
if (packetJson) {
|
|
69
|
+
return JSON.parse(packetJson);
|
|
70
|
+
}
|
|
71
|
+
throw new Error("No bootstrap packet found. Provide --bootstrap <path>, " +
|
|
72
|
+
"POLARIS_BOOTSTRAP_PACKET, POLARIS_PACKET_FILE, or POLARIS_PACKET_JSON.");
|
|
73
|
+
}
|
|
74
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
75
|
+
// Telemetry helpers
|
|
76
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
77
|
+
function appendTelemetry(telemetryFile, event) {
|
|
78
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(telemetryFile), { recursive: true });
|
|
79
|
+
(0, node_fs_1.appendFileSync)(telemetryFile, JSON.stringify(event) + "\n", "utf-8");
|
|
80
|
+
}
|
|
81
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
82
|
+
// Git helpers
|
|
83
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
84
|
+
function getHeadShort(cwd) {
|
|
85
|
+
try {
|
|
86
|
+
return (0, node_child_process_1.execFileSync)("git", ["rev-parse", "--short", "HEAD"], {
|
|
87
|
+
cwd,
|
|
88
|
+
encoding: "utf-8",
|
|
89
|
+
}).trim();
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return "";
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
96
|
+
// Work note helpers
|
|
97
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
98
|
+
/**
|
|
99
|
+
* Determine the primary folder (folder_slug) from touched files.
|
|
100
|
+
* Returns the folder containing the most changed files, normalized to lowercase with / → -.
|
|
101
|
+
*/
|
|
102
|
+
function determineFolderSlug(touchedFiles) {
|
|
103
|
+
if (touchedFiles.length === 0) {
|
|
104
|
+
return "root";
|
|
105
|
+
}
|
|
106
|
+
// Count files by folder depth, preferring the shallowest common folder
|
|
107
|
+
const folderCounts = {};
|
|
108
|
+
for (const file of touchedFiles) {
|
|
109
|
+
const parts = file.split("/");
|
|
110
|
+
// Try each folder level from root down
|
|
111
|
+
for (let i = 1; i <= parts.length; i++) {
|
|
112
|
+
const folder = parts.slice(0, i).join("/");
|
|
113
|
+
folderCounts[folder] = (folderCounts[folder] ?? 0) + 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Find the folder with the most files (deepest common folder)
|
|
117
|
+
let maxFolder = "root";
|
|
118
|
+
let maxCount = 0;
|
|
119
|
+
for (const [folder, count] of Object.entries(folderCounts)) {
|
|
120
|
+
if (count > maxCount) {
|
|
121
|
+
maxCount = count;
|
|
122
|
+
maxFolder = folder;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Normalize: replace / with -, handle edge cases
|
|
126
|
+
if (maxFolder === "root" || maxFolder === "") {
|
|
127
|
+
return "root";
|
|
128
|
+
}
|
|
129
|
+
return maxFolder.replace(/\//g, "-").toLowerCase();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Determine docs_impact based on cognition delta results.
|
|
133
|
+
* Returns one of: none, polaris-update, summary-update, both, archive-only
|
|
134
|
+
*/
|
|
135
|
+
function determineDocsImpact(cognitionDelta, summaryDelta) {
|
|
136
|
+
const polarisUpdate = cognitionDelta?.updateWarranted ?? false;
|
|
137
|
+
const summaryUpdate = summaryDelta?.updateWarranted ?? false;
|
|
138
|
+
if (polarisUpdate && summaryUpdate) {
|
|
139
|
+
return "both";
|
|
140
|
+
}
|
|
141
|
+
else if (polarisUpdate) {
|
|
142
|
+
return "polaris-update";
|
|
143
|
+
}
|
|
144
|
+
else if (summaryUpdate) {
|
|
145
|
+
return "summary-update";
|
|
146
|
+
}
|
|
147
|
+
return "none";
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Write a work note to .polaris/cognition/pending/<folder-slug>/<run-id>-<child-id>.md
|
|
151
|
+
* Returns the repo-relative path to the written note.
|
|
152
|
+
*/
|
|
153
|
+
function writeWorkNote(repoRoot, runId, childId, issueId, folderSlug, touchedFiles, docsImpact, commit, validationPerformed) {
|
|
154
|
+
const timestamp = new Date().toISOString();
|
|
155
|
+
const primaryFolder = folderSlug === "root" ? "" : folderSlug.replace(/-/g, "/");
|
|
156
|
+
// Build frontmatter
|
|
157
|
+
const frontmatter = [
|
|
158
|
+
"---",
|
|
159
|
+
`run_id: ${runId}`,
|
|
160
|
+
`child_id: ${childId}`,
|
|
161
|
+
`issue_id: ${issueId}`,
|
|
162
|
+
`folder: ${primaryFolder || "."}`,
|
|
163
|
+
`folder_slug: ${folderSlug}`,
|
|
164
|
+
"affected_files:",
|
|
165
|
+
...touchedFiles.map((f) => ` - ${f}`),
|
|
166
|
+
`validation_performed: ${validationPerformed}`,
|
|
167
|
+
`docs_impact: ${docsImpact}`,
|
|
168
|
+
`commit: ${commit}`,
|
|
169
|
+
`timestamp: ${timestamp}`,
|
|
170
|
+
"---",
|
|
171
|
+
];
|
|
172
|
+
// Build prose body (minimal, ≤150 words)
|
|
173
|
+
const proseBody = `Completed task ${childId} (${issueId}). Implementation changes applied, validation passed. ${docsImpact !== "none" ? `Cognition surfaces require update (${docsImpact}).` : "No cognition surface updates needed."}`;
|
|
174
|
+
// Combine
|
|
175
|
+
const noteContent = [...frontmatter, "", proseBody].join("\n");
|
|
176
|
+
// Write to file
|
|
177
|
+
const notePath = (0, node_path_1.resolve)(repoRoot, ".polaris/cognition/pending", folderSlug, `${runId}-${childId}.md`);
|
|
178
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(notePath), { recursive: true });
|
|
179
|
+
(0, node_fs_1.writeFileSync)(notePath, noteContent, "utf-8");
|
|
180
|
+
// Return repo-relative path
|
|
181
|
+
return notePath.replace(repoRoot + "/", "");
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Build a CompactReturn for an error case without touching durable state.
|
|
185
|
+
*/
|
|
186
|
+
function blockedReturn(childId, _reason) {
|
|
187
|
+
return {
|
|
188
|
+
child_id: childId,
|
|
189
|
+
status: 'blocked',
|
|
190
|
+
commit: null,
|
|
191
|
+
validation: 'skipped',
|
|
192
|
+
tracker_updated: false,
|
|
193
|
+
state_updated: false,
|
|
194
|
+
telemetry_updated: false,
|
|
195
|
+
next_recommended_action: 'stop',
|
|
196
|
+
result_data: {},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Execute one child task, update all durable state, and return a CompactReturn.
|
|
201
|
+
*
|
|
202
|
+
* This function does NOT call process.exit(). The caller (runWorker) does.
|
|
203
|
+
*/
|
|
204
|
+
async function executeOneChild(packet, options = {}) {
|
|
205
|
+
const repoRoot = options.repoRoot ?? process.cwd();
|
|
206
|
+
const childId = packet.active_child;
|
|
207
|
+
const stateFile = (0, node_path_1.isAbsolute)(packet.state_file)
|
|
208
|
+
? packet.state_file
|
|
209
|
+
: (0, node_path_1.resolve)(repoRoot, packet.state_file);
|
|
210
|
+
const telemetryFile = (0, node_path_1.isAbsolute)(packet.telemetry_file)
|
|
211
|
+
? packet.telemetry_file
|
|
212
|
+
: (0, node_path_1.resolve)(repoRoot, packet.telemetry_file);
|
|
213
|
+
const now = monotonic_timestamp_js_1.getMonotonicTimestamp;
|
|
214
|
+
let stateUpdated = false;
|
|
215
|
+
let telemetryUpdated = false;
|
|
216
|
+
let commit = null;
|
|
217
|
+
let validation = 'skipped';
|
|
218
|
+
let cognitionDelta = null;
|
|
219
|
+
let summaryDelta = null;
|
|
220
|
+
// Create a new packet with absolute paths for child execution
|
|
221
|
+
const newPacket = {
|
|
222
|
+
...packet,
|
|
223
|
+
state_file: stateFile,
|
|
224
|
+
telemetry_file: telemetryFile,
|
|
225
|
+
};
|
|
226
|
+
// ── Step 03b: Emit worker-acknowledged event ────────────────────────────
|
|
227
|
+
// Must be emitted after packet read and SHA computation, before any work
|
|
228
|
+
// output (telemetry spec §5.1). Acknowledges receipt of the dispatch packet.
|
|
229
|
+
{
|
|
230
|
+
let packetSha = "";
|
|
231
|
+
if (options.packetPath) {
|
|
232
|
+
try {
|
|
233
|
+
const raw = (0, node_fs_1.readFileSync)(options.packetPath, "utf-8");
|
|
234
|
+
packetSha = (0, node_crypto_1.createHash)("sha256").update(raw, "utf-8").digest("hex");
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
// SHA computation failure is non-fatal; emit empty string
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
else if (options.packetRawJson) {
|
|
241
|
+
packetSha = (0, node_crypto_1.createHash)("sha256").update(options.packetRawJson, "utf-8").digest("hex");
|
|
242
|
+
}
|
|
243
|
+
appendTelemetry(telemetryFile, {
|
|
244
|
+
event: "worker-acknowledged",
|
|
245
|
+
event_id: (0, node_crypto_1.randomUUID)(),
|
|
246
|
+
run_id: packet.run_id,
|
|
247
|
+
child_id: childId,
|
|
248
|
+
dispatch_id: packet.dispatch_id ?? "",
|
|
249
|
+
worker_id: packet.worker_id ?? "",
|
|
250
|
+
packet_sha: packetSha,
|
|
251
|
+
timestamp: now(),
|
|
252
|
+
});
|
|
253
|
+
telemetryUpdated = true;
|
|
254
|
+
}
|
|
255
|
+
// ── Step 04: Execute child ──────────────────────────────────────────────
|
|
256
|
+
try {
|
|
257
|
+
if (options.executeChild) {
|
|
258
|
+
options.executeChild(childId, newPacket);
|
|
259
|
+
}
|
|
260
|
+
// If no executeChild hook is provided, the worker is acting as a thin
|
|
261
|
+
// wrapper — real child work was done in the agent session itself before
|
|
262
|
+
// calling runWorker(). This is the standard usage pattern.
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
266
|
+
appendTelemetry(telemetryFile, {
|
|
267
|
+
event: "child-execution-error",
|
|
268
|
+
run_id: packet.run_id,
|
|
269
|
+
child_id: childId,
|
|
270
|
+
error: msg,
|
|
271
|
+
timestamp: now(),
|
|
272
|
+
});
|
|
273
|
+
return {
|
|
274
|
+
child_id: childId,
|
|
275
|
+
status: 'failed',
|
|
276
|
+
commit: null,
|
|
277
|
+
validation: 'failed',
|
|
278
|
+
tracker_updated: false,
|
|
279
|
+
state_updated: false,
|
|
280
|
+
telemetry_updated: true,
|
|
281
|
+
next_recommended_action: 'investigate',
|
|
282
|
+
result_data: {},
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// ── Step 05: Validate child ─────────────────────────────────────────────
|
|
286
|
+
// Validation is treated as passed when child execution succeeds.
|
|
287
|
+
// A real implementation would run `npm run build && npm test` here.
|
|
288
|
+
validation = 'passed';
|
|
289
|
+
// ── Step 05b: Route cognition delta ─────────────────────────────────────
|
|
290
|
+
// Inspect touched files and determine whether route-local POLARIS.md /
|
|
291
|
+
// SUMMARY.md surfaces need updating. Bounded by locality — no repo-wide
|
|
292
|
+
// regeneration. Parent runtime is never involved in cognition reconciliation.
|
|
293
|
+
const touchedFiles = options.touchedFiles ?? [];
|
|
294
|
+
if (touchedFiles.length > 0) {
|
|
295
|
+
try {
|
|
296
|
+
cognitionDelta = (0, index_js_1.applyRouteCognitionDelta)({
|
|
297
|
+
repoRoot,
|
|
298
|
+
touchedFiles,
|
|
299
|
+
skipRoot: true,
|
|
300
|
+
});
|
|
301
|
+
summaryDelta = (0, index_js_1.applySummaryDelta)({
|
|
302
|
+
repoRoot,
|
|
303
|
+
touchedFiles,
|
|
304
|
+
skipRoot: true,
|
|
305
|
+
});
|
|
306
|
+
appendTelemetry(telemetryFile, {
|
|
307
|
+
event: "cognition-delta",
|
|
308
|
+
run_id: packet.run_id,
|
|
309
|
+
child_id: childId,
|
|
310
|
+
polaris_update_warranted: cognitionDelta.updateWarranted,
|
|
311
|
+
polaris_reasons: cognitionDelta.reasons,
|
|
312
|
+
polaris_targets: cognitionDelta.routeLocalTargets,
|
|
313
|
+
polaris_missing: cognitionDelta.missingCognitionSurfaces,
|
|
314
|
+
summary_update_warranted: summaryDelta.updateWarranted,
|
|
315
|
+
summary_reasons: summaryDelta.reasons,
|
|
316
|
+
summary_targets: summaryDelta.summaryTargets,
|
|
317
|
+
summary_missing: summaryDelta.missingSummaries,
|
|
318
|
+
timestamp: now(),
|
|
319
|
+
});
|
|
320
|
+
telemetryUpdated = true;
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
// Cognition delta failure is non-fatal — implementation already done
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// ── Step 06: Commit ─────────────────────────────────────────────────────
|
|
327
|
+
commit = getHeadShort(repoRoot);
|
|
328
|
+
// ── Update current-state.json ───────────────────────────────────────────
|
|
329
|
+
try {
|
|
330
|
+
const state = (0, checkpoint_js_1.readState)(stateFile);
|
|
331
|
+
const remaining = state.open_children.filter((c) => c !== childId);
|
|
332
|
+
const completed = [...state.completed_children, childId];
|
|
333
|
+
const updatedState = {
|
|
334
|
+
...state,
|
|
335
|
+
active_child: "",
|
|
336
|
+
open_children: remaining,
|
|
337
|
+
completed_children: completed,
|
|
338
|
+
next_open_child: remaining[0] ?? null,
|
|
339
|
+
step_cursor: "checkpoint",
|
|
340
|
+
status: remaining.length > 0 ? "running" : "cluster-complete",
|
|
341
|
+
last_commit: commit ?? state.last_commit,
|
|
342
|
+
context_budget: {
|
|
343
|
+
...state.context_budget,
|
|
344
|
+
children_completed: completed.length,
|
|
345
|
+
},
|
|
346
|
+
updated_at: now(),
|
|
347
|
+
};
|
|
348
|
+
(0, checkpoint_js_1.writeStateAtomic)(stateFile, updatedState);
|
|
349
|
+
stateUpdated = true;
|
|
350
|
+
}
|
|
351
|
+
catch (err) {
|
|
352
|
+
// State persistence failure is critical — return error status
|
|
353
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
354
|
+
appendTelemetry(telemetryFile, {
|
|
355
|
+
event: "state-update-error",
|
|
356
|
+
run_id: packet.run_id,
|
|
357
|
+
child_id: childId,
|
|
358
|
+
error: msg,
|
|
359
|
+
timestamp: now(),
|
|
360
|
+
});
|
|
361
|
+
return {
|
|
362
|
+
child_id: childId,
|
|
363
|
+
status: 'failed',
|
|
364
|
+
commit,
|
|
365
|
+
validation,
|
|
366
|
+
tracker_updated: false,
|
|
367
|
+
state_updated: false,
|
|
368
|
+
telemetry_updated: telemetryUpdated,
|
|
369
|
+
next_recommended_action: 'investigate',
|
|
370
|
+
result_data: {},
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
// Linear tracker update is intentionally skipped by the worker:
|
|
374
|
+
// the spec says "Do NOT mark POL-69 as Done in Linear (parent handles Linear updates)".
|
|
375
|
+
// tracker_updated is therefore always false from the worker's perspective.
|
|
376
|
+
const trackerUpdated = false;
|
|
377
|
+
// ── Step 07: Write work note ────────────────────────────────────────────
|
|
378
|
+
let workNotePaths = [];
|
|
379
|
+
try {
|
|
380
|
+
const folderSlug = determineFolderSlug(touchedFiles);
|
|
381
|
+
const docsImpact = determineDocsImpact(cognitionDelta, summaryDelta);
|
|
382
|
+
const validationPerformed = "child execution and validation completed";
|
|
383
|
+
const notePath = writeWorkNote(repoRoot, packet.run_id, childId, childId, folderSlug, touchedFiles, docsImpact, commit, validationPerformed);
|
|
384
|
+
workNotePaths = [notePath];
|
|
385
|
+
appendTelemetry(telemetryFile, {
|
|
386
|
+
event: "work-note-written",
|
|
387
|
+
run_id: packet.run_id,
|
|
388
|
+
child_id: childId,
|
|
389
|
+
note_path: notePath,
|
|
390
|
+
folder_slug: folderSlug,
|
|
391
|
+
docs_impact: docsImpact,
|
|
392
|
+
timestamp: now(),
|
|
393
|
+
});
|
|
394
|
+
telemetryUpdated = true;
|
|
395
|
+
}
|
|
396
|
+
catch (err) {
|
|
397
|
+
// Work note failure is non-fatal — implementation already done
|
|
398
|
+
// Log but don't block CompactReturn
|
|
399
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
400
|
+
appendTelemetry(telemetryFile, {
|
|
401
|
+
event: "work-note-error",
|
|
402
|
+
run_id: packet.run_id,
|
|
403
|
+
child_id: childId,
|
|
404
|
+
error: msg,
|
|
405
|
+
timestamp: now(),
|
|
406
|
+
});
|
|
407
|
+
telemetryUpdated = true;
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
child_id: childId,
|
|
411
|
+
status: 'done',
|
|
412
|
+
commit,
|
|
413
|
+
validation,
|
|
414
|
+
tracker_updated: trackerUpdated,
|
|
415
|
+
state_updated: stateUpdated,
|
|
416
|
+
telemetry_updated: telemetryUpdated,
|
|
417
|
+
next_recommended_action: 'continue',
|
|
418
|
+
result_data: {},
|
|
419
|
+
work_note_paths: workNotePaths.length > 0 ? workNotePaths : undefined,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
423
|
+
// CLI entry point
|
|
424
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
425
|
+
/**
|
|
426
|
+
* Main worker entry point. Reads the bootstrap packet, executes one child,
|
|
427
|
+
* writes a CompactReturn JSON line to stdout, and calls process.exit(0).
|
|
428
|
+
*
|
|
429
|
+
* MUST NOT continue to the next child.
|
|
430
|
+
*/
|
|
431
|
+
async function runWorker(options = {}) {
|
|
432
|
+
let packet;
|
|
433
|
+
let resolvedPacketPath = options.packetPath;
|
|
434
|
+
let resolvedPacketRawJson = options.packetRawJson;
|
|
435
|
+
try {
|
|
436
|
+
if (options.packetPath) {
|
|
437
|
+
packet = JSON.parse((0, node_fs_1.readFileSync)(options.packetPath, "utf-8"));
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
// Capture raw JSON from env var sources for SHA computation
|
|
441
|
+
const cliPath = (() => {
|
|
442
|
+
const idx = process.argv.indexOf("--bootstrap");
|
|
443
|
+
return idx !== -1 && idx + 1 < process.argv.length ? process.argv[idx + 1] : null;
|
|
444
|
+
})();
|
|
445
|
+
if (cliPath) {
|
|
446
|
+
resolvedPacketPath = cliPath;
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
const envPath = process.env["POLARIS_BOOTSTRAP_PACKET"] ?? process.env["POLARIS_PACKET_FILE"];
|
|
450
|
+
if (envPath) {
|
|
451
|
+
resolvedPacketPath = envPath;
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
const packetJson = process.env["POLARIS_PACKET_JSON"];
|
|
455
|
+
if (packetJson) {
|
|
456
|
+
resolvedPacketRawJson = packetJson;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
packet = readBootstrapPacket(process.argv);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
catch (err) {
|
|
464
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
465
|
+
const ret = {
|
|
466
|
+
child_id: "",
|
|
467
|
+
status: 'failed',
|
|
468
|
+
commit: null,
|
|
469
|
+
validation: 'skipped',
|
|
470
|
+
tracker_updated: false,
|
|
471
|
+
state_updated: false,
|
|
472
|
+
telemetry_updated: false,
|
|
473
|
+
next_recommended_action: 'investigate',
|
|
474
|
+
result_data: {},
|
|
475
|
+
};
|
|
476
|
+
process.stdout.write(JSON.stringify(ret) + "\n");
|
|
477
|
+
process.stderr.write(`[polaris-worker] Failed to read bootstrap packet: ${msg}\n`);
|
|
478
|
+
process.exit(1);
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
let result;
|
|
482
|
+
try {
|
|
483
|
+
result = await executeOneChild(packet, {
|
|
484
|
+
...options,
|
|
485
|
+
packetPath: resolvedPacketPath,
|
|
486
|
+
packetRawJson: resolvedPacketRawJson,
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
catch (err) {
|
|
490
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
491
|
+
result = blockedReturn(packet.active_child, msg);
|
|
492
|
+
process.stderr.write(`[polaris-worker] Unexpected error: ${msg}\n`);
|
|
493
|
+
}
|
|
494
|
+
// Write compact return as the last (and only) JSON line to stdout, then exit.
|
|
495
|
+
// No continuation to the next child — process.exit() ensures this.
|
|
496
|
+
process.stdout.write(JSON.stringify(result) + "\n");
|
|
497
|
+
process.exit(result.status === 'done' ? 0 : 1);
|
|
498
|
+
}
|