feat: compact workflow status context

This commit is contained in:
MerlinH
2026-07-27 00:19:37 +10:00
parent 72e6117cf4
commit bfee763ab2
10 changed files with 95 additions and 13 deletions
-2
View File
@@ -11,8 +11,6 @@ truthmark:
generated:
portal:
enabled: false
instruction_targets:
- AGENTS.md
frontmatter:
required: []
recommended:
@@ -10,3 +10,4 @@ SemVer rationale: This is a backward-compatible release that adds platform-deriv
- Check and RepoIndex share Git-visible, NUL-safe repository discovery, including functional code under arbitrary roots.
- Init reconciles exact safely recognized inactive generated surfaces while preserving diverged, Gemini, and unrelated files.
- `truthmark uninstall --dry-run|--apply [--json]` provides a deterministic removal plan and preserves authored truth, configuration, templates, Portal output, and global package installation.
- Human-readable `truthmark workflow status` output now presents bounded applicability and advisory context while JSON retains the full schema-versioned contract; duplicate diagnostics are collapsed at WorkflowState composition.
@@ -1,7 +1,7 @@
---
status: active
truth_kind: engineering-contract
last_reviewed: 2026-06-20
last_reviewed: 2026-07-26
---
# Config, Route, And Check Contracts
@@ -47,7 +47,7 @@ Conflicting duplicate kinds or lanes are reported as area-index errors.
The public ContextPack command surface is retired.
Agents use `truthmark workflow status --workflow <workflow> [--base <ref>] --json` for:
Agents use `truthmark workflow status --workflow <workflow> [--base <ref>]` for a bounded human-readable advisory card and add `--json` when they need the schema-versioned contract for:
- an advisory workflow card
- write-boundary suggestions
@@ -61,6 +61,10 @@ Agents use `truthmark workflow status --workflow <workflow> [--base <ref>] --jso
- next steps
- compact affected-test guidance
The human-readable card reports applicability and non-empty affected files, likely route owners, suggested truth docs, open questions, and next steps. Each list is capped at five entries with a remaining-count summary.
WorkflowState composes diagnostics from config, RepoIndex, ImpactSet, and Check by exact-value deduplication so the same review or error signal appears once.
Agents use `truthmark impact --base <ref> --json` for branch-diff routing.
These replacement JSON outputs emit paths, metadata, diagnostics, and command arrays only.
@@ -121,6 +125,8 @@ The target model is lane-first and does not use `docs/truthmark/truth` as the ca
- Decision (2026-06-15): Route relationships are route-local metadata; checks validate relationship targets for existence and lane compatibility without requiring a reciprocal global graph edge.
- Decision (2026-06-15): ContextPack is folded into workflow status and impact; the standalone `truthmark context` command is hard-removed from the public CLI.
- Decision (2026-06-18): Omitted `platforms` normalize to an empty platform list; all host-specific generated surfaces, including Codex, are explicit opt-in config.
- Decision (2026-07-26): Human workflow status reuses the existing advisory card with bounded lists, while JSON retains the full schema-versioned state.
- Exact duplicate diagnostics are collapsed at WorkflowState composition so optional helper output stays compact without hiding distinct signals.
## Rationale
@@ -1,7 +1,7 @@
---
status: active
truth_kind: engineering-behavior
last_reviewed: 2026-06-26
last_reviewed: 2026-07-26
---
# Repository Intelligence
@@ -42,6 +42,8 @@ It covers RepoIndex, RouteMap, ImpactSet, evidence validation, freshness, and Wo
- next steps
- report sections
- The advisory card presents affected files, likely route owners, suggested truth docs, open questions, and skipped optional-helper status so helper output remains review material rather than repository authority.
- Human workflow status renders applicability plus non-empty advisory-card and next-step lists, capped at five entries per list; JSON retains the complete WorkflowState contract.
- WorkflowState collapses exact duplicate diagnostics collected from config, RepoIndex, ImpactSet, and Check while preserving distinct diagnostics.
- Workflow applicability uses context-shaped states such as `ready`, `needs_manual_review`, and `needs_routing_review`.
- Diagnostics or missing route ownership produce open questions and manual handoff guidance instead of making the CLI the arbiter.
- `truthmark-sync` includes `Sync Intent` in its report sections as a transient pre-write checklist and keeps affected truth docs in `targetTruthDocs` for review focus.
@@ -125,6 +127,8 @@ It covers RepoIndex, RouteMap, ImpactSet, evidence validation, freshness, and Wo
- Decision (2026-06-21): Sync `candidateStaleTruthDocs` stays signal-based.
- WorkflowState does not enumerate every indexed truth doc outside the impact set.
- It returns an empty candidate list unless freshness, relationships, source references, changed route metadata, or changed linked docs indicate a possible stale-truth repair.
- Decision (2026-07-26): Human workflow status renders the existing advisory card as bounded context rather than requiring callers to load the full JSON contract.
- WorkflowState removes exact duplicate diagnostics at its composition boundary.
## Rationale
+2 -1
View File
@@ -1,7 +1,7 @@
---
status: active
doc_type: routing
last_reviewed: 2026-05-16
last_reviewed: 2026-07-26
---
# Truthmark Areas
@@ -85,6 +85,7 @@ Code surface:
- src/templates/workflow-surfaces.ts
- src/templates/generated-surfaces.ts
- src/checks/generated-surfaces.ts
- src/managed-block.ts
- src/truth/\*\*
- src/version.ts
- workflow-eval-framwork/\*\*
@@ -1,7 +1,7 @@
---
status: active
doc_type: routing
last_reviewed: 2026-05-16
last_reviewed: 2026-07-26
---
# Installed Workflows Areas
@@ -40,6 +40,7 @@ Code surface:
- src/templates/workflow-surfaces.ts
- src/templates/generated-surfaces.ts
- src/checks/generated-surfaces.ts
- src/managed-block.ts
- src/truth/\*\*
- src/version.ts
- workflow-eval-framwork/\*\*
+31 -1
View File
@@ -12,6 +12,7 @@ import {
type TruthmarkWorkflowId,
} from "../agents/workflow-manifest.js";
import { buildWorkflowState } from "../workflow-state/build.js";
import type { WorkflowState } from "../workflow-state/types.js";
import fs from "node:fs/promises";
import {
@@ -130,6 +131,35 @@ const invalidWorkflowResult = (
},
});
const summarizeValues = (values: string[]): string =>
values.length <= 5
? values.join(", ")
: `${values.slice(0, 5).join(", ")} (+${values.length - 5} more)`;
const renderWorkflowStatusSummary = (state: WorkflowState): string => {
const card = state.workflowCard;
return [
`Truthmark workflow status completed for ${state.workflow}.`,
`Applicability: ${state.applicability.state}.`,
...(card.affectedFiles.length > 0
? [`Affected files: ${summarizeValues(card.affectedFiles)}`]
: []),
...(card.likelyRouteOwners.length > 0
? [`Likely route owners: ${summarizeValues(card.likelyRouteOwners)}`]
: []),
...(card.suggestedTruthDocs.length > 0
? [`Suggested truth docs: ${summarizeValues(card.suggestedTruthDocs)}`]
: []),
...(card.openQuestions.length > 0
? [`Open questions: ${summarizeValues(card.openQuestions)}`]
: []),
...(state.nextSteps.length > 0
? [`Next steps: ${summarizeValues(state.nextSteps)}`]
: []),
].join("\n");
};
const readHelperFile = async (
filePath: string,
helper: string,
@@ -193,7 +223,7 @@ export const runWorkflowStatus = async (options: {
return {
command: "workflow status",
summary: `Truthmark workflow status completed for ${options.workflow}.`,
summary: renderWorkflowStatusSummary(workflowState),
diagnostics: workflowState.diagnostics,
data: {
request: {
+10 -5
View File
@@ -153,7 +153,8 @@ const candidateStaleTruthDocsFor = (
doc.sourceOfTruth.some((reference) =>
[...changedPaths].some(
(changedPath) =>
reference === changedPath || micromatch.isMatch(changedPath, reference),
reference === changedPath ||
micromatch.isMatch(changedPath, reference),
),
)
) {
@@ -363,10 +364,14 @@ export const buildWorkflowState = async (
comparisonBase ? { base: comparisonBase } : {},
);
const diagnostics = [
...loadResult.diagnostics,
...repoIndex.diagnostics,
...(impactSet?.diagnostics ?? []),
...checkResult.diagnostics,
...new Map(
[
...loadResult.diagnostics,
...repoIndex.diagnostics,
...(impactSet?.diagnostics ?? []),
...checkResult.diagnostics,
].map((diagnostic) => [JSON.stringify(diagnostic), diagnostic] as const),
).values(),
];
const applicability = applicabilityFor(
options.workflow,
+16
View File
@@ -192,6 +192,22 @@ describe("repository intelligence CLI commands", () => {
expect(Array.isArray(state.nextSteps)).toBe(true);
expect(Array.isArray(state.diagnostics)).toBe(true);
expect(compactTestGuidance.join("\n")).toContain("tests/math.test.ts");
const humanResult = await runCli(
[
"workflow",
"status",
"--workflow",
"truthmark-sync",
"--base",
"main",
],
{ cwd: repo.rootDir },
);
expect(humanResult.stdout).toContain("Applicability: ready.");
expect(humanResult.stdout).toContain("Affected files: src/math.ts");
expect(humanResult.stdout).toContain("Likely route owners:");
expect(humanResult.stdout).toContain("Suggested truth docs:");
} finally {
await repo.cleanup();
}
+20
View File
@@ -323,6 +323,26 @@ describe("buildWorkflowState", () => {
expect(JSON.stringify(state)).not.toContain('"content":');
});
it("deduplicates diagnostics composed from repository helpers", async () => {
const repo = await setupConfiguredRepo();
repos.push(repo);
await repo.writeFile(
".truthmark/config.yml",
`${await repo.readFile(".truthmark/config.yml")}instruction_targets:\n - AGENTS.md\n`,
);
const state = await buildWorkflowState(repo.rootDir, {
workflow: "truthmark-sync",
base: "main",
});
expect(
state.diagnostics.filter((diagnostic) =>
diagnostic.message.includes("instruction_targets"),
),
).toHaveLength(1);
});
it("authorizes sync to correct signal-linked truth docs and routing files", async () => {
const repo = await setupConfiguredRepo({ includeUnrelatedRoute: true });
repos.push(repo);