@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,406 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Compiled worker packet for delegated-chain execution.
|
|
4
|
+
*
|
|
5
|
+
* Instead of workers ingesting the full Polaris skill on each dispatch,
|
|
6
|
+
* the parent compiles a WorkerPacket containing pre-baked instructions,
|
|
7
|
+
* allowed scope, and lifecycle teardown rules. Workers read the packet
|
|
8
|
+
* and execute immediately — no skill re-ingestion required.
|
|
9
|
+
*
|
|
10
|
+
* WorkerPacket extends BootstrapPacket so all existing adapters that
|
|
11
|
+
* accept BootstrapPacket transparently accept WorkerPacket.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.STARTUP_RETURN_CONTRACT = exports.PREFLIGHT_RETURN_CONTRACT = exports.WORKER_PROHIBITED_WRITE_PATHS = exports.FINALIZE_RETURN_CONTRACT = exports.IMPL_RETURN_CONTRACT = void 0;
|
|
15
|
+
exports.roleContextForWorkerRole = roleContextForWorkerRole;
|
|
16
|
+
exports.isWorkerPacket = isWorkerPacket;
|
|
17
|
+
exports.getWorkerCommitPolicy = getWorkerCommitPolicy;
|
|
18
|
+
exports.compileStartupPacket = compileStartupPacket;
|
|
19
|
+
exports.compileImplPacket = compileImplPacket;
|
|
20
|
+
exports.compileFinalizePacket = compileFinalizePacket;
|
|
21
|
+
exports.compilePreflightPacket = compilePreflightPacket;
|
|
22
|
+
const worker_prompt_js_1 = require("./worker-prompt.js");
|
|
23
|
+
const body_parser_js_1 = require("./body-parser.js");
|
|
24
|
+
const WORKER_ROLE_CONTEXT = {
|
|
25
|
+
role: 'worker',
|
|
26
|
+
role_authority: 'implementation',
|
|
27
|
+
may_implement: true,
|
|
28
|
+
may_assign_workers: false,
|
|
29
|
+
prohibited_actions: [
|
|
30
|
+
'modify-cluster-plan',
|
|
31
|
+
'dispatch-children',
|
|
32
|
+
'polaris-loop-dispatch',
|
|
33
|
+
'polaris-loop-continue',
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
const FOREMAN_ROLE_CONTEXT = {
|
|
37
|
+
role: 'foreman',
|
|
38
|
+
role_authority: 'coordination-only',
|
|
39
|
+
may_implement: false,
|
|
40
|
+
may_assign_workers: true,
|
|
41
|
+
prohibited_actions: [
|
|
42
|
+
'inline-implementation',
|
|
43
|
+
'scope-expansion',
|
|
44
|
+
'skip-checkpoint',
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
const ANALYSIS_ROLE_CONTEXT = {
|
|
48
|
+
role: 'analyst',
|
|
49
|
+
role_authority: 'analysis',
|
|
50
|
+
may_implement: false,
|
|
51
|
+
may_assign_workers: false,
|
|
52
|
+
prohibited_actions: [
|
|
53
|
+
'modify-cluster-plan',
|
|
54
|
+
'dispatch-children',
|
|
55
|
+
'polaris-loop-dispatch',
|
|
56
|
+
'polaris-loop-continue',
|
|
57
|
+
'inline-implementation',
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
const LIBRARIAN_ROLE_CONTEXT = {
|
|
61
|
+
role: 'librarian',
|
|
62
|
+
role_authority: 'documentation',
|
|
63
|
+
may_implement: false,
|
|
64
|
+
may_assign_workers: false,
|
|
65
|
+
prohibited_actions: [
|
|
66
|
+
'modify-cluster-plan',
|
|
67
|
+
'dispatch-children',
|
|
68
|
+
'polaris-loop-dispatch',
|
|
69
|
+
'polaris-loop-continue',
|
|
70
|
+
'inline-implementation',
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
function roleContextForWorkerRole(workerRole) {
|
|
74
|
+
switch (workerRole) {
|
|
75
|
+
case 'impl':
|
|
76
|
+
case 'validation':
|
|
77
|
+
case 'repair':
|
|
78
|
+
return WORKER_ROLE_CONTEXT;
|
|
79
|
+
case 'analysis':
|
|
80
|
+
return ANALYSIS_ROLE_CONTEXT;
|
|
81
|
+
case 'librarian':
|
|
82
|
+
return LIBRARIAN_ROLE_CONTEXT;
|
|
83
|
+
case 'startup':
|
|
84
|
+
case 'finalize':
|
|
85
|
+
case 'preflight':
|
|
86
|
+
default:
|
|
87
|
+
return FOREMAN_ROLE_CONTEXT;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Type guard: returns true when packet is a compiled WorkerPacket. */
|
|
91
|
+
function isWorkerPacket(packet) {
|
|
92
|
+
const p = packet;
|
|
93
|
+
// Accept both '2.0' (legacy) and '2.1' (dispatch contract) schema versions
|
|
94
|
+
// role_context is not required for backward compat with packets that predate this field
|
|
95
|
+
const isV2 = (packet.schema_version === '2.0' || packet.schema_version === '2.1') &&
|
|
96
|
+
typeof p['worker_role'] === 'string' &&
|
|
97
|
+
typeof p['instructions'] === 'object' && p['instructions'] !== null && !Array.isArray(p['instructions']) &&
|
|
98
|
+
typeof p['lifecycle'] === 'object' && p['lifecycle'] !== null &&
|
|
99
|
+
Array.isArray(p['return_contract']);
|
|
100
|
+
if (!isV2) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
// result_file_contract is required on every v2.1 packet.
|
|
104
|
+
const rfc = p.result_file_contract;
|
|
105
|
+
if (rfc === null || rfc === undefined || typeof rfc !== 'object' || Array.isArray(rfc)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const rfcRecord = rfc;
|
|
109
|
+
return typeof rfcRecord.result_file === 'string';
|
|
110
|
+
}
|
|
111
|
+
// ── Return contracts ──────────────────────────────────────────────────────────
|
|
112
|
+
exports.IMPL_RETURN_CONTRACT = [
|
|
113
|
+
'child_id',
|
|
114
|
+
'status',
|
|
115
|
+
'commit',
|
|
116
|
+
'validation',
|
|
117
|
+
'next_recommended_action',
|
|
118
|
+
];
|
|
119
|
+
exports.FINALIZE_RETURN_CONTRACT = [
|
|
120
|
+
'run_id',
|
|
121
|
+
'status',
|
|
122
|
+
'pr_url',
|
|
123
|
+
'commit',
|
|
124
|
+
'next_recommended_action',
|
|
125
|
+
];
|
|
126
|
+
exports.WORKER_PROHIBITED_WRITE_PATHS = [
|
|
127
|
+
".taskchain_artifacts/",
|
|
128
|
+
".polaris/clusters/",
|
|
129
|
+
".polaris/runs/",
|
|
130
|
+
"**/telemetry.jsonl",
|
|
131
|
+
];
|
|
132
|
+
function getWorkerCommitPolicy(packet) {
|
|
133
|
+
return {
|
|
134
|
+
allowedScope: [...packet.instructions.allowed_scope],
|
|
135
|
+
prohibitedWritePaths: [...(packet.prohibited_write_paths ?? [])],
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
exports.PREFLIGHT_RETURN_CONTRACT = [
|
|
139
|
+
'status',
|
|
140
|
+
'checks_passed',
|
|
141
|
+
'blockers',
|
|
142
|
+
'next_recommended_action',
|
|
143
|
+
];
|
|
144
|
+
exports.STARTUP_RETURN_CONTRACT = [
|
|
145
|
+
'run_id',
|
|
146
|
+
'status',
|
|
147
|
+
'execution_plan',
|
|
148
|
+
'first_child',
|
|
149
|
+
'next_recommended_action',
|
|
150
|
+
];
|
|
151
|
+
// ── Lifecycle helpers ─────────────────────────────────────────────────────────
|
|
152
|
+
function defaultLifecycle(maxConcurrent, cleanupOnExit) {
|
|
153
|
+
return {
|
|
154
|
+
terminate_after_completion: true,
|
|
155
|
+
max_concurrent: maxConcurrent,
|
|
156
|
+
cleanup_on_exit: cleanupOnExit,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Build a compiled startup worker packet.
|
|
161
|
+
* Startup workers prepare tracker/graph/config/run-state evidence; the parent
|
|
162
|
+
* consumes the sealed result before selecting the first implementation child.
|
|
163
|
+
*/
|
|
164
|
+
function compileStartupPacket(input) {
|
|
165
|
+
const steps = [
|
|
166
|
+
`Sync or import tracker data for cluster ${input.clusterId} when configured.`,
|
|
167
|
+
`Build or refresh the local execution graph for ${input.clusterId}.`,
|
|
168
|
+
`Validate Polaris config and the execution provider roster.`,
|
|
169
|
+
`Prepare run ledger/state evidence for ${input.runId}.`,
|
|
170
|
+
`Select the execution plan and first child without implementing it.`,
|
|
171
|
+
`Write compact startup JSON to stdout (fields: ${exports.STARTUP_RETURN_CONTRACT.join(', ')}).`,
|
|
172
|
+
`TERMINATE SESSION IMMEDIATELY.`,
|
|
173
|
+
];
|
|
174
|
+
return {
|
|
175
|
+
schema_version: '2.1',
|
|
176
|
+
worker_role: 'startup',
|
|
177
|
+
run_id: input.runId,
|
|
178
|
+
cluster_id: input.clusterId,
|
|
179
|
+
active_child: '',
|
|
180
|
+
state_file: input.stateFile,
|
|
181
|
+
telemetry_file: input.telemetryFile,
|
|
182
|
+
instructions: {
|
|
183
|
+
primary_goal: `Startup cluster ${input.clusterId} for run ${input.runId}: sync tracker data, refresh graph, ` +
|
|
184
|
+
`validate config/providers, and return the first executable dispatch plan.`,
|
|
185
|
+
steps,
|
|
186
|
+
allowed_scope: [
|
|
187
|
+
'.taskchain_artifacts/**',
|
|
188
|
+
'.polaris/runs/**',
|
|
189
|
+
'.polaris/map/**',
|
|
190
|
+
],
|
|
191
|
+
validation_commands: [],
|
|
192
|
+
},
|
|
193
|
+
lifecycle: defaultLifecycle(input.maxConcurrentWorkers ?? 1, 'commit-and-exit'),
|
|
194
|
+
return_contract: exports.STARTUP_RETURN_CONTRACT,
|
|
195
|
+
prompt_mode: 'full',
|
|
196
|
+
prompt_metrics: { mode: 'full', char_count: 0, estimated_tokens: 0 },
|
|
197
|
+
role_context: roleContextForWorkerRole('startup'),
|
|
198
|
+
result_file_contract: {
|
|
199
|
+
result_file: input.resultFile,
|
|
200
|
+
result_required_fields: Object.fromEntries([
|
|
201
|
+
['run_id', input.runId],
|
|
202
|
+
['cluster_id', input.clusterId],
|
|
203
|
+
['child_id', '<active_child from packet>'],
|
|
204
|
+
...exports.STARTUP_RETURN_CONTRACT.map(key => [key, `<${key}>`]),
|
|
205
|
+
]),
|
|
206
|
+
},
|
|
207
|
+
context: {
|
|
208
|
+
branch: input.branch,
|
|
209
|
+
worker_role: 'startup',
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Create a compiled implementation (impl) WorkerPacket for executing a single child task.
|
|
215
|
+
*
|
|
216
|
+
* If `input.issueContext.body` is present, `allowed_scope`, `validation_commands`, and requirement
|
|
217
|
+
* text are derived from the parsed body when corresponding explicit fields are not provided.
|
|
218
|
+
*
|
|
219
|
+
* @param input - Configuration and contextual data (run/cluster/child identifiers, file paths,
|
|
220
|
+
* optional issueContext, scope/validation overrides, concurrency, prompt mode, and optional
|
|
221
|
+
* result file) used to construct the packet
|
|
222
|
+
* @returns A WorkerPacket pre-populated with instructions, lifecycle, prompt data, role context,
|
|
223
|
+
* and the IMPL return contract suitable for an implementation worker
|
|
224
|
+
*/
|
|
225
|
+
function compileImplPacket(input) {
|
|
226
|
+
const childRef = input.issueContext?.id ?? input.childId;
|
|
227
|
+
const childTitle = input.issueContext?.title ?? input.childId;
|
|
228
|
+
const promptMode = input.promptMode ?? 'compact';
|
|
229
|
+
// Derive scope/validation/requirements from body when not explicitly provided.
|
|
230
|
+
const bodyParsed = input.issueContext?.body ? (0, body_parser_js_1.parseIssueBody)(input.issueContext.body) : null;
|
|
231
|
+
const resolvedScope = input.allowedScope?.length
|
|
232
|
+
? input.allowedScope
|
|
233
|
+
: bodyParsed?.scope ?? [];
|
|
234
|
+
const resolvedValidation = input.validationCommands?.length
|
|
235
|
+
? input.validationCommands
|
|
236
|
+
: bodyParsed?.validationCommands ?? [];
|
|
237
|
+
const resolvedRequirements = input.issueContext?.key_requirements.length
|
|
238
|
+
? input.issueContext.key_requirements
|
|
239
|
+
: bodyParsed?.requirements ?? [];
|
|
240
|
+
const requirementLines = resolvedRequirements.map((r, i) => ` ${i + 1}. ${r}`);
|
|
241
|
+
const bodyLines = input.issueContext?.body
|
|
242
|
+
? [`Issue description:\n${input.issueContext.body}`]
|
|
243
|
+
: [];
|
|
244
|
+
const steps = [
|
|
245
|
+
`Verify: read ${input.stateFile} and confirm active_child === "${input.childId}".`,
|
|
246
|
+
`Implement ${childRef}: "${childTitle}".`,
|
|
247
|
+
...bodyLines,
|
|
248
|
+
...(requirementLines.length > 0 ? [`Requirements:`, ...requirementLines] : []),
|
|
249
|
+
`Run validation commands and confirm all pass.`,
|
|
250
|
+
`Create exactly ONE git commit: [${input.childId}] ${childTitle}.`,
|
|
251
|
+
`Do NOT modify open_children or completed_children in ${input.stateFile}. The parent runtime (loop continue) owns that state transition.`,
|
|
252
|
+
`Append a telemetry event to ${input.telemetryFile}.`,
|
|
253
|
+
`Write compact return JSON to stdout (fields: ${exports.IMPL_RETURN_CONTRACT.join(', ')}).`,
|
|
254
|
+
`TERMINATE SESSION IMMEDIATELY. Do not select or execute the next child.`,
|
|
255
|
+
];
|
|
256
|
+
// Build compact or full prompt; primary_goal uses the structured template.
|
|
257
|
+
const promptResult = (0, worker_prompt_js_1.buildPromptFromPacketInput)({
|
|
258
|
+
issueId: input.childId,
|
|
259
|
+
title: childTitle,
|
|
260
|
+
worktree: '.',
|
|
261
|
+
branch: input.branch,
|
|
262
|
+
stateFile: input.stateFile,
|
|
263
|
+
telemetryFile: input.telemetryFile,
|
|
264
|
+
issueContext: input.issueContext,
|
|
265
|
+
allowedScope: resolvedScope,
|
|
266
|
+
validationCommands: resolvedValidation,
|
|
267
|
+
mode: promptMode,
|
|
268
|
+
});
|
|
269
|
+
return {
|
|
270
|
+
schema_version: '2.1',
|
|
271
|
+
worker_role: 'impl',
|
|
272
|
+
run_id: input.runId,
|
|
273
|
+
cluster_id: input.clusterId,
|
|
274
|
+
active_child: input.childId,
|
|
275
|
+
state_file: input.stateFile,
|
|
276
|
+
telemetry_file: input.telemetryFile,
|
|
277
|
+
instructions: {
|
|
278
|
+
primary_goal: promptResult.prompt,
|
|
279
|
+
steps,
|
|
280
|
+
allowed_scope: resolvedScope,
|
|
281
|
+
validation_commands: resolvedValidation,
|
|
282
|
+
issue_context: input.issueContext,
|
|
283
|
+
},
|
|
284
|
+
lifecycle: defaultLifecycle(input.maxConcurrentWorkers ?? 1, 'commit-and-exit'),
|
|
285
|
+
return_contract: exports.IMPL_RETURN_CONTRACT,
|
|
286
|
+
prompt_mode: promptMode,
|
|
287
|
+
prompt_metrics: promptResult.metrics,
|
|
288
|
+
role_context: roleContextForWorkerRole('impl'),
|
|
289
|
+
prohibited_write_paths: exports.WORKER_PROHIBITED_WRITE_PATHS,
|
|
290
|
+
result_file_contract: {
|
|
291
|
+
result_file: input.resultFile,
|
|
292
|
+
result_required_fields: Object.fromEntries([
|
|
293
|
+
['run_id', input.runId],
|
|
294
|
+
['cluster_id', input.clusterId],
|
|
295
|
+
['child_id', input.childId],
|
|
296
|
+
...exports.IMPL_RETURN_CONTRACT.map(key => [key, `<${key}>`]),
|
|
297
|
+
]),
|
|
298
|
+
},
|
|
299
|
+
context: {
|
|
300
|
+
branch: input.branch,
|
|
301
|
+
worker_role: 'impl',
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Build a compiled finalize worker packet.
|
|
307
|
+
* Delegates the 12-step delivery sequence to a disposable finalize worker.
|
|
308
|
+
*/
|
|
309
|
+
function compileFinalizePacket(input) {
|
|
310
|
+
const targetBranch = input.targetBranch ?? 'main';
|
|
311
|
+
const steps = [
|
|
312
|
+
`Read ${input.stateFile} — confirm status is "cluster-complete" (open_children is empty).`,
|
|
313
|
+
`Run polaris map validate.`,
|
|
314
|
+
`Run polaris finalize run --state-file ${input.stateFile} --skip-delivery (local validation only).`,
|
|
315
|
+
`Push branch "${input.branch}" to origin.`,
|
|
316
|
+
`Create PR targeting "${targetBranch}".`,
|
|
317
|
+
`Write PR URL to ${input.stateFile}.`,
|
|
318
|
+
`Update Linear parent issue ${input.clusterId} to Done.`,
|
|
319
|
+
`Append finalize telemetry events to ${input.telemetryFile}.`,
|
|
320
|
+
`Write compact finalize JSON to stdout (fields: ${exports.FINALIZE_RETURN_CONTRACT.join(', ')}).`,
|
|
321
|
+
`TERMINATE SESSION IMMEDIATELY.`,
|
|
322
|
+
];
|
|
323
|
+
return {
|
|
324
|
+
schema_version: '2.1',
|
|
325
|
+
worker_role: 'finalize',
|
|
326
|
+
run_id: input.runId,
|
|
327
|
+
cluster_id: input.clusterId,
|
|
328
|
+
active_child: '',
|
|
329
|
+
state_file: input.stateFile,
|
|
330
|
+
telemetry_file: input.telemetryFile,
|
|
331
|
+
instructions: {
|
|
332
|
+
primary_goal: `Finalize cluster ${input.clusterId} on branch "${input.branch}" and create PR targeting "${targetBranch}". ` +
|
|
333
|
+
`This is a delivery-only pass — no implementation work.`,
|
|
334
|
+
steps,
|
|
335
|
+
allowed_scope: ['**/*'],
|
|
336
|
+
validation_commands: ['npm run build', 'npm test'],
|
|
337
|
+
},
|
|
338
|
+
lifecycle: defaultLifecycle(input.maxConcurrentWorkers ?? 1, 'commit-and-exit'),
|
|
339
|
+
return_contract: exports.FINALIZE_RETURN_CONTRACT,
|
|
340
|
+
prompt_mode: 'full',
|
|
341
|
+
prompt_metrics: { mode: 'full', char_count: 0, estimated_tokens: 0 },
|
|
342
|
+
role_context: roleContextForWorkerRole('finalize'),
|
|
343
|
+
result_file_contract: {
|
|
344
|
+
result_file: input.resultFile,
|
|
345
|
+
result_required_fields: Object.fromEntries([
|
|
346
|
+
['run_id', input.runId],
|
|
347
|
+
['cluster_id', input.clusterId],
|
|
348
|
+
['child_id', '<active_child from packet>'],
|
|
349
|
+
...exports.FINALIZE_RETURN_CONTRACT.map(key => [key, `<${key}>`]),
|
|
350
|
+
]),
|
|
351
|
+
},
|
|
352
|
+
context: {
|
|
353
|
+
branch: input.branch,
|
|
354
|
+
worker_role: 'finalize',
|
|
355
|
+
target_branch: targetBranch,
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Build a compiled preflight worker packet.
|
|
361
|
+
* Preflight validates state, branch, and map integrity before the first impl dispatch.
|
|
362
|
+
*/
|
|
363
|
+
function compilePreflightPacket(input) {
|
|
364
|
+
const steps = [
|
|
365
|
+
`Read ${input.stateFile} and validate schema (required fields, correct types).`,
|
|
366
|
+
`Confirm current git branch is "${input.branch}".`,
|
|
367
|
+
`Confirm working tree has no unexpected dirty files.`,
|
|
368
|
+
`Confirm active_child is empty (no orphaned worker claims in state).`,
|
|
369
|
+
`Run polaris map validate.`,
|
|
370
|
+
`Write compact preflight JSON to stdout (fields: ${exports.PREFLIGHT_RETURN_CONTRACT.join(', ')}).`,
|
|
371
|
+
`TERMINATE SESSION IMMEDIATELY.`,
|
|
372
|
+
];
|
|
373
|
+
return {
|
|
374
|
+
schema_version: '2.1',
|
|
375
|
+
worker_role: 'preflight',
|
|
376
|
+
run_id: input.runId,
|
|
377
|
+
cluster_id: input.clusterId,
|
|
378
|
+
active_child: '',
|
|
379
|
+
state_file: input.stateFile,
|
|
380
|
+
telemetry_file: input.telemetryFile,
|
|
381
|
+
instructions: {
|
|
382
|
+
primary_goal: `Preflight check for cluster ${input.clusterId}: validate state integrity, branch, and map before impl dispatch.`,
|
|
383
|
+
steps,
|
|
384
|
+
allowed_scope: [],
|
|
385
|
+
validation_commands: [],
|
|
386
|
+
},
|
|
387
|
+
lifecycle: defaultLifecycle(input.maxConcurrentWorkers ?? 1, 'exit-immediately'),
|
|
388
|
+
return_contract: exports.PREFLIGHT_RETURN_CONTRACT,
|
|
389
|
+
prompt_mode: 'full',
|
|
390
|
+
prompt_metrics: { mode: 'full', char_count: 0, estimated_tokens: 0 },
|
|
391
|
+
role_context: roleContextForWorkerRole('preflight'),
|
|
392
|
+
result_file_contract: {
|
|
393
|
+
result_file: input.resultFile,
|
|
394
|
+
result_required_fields: Object.fromEntries([
|
|
395
|
+
['run_id', input.runId],
|
|
396
|
+
['cluster_id', input.clusterId],
|
|
397
|
+
['child_id', '<active_child from packet>'],
|
|
398
|
+
...exports.PREFLIGHT_RETURN_CONTRACT.map(key => [key, `<${key}>`]),
|
|
399
|
+
]),
|
|
400
|
+
},
|
|
401
|
+
context: {
|
|
402
|
+
branch: input.branch,
|
|
403
|
+
worker_role: 'preflight',
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Unit tests for src/loop/worker-packet.ts
|
|
4
|
+
*
|
|
5
|
+
* Verifies compiled packet shape, type guard, and that no skill files are
|
|
6
|
+
* referenced (workers receive self-contained instructions).
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const vitest_1 = require("vitest");
|
|
10
|
+
const worker_packet_js_1 = require("./worker-packet.js");
|
|
11
|
+
// ── Fixtures ──────────────────────────────────────────────────────────────────
|
|
12
|
+
const BASE = {
|
|
13
|
+
runId: "run-001",
|
|
14
|
+
clusterId: "POL-120",
|
|
15
|
+
branch: "feature/pol-120",
|
|
16
|
+
stateFile: "/repo/.taskchain_artifacts/polaris-run/current-state.json",
|
|
17
|
+
telemetryFile: "/repo/.taskchain_artifacts/polaris-run/runs/run-001/telemetry.jsonl",
|
|
18
|
+
};
|
|
19
|
+
// ── isWorkerPacket type guard ─────────────────────────────────────────────────
|
|
20
|
+
(0, vitest_1.describe)("isWorkerPacket", () => {
|
|
21
|
+
(0, vitest_1.it)("returns false for a v1 BootstrapPacket", () => {
|
|
22
|
+
const v1 = {
|
|
23
|
+
schema_version: "1.0",
|
|
24
|
+
run_id: "run-001",
|
|
25
|
+
cluster_id: "POL-120",
|
|
26
|
+
active_child: "POL-121",
|
|
27
|
+
state_file: BASE.stateFile,
|
|
28
|
+
telemetry_file: BASE.telemetryFile,
|
|
29
|
+
};
|
|
30
|
+
(0, vitest_1.expect)((0, worker_packet_js_1.isWorkerPacket)(v1)).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
(0, vitest_1.it)("returns true for a compiled WorkerPacket", () => {
|
|
33
|
+
const packet = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
34
|
+
(0, vitest_1.expect)((0, worker_packet_js_1.isWorkerPacket)(packet)).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
(0, vitest_1.it)("returns true for a compiled WorkerPacket with result_file_contract", () => {
|
|
37
|
+
const packet = (0, worker_packet_js_1.compileImplPacket)({
|
|
38
|
+
...BASE,
|
|
39
|
+
childId: "POL-121",
|
|
40
|
+
resultFile: "/tmp/result.json",
|
|
41
|
+
});
|
|
42
|
+
(0, vitest_1.expect)((0, worker_packet_js_1.isWorkerPacket)(packet)).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
(0, vitest_1.it)("returns false if result_file_contract is malformed", () => {
|
|
45
|
+
const packet = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
46
|
+
packet.result_file_contract = { result_file: 123 };
|
|
47
|
+
(0, vitest_1.expect)((0, worker_packet_js_1.isWorkerPacket)(packet)).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
// ── compileImplPacket ─────────────────────────────────────────────────────────
|
|
51
|
+
(0, vitest_1.describe)("compileImplPacket", () => {
|
|
52
|
+
(0, vitest_1.it)("produces schema_version 2.1 and worker_role impl", () => {
|
|
53
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
54
|
+
(0, vitest_1.expect)(p.schema_version).toBe("2.1");
|
|
55
|
+
(0, vitest_1.expect)(p.worker_role).toBe("impl");
|
|
56
|
+
});
|
|
57
|
+
(0, vitest_1.it)("sets active_child to the child ID (BootstrapPacket compat)", () => {
|
|
58
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
59
|
+
(0, vitest_1.expect)(p.active_child).toBe("POL-121");
|
|
60
|
+
});
|
|
61
|
+
(0, vitest_1.it)("includes the child ID in steps and primary_goal", () => {
|
|
62
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
63
|
+
(0, vitest_1.expect)(p.instructions.primary_goal).toContain("POL-121");
|
|
64
|
+
const stepsText = p.instructions.steps.join(" ");
|
|
65
|
+
(0, vitest_1.expect)(stepsText).toContain("POL-121");
|
|
66
|
+
});
|
|
67
|
+
(0, vitest_1.it)("embeds pre-compiled steps so workers do not re-ingest skills", () => {
|
|
68
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
69
|
+
// Steps must not reference any skill file path
|
|
70
|
+
const stepsText = p.instructions.steps.join(" ");
|
|
71
|
+
(0, vitest_1.expect)(stepsText).not.toContain(".codex/skills");
|
|
72
|
+
(0, vitest_1.expect)(stepsText).not.toContain("chain.md");
|
|
73
|
+
// Steps must include one-child termination instruction
|
|
74
|
+
(0, vitest_1.expect)(stepsText.toUpperCase()).toContain("TERMINATE");
|
|
75
|
+
});
|
|
76
|
+
(0, vitest_1.it)("includes issue context requirements in steps when provided", () => {
|
|
77
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({
|
|
78
|
+
...BASE,
|
|
79
|
+
childId: "POL-121",
|
|
80
|
+
issueContext: {
|
|
81
|
+
id: "POL-121",
|
|
82
|
+
title: "Add validation layer",
|
|
83
|
+
key_requirements: ["Validate schema on load", "Emit error events"],
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
const stepsText = p.instructions.steps.join(" ");
|
|
87
|
+
(0, vitest_1.expect)(stepsText).toContain("Validate schema on load");
|
|
88
|
+
(0, vitest_1.expect)(stepsText).toContain("Emit error events");
|
|
89
|
+
});
|
|
90
|
+
(0, vitest_1.it)("respects allowedScope and validationCommands", () => {
|
|
91
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({
|
|
92
|
+
...BASE,
|
|
93
|
+
childId: "POL-121",
|
|
94
|
+
allowedScope: ["src/loop/**"],
|
|
95
|
+
validationCommands: ["npm test"],
|
|
96
|
+
});
|
|
97
|
+
(0, vitest_1.expect)(p.instructions.allowed_scope).toEqual(["src/loop/**"]);
|
|
98
|
+
(0, vitest_1.expect)(p.instructions.validation_commands).toEqual(["npm test"]);
|
|
99
|
+
});
|
|
100
|
+
(0, vitest_1.it)("has terminate_after_completion: true in lifecycle", () => {
|
|
101
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
102
|
+
(0, vitest_1.expect)(p.lifecycle.terminate_after_completion).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
(0, vitest_1.it)("defaults max_concurrent to 1", () => {
|
|
105
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
106
|
+
(0, vitest_1.expect)(p.lifecycle.max_concurrent).toBe(1);
|
|
107
|
+
});
|
|
108
|
+
(0, vitest_1.it)("uses cleanup_on_exit: commit-and-exit", () => {
|
|
109
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
110
|
+
(0, vitest_1.expect)(p.lifecycle.cleanup_on_exit).toBe("commit-and-exit");
|
|
111
|
+
});
|
|
112
|
+
(0, vitest_1.it)("return_contract matches IMPL_RETURN_CONTRACT", () => {
|
|
113
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
114
|
+
(0, vitest_1.expect)(p.return_contract).toEqual(worker_packet_js_1.IMPL_RETURN_CONTRACT);
|
|
115
|
+
});
|
|
116
|
+
(0, vitest_1.it)("populates result_file_contract when resultFile is provided", () => {
|
|
117
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({
|
|
118
|
+
...BASE,
|
|
119
|
+
childId: "POL-121",
|
|
120
|
+
resultFile: "/tmp/result.json",
|
|
121
|
+
});
|
|
122
|
+
(0, vitest_1.expect)(p.result_file_contract).toEqual({ result_file: "/tmp/result.json" });
|
|
123
|
+
});
|
|
124
|
+
(0, vitest_1.it)("is a valid BootstrapPacket (has all required v1 fields)", () => {
|
|
125
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
126
|
+
(0, vitest_1.expect)(typeof p.run_id).toBe("string");
|
|
127
|
+
(0, vitest_1.expect)(typeof p.cluster_id).toBe("string");
|
|
128
|
+
(0, vitest_1.expect)(typeof p.active_child).toBe("string");
|
|
129
|
+
(0, vitest_1.expect)(typeof p.state_file).toBe("string");
|
|
130
|
+
(0, vitest_1.expect)(typeof p.telemetry_file).toBe("string");
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
// ── compileFinalizePacket ─────────────────────────────────────────────────────
|
|
134
|
+
(0, vitest_1.describe)("compileFinalizePacket", () => {
|
|
135
|
+
(0, vitest_1.it)("produces worker_role finalize with empty active_child", () => {
|
|
136
|
+
const p = (0, worker_packet_js_1.compileFinalizePacket)(BASE);
|
|
137
|
+
(0, vitest_1.expect)(p.worker_role).toBe("finalize");
|
|
138
|
+
(0, vitest_1.expect)(p.active_child).toBe("");
|
|
139
|
+
});
|
|
140
|
+
(0, vitest_1.it)("includes the target branch in steps", () => {
|
|
141
|
+
const p = (0, worker_packet_js_1.compileFinalizePacket)({ ...BASE, targetBranch: "main" });
|
|
142
|
+
const stepsText = p.instructions.steps.join(" ");
|
|
143
|
+
(0, vitest_1.expect)(stepsText).toContain("main");
|
|
144
|
+
});
|
|
145
|
+
(0, vitest_1.it)("defaults targetBranch to main", () => {
|
|
146
|
+
const p = (0, worker_packet_js_1.compileFinalizePacket)(BASE);
|
|
147
|
+
(0, vitest_1.expect)(p.instructions.primary_goal).toContain("main");
|
|
148
|
+
});
|
|
149
|
+
(0, vitest_1.it)("has terminate_after_completion: true", () => {
|
|
150
|
+
const p = (0, worker_packet_js_1.compileFinalizePacket)(BASE);
|
|
151
|
+
(0, vitest_1.expect)(p.lifecycle.terminate_after_completion).toBe(true);
|
|
152
|
+
});
|
|
153
|
+
(0, vitest_1.it)("return_contract matches FINALIZE_RETURN_CONTRACT", () => {
|
|
154
|
+
const p = (0, worker_packet_js_1.compileFinalizePacket)(BASE);
|
|
155
|
+
(0, vitest_1.expect)(p.return_contract).toEqual(worker_packet_js_1.FINALIZE_RETURN_CONTRACT);
|
|
156
|
+
});
|
|
157
|
+
(0, vitest_1.it)("populates result_file_contract when resultFile is provided", () => {
|
|
158
|
+
const p = (0, worker_packet_js_1.compileFinalizePacket)({ ...BASE, resultFile: "/tmp/result.json" });
|
|
159
|
+
(0, vitest_1.expect)(p.result_file_contract).toEqual({ result_file: "/tmp/result.json" });
|
|
160
|
+
});
|
|
161
|
+
(0, vitest_1.it)("does not reference skill files", () => {
|
|
162
|
+
const p = (0, worker_packet_js_1.compileFinalizePacket)(BASE);
|
|
163
|
+
const stepsText = p.instructions.steps.join(" ");
|
|
164
|
+
(0, vitest_1.expect)(stepsText).not.toContain(".codex/skills");
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
// ── compileStartupPacket ──────────────────────────────────────────────────────
|
|
168
|
+
(0, vitest_1.describe)("compileStartupPacket", () => {
|
|
169
|
+
(0, vitest_1.it)("produces worker_role startup with empty active_child", () => {
|
|
170
|
+
const p = (0, worker_packet_js_1.compileStartupPacket)(BASE);
|
|
171
|
+
(0, vitest_1.expect)(p.worker_role).toBe("startup");
|
|
172
|
+
(0, vitest_1.expect)(p.active_child).toBe("");
|
|
173
|
+
});
|
|
174
|
+
(0, vitest_1.it)("return_contract matches STARTUP_RETURN_CONTRACT", () => {
|
|
175
|
+
const p = (0, worker_packet_js_1.compileStartupPacket)(BASE);
|
|
176
|
+
(0, vitest_1.expect)(p.return_contract).toEqual(worker_packet_js_1.STARTUP_RETURN_CONTRACT);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
// ── compilePreflightPacket ────────────────────────────────────────────────────
|
|
180
|
+
(0, vitest_1.describe)("compilePreflightPacket", () => {
|
|
181
|
+
(0, vitest_1.it)("produces worker_role preflight", () => {
|
|
182
|
+
const p = (0, worker_packet_js_1.compilePreflightPacket)(BASE);
|
|
183
|
+
(0, vitest_1.expect)(p.worker_role).toBe("preflight");
|
|
184
|
+
});
|
|
185
|
+
(0, vitest_1.it)("has empty active_child", () => {
|
|
186
|
+
const p = (0, worker_packet_js_1.compilePreflightPacket)(BASE);
|
|
187
|
+
(0, vitest_1.expect)(p.active_child).toBe("");
|
|
188
|
+
});
|
|
189
|
+
(0, vitest_1.it)("uses cleanup_on_exit: exit-immediately", () => {
|
|
190
|
+
const p = (0, worker_packet_js_1.compilePreflightPacket)(BASE);
|
|
191
|
+
(0, vitest_1.expect)(p.lifecycle.cleanup_on_exit).toBe("exit-immediately");
|
|
192
|
+
});
|
|
193
|
+
(0, vitest_1.it)("has empty allowed_scope (read-only check)", () => {
|
|
194
|
+
const p = (0, worker_packet_js_1.compilePreflightPacket)(BASE);
|
|
195
|
+
(0, vitest_1.expect)(p.instructions.allowed_scope).toEqual([]);
|
|
196
|
+
});
|
|
197
|
+
(0, vitest_1.it)("return_contract matches PREFLIGHT_RETURN_CONTRACT", () => {
|
|
198
|
+
const p = (0, worker_packet_js_1.compilePreflightPacket)(BASE);
|
|
199
|
+
(0, vitest_1.expect)(p.return_contract).toEqual(worker_packet_js_1.PREFLIGHT_RETURN_CONTRACT);
|
|
200
|
+
});
|
|
201
|
+
(0, vitest_1.it)("populates result_file_contract when resultFile is provided", () => {
|
|
202
|
+
const p = (0, worker_packet_js_1.compilePreflightPacket)({ ...BASE, resultFile: "/tmp/result.json" });
|
|
203
|
+
(0, vitest_1.expect)(p.result_file_contract).toEqual({ result_file: "/tmp/result.json" });
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
// ── Role context (POL-227) ────────────────────────────────────────────────────
|
|
207
|
+
(0, vitest_1.describe)("role_context", () => {
|
|
208
|
+
(0, vitest_1.it)("impl packet has worker role context", () => {
|
|
209
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
210
|
+
(0, vitest_1.expect)(p.role_context.role).toBe("worker");
|
|
211
|
+
(0, vitest_1.expect)(p.role_context.role_authority).toBe("implementation");
|
|
212
|
+
(0, vitest_1.expect)(p.role_context.may_implement).toBe(true);
|
|
213
|
+
(0, vitest_1.expect)(p.role_context.may_assign_workers).toBe(false);
|
|
214
|
+
(0, vitest_1.expect)(Array.isArray(p.role_context.prohibited_actions)).toBe(true);
|
|
215
|
+
(0, vitest_1.expect)(p.role_context.prohibited_actions.length).toBeGreaterThan(0);
|
|
216
|
+
});
|
|
217
|
+
(0, vitest_1.it)("startup packet has foreman role context", () => {
|
|
218
|
+
const p = (0, worker_packet_js_1.compileStartupPacket)(BASE);
|
|
219
|
+
(0, vitest_1.expect)(p.role_context.role).toBe("foreman");
|
|
220
|
+
(0, vitest_1.expect)(p.role_context.may_implement).toBe(false);
|
|
221
|
+
(0, vitest_1.expect)(p.role_context.may_assign_workers).toBe(true);
|
|
222
|
+
});
|
|
223
|
+
(0, vitest_1.it)("finalize packet has foreman role context", () => {
|
|
224
|
+
const p = (0, worker_packet_js_1.compileFinalizePacket)(BASE);
|
|
225
|
+
(0, vitest_1.expect)(p.role_context.role).toBe("foreman");
|
|
226
|
+
(0, vitest_1.expect)(p.role_context.may_implement).toBe(false);
|
|
227
|
+
});
|
|
228
|
+
(0, vitest_1.it)("preflight packet has foreman role context", () => {
|
|
229
|
+
const p = (0, worker_packet_js_1.compilePreflightPacket)(BASE);
|
|
230
|
+
(0, vitest_1.expect)(p.role_context.role).toBe("foreman");
|
|
231
|
+
(0, vitest_1.expect)(p.role_context.may_implement).toBe(false);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
// ── WorkerPacket as BootstrapPacket ───────────────────────────────────────────
|
|
235
|
+
(0, vitest_1.describe)("WorkerPacket structural compatibility", () => {
|
|
236
|
+
(0, vitest_1.it)("impl packet passes as BootstrapPacket (structural subtype)", () => {
|
|
237
|
+
const p = (0, worker_packet_js_1.compileImplPacket)({ ...BASE, childId: "POL-121" });
|
|
238
|
+
// Assign to BootstrapPacket — should compile without errors
|
|
239
|
+
const bp = p;
|
|
240
|
+
(0, vitest_1.expect)(bp.run_id).toBe("run-001");
|
|
241
|
+
(0, vitest_1.expect)(bp.active_child).toBe("POL-121");
|
|
242
|
+
});
|
|
243
|
+
});
|