@productbrain/mcp 0.0.1-beta.951 → 0.0.1-beta.958
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.
|
@@ -12527,11 +12527,16 @@ function replaceVocabTokens(body, workspaceCtx, collectionCtxMap) {
|
|
|
12527
12527
|
|
|
12528
12528
|
// src/tools/orient.ts
|
|
12529
12529
|
var PURPOSE_GAP_PREFIX = "purpose-gap-";
|
|
12530
|
-
|
|
12530
|
+
var NON_MEANINGFUL_TASK_RE = /^[\s]*$/u;
|
|
12531
|
+
function taskIsMeaningful(task) {
|
|
12532
|
+
if (typeof task !== "string") return false;
|
|
12533
|
+
return !NON_MEANINGFUL_TASK_RE.test(task);
|
|
12534
|
+
}
|
|
12535
|
+
function reportOrientWrapperBytes(toolResult, truncated, tier, taskProvided) {
|
|
12531
12536
|
try {
|
|
12532
12537
|
const fullToolOutput = JSON.stringify({ content: toolResult.content ?? [] });
|
|
12533
12538
|
const bytes = Buffer.byteLength(fullToolOutput, "utf8");
|
|
12534
|
-
void kernelMutation("agent.reportOrientMetric", { bytes, truncated }).catch(() => {
|
|
12539
|
+
void kernelMutation("agent.reportOrientMetric", { bytes, truncated, tier, taskProvided }).catch(() => {
|
|
12535
12540
|
});
|
|
12536
12541
|
} catch {
|
|
12537
12542
|
}
|
|
@@ -12584,7 +12589,7 @@ var VALID_TASK_DOMAINS = [
|
|
|
12584
12589
|
var orientSchema = z21.object({
|
|
12585
12590
|
mode: z21.enum(["full", "brief"]).optional().default("full").describe("full = full context (default). brief = compact summary for mid-session re-orientation. Prefer using the `tier` param for depth control."),
|
|
12586
12591
|
tier: z21.enum(["summary", "standard", "full"]).optional().describe(
|
|
12587
|
-
"Payload depth. summary
|
|
12592
|
+
"Payload depth. Defaults to summary (~10 KB) when task is provided; standard (~256 KB) when task is absent. Pass summary, standard, or full to override."
|
|
12588
12593
|
),
|
|
12589
12594
|
task: z21.string().optional().describe("Natural-language task description for task-scoped context. When provided, orient returns scored, relevant entries for the task."),
|
|
12590
12595
|
scope: z21.enum(VALID_TASK_DOMAINS).optional().describe(`Optional domain scope to filter governance to entries relevant for this domain. Valid values: ${VALID_TASK_DOMAINS.join(", ")}.`)
|
|
@@ -12613,712 +12618,725 @@ function registerOrientTool(server) {
|
|
|
12613
12618
|
"orient",
|
|
12614
12619
|
{
|
|
12615
12620
|
title: "Orient \u2014 Task Grounding",
|
|
12616
|
-
description: "Task-grounded context loader. Use AFTER `start_pb` (the canonical session opener) to load governance and context for a specific task. Returns workspace context with a single recommended next action for low-readiness workspaces, or a standup-style briefing for established workspaces.\n\n**Not the session opener.** For 'how do I begin a session' or 'Start PB', call `start_pb` instead. `orient` is for refreshing or scoping context once a session is already underway.\n\nCompleting orientation unlocks write tools for the active session.\n\n**tier:** Controls payload depth
|
|
12621
|
+
description: "Task-grounded context loader. Use AFTER `start_pb` (the canonical session opener) to load governance and context for a specific task. Returns workspace context with a single recommended next action for low-readiness workspaces, or a standup-style briefing for established workspaces.\n\n**Not the session opener.** For 'how do I begin a session' or 'Start PB', call `start_pb` instead. `orient` is for refreshing or scoping context once a session is already underway.\n\nCompleting orientation unlocks write tools for the active session.\n\n**tier:** Controls payload depth.\n- `summary` (~10 KB) \u2014 compact, calibrated for task-scoped retrieval.\n- `standard` (~256 KB) \u2014 rich, suited to workspace standups.\n- `full` \u2014 complete payload, no cap (use with deliberation).\n\nDefaults: `summary` when `task` is provided; `standard` when `task` is absent. Explicit `tier` always wins. Pair with `mode='brief'` for compact formatting (orthogonal to depth).\n\n**mode:** `full` (default) returns full context. `brief` returns compact summary \u2014 mapped to tier=summary internally. Prefer `tier` for explicit depth control.\n\n**task:** Optional natural-language task description. When provided, returns task-scoped context (scored, relevant entries) in addition to standard orient sections.\n\n**scope:** Optional domain scope. Filters governance entries to those relevant for the specified domain. Authority roots include strategy, product, product-design, engineering, architecture, data, governance, and go-to-market. Child scopes such as product-design/ux, engineering/frontend, data/analytics, and governance/principles are accepted. Legacy internal scopes remain accepted.",
|
|
12617
12622
|
inputSchema: orientSchema,
|
|
12618
12623
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
12619
12624
|
},
|
|
12620
|
-
thinWrapper(
|
|
12621
|
-
|
|
12622
|
-
|
|
12623
|
-
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12625
|
+
thinWrapper(_handleOrient)
|
|
12626
|
+
);
|
|
12627
|
+
}
|
|
12628
|
+
async function _handleOrient({ mode = "full", tier, task, scope }) {
|
|
12629
|
+
const errors = [];
|
|
12630
|
+
const callTier = tier ?? (mode === "brief" ? "summary" : void 0);
|
|
12631
|
+
const resolvedTier = callTier ?? (taskIsMeaningful(task) ? "summary" : "standard");
|
|
12632
|
+
if (scope && !task) {
|
|
12633
|
+
errors.push("--scope requires --task to filter governance. Scope was ignored.");
|
|
12634
|
+
}
|
|
12635
|
+
const agentSessionId = getAgentSessionId();
|
|
12636
|
+
if (isSessionOriented() && mode === "brief" && !task) {
|
|
12637
|
+
return {
|
|
12638
|
+
content: [{
|
|
12639
|
+
type: "text",
|
|
12640
|
+
text: "Already oriented. Session active, writes unlocked.\n\n" + taskGroundingWarningLines().join("\n") + "Use `orient mode='full'` for workspace context or `orient task='...'` before substantive work."
|
|
12641
|
+
}],
|
|
12642
|
+
structuredContent: success(
|
|
12643
|
+
"Already oriented. Session active, writes unlocked.",
|
|
12644
|
+
{
|
|
12645
|
+
alreadyOriented: true,
|
|
12646
|
+
sessionId: agentSessionId,
|
|
12647
|
+
taskGroundingStatus: "workspace_only",
|
|
12648
|
+
taskGroundingRequired: true,
|
|
12649
|
+
nextStep: 'Run `orient task="describe the work"` before substantive work.'
|
|
12650
|
+
}
|
|
12651
|
+
)
|
|
12652
|
+
};
|
|
12653
|
+
}
|
|
12654
|
+
let wsCtx = null;
|
|
12655
|
+
try {
|
|
12656
|
+
wsCtx = await getWorkspaceContext();
|
|
12657
|
+
} catch (e) {
|
|
12658
|
+
errors.push(`Workspace: ${e instanceof Error ? e.message : String(e)}`);
|
|
12659
|
+
}
|
|
12660
|
+
let priorSessions = [];
|
|
12661
|
+
let recoveryBlock = null;
|
|
12662
|
+
let orientView = null;
|
|
12663
|
+
try {
|
|
12664
|
+
const orientArgs = {};
|
|
12665
|
+
if (task) orientArgs.task = task;
|
|
12666
|
+
if (scope) orientArgs.scope = scope;
|
|
12667
|
+
if (callTier) orientArgs.tier = callTier;
|
|
12668
|
+
orientView = await kernelQuery("chain.getOrientView", orientArgs);
|
|
12669
|
+
} catch {
|
|
12670
|
+
}
|
|
12671
|
+
let vocabCtx;
|
|
12672
|
+
try {
|
|
12673
|
+
const vocab = await kernelQuery("chain.getVocabulary", {});
|
|
12674
|
+
if (vocab?.collectionLabels || vocab?.collectionDefaults) {
|
|
12675
|
+
vocabCtx = {
|
|
12676
|
+
...vocab.collectionLabels ? { collectionLabels: vocab.collectionLabels } : {},
|
|
12677
|
+
...vocab.collectionDefaults ? { collectionDefaults: vocab.collectionDefaults } : {}
|
|
12678
|
+
};
|
|
12679
|
+
}
|
|
12680
|
+
} catch {
|
|
12681
|
+
}
|
|
12682
|
+
if (orientView) {
|
|
12683
|
+
priorSessions = orientView.priorSessions ?? [];
|
|
12684
|
+
recoveryBlock = orientView.recoveryBlock ?? null;
|
|
12685
|
+
}
|
|
12686
|
+
const hasTaskGrounding = Boolean(task && orientView?.taskContext?.context?.length > 0);
|
|
12687
|
+
if (wsCtx && hasTaskGrounding && orientView?.writeBackHints) {
|
|
12688
|
+
const hints = Array.isArray(orientView.writeBackHints) ? orientView.writeBackHints : [];
|
|
12689
|
+
if (hints.length > 0) {
|
|
12690
|
+
trackWriteBackHintServed(wsCtx.workspaceId, {
|
|
12691
|
+
hint_count: hints.length,
|
|
12692
|
+
has_task: !!task
|
|
12693
|
+
});
|
|
12694
|
+
}
|
|
12695
|
+
}
|
|
12696
|
+
let openTensions = [];
|
|
12697
|
+
try {
|
|
12698
|
+
const tensions = await kernelQuery("chain.listEntries", { collectionSlug: "tensions" });
|
|
12699
|
+
openTensions = (tensions ?? []).filter((e) => e.workflowStatus === "open");
|
|
12700
|
+
} catch {
|
|
12701
|
+
}
|
|
12702
|
+
let allCollections = [];
|
|
12703
|
+
try {
|
|
12704
|
+
allCollections = await kernelQuery("chain.listCollections") ?? [];
|
|
12705
|
+
} catch {
|
|
12706
|
+
}
|
|
12707
|
+
let readiness = null;
|
|
12708
|
+
try {
|
|
12709
|
+
readiness = await kernelQuery("chain.workspaceReadiness");
|
|
12710
|
+
} catch (e) {
|
|
12711
|
+
errors.push(`Readiness: ${e instanceof Error ? e.message : String(e)}`);
|
|
12712
|
+
}
|
|
12713
|
+
if (readiness?.stage === "blank") {
|
|
12714
|
+
const scanLines = [
|
|
12715
|
+
`# Welcome to ${wsCtx?.workspaceName ?? "your workspace"}`,
|
|
12716
|
+
"",
|
|
12717
|
+
"Your workspace is fresh \u2014 let's set it up.",
|
|
12718
|
+
"",
|
|
12719
|
+
"**Recommended:** call the `start` tool instead of `orient` for the best first-run experience.",
|
|
12720
|
+
"It will guide you through setting up your workspace \u2014 you can tell me about your product, scan your codebase, or use a preset.",
|
|
12721
|
+
"",
|
|
12722
|
+
"Or tell me about your product and I'll start capturing knowledge directly."
|
|
12723
|
+
];
|
|
12724
|
+
let oriented = false;
|
|
12725
|
+
let orientationStatus2 = "no_session";
|
|
12726
|
+
if (agentSessionId) {
|
|
12654
12727
|
try {
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
orientView = await kernelQuery("chain.getOrientView", orientArgs);
|
|
12728
|
+
await kernelCall("agent.markOriented", { sessionId: agentSessionId });
|
|
12729
|
+
setSessionOriented(true);
|
|
12730
|
+
oriented = true;
|
|
12731
|
+
orientationStatus2 = "complete";
|
|
12660
12732
|
} catch {
|
|
12733
|
+
orientationStatus2 = "failed";
|
|
12661
12734
|
}
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12735
|
+
}
|
|
12736
|
+
const blankResult = {
|
|
12737
|
+
content: [{ type: "text", text: scanLines.join("\n") }],
|
|
12738
|
+
structuredContent: success(
|
|
12739
|
+
"Workspace is blank. Use the start_pb tool for guided setup.",
|
|
12740
|
+
{ stage: "blank", readinessScore: readiness?.score ?? 0, oriented, orientationStatus: orientationStatus2, redirectHint: "Use the `start_pb` tool for the full guided setup experience." },
|
|
12741
|
+
[{ tool: "start_pb", description: "Guided workspace setup", parameters: {} }]
|
|
12742
|
+
)
|
|
12743
|
+
};
|
|
12744
|
+
reportOrientWrapperBytes(blankResult, false, resolvedTier, taskIsMeaningful(task));
|
|
12745
|
+
return blankResult;
|
|
12746
|
+
}
|
|
12747
|
+
const lines = [];
|
|
12748
|
+
const isLowReadiness = readiness && readiness.score < 50;
|
|
12749
|
+
if (wsCtx) {
|
|
12750
|
+
lines.push(`# ${wsCtx.workspaceName}`);
|
|
12751
|
+
lines.push(`_Workspace \`${wsCtx.workspaceSlug}\` \u2014 Product Brain is healthy._`);
|
|
12752
|
+
} else {
|
|
12753
|
+
lines.push("# Workspace");
|
|
12754
|
+
lines.push("_Could not resolve workspace._");
|
|
12755
|
+
}
|
|
12756
|
+
lines.push("");
|
|
12757
|
+
lines.push(...taskGroundingWarningLines(task, hasTaskGrounding));
|
|
12758
|
+
if (mode === "brief") {
|
|
12759
|
+
const briefStage = readiness?.stage ?? (readiness?.score != null ? readiness.score < 50 ? "seeded" : "grounded" : "unknown");
|
|
12760
|
+
lines.push(`Brain stage: ${briefStage}`);
|
|
12761
|
+
if (orientView?.strategicContext) {
|
|
12762
|
+
const sc = orientView.strategicContext;
|
|
12763
|
+
if (sc.vision) lines.push(`Vision: ${sc.vision}`);
|
|
12764
|
+
if (sc.purpose) lines.push(`Purpose: ${sc.purpose}`);
|
|
12765
|
+
if (sc.productAreaCount != null && sc.productAreaCount > 0) {
|
|
12766
|
+
lines.push(`Product areas (${sc.productAreaCount}): ${(sc.productAreas ?? []).join(", ")}`);
|
|
12767
|
+
}
|
|
12768
|
+
if (sc.playingFieldCount != null && sc.playingFieldCount > 0) {
|
|
12769
|
+
lines.push(`Playing field (${sc.playingFieldCount}): ${(sc.playingField ?? []).join(", ")}`);
|
|
12770
|
+
}
|
|
12771
|
+
const wpPlural = getCollectionLabel("work_package", "plural", vocabCtx);
|
|
12772
|
+
lines.push(`${sc.activeBetCount} active ${wpPlural}, ${sc.activeTensionCount} tension(s).`);
|
|
12773
|
+
}
|
|
12774
|
+
if (orientView?.taskContext && orientView.taskContext.context.length > 0) {
|
|
12775
|
+
lines.push(`Task context: ${orientView.taskContext.totalFound} relevant entries (${orientView.taskContext.confidence} confidence).`);
|
|
12776
|
+
if (orientView.taskContext.isGroundingStub && orientView.taskContext.groundingNote) {
|
|
12777
|
+
lines.push(`\u26A0\uFE0F ${orientView.taskContext.groundingNote}`);
|
|
12778
|
+
}
|
|
12779
|
+
}
|
|
12780
|
+
if (orientView?.startup?.domainRetrieval) {
|
|
12781
|
+
const retrieval = orientView.startup.domainRetrieval;
|
|
12782
|
+
const scopedTo = retrieval.resolvedDomainSlug ? ` (${retrieval.resolvedDomainSlug})` : "";
|
|
12783
|
+
lines.push(`Domain retrieval: ${retrieval.state}${scopedTo}`);
|
|
12784
|
+
if (retrieval.activeSource) lines.push(`Active source: ${retrieval.activeSource}`);
|
|
12785
|
+
if (retrieval.fallbackReason) lines.push(`Fallback: ${retrieval.fallbackReason}`);
|
|
12786
|
+
if (retrieval.fallbackAction) lines.push(`Action: ${retrieval.fallbackAction}`);
|
|
12787
|
+
if (retrieval.evidenceGap) lines.push(`Evidence gap: ${retrieval.evidenceGap}`);
|
|
12788
|
+
if (retrieval.directRatifiedCount != null || retrieval.inheritedRatifiedCount != null || retrieval.orgFallbackCount != null) {
|
|
12789
|
+
lines.push(`Domain relation evidence: ${retrieval.directRatifiedCount ?? 0} direct, ${retrieval.inheritedRatifiedCount ?? 0} inherited, ${retrieval.orgFallbackCount ?? 0} org fallback`);
|
|
12790
|
+
}
|
|
12791
|
+
}
|
|
12792
|
+
if (orientView?.writeBackHints && orientView.writeBackHints.length > 0) {
|
|
12793
|
+
lines.push("");
|
|
12794
|
+
lines.push("Write-back hints (what to capture this session):");
|
|
12795
|
+
for (const h of orientView.writeBackHints) {
|
|
12796
|
+
lines.push(` ${h.collectionSlug}: ${h.hint}`);
|
|
12672
12797
|
}
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
if (hints.length > 0) {
|
|
12681
|
-
trackWriteBackHintServed(wsCtx.workspaceId, {
|
|
12682
|
-
hint_count: hints.length,
|
|
12683
|
-
has_task: !!task
|
|
12684
|
-
});
|
|
12685
|
-
}
|
|
12798
|
+
}
|
|
12799
|
+
if (orientView?.activeWorkPackages?.length > 0) {
|
|
12800
|
+
for (const e of orientView.activeWorkPackages) {
|
|
12801
|
+
const tensions = e.linkedTensions;
|
|
12802
|
+
const tensionPart = tensions?.length ? ` \u2014 ${tensions.map((t) => `${t.entryId ?? t.name} (${t.severity ?? "\u2014"})`).join(", ")}` : "";
|
|
12803
|
+
const originPart = e.origin ? ` (origin: ${e.origin})` : "";
|
|
12804
|
+
lines.push(`- \`${e.entryId ?? e._id}\` ${e.name}${originPart}${tensionPart}`);
|
|
12686
12805
|
}
|
|
12687
|
-
|
|
12688
|
-
|
|
12689
|
-
|
|
12690
|
-
|
|
12691
|
-
|
|
12806
|
+
}
|
|
12807
|
+
if (orientView?.trustMetrics) {
|
|
12808
|
+
const tm = orientView.trustMetrics;
|
|
12809
|
+
if (tm.unverified > 0 || tm.verified > 0) {
|
|
12810
|
+
const capNote = tm.scannedCap ? "+" : "";
|
|
12811
|
+
lines.push(`Trust: ${tm.verified} verified, ${tm.unverified} unverified, ${tm.noStatus} no-status (${tm.total}${capNote} scanned).`);
|
|
12692
12812
|
}
|
|
12693
|
-
|
|
12694
|
-
|
|
12695
|
-
|
|
12696
|
-
|
|
12813
|
+
}
|
|
12814
|
+
const briefWna = formatWhatNeedsAttentionBrief(orientView?.whatNeedsAttention);
|
|
12815
|
+
if (briefWna.length > 0) {
|
|
12816
|
+
lines.push("");
|
|
12817
|
+
lines.push(...briefWna);
|
|
12818
|
+
}
|
|
12819
|
+
const briefGaps = readiness?.gaps ?? [];
|
|
12820
|
+
if (briefGaps.length > 0) {
|
|
12821
|
+
const oneLiner = formatGapOneLiner(briefGaps[0]);
|
|
12822
|
+
if (oneLiner) lines.push(oneLiner);
|
|
12823
|
+
}
|
|
12824
|
+
const briefClassificationGaps = briefGaps.filter((g) => g.id?.startsWith?.(PURPOSE_GAP_PREFIX));
|
|
12825
|
+
if (briefClassificationGaps.length > 0) {
|
|
12826
|
+
lines.push(`${briefClassificationGaps.length} collection(s) with weak purpose \u2014 classification may be inaccurate.`);
|
|
12827
|
+
}
|
|
12828
|
+
if (recoveryBlock) {
|
|
12829
|
+
lines.push("");
|
|
12830
|
+
lines.push(...formatRecoveryBlock(recoveryBlock));
|
|
12831
|
+
} else if (priorSessions.length > 0) {
|
|
12832
|
+
const last = priorSessions[0];
|
|
12833
|
+
const date = last.startedAt ? new Date(last.startedAt).toISOString().split("T")[0] : "unknown";
|
|
12834
|
+
const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;
|
|
12835
|
+
const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;
|
|
12836
|
+
lines.push(`Last session (${date}): ${created} created, ${modified} modified`);
|
|
12837
|
+
}
|
|
12838
|
+
let coherenceSnapshot;
|
|
12839
|
+
const coherence = buildCoherenceSection();
|
|
12840
|
+
if (coherence) {
|
|
12841
|
+
lines.push("");
|
|
12842
|
+
lines.push(...coherence.lines);
|
|
12843
|
+
coherenceSnapshot = coherence.snapshot;
|
|
12844
|
+
}
|
|
12845
|
+
if (allCollections.length > 0) {
|
|
12846
|
+
const docCompleteness = buildDocCompletenessSection(allCollections);
|
|
12847
|
+
if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {
|
|
12848
|
+
lines.push(...docCompleteness.lines);
|
|
12697
12849
|
}
|
|
12698
|
-
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12850
|
+
}
|
|
12851
|
+
if (orientView) {
|
|
12852
|
+
lines.push("");
|
|
12853
|
+
if (task) {
|
|
12854
|
+
const mapGovernanceEntry = (e) => ({
|
|
12855
|
+
entryId: e.entryId,
|
|
12856
|
+
name: e.name,
|
|
12857
|
+
description: typeof e.preview === "string" ? e.preview : void 0,
|
|
12858
|
+
tier: typeof e.tier === "number" ? e.tier : void 0,
|
|
12859
|
+
// Phase 4 (DEC-1141): thread provenance fields to buildOperatingProtocol.
|
|
12860
|
+
provenance: e.provenance,
|
|
12861
|
+
anchoredBy: typeof e.anchoredBy === "string" ? e.anchoredBy : void 0
|
|
12862
|
+
});
|
|
12863
|
+
const gov = orientView.governance ?? { principles: [], standards: [], businessRules: [] };
|
|
12864
|
+
lines.push(...buildOperatingProtocol({
|
|
12865
|
+
principles: (gov.principles ?? []).map(mapGovernanceEntry),
|
|
12866
|
+
standards: (gov.standards ?? []).map(mapGovernanceEntry),
|
|
12867
|
+
businessRules: (gov.businessRules ?? []).map(mapGovernanceEntry)
|
|
12868
|
+
}, task));
|
|
12869
|
+
} else {
|
|
12870
|
+
lines.push(...buildOperatingProtocol());
|
|
12703
12871
|
}
|
|
12704
|
-
|
|
12705
|
-
|
|
12706
|
-
|
|
12707
|
-
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
|
|
12716
|
-
let orientationStatus2 = "no_session";
|
|
12717
|
-
if (agentSessionId) {
|
|
12718
|
-
try {
|
|
12719
|
-
await kernelCall("agent.markOriented", { sessionId: agentSessionId });
|
|
12720
|
-
setSessionOriented(true);
|
|
12721
|
-
oriented = true;
|
|
12722
|
-
orientationStatus2 = "complete";
|
|
12723
|
-
} catch {
|
|
12724
|
-
orientationStatus2 = "failed";
|
|
12725
|
-
}
|
|
12726
|
-
}
|
|
12727
|
-
const blankResult = {
|
|
12728
|
-
content: [{ type: "text", text: scanLines.join("\n") }],
|
|
12729
|
-
structuredContent: success(
|
|
12730
|
-
"Workspace is blank. Use the start_pb tool for guided setup.",
|
|
12731
|
-
{ stage: "blank", readinessScore: readiness?.score ?? 0, oriented, orientationStatus: orientationStatus2, redirectHint: "Use the `start_pb` tool for the full guided setup experience." },
|
|
12732
|
-
[{ tool: "start_pb", description: "Guided workspace setup", parameters: {} }]
|
|
12733
|
-
)
|
|
12734
|
-
};
|
|
12735
|
-
reportOrientWrapperBytes(blankResult, false);
|
|
12736
|
-
return blankResult;
|
|
12872
|
+
}
|
|
12873
|
+
let orientationStatus2 = "no_session";
|
|
12874
|
+
if (agentSessionId && hasTaskGrounding) {
|
|
12875
|
+
const orientedOk = await markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapshot);
|
|
12876
|
+
if (orientedOk) {
|
|
12877
|
+
orientationStatus2 = "complete";
|
|
12878
|
+
lines.push("---");
|
|
12879
|
+
lines.push(`Orientation complete. Session ${agentSessionId}. Write tools available.`);
|
|
12880
|
+
} else {
|
|
12881
|
+
orientationStatus2 = "failed";
|
|
12882
|
+
lines.push("---");
|
|
12883
|
+
lines.push("_Warning: Could not mark session as oriented. Write tools may be restricted._");
|
|
12737
12884
|
}
|
|
12738
|
-
|
|
12739
|
-
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
|
|
12885
|
+
} else if (agentSessionId) {
|
|
12886
|
+
orientationStatus2 = "task_required";
|
|
12887
|
+
lines.push("---");
|
|
12888
|
+
lines.push('Workspace orientation loaded. Write tools stay locked until you run `orient task="describe the work"`.');
|
|
12889
|
+
} else {
|
|
12890
|
+
lines.push("---");
|
|
12891
|
+
lines.push("_No active agent session. Call `session action=start` to begin._");
|
|
12892
|
+
}
|
|
12893
|
+
const briefTruncated = orientView?._budget?.truncated ?? orientView?._truncated ?? false;
|
|
12894
|
+
if (briefTruncated) {
|
|
12895
|
+
const reasons = orientView?._budget?.truncationReasons;
|
|
12896
|
+
lines.push("");
|
|
12897
|
+
if (reasons && reasons.length > 0) {
|
|
12898
|
+
lines.push(`_Context truncated to fit tier budget: ${reasons.join(", ")}. Use tier=full for complete payload._`);
|
|
12743
12899
|
} else {
|
|
12744
|
-
lines.push("
|
|
12745
|
-
|
|
12900
|
+
lines.push("_Context truncated to fit tier budget. Use tier=full for complete payload._");
|
|
12901
|
+
}
|
|
12902
|
+
}
|
|
12903
|
+
if (errors.length > 0) {
|
|
12904
|
+
lines.push("");
|
|
12905
|
+
for (const err of errors) lines.push(`- ${err}`);
|
|
12906
|
+
}
|
|
12907
|
+
const briefResult = {
|
|
12908
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
12909
|
+
structuredContent: success(
|
|
12910
|
+
`Oriented (brief). Stage: ${readiness?.stage ?? "unknown"}.`,
|
|
12911
|
+
{
|
|
12912
|
+
mode: "brief",
|
|
12913
|
+
stage: readiness?.stage ?? "unknown",
|
|
12914
|
+
oriented: hasTaskGrounding ? isSessionOriented() : false,
|
|
12915
|
+
sessionId: agentSessionId,
|
|
12916
|
+
taskGroundingStatus: hasTaskGrounding ? "task_scoped" : task ? "missing_task_context" : "workspace_only",
|
|
12917
|
+
taskGroundingRequired: !hasTaskGrounding,
|
|
12918
|
+
// STD-219 §4 (DEC-1147): machine-readable stub flag for agent consumers.
|
|
12919
|
+
...orientView?.taskContext?.isGroundingStub ? { groundingStub: true } : {},
|
|
12920
|
+
orientationStatus: orientationStatus2,
|
|
12921
|
+
nextStep: hasTaskGrounding ? void 0 : 'Run `orient task="describe the work"` before substantive work.',
|
|
12922
|
+
...orientView?._budget ? { _budget: orientView._budget } : {}
|
|
12923
|
+
}
|
|
12924
|
+
)
|
|
12925
|
+
};
|
|
12926
|
+
reportOrientWrapperBytes(briefResult, briefTruncated, resolvedTier, taskIsMeaningful(task));
|
|
12927
|
+
return briefResult;
|
|
12928
|
+
}
|
|
12929
|
+
const orientStage = readiness?.stage ?? "seeded";
|
|
12930
|
+
if (isLowReadiness && wsCtx?.createdAt) {
|
|
12931
|
+
const ageDays = Math.floor((Date.now() - wsCtx.createdAt) / (1e3 * 60 * 60 * 24));
|
|
12932
|
+
if (ageDays >= 30) {
|
|
12933
|
+
lines.push(`Your workspace has been around for ${ageDays} days and is still at the **${orientStage}** stage.`);
|
|
12934
|
+
lines.push("Let's close the gaps \u2014 or if the current structure doesn't fit, we can reshape it.");
|
|
12935
|
+
lines.push("");
|
|
12936
|
+
}
|
|
12937
|
+
}
|
|
12938
|
+
let fullCoherenceSnapshot;
|
|
12939
|
+
if (isLowReadiness) {
|
|
12940
|
+
const captureBehaviorNote = (readiness?.governanceMode ?? wsCtx?.governanceMode ?? "open") === "open" ? "_In Open mode, captures commit automatically unless you ask me to keep them as drafts._" : "_Everything stays as a draft until you confirm._";
|
|
12941
|
+
const gaps = readiness.gaps ?? [];
|
|
12942
|
+
if (gaps.length > 0) {
|
|
12943
|
+
const gapCtx = {
|
|
12944
|
+
stage: orientStage,
|
|
12945
|
+
passedChecks: readiness.passedChecks ?? 0,
|
|
12946
|
+
totalChecks: readiness.totalChecks ?? 0,
|
|
12947
|
+
score: readiness.score ?? 0
|
|
12948
|
+
};
|
|
12949
|
+
lines.push(formatTopGapPrompt(gaps[0], gaps.length - 1, gapCtx));
|
|
12950
|
+
lines.push("");
|
|
12951
|
+
lines.push(captureBehaviorNote);
|
|
12952
|
+
lines.push("");
|
|
12953
|
+
const remainingGaps = gaps.length - 1;
|
|
12954
|
+
if (remainingGaps > 0 || openTensions.length > 0) {
|
|
12955
|
+
const parts = [];
|
|
12956
|
+
if (remainingGaps > 0) parts.push(`${remainingGaps} more area${remainingGaps === 1 ? "" : "s"} to cover`);
|
|
12957
|
+
if (openTensions.length > 0) parts.push(`${openTensions.length} open tension${openTensions.length === 1 ? "" : "s"}`);
|
|
12958
|
+
lines.push(`_${parts.join(" and ")} \u2014 ask for full status to see everything._`);
|
|
12959
|
+
lines.push("");
|
|
12746
12960
|
}
|
|
12961
|
+
}
|
|
12962
|
+
lines.push("_Need a collection that doesn't exist yet? Just ask \u2014 I'll set it up._");
|
|
12963
|
+
lines.push("");
|
|
12964
|
+
} else if (readiness) {
|
|
12965
|
+
const fmt = (e) => {
|
|
12966
|
+
const type = e.canonicalKey ?? "generic";
|
|
12967
|
+
const stratum = e.stratum ?? "?";
|
|
12968
|
+
const confidencePart = e.confidence ? ` [confidence: ${e.confidence}]` : "";
|
|
12969
|
+
const reviewOverdue = e.reviewAt && new Date(e.reviewAt).getTime() < Date.now();
|
|
12970
|
+
const overduePart = reviewOverdue ? " [review overdue]" : "";
|
|
12971
|
+
const originPart = e.origin ? ` (origin: ${e.origin})` : "";
|
|
12972
|
+
const mark = provenanceMark(e.provenance);
|
|
12973
|
+
const anchorSuffix = e.anchoredBy ? ` (${e.anchoredBy})` : "";
|
|
12974
|
+
return `- ${mark}\`${e.entryId ?? e._id}\` [${type} \xB7 ${stratum}] ${e.name}${anchorSuffix}${originPart}${confidencePart}${overduePart}`;
|
|
12975
|
+
};
|
|
12976
|
+
const fullCoherence = buildCoherenceSection();
|
|
12977
|
+
if (fullCoherence) {
|
|
12978
|
+
fullCoherenceSnapshot = fullCoherence.snapshot;
|
|
12979
|
+
}
|
|
12980
|
+
if (task) {
|
|
12981
|
+
lines.push(`**Brain stage: ${orientStage}.** Working on: **${task}**`);
|
|
12747
12982
|
lines.push("");
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
12751
|
-
lines.push(
|
|
12752
|
-
if (
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12983
|
+
if (orientView?.strategicContext) {
|
|
12984
|
+
const sc = orientView.strategicContext;
|
|
12985
|
+
lines.push("## Strategic Context");
|
|
12986
|
+
if (sc.vision) lines.push(`**Vision:** ${sc.vision}`);
|
|
12987
|
+
if (sc.purpose) lines.push(`**Purpose:** ${sc.purpose}`);
|
|
12988
|
+
if (sc.productAreaCount != null && sc.productAreaCount > 0) {
|
|
12989
|
+
lines.push(`**Product areas (${sc.productAreaCount}):** ${(sc.productAreas ?? []).join(", ")}`);
|
|
12990
|
+
}
|
|
12991
|
+
if (sc.playingFieldCount != null && sc.playingFieldCount > 0) {
|
|
12992
|
+
lines.push(`**Playing field (${sc.playingFieldCount}):** ${(sc.playingField ?? []).join(", ")}`);
|
|
12993
|
+
}
|
|
12994
|
+
const currentWP = sc.currentWorkPackage;
|
|
12995
|
+
const wpSingularFull = getCollectionLabel("work_package", "singular", vocabCtx);
|
|
12996
|
+
const wpPluralFull = getCollectionLabel("work_package", "plural", vocabCtx);
|
|
12997
|
+
const betLine = currentWP ? `**Current ${wpSingularFull}:** ${currentWP}. ${sc.activeBetCount} active ${wpPluralFull}.` : `No active ${wpPluralFull}.`;
|
|
12998
|
+
lines.push(`${betLine} ${sc.activeTensionCount} open tension(s).`);
|
|
12999
|
+
lines.push("");
|
|
13000
|
+
}
|
|
13001
|
+
if (orientView?.continuingFrom && orientView.continuingFrom.length > 0) {
|
|
13002
|
+
lines.push("## Continuing from");
|
|
13003
|
+
lines.push("_Prior-session entries most relevant to your task._");
|
|
13004
|
+
lines.push("");
|
|
13005
|
+
for (const e of orientView.continuingFrom) {
|
|
13006
|
+
const id = e.entryId ?? e.name;
|
|
13007
|
+
const type = e.canonicalKey ?? "generic";
|
|
13008
|
+
const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
|
|
13009
|
+
lines.push(`- \`${id}\` (score ${e.score}) [${type}]${coll} \u2014 ${e.name}`);
|
|
13010
|
+
if (e.reasoning) lines.push(` _${e.reasoning}_`);
|
|
13011
|
+
if ("primer" in e && typeof e.primer === "string" && e.primer.length > 0) {
|
|
13012
|
+
const PRIMER_MAX = 1200;
|
|
13013
|
+
const primerText = e.primer.length > PRIMER_MAX ? e.primer.slice(0, PRIMER_MAX) + "\n\u2026 (truncated \u2014 use entries action=get for full primer)" : e.primer;
|
|
13014
|
+
lines.push("");
|
|
13015
|
+
lines.push(" **Primer (paste when starting implementation):**");
|
|
13016
|
+
lines.push(" ```");
|
|
13017
|
+
for (const line of primerText.split("\n")) lines.push(" " + line);
|
|
13018
|
+
lines.push(" ```");
|
|
13019
|
+
lines.push("");
|
|
12758
13020
|
}
|
|
12759
|
-
|
|
12760
|
-
|
|
13021
|
+
}
|
|
13022
|
+
lines.push("");
|
|
13023
|
+
}
|
|
13024
|
+
if (orientView?.lastSessionTouched && orientView.lastSessionTouched.length > 0) {
|
|
13025
|
+
lines.push("## Last session touched");
|
|
13026
|
+
lines.push("_Entries created or modified in your most recent session._");
|
|
13027
|
+
lines.push("");
|
|
13028
|
+
for (const e of orientView.lastSessionTouched) {
|
|
13029
|
+
const id = e.entryId ?? e.name;
|
|
13030
|
+
const type = e.canonicalKey ?? "generic";
|
|
13031
|
+
const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
|
|
13032
|
+
lines.push(`- \`${id}\` [${type}]${coll} \u2014 ${e.name}`);
|
|
13033
|
+
if ("primer" in e && typeof e.primer === "string" && e.primer.length > 0) {
|
|
13034
|
+
const PRIMER_MAX = 1200;
|
|
13035
|
+
const primerText = e.primer.length > PRIMER_MAX ? e.primer.slice(0, PRIMER_MAX) + "\n\u2026 (truncated \u2014 use entries action=get for full primer)" : e.primer;
|
|
13036
|
+
lines.push("");
|
|
13037
|
+
lines.push(" **Primer:**");
|
|
13038
|
+
lines.push(" ```");
|
|
13039
|
+
for (const line of primerText.split("\n")) lines.push(" " + line);
|
|
13040
|
+
lines.push(" ```");
|
|
13041
|
+
lines.push("");
|
|
12761
13042
|
}
|
|
12762
|
-
const wpPlural = getCollectionLabel("work_package", "plural", vocabCtx);
|
|
12763
|
-
lines.push(`${sc.activeBetCount} active ${wpPlural}, ${sc.activeTensionCount} tension(s).`);
|
|
12764
13043
|
}
|
|
12765
|
-
|
|
12766
|
-
|
|
13044
|
+
lines.push("");
|
|
13045
|
+
}
|
|
13046
|
+
if (orientView?.taskContext && orientView.taskContext.context.length > 0) {
|
|
13047
|
+
const tc = orientView.taskContext;
|
|
13048
|
+
lines.push("## Task Context");
|
|
13049
|
+
if (tc.isGroundingStub && tc.groundingNote) {
|
|
13050
|
+
lines.push(`> \u26A0\uFE0F ${tc.groundingNote}`);
|
|
13051
|
+
lines.push("");
|
|
12767
13052
|
}
|
|
12768
|
-
if (orientView
|
|
13053
|
+
if (orientView.startup?.domainRetrieval) {
|
|
12769
13054
|
const retrieval = orientView.startup.domainRetrieval;
|
|
12770
13055
|
const scopedTo = retrieval.resolvedDomainSlug ? ` (${retrieval.resolvedDomainSlug})` : "";
|
|
12771
|
-
lines.push(`
|
|
12772
|
-
if (retrieval.activeSource) lines.push(`
|
|
12773
|
-
if (retrieval.fallbackReason) lines.push(`
|
|
12774
|
-
if (retrieval.fallbackAction) lines.push(`
|
|
12775
|
-
if (retrieval.evidenceGap) lines.push(`
|
|
12776
|
-
if (retrieval.directRatifiedCount != null || retrieval.inheritedRatifiedCount != null || retrieval.orgFallbackCount != null) {
|
|
12777
|
-
lines.push(`Domain relation evidence: ${retrieval.directRatifiedCount ?? 0} direct, ${retrieval.inheritedRatifiedCount ?? 0} inherited, ${retrieval.orgFallbackCount ?? 0} org fallback`);
|
|
12778
|
-
}
|
|
12779
|
-
}
|
|
12780
|
-
if (orientView?.writeBackHints && orientView.writeBackHints.length > 0) {
|
|
13056
|
+
lines.push(`_Domain retrieval: ${retrieval.state}${scopedTo}_`);
|
|
13057
|
+
if (retrieval.activeSource) lines.push(`_Active source: ${retrieval.activeSource}_`);
|
|
13058
|
+
if (retrieval.fallbackReason) lines.push(`_${retrieval.fallbackReason}_`);
|
|
13059
|
+
if (retrieval.fallbackAction) lines.push(`_${retrieval.fallbackAction}_`);
|
|
13060
|
+
if (retrieval.evidenceGap) lines.push(`_Evidence gap: ${retrieval.evidenceGap}_`);
|
|
12781
13061
|
lines.push("");
|
|
12782
|
-
lines.push("Write-back hints (what to capture this session):");
|
|
12783
|
-
for (const h of orientView.writeBackHints) {
|
|
12784
|
-
lines.push(` ${h.collectionSlug}: ${h.hint}`);
|
|
12785
|
-
}
|
|
12786
13062
|
}
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
|
|
12790
|
-
|
|
12791
|
-
|
|
12792
|
-
|
|
12793
|
-
}
|
|
13063
|
+
lines.push(`_Task-scoped entries (${tc.confidence} confidence, ${tc.totalFound} relevant)`);
|
|
13064
|
+
lines.push("");
|
|
13065
|
+
for (const e of tc.context) {
|
|
13066
|
+
const id = e.entryId ?? e.name;
|
|
13067
|
+
const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
|
|
13068
|
+
const originTag = e.origin ? ` (origin: ${e.origin})` : "";
|
|
13069
|
+
lines.push(`- \`${id}\` (score ${e.score})${coll}${originTag}${e.name !== id ? ` \u2014 ${e.name}` : ""}`);
|
|
13070
|
+
if (e.preview) lines.push(` _${e.preview}_`);
|
|
13071
|
+
}
|
|
13072
|
+
lines.push("");
|
|
13073
|
+
}
|
|
13074
|
+
if (orientView?.taskContext?.constellationEntries && orientView.taskContext.constellationEntries.length > 0) {
|
|
13075
|
+
lines.push(...formatBetConstellationLines(
|
|
13076
|
+
orientView.taskContext.constellationEntries,
|
|
13077
|
+
orientView.taskContext.constellationBetName
|
|
13078
|
+
));
|
|
13079
|
+
}
|
|
13080
|
+
if (orientView?.writeBackHints && orientView.writeBackHints.length > 0) {
|
|
13081
|
+
lines.push("");
|
|
13082
|
+
lines.push("## Write-Back Hints");
|
|
13083
|
+
lines.push("_What to capture this session (derived from task context):_");
|
|
13084
|
+
lines.push("");
|
|
13085
|
+
for (const h of orientView.writeBackHints) {
|
|
13086
|
+
lines.push(`- **${h.collectionSlug}**: ${h.hint}`);
|
|
12794
13087
|
}
|
|
12795
|
-
|
|
13088
|
+
lines.push("");
|
|
13089
|
+
}
|
|
13090
|
+
if (orientView) {
|
|
13091
|
+
const result = await runAlignmentCheck(
|
|
13092
|
+
task,
|
|
13093
|
+
orientView.activeWorkPackages ?? [],
|
|
13094
|
+
orientView.taskContext?.context
|
|
13095
|
+
);
|
|
13096
|
+
lines.push(...buildAlignmentCheckLines(result));
|
|
13097
|
+
lines.push(...formatInitiativeStatusLines(orientView.initiativeStatus));
|
|
13098
|
+
lines.push(...formatWorkstreamHealthLines(orientView.workstreamHealth));
|
|
13099
|
+
lines.push(...formatWhatNeedsAttentionLines(orientView.whatNeedsAttention));
|
|
13100
|
+
if (orientView.trustMetrics) {
|
|
12796
13101
|
const tm = orientView.trustMetrics;
|
|
12797
|
-
if (tm.
|
|
12798
|
-
const capNote = tm.scannedCap ? "
|
|
12799
|
-
lines.push(
|
|
13102
|
+
if (tm.verified > 0 || tm.unverified > 0) {
|
|
13103
|
+
const capNote = tm.scannedCap ? " (capped at 500)" : "";
|
|
13104
|
+
lines.push("## Trust metrics");
|
|
13105
|
+
lines.push(`_Entry verification status across workspace${capNote}._`);
|
|
13106
|
+
lines.push("");
|
|
13107
|
+
lines.push(`- **Verified:** ${tm.verified}`);
|
|
13108
|
+
lines.push(`- **Unverified:** ${tm.unverified}`);
|
|
13109
|
+
lines.push(`- **No status (pre-BET-240):** ${tm.noStatus}`);
|
|
13110
|
+
lines.push(`- **Total scanned:** ${tm.total}`);
|
|
13111
|
+
lines.push("");
|
|
12800
13112
|
}
|
|
12801
13113
|
}
|
|
12802
|
-
|
|
12803
|
-
|
|
12804
|
-
|
|
12805
|
-
|
|
12806
|
-
|
|
12807
|
-
const
|
|
12808
|
-
if (
|
|
12809
|
-
|
|
12810
|
-
if (oneLiner) lines.push(oneLiner);
|
|
12811
|
-
}
|
|
12812
|
-
const briefClassificationGaps = briefGaps.filter((g) => g.id?.startsWith?.(PURPOSE_GAP_PREFIX));
|
|
12813
|
-
if (briefClassificationGaps.length > 0) {
|
|
12814
|
-
lines.push(`${briefClassificationGaps.length} collection(s) with weak purpose \u2014 classification may be inaccurate.`);
|
|
13114
|
+
}
|
|
13115
|
+
if (fullCoherence) {
|
|
13116
|
+
lines.push(...fullCoherence.lines);
|
|
13117
|
+
}
|
|
13118
|
+
if (allCollections.length > 0) {
|
|
13119
|
+
const docCompleteness = buildDocCompletenessSection(allCollections);
|
|
13120
|
+
if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {
|
|
13121
|
+
lines.push(...docCompleteness.lines);
|
|
12815
13122
|
}
|
|
12816
|
-
|
|
12817
|
-
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
const date = last.startedAt ? new Date(last.startedAt).toISOString().split("T")[0] : "unknown";
|
|
12822
|
-
const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;
|
|
12823
|
-
const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;
|
|
12824
|
-
lines.push(`Last session (${date}): ${created} created, ${modified} modified`);
|
|
12825
|
-
}
|
|
12826
|
-
let coherenceSnapshot;
|
|
12827
|
-
const coherence = buildCoherenceSection();
|
|
12828
|
-
if (coherence) {
|
|
13123
|
+
}
|
|
13124
|
+
if (orientView) {
|
|
13125
|
+
if (orientView.activeWorkPackages?.length > 0) {
|
|
13126
|
+
lines.push("## Active work packages \u2014 current scope");
|
|
13127
|
+
lines.push("_Work outside these work packages requires explicit user confirmation._");
|
|
12829
13128
|
lines.push("");
|
|
12830
|
-
|
|
12831
|
-
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
13129
|
+
for (const e of orientView.activeWorkPackages) {
|
|
13130
|
+
lines.push(fmt(e));
|
|
13131
|
+
const tensions = e.linkedTensions;
|
|
13132
|
+
if (tensions?.length) {
|
|
13133
|
+
const tensionLines = tensions.map((t) => {
|
|
13134
|
+
const meta = [t.severity, t.priority].filter(Boolean).join(", ");
|
|
13135
|
+
return `\`${t.entryId ?? t.name}\` (${t.name}${meta ? `, ${meta}` : ""})`;
|
|
13136
|
+
});
|
|
13137
|
+
lines.push(` Tensions: ${tensionLines.join("; ")}`);
|
|
13138
|
+
}
|
|
12837
13139
|
}
|
|
12838
|
-
}
|
|
12839
|
-
if (orientView) {
|
|
12840
13140
|
lines.push("");
|
|
12841
|
-
if (task) {
|
|
12842
|
-
const mapGovernanceEntry = (e) => ({
|
|
12843
|
-
entryId: e.entryId,
|
|
12844
|
-
name: e.name,
|
|
12845
|
-
description: typeof e.preview === "string" ? e.preview : void 0,
|
|
12846
|
-
tier: typeof e.tier === "number" ? e.tier : void 0,
|
|
12847
|
-
// Phase 4 (DEC-1141): thread provenance fields to buildOperatingProtocol.
|
|
12848
|
-
provenance: e.provenance,
|
|
12849
|
-
anchoredBy: typeof e.anchoredBy === "string" ? e.anchoredBy : void 0
|
|
12850
|
-
});
|
|
12851
|
-
const gov = orientView.governance ?? { principles: [], standards: [], businessRules: [] };
|
|
12852
|
-
lines.push(...buildOperatingProtocol({
|
|
12853
|
-
principles: (gov.principles ?? []).map(mapGovernanceEntry),
|
|
12854
|
-
standards: (gov.standards ?? []).map(mapGovernanceEntry),
|
|
12855
|
-
businessRules: (gov.businessRules ?? []).map(mapGovernanceEntry)
|
|
12856
|
-
}, task));
|
|
12857
|
-
} else {
|
|
12858
|
-
lines.push(...buildOperatingProtocol());
|
|
12859
|
-
}
|
|
12860
|
-
}
|
|
12861
|
-
let orientationStatus2 = "no_session";
|
|
12862
|
-
if (agentSessionId && hasTaskGrounding) {
|
|
12863
|
-
const orientedOk = await markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapshot);
|
|
12864
|
-
if (orientedOk) {
|
|
12865
|
-
orientationStatus2 = "complete";
|
|
12866
|
-
lines.push("---");
|
|
12867
|
-
lines.push(`Orientation complete. Session ${agentSessionId}. Write tools available.`);
|
|
12868
|
-
} else {
|
|
12869
|
-
orientationStatus2 = "failed";
|
|
12870
|
-
lines.push("---");
|
|
12871
|
-
lines.push("_Warning: Could not mark session as oriented. Write tools may be restricted._");
|
|
12872
|
-
}
|
|
12873
|
-
} else if (agentSessionId) {
|
|
12874
|
-
orientationStatus2 = "task_required";
|
|
12875
|
-
lines.push("---");
|
|
12876
|
-
lines.push('Workspace orientation loaded. Write tools stay locked until you run `orient task="describe the work"`.');
|
|
12877
|
-
} else {
|
|
12878
|
-
lines.push("---");
|
|
12879
|
-
lines.push("_No active agent session. Call `session action=start` to begin._");
|
|
12880
13141
|
}
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
13142
|
+
if (orientView.activeGoals?.length > 0) {
|
|
13143
|
+
lines.push("## Active goals");
|
|
13144
|
+
orientView.activeGoals.forEach((e) => lines.push(fmt(e)));
|
|
12884
13145
|
lines.push("");
|
|
12885
|
-
if (reasons && reasons.length > 0) {
|
|
12886
|
-
lines.push(`_Context truncated to fit tier budget: ${reasons.join(", ")}. Use tier=full for complete payload._`);
|
|
12887
|
-
} else {
|
|
12888
|
-
lines.push("_Context truncated to fit tier budget. Use tier=full for complete payload._");
|
|
12889
|
-
}
|
|
12890
13146
|
}
|
|
12891
|
-
if (
|
|
13147
|
+
if (orientView.strategyHighlights?.length > 0) {
|
|
13148
|
+
lines.push("## Strategy highlights");
|
|
13149
|
+
lines.push("_One-sentence strategy, positioning, moat, business model, GTM \u2014 high-level strategic context._");
|
|
12892
13150
|
lines.push("");
|
|
12893
|
-
|
|
12894
|
-
}
|
|
12895
|
-
const briefResult = {
|
|
12896
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
12897
|
-
structuredContent: success(
|
|
12898
|
-
`Oriented (brief). Stage: ${readiness?.stage ?? "unknown"}.`,
|
|
12899
|
-
{
|
|
12900
|
-
mode: "brief",
|
|
12901
|
-
stage: readiness?.stage ?? "unknown",
|
|
12902
|
-
oriented: hasTaskGrounding ? isSessionOriented() : false,
|
|
12903
|
-
sessionId: agentSessionId,
|
|
12904
|
-
taskGroundingStatus: hasTaskGrounding ? "task_scoped" : task ? "missing_task_context" : "workspace_only",
|
|
12905
|
-
taskGroundingRequired: !hasTaskGrounding,
|
|
12906
|
-
orientationStatus: orientationStatus2,
|
|
12907
|
-
nextStep: hasTaskGrounding ? void 0 : 'Run `orient task="describe the work"` before substantive work.',
|
|
12908
|
-
...orientView?._budget ? { _budget: orientView._budget } : {}
|
|
12909
|
-
}
|
|
12910
|
-
)
|
|
12911
|
-
};
|
|
12912
|
-
reportOrientWrapperBytes(briefResult, briefTruncated);
|
|
12913
|
-
return briefResult;
|
|
12914
|
-
}
|
|
12915
|
-
const orientStage = readiness?.stage ?? "seeded";
|
|
12916
|
-
if (isLowReadiness && wsCtx?.createdAt) {
|
|
12917
|
-
const ageDays = Math.floor((Date.now() - wsCtx.createdAt) / (1e3 * 60 * 60 * 24));
|
|
12918
|
-
if (ageDays >= 30) {
|
|
12919
|
-
lines.push(`Your workspace has been around for ${ageDays} days and is still at the **${orientStage}** stage.`);
|
|
12920
|
-
lines.push("Let's close the gaps \u2014 or if the current structure doesn't fit, we can reshape it.");
|
|
13151
|
+
orientView.strategyHighlights.forEach((e) => lines.push(fmt(e)));
|
|
12921
13152
|
lines.push("");
|
|
12922
13153
|
}
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
const captureBehaviorNote = (readiness?.governanceMode ?? wsCtx?.governanceMode ?? "open") === "open" ? "_In Open mode, captures commit automatically unless you ask me to keep them as drafts._" : "_Everything stays as a draft until you confirm._";
|
|
12927
|
-
const gaps = readiness.gaps ?? [];
|
|
12928
|
-
if (gaps.length > 0) {
|
|
12929
|
-
const gapCtx = {
|
|
12930
|
-
stage: orientStage,
|
|
12931
|
-
passedChecks: readiness.passedChecks ?? 0,
|
|
12932
|
-
totalChecks: readiness.totalChecks ?? 0,
|
|
12933
|
-
score: readiness.score ?? 0
|
|
12934
|
-
};
|
|
12935
|
-
lines.push(formatTopGapPrompt(gaps[0], gaps.length - 1, gapCtx));
|
|
13154
|
+
if (orientView.playingField?.length > 0) {
|
|
13155
|
+
lines.push("## Playing field");
|
|
13156
|
+
lines.push("_Products and opportunities in the strategic landscape._");
|
|
12936
13157
|
lines.push("");
|
|
12937
|
-
lines.push(
|
|
13158
|
+
orientView.playingField.forEach((e) => lines.push(fmt(e)));
|
|
12938
13159
|
lines.push("");
|
|
12939
|
-
const remainingGaps = gaps.length - 1;
|
|
12940
|
-
if (remainingGaps > 0 || openTensions.length > 0) {
|
|
12941
|
-
const parts = [];
|
|
12942
|
-
if (remainingGaps > 0) parts.push(`${remainingGaps} more area${remainingGaps === 1 ? "" : "s"} to cover`);
|
|
12943
|
-
if (openTensions.length > 0) parts.push(`${openTensions.length} open tension${openTensions.length === 1 ? "" : "s"}`);
|
|
12944
|
-
lines.push(`_${parts.join(" and ")} \u2014 ask for full status to see everything._`);
|
|
12945
|
-
lines.push("");
|
|
12946
|
-
}
|
|
12947
13160
|
}
|
|
12948
|
-
|
|
12949
|
-
|
|
12950
|
-
|
|
12951
|
-
|
|
12952
|
-
const type = e.canonicalKey ?? "generic";
|
|
12953
|
-
const stratum = e.stratum ?? "?";
|
|
12954
|
-
const confidencePart = e.confidence ? ` [confidence: ${e.confidence}]` : "";
|
|
12955
|
-
const reviewOverdue = e.reviewAt && new Date(e.reviewAt).getTime() < Date.now();
|
|
12956
|
-
const overduePart = reviewOverdue ? " [review overdue]" : "";
|
|
12957
|
-
const originPart = e.origin ? ` (origin: ${e.origin})` : "";
|
|
12958
|
-
const mark = provenanceMark(e.provenance);
|
|
12959
|
-
const anchorSuffix = e.anchoredBy ? ` (${e.anchoredBy})` : "";
|
|
12960
|
-
return `- ${mark}\`${e.entryId ?? e._id}\` [${type} \xB7 ${stratum}] ${e.name}${anchorSuffix}${originPart}${confidencePart}${overduePart}`;
|
|
12961
|
-
};
|
|
12962
|
-
const fullCoherence = buildCoherenceSection();
|
|
12963
|
-
if (fullCoherence) {
|
|
12964
|
-
fullCoherenceSnapshot = fullCoherence.snapshot;
|
|
13161
|
+
if (orientView.recentDecisions?.length > 0) {
|
|
13162
|
+
lines.push("## Recent decisions");
|
|
13163
|
+
orientView.recentDecisions.forEach((e) => lines.push(fmt(e)));
|
|
13164
|
+
lines.push("");
|
|
12965
13165
|
}
|
|
12966
|
-
if (
|
|
12967
|
-
lines.push(
|
|
13166
|
+
if (orientView.recentlySuperseded?.length > 0) {
|
|
13167
|
+
lines.push("## Recently superseded");
|
|
13168
|
+
orientView.recentlySuperseded.forEach((e) => lines.push(fmt(e)));
|
|
12968
13169
|
lines.push("");
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
|
|
12972
|
-
|
|
12973
|
-
|
|
12974
|
-
if (sc.productAreaCount != null && sc.productAreaCount > 0) {
|
|
12975
|
-
lines.push(`**Product areas (${sc.productAreaCount}):** ${(sc.productAreas ?? []).join(", ")}`);
|
|
12976
|
-
}
|
|
12977
|
-
if (sc.playingFieldCount != null && sc.playingFieldCount > 0) {
|
|
12978
|
-
lines.push(`**Playing field (${sc.playingFieldCount}):** ${(sc.playingField ?? []).join(", ")}`);
|
|
12979
|
-
}
|
|
12980
|
-
const currentWP = sc.currentWorkPackage;
|
|
12981
|
-
const wpSingularFull = getCollectionLabel("work_package", "singular", vocabCtx);
|
|
12982
|
-
const wpPluralFull = getCollectionLabel("work_package", "plural", vocabCtx);
|
|
12983
|
-
const betLine = currentWP ? `**Current ${wpSingularFull}:** ${currentWP}. ${sc.activeBetCount} active ${wpPluralFull}.` : `No active ${wpPluralFull}.`;
|
|
12984
|
-
lines.push(`${betLine} ${sc.activeTensionCount} open tension(s).`);
|
|
12985
|
-
lines.push("");
|
|
12986
|
-
}
|
|
12987
|
-
if (orientView?.continuingFrom && orientView.continuingFrom.length > 0) {
|
|
12988
|
-
lines.push("## Continuing from");
|
|
12989
|
-
lines.push("_Prior-session entries most relevant to your task._");
|
|
12990
|
-
lines.push("");
|
|
12991
|
-
for (const e of orientView.continuingFrom) {
|
|
12992
|
-
const id = e.entryId ?? e.name;
|
|
12993
|
-
const type = e.canonicalKey ?? "generic";
|
|
12994
|
-
const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
|
|
12995
|
-
lines.push(`- \`${id}\` (score ${e.score}) [${type}]${coll} \u2014 ${e.name}`);
|
|
12996
|
-
if (e.reasoning) lines.push(` _${e.reasoning}_`);
|
|
12997
|
-
if ("primer" in e && typeof e.primer === "string" && e.primer.length > 0) {
|
|
12998
|
-
const PRIMER_MAX = 1200;
|
|
12999
|
-
const primerText = e.primer.length > PRIMER_MAX ? e.primer.slice(0, PRIMER_MAX) + "\n\u2026 (truncated \u2014 use entries action=get for full primer)" : e.primer;
|
|
13000
|
-
lines.push("");
|
|
13001
|
-
lines.push(" **Primer (paste when starting implementation):**");
|
|
13002
|
-
lines.push(" ```");
|
|
13003
|
-
for (const line of primerText.split("\n")) lines.push(" " + line);
|
|
13004
|
-
lines.push(" ```");
|
|
13005
|
-
lines.push("");
|
|
13006
|
-
}
|
|
13007
|
-
}
|
|
13008
|
-
lines.push("");
|
|
13009
|
-
}
|
|
13010
|
-
if (orientView?.lastSessionTouched && orientView.lastSessionTouched.length > 0) {
|
|
13011
|
-
lines.push("## Last session touched");
|
|
13012
|
-
lines.push("_Entries created or modified in your most recent session._");
|
|
13013
|
-
lines.push("");
|
|
13014
|
-
for (const e of orientView.lastSessionTouched) {
|
|
13015
|
-
const id = e.entryId ?? e.name;
|
|
13016
|
-
const type = e.canonicalKey ?? "generic";
|
|
13017
|
-
const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
|
|
13018
|
-
lines.push(`- \`${id}\` [${type}]${coll} \u2014 ${e.name}`);
|
|
13019
|
-
if ("primer" in e && typeof e.primer === "string" && e.primer.length > 0) {
|
|
13020
|
-
const PRIMER_MAX = 1200;
|
|
13021
|
-
const primerText = e.primer.length > PRIMER_MAX ? e.primer.slice(0, PRIMER_MAX) + "\n\u2026 (truncated \u2014 use entries action=get for full primer)" : e.primer;
|
|
13022
|
-
lines.push("");
|
|
13023
|
-
lines.push(" **Primer:**");
|
|
13024
|
-
lines.push(" ```");
|
|
13025
|
-
for (const line of primerText.split("\n")) lines.push(" " + line);
|
|
13026
|
-
lines.push(" ```");
|
|
13027
|
-
lines.push("");
|
|
13028
|
-
}
|
|
13029
|
-
}
|
|
13030
|
-
lines.push("");
|
|
13031
|
-
}
|
|
13032
|
-
if (orientView?.taskContext && orientView.taskContext.context.length > 0) {
|
|
13033
|
-
const tc = orientView.taskContext;
|
|
13034
|
-
lines.push("## Task Context");
|
|
13035
|
-
if (orientView.startup?.domainRetrieval) {
|
|
13036
|
-
const retrieval = orientView.startup.domainRetrieval;
|
|
13037
|
-
const scopedTo = retrieval.resolvedDomainSlug ? ` (${retrieval.resolvedDomainSlug})` : "";
|
|
13038
|
-
lines.push(`_Domain retrieval: ${retrieval.state}${scopedTo}_`);
|
|
13039
|
-
if (retrieval.activeSource) lines.push(`_Active source: ${retrieval.activeSource}_`);
|
|
13040
|
-
if (retrieval.fallbackReason) lines.push(`_${retrieval.fallbackReason}_`);
|
|
13041
|
-
if (retrieval.fallbackAction) lines.push(`_${retrieval.fallbackAction}_`);
|
|
13042
|
-
if (retrieval.evidenceGap) lines.push(`_Evidence gap: ${retrieval.evidenceGap}_`);
|
|
13043
|
-
lines.push("");
|
|
13044
|
-
}
|
|
13045
|
-
lines.push(`_Task-scoped entries (${tc.confidence} confidence, ${tc.totalFound} relevant)`);
|
|
13046
|
-
lines.push("");
|
|
13047
|
-
for (const e of tc.context) {
|
|
13048
|
-
const id = e.entryId ?? e.name;
|
|
13049
|
-
const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : "";
|
|
13050
|
-
const originTag = e.origin ? ` (origin: ${e.origin})` : "";
|
|
13051
|
-
lines.push(`- \`${id}\` (score ${e.score})${coll}${originTag}${e.name !== id ? ` \u2014 ${e.name}` : ""}`);
|
|
13052
|
-
if (e.preview) lines.push(` _${e.preview}_`);
|
|
13053
|
-
}
|
|
13054
|
-
lines.push("");
|
|
13055
|
-
}
|
|
13056
|
-
if (orientView?.taskContext?.constellationEntries && orientView.taskContext.constellationEntries.length > 0) {
|
|
13057
|
-
lines.push(...formatBetConstellationLines(
|
|
13058
|
-
orientView.taskContext.constellationEntries,
|
|
13059
|
-
orientView.taskContext.constellationBetName
|
|
13060
|
-
));
|
|
13061
|
-
}
|
|
13062
|
-
if (orientView?.writeBackHints && orientView.writeBackHints.length > 0) {
|
|
13063
|
-
lines.push("");
|
|
13064
|
-
lines.push("## Write-Back Hints");
|
|
13065
|
-
lines.push("_What to capture this session (derived from task context):_");
|
|
13066
|
-
lines.push("");
|
|
13067
|
-
for (const h of orientView.writeBackHints) {
|
|
13068
|
-
lines.push(`- **${h.collectionSlug}**: ${h.hint}`);
|
|
13069
|
-
}
|
|
13070
|
-
lines.push("");
|
|
13071
|
-
}
|
|
13072
|
-
if (orientView) {
|
|
13073
|
-
const result = await runAlignmentCheck(
|
|
13074
|
-
task,
|
|
13075
|
-
orientView.activeWorkPackages ?? [],
|
|
13076
|
-
orientView.taskContext?.context
|
|
13077
|
-
);
|
|
13078
|
-
lines.push(...buildAlignmentCheckLines(result));
|
|
13079
|
-
lines.push(...formatInitiativeStatusLines(orientView.initiativeStatus));
|
|
13080
|
-
lines.push(...formatWorkstreamHealthLines(orientView.workstreamHealth));
|
|
13081
|
-
lines.push(...formatWhatNeedsAttentionLines(orientView.whatNeedsAttention));
|
|
13082
|
-
if (orientView.trustMetrics) {
|
|
13083
|
-
const tm = orientView.trustMetrics;
|
|
13084
|
-
if (tm.verified > 0 || tm.unverified > 0) {
|
|
13085
|
-
const capNote = tm.scannedCap ? " (capped at 500)" : "";
|
|
13086
|
-
lines.push("## Trust metrics");
|
|
13087
|
-
lines.push(`_Entry verification status across workspace${capNote}._`);
|
|
13088
|
-
lines.push("");
|
|
13089
|
-
lines.push(`- **Verified:** ${tm.verified}`);
|
|
13090
|
-
lines.push(`- **Unverified:** ${tm.unverified}`);
|
|
13091
|
-
lines.push(`- **No status (pre-BET-240):** ${tm.noStatus}`);
|
|
13092
|
-
lines.push(`- **Total scanned:** ${tm.total}`);
|
|
13093
|
-
lines.push("");
|
|
13094
|
-
}
|
|
13095
|
-
}
|
|
13096
|
-
}
|
|
13097
|
-
if (fullCoherence) {
|
|
13098
|
-
lines.push(...fullCoherence.lines);
|
|
13099
|
-
}
|
|
13100
|
-
if (allCollections.length > 0) {
|
|
13101
|
-
const docCompleteness = buildDocCompletenessSection(allCollections);
|
|
13102
|
-
if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {
|
|
13103
|
-
lines.push(...docCompleteness.lines);
|
|
13104
|
-
}
|
|
13105
|
-
}
|
|
13106
|
-
if (orientView) {
|
|
13107
|
-
if (orientView.activeWorkPackages?.length > 0) {
|
|
13108
|
-
lines.push("## Active work packages \u2014 current scope");
|
|
13109
|
-
lines.push("_Work outside these work packages requires explicit user confirmation._");
|
|
13110
|
-
lines.push("");
|
|
13111
|
-
for (const e of orientView.activeWorkPackages) {
|
|
13112
|
-
lines.push(fmt(e));
|
|
13113
|
-
const tensions = e.linkedTensions;
|
|
13114
|
-
if (tensions?.length) {
|
|
13115
|
-
const tensionLines = tensions.map((t) => {
|
|
13116
|
-
const meta = [t.severity, t.priority].filter(Boolean).join(", ");
|
|
13117
|
-
return `\`${t.entryId ?? t.name}\` (${t.name}${meta ? `, ${meta}` : ""})`;
|
|
13118
|
-
});
|
|
13119
|
-
lines.push(` Tensions: ${tensionLines.join("; ")}`);
|
|
13120
|
-
}
|
|
13121
|
-
}
|
|
13122
|
-
lines.push("");
|
|
13123
|
-
}
|
|
13124
|
-
if (orientView.activeGoals?.length > 0) {
|
|
13125
|
-
lines.push("## Active goals");
|
|
13126
|
-
orientView.activeGoals.forEach((e) => lines.push(fmt(e)));
|
|
13127
|
-
lines.push("");
|
|
13128
|
-
}
|
|
13129
|
-
if (orientView.strategyHighlights?.length > 0) {
|
|
13130
|
-
lines.push("## Strategy highlights");
|
|
13131
|
-
lines.push("_One-sentence strategy, positioning, moat, business model, GTM \u2014 high-level strategic context._");
|
|
13132
|
-
lines.push("");
|
|
13133
|
-
orientView.strategyHighlights.forEach((e) => lines.push(fmt(e)));
|
|
13134
|
-
lines.push("");
|
|
13135
|
-
}
|
|
13136
|
-
if (orientView.playingField?.length > 0) {
|
|
13137
|
-
lines.push("## Playing field");
|
|
13138
|
-
lines.push("_Products and opportunities in the strategic landscape._");
|
|
13139
|
-
lines.push("");
|
|
13140
|
-
orientView.playingField.forEach((e) => lines.push(fmt(e)));
|
|
13141
|
-
lines.push("");
|
|
13142
|
-
}
|
|
13143
|
-
if (orientView.recentDecisions?.length > 0) {
|
|
13144
|
-
lines.push("## Recent decisions");
|
|
13145
|
-
orientView.recentDecisions.forEach((e) => lines.push(fmt(e)));
|
|
13146
|
-
lines.push("");
|
|
13147
|
-
}
|
|
13148
|
-
if (orientView.recentlySuperseded?.length > 0) {
|
|
13149
|
-
lines.push("## Recently superseded");
|
|
13150
|
-
orientView.recentlySuperseded.forEach((e) => lines.push(fmt(e)));
|
|
13151
|
-
lines.push("");
|
|
13152
|
-
}
|
|
13153
|
-
if (orientView.staleEntries?.length > 0) {
|
|
13154
|
-
lines.push("## Needs confirmation");
|
|
13155
|
-
lines.push(`_Domain stratum entries not confirmed in ${orientView.stalenessThresholdDays} days._`);
|
|
13156
|
-
orientView.staleEntries.forEach((e) => lines.push(fmt(e)));
|
|
13157
|
-
lines.push("");
|
|
13158
|
-
}
|
|
13159
|
-
if (orientView.architectureNotes?.length > 0) {
|
|
13160
|
-
lines.push("## Architecture notes");
|
|
13161
|
-
orientView.architectureNotes.forEach((e) => lines.push(fmt(e)));
|
|
13162
|
-
lines.push("");
|
|
13163
|
-
}
|
|
13164
|
-
const mapGovernanceEntry = (e) => ({
|
|
13165
|
-
entryId: e.entryId,
|
|
13166
|
-
name: e.name,
|
|
13167
|
-
description: typeof e.preview === "string" ? e.preview : void 0,
|
|
13168
|
-
tier: typeof e.tier === "number" ? e.tier : void 0,
|
|
13169
|
-
// Phase 4 (DEC-1141): thread provenance fields to buildOperatingProtocol.
|
|
13170
|
-
provenance: e.provenance,
|
|
13171
|
-
anchoredBy: typeof e.anchoredBy === "string" ? e.anchoredBy : void 0
|
|
13172
|
-
});
|
|
13173
|
-
const gov = orientView.governance ?? { principles: [], standards: [], businessRules: [] };
|
|
13174
|
-
lines.push(...buildOperatingProtocol({
|
|
13175
|
-
principles: (gov.principles ?? []).map(mapGovernanceEntry),
|
|
13176
|
-
standards: (gov.standards ?? []).map(mapGovernanceEntry),
|
|
13177
|
-
businessRules: (gov.businessRules ?? []).map(mapGovernanceEntry)
|
|
13178
|
-
}, task));
|
|
13179
|
-
}
|
|
13180
|
-
let allEntries = [];
|
|
13181
|
-
try {
|
|
13182
|
-
allEntries = await kernelQuery("chain.listEntries", {}) ?? [];
|
|
13183
|
-
} catch {
|
|
13184
|
-
}
|
|
13185
|
-
const plannedWork = buildPlannedWork(allEntries);
|
|
13186
|
-
if (hasPlannedWork(plannedWork)) {
|
|
13187
|
-
lines.push(...buildPlannedWorkSection(plannedWork, priorSessions, recoveryBlock));
|
|
13188
|
-
} else if (recoveryBlock) {
|
|
13189
|
-
lines.push(...formatRecoveryBlock(recoveryBlock));
|
|
13190
|
-
}
|
|
13191
|
-
} else {
|
|
13192
|
-
lines.push(`**Brain stage: ${orientStage}.**`);
|
|
13170
|
+
}
|
|
13171
|
+
if (orientView.staleEntries?.length > 0) {
|
|
13172
|
+
lines.push("## Needs confirmation");
|
|
13173
|
+
lines.push(`_Domain stratum entries not confirmed in ${orientView.stalenessThresholdDays} days._`);
|
|
13174
|
+
orientView.staleEntries.forEach((e) => lines.push(fmt(e)));
|
|
13193
13175
|
lines.push("");
|
|
13194
|
-
|
|
13195
|
-
|
|
13196
|
-
|
|
13197
|
-
|
|
13198
|
-
for (const e of orientView.activeWorkPackages) {
|
|
13199
|
-
lines.push(fmt(e));
|
|
13200
|
-
}
|
|
13201
|
-
lines.push("");
|
|
13202
|
-
}
|
|
13203
|
-
lines.push(...formatInitiativeStatusLines(orientView?.initiativeStatus));
|
|
13204
|
-
lines.push(...formatWorkstreamHealthLines(orientView?.workstreamHealth));
|
|
13205
|
-
lines.push(...formatWhatNeedsAttentionLines(orientView?.whatNeedsAttention));
|
|
13206
|
-
if (orientView?.trustMetrics) {
|
|
13207
|
-
const tm = orientView.trustMetrics;
|
|
13208
|
-
if (tm.verified > 0 || tm.unverified > 0) {
|
|
13209
|
-
const capNote = tm.scannedCap ? " (capped at 500)" : "";
|
|
13210
|
-
lines.push("## Trust metrics");
|
|
13211
|
-
lines.push(`_Entry verification status across workspace${capNote}._`);
|
|
13212
|
-
lines.push("");
|
|
13213
|
-
lines.push(`- **Verified:** ${tm.verified}`);
|
|
13214
|
-
lines.push(`- **Unverified:** ${tm.unverified}`);
|
|
13215
|
-
lines.push(`- **No status (pre-BET-240):** ${tm.noStatus}`);
|
|
13216
|
-
lines.push(`- **Total scanned:** ${tm.total}`);
|
|
13217
|
-
lines.push("");
|
|
13218
|
-
}
|
|
13219
|
-
}
|
|
13220
|
-
lines.push(...buildOperatingProtocol());
|
|
13221
|
-
if (fullCoherence) {
|
|
13222
|
-
lines.push(...fullCoherence.lines);
|
|
13223
|
-
}
|
|
13224
|
-
if (allCollections.length > 0) {
|
|
13225
|
-
const docCompleteness = buildDocCompletenessSection(allCollections);
|
|
13226
|
-
if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {
|
|
13227
|
-
lines.push(...docCompleteness.lines);
|
|
13228
|
-
}
|
|
13229
|
-
}
|
|
13230
|
-
if (priorSessions.length > 0 && !recoveryBlock) {
|
|
13231
|
-
const last = priorSessions[0];
|
|
13232
|
-
const date = last.startedAt ? new Date(last.startedAt).toISOString().split("T")[0] : "unknown";
|
|
13233
|
-
const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;
|
|
13234
|
-
const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;
|
|
13235
|
-
lines.push(`_Last session (${date}): ${created} created, ${modified} modified._`);
|
|
13236
|
-
lines.push("");
|
|
13237
|
-
}
|
|
13238
|
-
if (recoveryBlock) {
|
|
13239
|
-
lines.push(...formatRecoveryBlock(recoveryBlock));
|
|
13240
|
-
}
|
|
13241
|
-
lines.push("**What are you working on?** Tell me and I'll load relevant governance and context.");
|
|
13176
|
+
}
|
|
13177
|
+
if (orientView.architectureNotes?.length > 0) {
|
|
13178
|
+
lines.push("## Architecture notes");
|
|
13179
|
+
orientView.architectureNotes.forEach((e) => lines.push(fmt(e)));
|
|
13242
13180
|
lines.push("");
|
|
13243
13181
|
}
|
|
13182
|
+
const mapGovernanceEntry = (e) => ({
|
|
13183
|
+
entryId: e.entryId,
|
|
13184
|
+
name: e.name,
|
|
13185
|
+
description: typeof e.preview === "string" ? e.preview : void 0,
|
|
13186
|
+
tier: typeof e.tier === "number" ? e.tier : void 0,
|
|
13187
|
+
// Phase 4 (DEC-1141): thread provenance fields to buildOperatingProtocol.
|
|
13188
|
+
provenance: e.provenance,
|
|
13189
|
+
anchoredBy: typeof e.anchoredBy === "string" ? e.anchoredBy : void 0
|
|
13190
|
+
});
|
|
13191
|
+
const gov = orientView.governance ?? { principles: [], standards: [], businessRules: [] };
|
|
13192
|
+
lines.push(...buildOperatingProtocol({
|
|
13193
|
+
principles: (gov.principles ?? []).map(mapGovernanceEntry),
|
|
13194
|
+
standards: (gov.standards ?? []).map(mapGovernanceEntry),
|
|
13195
|
+
businessRules: (gov.businessRules ?? []).map(mapGovernanceEntry)
|
|
13196
|
+
}, task));
|
|
13197
|
+
}
|
|
13198
|
+
let allEntries = [];
|
|
13199
|
+
try {
|
|
13200
|
+
allEntries = await kernelQuery("chain.listEntries", {}) ?? [];
|
|
13201
|
+
} catch {
|
|
13244
13202
|
}
|
|
13245
|
-
const
|
|
13246
|
-
if (
|
|
13247
|
-
lines.push(
|
|
13248
|
-
|
|
13203
|
+
const plannedWork = buildPlannedWork(allEntries);
|
|
13204
|
+
if (hasPlannedWork(plannedWork)) {
|
|
13205
|
+
lines.push(...buildPlannedWorkSection(plannedWork, priorSessions, recoveryBlock));
|
|
13206
|
+
} else if (recoveryBlock) {
|
|
13207
|
+
lines.push(...formatRecoveryBlock(recoveryBlock));
|
|
13208
|
+
}
|
|
13209
|
+
} else {
|
|
13210
|
+
lines.push(`**Brain stage: ${orientStage}.**`);
|
|
13211
|
+
lines.push("");
|
|
13212
|
+
if (orientView?.activeWorkPackages?.length) {
|
|
13213
|
+
lines.push("## Active work packages \u2014 current scope");
|
|
13214
|
+
lines.push("_Work outside these work packages requires explicit user confirmation._");
|
|
13249
13215
|
lines.push("");
|
|
13250
|
-
for (const
|
|
13251
|
-
lines.push(
|
|
13216
|
+
for (const e of orientView.activeWorkPackages) {
|
|
13217
|
+
lines.push(fmt(e));
|
|
13252
13218
|
}
|
|
13253
13219
|
lines.push("");
|
|
13254
13220
|
}
|
|
13255
|
-
|
|
13256
|
-
|
|
13257
|
-
|
|
13258
|
-
|
|
13259
|
-
|
|
13260
|
-
|
|
13261
|
-
|
|
13262
|
-
|
|
13263
|
-
|
|
13264
|
-
|
|
13265
|
-
lines.push(
|
|
13266
|
-
lines.push(
|
|
13267
|
-
|
|
13268
|
-
|
|
13269
|
-
lines.push("
|
|
13270
|
-
lines.push("_Warning: Could not mark session as oriented. Write tools may be restricted._");
|
|
13221
|
+
lines.push(...formatInitiativeStatusLines(orientView?.initiativeStatus));
|
|
13222
|
+
lines.push(...formatWorkstreamHealthLines(orientView?.workstreamHealth));
|
|
13223
|
+
lines.push(...formatWhatNeedsAttentionLines(orientView?.whatNeedsAttention));
|
|
13224
|
+
if (orientView?.trustMetrics) {
|
|
13225
|
+
const tm = orientView.trustMetrics;
|
|
13226
|
+
if (tm.verified > 0 || tm.unverified > 0) {
|
|
13227
|
+
const capNote = tm.scannedCap ? " (capped at 500)" : "";
|
|
13228
|
+
lines.push("## Trust metrics");
|
|
13229
|
+
lines.push(`_Entry verification status across workspace${capNote}._`);
|
|
13230
|
+
lines.push("");
|
|
13231
|
+
lines.push(`- **Verified:** ${tm.verified}`);
|
|
13232
|
+
lines.push(`- **Unverified:** ${tm.unverified}`);
|
|
13233
|
+
lines.push(`- **No status (pre-BET-240):** ${tm.noStatus}`);
|
|
13234
|
+
lines.push(`- **Total scanned:** ${tm.total}`);
|
|
13235
|
+
lines.push("");
|
|
13271
13236
|
}
|
|
13272
|
-
|
|
13273
|
-
|
|
13274
|
-
|
|
13275
|
-
|
|
13276
|
-
|
|
13277
|
-
|
|
13278
|
-
|
|
13279
|
-
|
|
13280
|
-
|
|
13237
|
+
}
|
|
13238
|
+
lines.push(...buildOperatingProtocol());
|
|
13239
|
+
if (fullCoherence) {
|
|
13240
|
+
lines.push(...fullCoherence.lines);
|
|
13241
|
+
}
|
|
13242
|
+
if (allCollections.length > 0) {
|
|
13243
|
+
const docCompleteness = buildDocCompletenessSection(allCollections);
|
|
13244
|
+
if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {
|
|
13245
|
+
lines.push(...docCompleteness.lines);
|
|
13281
13246
|
}
|
|
13282
|
-
} else if (agentSessionId) {
|
|
13283
|
-
orientationStatus = "task_required";
|
|
13284
|
-
lines.push("---");
|
|
13285
|
-
lines.push('Workspace orientation loaded. Write tools stay locked until you run `orient task="describe the work"`.');
|
|
13286
|
-
} else {
|
|
13287
|
-
lines.push("---");
|
|
13288
|
-
lines.push("_No active agent session. Call `session action=start` to begin a tracked session._");
|
|
13289
13247
|
}
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
const
|
|
13248
|
+
if (priorSessions.length > 0 && !recoveryBlock) {
|
|
13249
|
+
const last = priorSessions[0];
|
|
13250
|
+
const date = last.startedAt ? new Date(last.startedAt).toISOString().split("T")[0] : "unknown";
|
|
13251
|
+
const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;
|
|
13252
|
+
const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;
|
|
13253
|
+
lines.push(`_Last session (${date}): ${created} created, ${modified} modified._`);
|
|
13293
13254
|
lines.push("");
|
|
13294
|
-
if (reasons && reasons.length > 0) {
|
|
13295
|
-
lines.push(`_Context truncated to fit tier budget: ${reasons.join(", ")}. Use tier=full for complete payload._`);
|
|
13296
|
-
} else {
|
|
13297
|
-
lines.push("_Context truncated to fit tier budget. Use tier=full for complete payload._");
|
|
13298
|
-
}
|
|
13299
13255
|
}
|
|
13300
|
-
|
|
13301
|
-
|
|
13302
|
-
|
|
13303
|
-
|
|
13304
|
-
|
|
13305
|
-
|
|
13306
|
-
|
|
13307
|
-
|
|
13308
|
-
|
|
13309
|
-
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13317
|
-
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
13256
|
+
if (recoveryBlock) {
|
|
13257
|
+
lines.push(...formatRecoveryBlock(recoveryBlock));
|
|
13258
|
+
}
|
|
13259
|
+
lines.push("**What are you working on?** Tell me and I'll load relevant governance and context.");
|
|
13260
|
+
lines.push("");
|
|
13261
|
+
}
|
|
13262
|
+
}
|
|
13263
|
+
const classificationGaps = readiness?.gaps?.filter((g) => g.id?.startsWith?.(PURPOSE_GAP_PREFIX)) ?? [];
|
|
13264
|
+
if (classificationGaps.length > 0) {
|
|
13265
|
+
lines.push("## Classification gaps");
|
|
13266
|
+
lines.push("_Collections with weak purpose \u2014 entry classification may be inaccurate._");
|
|
13267
|
+
lines.push("");
|
|
13268
|
+
for (const g of classificationGaps) {
|
|
13269
|
+
lines.push(`- ${g.label ?? g.id?.replace?.("purpose-gap-", "") ?? "unknown"}`);
|
|
13270
|
+
}
|
|
13271
|
+
lines.push("");
|
|
13272
|
+
}
|
|
13273
|
+
if (errors.length > 0) {
|
|
13274
|
+
lines.push("## Errors");
|
|
13275
|
+
for (const err of errors) lines.push(`- ${err}`);
|
|
13276
|
+
lines.push("");
|
|
13277
|
+
}
|
|
13278
|
+
let orientationStatus = "no_session";
|
|
13279
|
+
if (agentSessionId && hasTaskGrounding) {
|
|
13280
|
+
const orientedOk = await markOrientedWithSnapshotFallback(agentSessionId, fullCoherenceSnapshot);
|
|
13281
|
+
if (orientedOk) {
|
|
13282
|
+
orientationStatus = "complete";
|
|
13283
|
+
lines.push("---");
|
|
13284
|
+
lines.push(`Orientation complete. Session ${agentSessionId}. Write tools available.`);
|
|
13285
|
+
} else {
|
|
13286
|
+
orientationStatus = "failed";
|
|
13287
|
+
lines.push("---");
|
|
13288
|
+
lines.push("_Warning: Could not mark session as oriented. Write tools may be restricted._");
|
|
13289
|
+
}
|
|
13290
|
+
try {
|
|
13291
|
+
await kernelMutation("chain.recordSessionSignal", {
|
|
13292
|
+
sessionId: agentSessionId,
|
|
13293
|
+
signalType: "immediate_context_load",
|
|
13294
|
+
metadata: { source: "orient" }
|
|
13295
|
+
});
|
|
13296
|
+
} catch (err) {
|
|
13297
|
+
process.stderr.write(`[MCP] recordSessionSignal failed: ${err.message}
|
|
13298
|
+
`);
|
|
13299
|
+
}
|
|
13300
|
+
} else if (agentSessionId) {
|
|
13301
|
+
orientationStatus = "task_required";
|
|
13302
|
+
lines.push("---");
|
|
13303
|
+
lines.push('Workspace orientation loaded. Write tools stay locked until you run `orient task="describe the work"`.');
|
|
13304
|
+
} else {
|
|
13305
|
+
lines.push("---");
|
|
13306
|
+
lines.push("_No active agent session. Call `session action=start` to begin a tracked session._");
|
|
13307
|
+
}
|
|
13308
|
+
const fullTruncated = orientView?._budget?.truncated ?? orientView?._truncated ?? false;
|
|
13309
|
+
if (fullTruncated) {
|
|
13310
|
+
const reasons = orientView?._budget?.truncationReasons;
|
|
13311
|
+
lines.push("");
|
|
13312
|
+
if (reasons && reasons.length > 0) {
|
|
13313
|
+
lines.push(`_Context truncated to fit tier budget: ${reasons.join(", ")}. Use tier=full for complete payload._`);
|
|
13314
|
+
} else {
|
|
13315
|
+
lines.push("_Context truncated to fit tier budget. Use tier=full for complete payload._");
|
|
13316
|
+
}
|
|
13317
|
+
}
|
|
13318
|
+
const fullResult = {
|
|
13319
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
13320
|
+
structuredContent: success(
|
|
13321
|
+
`Oriented (full). Stage: ${orientStage}. ${isLowReadiness ? "Low readiness \u2014 gaps remain." : "Ready."}`,
|
|
13322
|
+
{
|
|
13323
|
+
mode: "full",
|
|
13324
|
+
stage: orientStage,
|
|
13325
|
+
oriented: hasTaskGrounding ? isSessionOriented() : false,
|
|
13326
|
+
sessionId: agentSessionId,
|
|
13327
|
+
taskGroundingStatus: hasTaskGrounding ? "task_scoped" : task ? "missing_task_context" : "workspace_only",
|
|
13328
|
+
taskGroundingRequired: !hasTaskGrounding,
|
|
13329
|
+
// STD-219 §4 (DEC-1147): machine-readable stub flag for agent consumers.
|
|
13330
|
+
...orientView?.taskContext?.isGroundingStub ? { groundingStub: true } : {},
|
|
13331
|
+
domainRetrieval: orientView?.startup?.domainRetrieval,
|
|
13332
|
+
orientationStatus,
|
|
13333
|
+
nextStep: hasTaskGrounding ? void 0 : 'Run `orient task="describe the work"` before substantive work.',
|
|
13334
|
+
...orientView?._budget ? { _budget: orientView._budget } : {}
|
|
13335
|
+
}
|
|
13336
|
+
)
|
|
13337
|
+
};
|
|
13338
|
+
reportOrientWrapperBytes(fullResult, fullTruncated, resolvedTier, taskIsMeaningful(task));
|
|
13339
|
+
return fullResult;
|
|
13322
13340
|
}
|
|
13323
13341
|
|
|
13324
13342
|
// src/tools/health.ts
|
|
@@ -15204,4 +15222,4 @@ export {
|
|
|
15204
15222
|
createProductBrainServer,
|
|
15205
15223
|
initFeatureFlags
|
|
15206
15224
|
};
|
|
15207
|
-
//# sourceMappingURL=chunk-
|
|
15225
|
+
//# sourceMappingURL=chunk-7BKN47NY.js.map
|