@indigoai-us/hq-cli 5.201.0 → 5.201.2
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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.201.2] — 2026-09-25
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- The checkpoint ontology plan tells the model to name a person by the full name the input or the company's entities give, not a first name alone.
|
|
10
|
+
|
|
11
|
+
## [5.201.1] — 2026-09-25
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Outpost grant checks now include child lanes from the owning Outpost. Owner
|
|
16
|
+
records take precedence over duplicate primary records, and each grant
|
|
17
|
+
command reads the owner lane list once.
|
|
18
|
+
- Outpost grant checks re-read owner lanes under the hire lock and use the
|
|
19
|
+
validated Outpost CLI override for the lane-list probe.
|
|
20
|
+
|
|
5
21
|
## [5.201.0] — 2026-09-25
|
|
6
22
|
|
|
7
23
|
### Added
|
package/dist/commands/lanes.js
CHANGED
|
@@ -479,6 +479,14 @@ function laneHireFields(lane, lanes) {
|
|
|
479
479
|
hire_summary: hireSummary,
|
|
480
480
|
};
|
|
481
481
|
}
|
|
482
|
+
function mergeOwnerLaneHierarchy(supplied, ownerLanes) {
|
|
483
|
+
const byId = new Map();
|
|
484
|
+
for (const lane of supplied)
|
|
485
|
+
byId.set(lane.lane_id, lane);
|
|
486
|
+
for (const lane of ownerLanes)
|
|
487
|
+
byId.set(lane.lane_id, lane);
|
|
488
|
+
return [...byId.values()];
|
|
489
|
+
}
|
|
482
490
|
function outpostCliOverride(ctx, outpostId) {
|
|
483
491
|
const envKey = `HQ_LANES_OUTPOST_CLI_${outpostId.toUpperCase().replace(/[^A-Z0-9_]/g, "_")}`;
|
|
484
492
|
const configured = ctx.env[envKey];
|
|
@@ -1031,11 +1039,12 @@ async function loadHostCapacitySnapshots(ctx, hqRoot, config = loadLanesConfig(h
|
|
|
1031
1039
|
};
|
|
1032
1040
|
}
|
|
1033
1041
|
async function readOutpostLaneRecords(ctx, outpostId) {
|
|
1042
|
+
const hqBinary = outpostCliOverride(ctx, outpostId);
|
|
1034
1043
|
let result;
|
|
1035
1044
|
try {
|
|
1036
1045
|
result = await ctx.dispatchOutpostExec({
|
|
1037
1046
|
outpostId,
|
|
1038
|
-
command: buildOutpostLaneListCommand(),
|
|
1047
|
+
command: buildOutpostLaneListCommand({ hqBinary }),
|
|
1039
1048
|
timeoutSeconds: CAPACITY_PROBE_TIMEOUT_MS / 1000,
|
|
1040
1049
|
waitMs: CAPACITY_PROBE_TIMEOUT_MS,
|
|
1041
1050
|
});
|
|
@@ -3312,9 +3321,20 @@ async function dispatchOutpostLaneCommand(ctx, lane, action, options) {
|
|
|
3312
3321
|
throw new LanesError("outpost_dispatch_failed", `Lane ${lane.lane_id} has no Outpost host to dispatch to`, { lane_id: lane.lane_id });
|
|
3313
3322
|
}
|
|
3314
3323
|
const outpostId = lane.host.id;
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3324
|
+
let grantContext;
|
|
3325
|
+
let grantHierarchy;
|
|
3326
|
+
if (action === "grant") {
|
|
3327
|
+
const enforcementEnabled = await ctx.laneHireGrantsEnabled(lane.company);
|
|
3328
|
+
let hierarchy = loadAllLanes(ctx.hqRoot());
|
|
3329
|
+
const ownerLanes = await readOutpostLaneRecords(ctx, outpostId);
|
|
3330
|
+
const byId = new Map(hierarchy.map((record) => [record.lane_id, record]));
|
|
3331
|
+
for (const ownerLane of ownerLanes) {
|
|
3332
|
+
byId.set(ownerLane.lane_id, ownerLane);
|
|
3333
|
+
}
|
|
3334
|
+
hierarchy = [...byId.values()];
|
|
3335
|
+
grantHierarchy = hierarchy;
|
|
3336
|
+
grantContext = createOutpostHireGrantContext(lane, hierarchy, enforcementEnabled);
|
|
3337
|
+
}
|
|
3318
3338
|
let dispatched;
|
|
3319
3339
|
try {
|
|
3320
3340
|
dispatched = await ctx.dispatchOutpostExec({
|
|
@@ -3407,6 +3427,7 @@ async function dispatchOutpostLaneCommand(ctx, lane, action, options) {
|
|
|
3407
3427
|
...remote,
|
|
3408
3428
|
lane_id: ownerLane.lane_id,
|
|
3409
3429
|
lane: ownerLane,
|
|
3430
|
+
...laneHireFields(ownerLane, grantHierarchy ?? []),
|
|
3410
3431
|
outpost_id: outpostId,
|
|
3411
3432
|
outpost_command_id: dispatched.commandId,
|
|
3412
3433
|
outpost_transport: "outposts_exec",
|
|
@@ -4518,7 +4539,11 @@ async function applyHireGrant(ctx, laneId, hireGrant, authorization, grantContex
|
|
|
4518
4539
|
(!grantContext || !sameHireGrantSenior(current.senior, grantContext.expected_senior))) {
|
|
4519
4540
|
throw new LanesError("hire_grant_senior_changed", `Lane ${laneId}'s senior changed before the Outpost applied the grant update`, { lane_id: laneId, current_senior: current.senior });
|
|
4520
4541
|
}
|
|
4521
|
-
const hierarchy = grantContext
|
|
4542
|
+
const hierarchy = grantContext
|
|
4543
|
+
? authorization === "ssm-owner-dispatch"
|
|
4544
|
+
? mergeOwnerLaneHierarchy(grantContext.hierarchy, loadAllLanes(hqRoot))
|
|
4545
|
+
: grantContext.hierarchy
|
|
4546
|
+
: loadAllLanes(hqRoot);
|
|
4522
4547
|
if (enforce && current.senior.kind === "lane") {
|
|
4523
4548
|
if (!current.senior.id) {
|
|
4524
4549
|
throw new LanesError("hire_grant_senior_invalid", `Lane ${laneId} has a lane senior without an id`, {
|
|
@@ -4604,7 +4629,8 @@ async function runGrantOwnerTarget(ctx, laneId, opts) {
|
|
|
4604
4629
|
const hireGrant = parseHireGrant(opts.hire);
|
|
4605
4630
|
const grantContext = parseOutpostHireGrantContext(opts.grantContext, laneId);
|
|
4606
4631
|
const hqRoot = ctx.hqRoot();
|
|
4607
|
-
|
|
4632
|
+
const updated = await applyHireGrant(ctx, laneId, hireGrant, "ssm-owner-dispatch", grantContext);
|
|
4633
|
+
printGrantResult(hqRoot, updated, mergeOwnerLaneHierarchy(grantContext.hierarchy, loadAllLanes(hqRoot)));
|
|
4608
4634
|
}
|
|
4609
4635
|
async function runBackfillGrants(ctx, opts) {
|
|
4610
4636
|
if (opts.apply && opts.dryRun) {
|
|
@@ -29,7 +29,7 @@ const CANDIDATE_INSTRUCTIONS = [
|
|
|
29
29
|
`Write ${CANDIDATES_FILE} in the run directory as {"schema":"${CANDIDATES_SCHEMA}","candidates":[...]} and nothing else.`,
|
|
30
30
|
"Each candidate: {input, type, name, aliases, confidence, evidence}. input is one of this plan's input ids; type is person, project, company or concept; name is the entity's full proper name; aliases are other names the input uses for it (at most 5); confidence is 0 to 1; evidence is a short quote from the input.",
|
|
31
31
|
"Read only the files and line ranges this plan lists. For a signal, read its body and name the entities in missing_refs if the signal supports them.",
|
|
32
|
-
"Name the specific people, projects, products, companies and named concepts that the input says something about. That includes the company that owns this knowledge and its own products when the input describes them. Name a third-party tool, vendor or service only when a section of the input is about it; skip ones that appear in a list, a stack summary or a passing mention. Skip generic words, file names and headings.",
|
|
32
|
+
"Name the specific people, projects, products, companies and named concepts that the input says something about. That includes the company that owns this knowledge and its own products when the input describes them. Name a third-party tool, vendor or service only when a section of the input is about it; skip ones that appear in a list, a stack summary or a passing mention. Skip generic words, file names and headings. Name a person by the full name the input or the company's entities give, not a first name alone.",
|
|
33
33
|
"For the session input (its text is session_text in this plan), name only entities that already exist in the company and that the session did work on. Session candidates are recorded as links, never created.",
|
|
34
34
|
"Do not create, edit, move or delete anything under ontology/, signals/ or sources/ yourself.",
|
|
35
35
|
];
|
|
@@ -72,7 +72,7 @@ export declare function parseOutpostPickupPayload(raw: unknown): OutpostPickupPa
|
|
|
72
72
|
export declare function buildOutpostPickupCommand(payloadUrl: string): string;
|
|
73
73
|
/** Bounded, read-only capacity query executed by the target Outpost CLI. */
|
|
74
74
|
export declare function buildOutpostCapacityCommand(): string;
|
|
75
|
-
/** Read
|
|
75
|
+
/** Read lane records owned by an Outpost, using its configured HQ binary when set. */
|
|
76
76
|
export declare function buildOutpostLaneListCommand(input?: {
|
|
77
77
|
hqBinary?: string;
|
|
78
78
|
}): string;
|
|
@@ -65,7 +65,7 @@ export function buildOutpostPickupCommand(payloadUrl) {
|
|
|
65
65
|
export function buildOutpostCapacityCommand() {
|
|
66
66
|
return withRemoteHqDir(joinCommandParts(["hq", "lanes", "capacity", "--json"]));
|
|
67
67
|
}
|
|
68
|
-
/** Read
|
|
68
|
+
/** Read lane records owned by an Outpost, using its configured HQ binary when set. */
|
|
69
69
|
export function buildOutpostLaneListCommand(input = {}) {
|
|
70
70
|
return withRemoteHqDir(joinCommandParts([
|
|
71
71
|
input.hqBinary?.trim() || "hq",
|