* feat: add OpenSpec-driven workflow state * docs: plan generated playbooks workflow contract * feat: add truth health scorecard Release Truthmark 2.1.0 with check JSON scorecard output. Archive the completed OpenSpec pass 4 scorecard change and update generated truth surfaces. * fix: unblock truthmark scorecard review - restore and update coverage for scorecard/evidence/workflow behavior - make truthmark-sync select a cheap local base when --base is omitted - report malformed evidence YAML blocks as diagnostics instead of throwing * fix: tighten workflow boundaries * fix: fail closed when sync has no comparison base * fix: tighten truth health review coverage - only parse fenced YAML evidence blocks with top-level evidence markers - convert coverage fixtures to valid v2 config and assert non-vacuous diagnostics - update Truthmark truth docs for source traceability and workflow-state tests * docs: clarify source traceability diagnostics * docs: harden optional CLI workflow boundary * docs: clarify product boundary is repo-local * fix: bound truthmark workflow fallback behavior - make live workflow preflight use the one-call instructions contract - keep missing-CLI fallback bounded for Sync, Document, Structure, and Realize - add routing and generated-surface coverage plus refreshed host surfaces * test: cover no-cli workflow fallback bounds - assert route-first fallback wording in generated workflow surfaces - clarify progressive-disclosure support files are conditional - align overview docs with bounded no-CLI behavior * docs: route workflow eval coverage * fix: remove workflow instructions preflight * fix: remove stale workflow preflight wording * fix: remove generic workflow validation blocks * fix: avoid duplicated markdown context JSON * fix: keep workflow status manifest-only * docs: align truth docs with v2 hierarchy --------- Co-authored-by: MerlinH <merlinh221@gmail.com>
34 KiB
Truthmark Improvement Plans From OpenSpec Research
For Hermes: Use
subagent-driven-developmentto implement these passes one pass at a time. Each pass should finish with focused tests,npm run checkwhen feasible, and a Truthmark Sync review if functional source changes were made.
Date: 2026-06-01
Source research: research/2026-06-01-openspec-comparison.md
Scope: Truthmark implementation, generated agent surfaces, CLI contract, validation/reporting UX.
Non-goal: do not turn Truthmark into OpenSpec, a spec-driver library, a proposal/task lifecycle, or an arbitrary workflow DAG engine.
Goal
Convert the OpenSpec comparison findings into staged implementation plans that improve Truthmark's own mission: local-first, Git-native repository-truth governance for coding agents.
The highest-value theme is to make Truthmark's existing route/truth/evidence/write-boundary knowledge as computable and agent-readable as OpenSpec's status, instructions, and actionContext, while preserving Truthmark's narrower repository-truth mission.
Architecture direction
Truthmark should add a thin workflow-state layer that composes existing systems instead of replacing them:
TRUTHMARK_WORKFLOW_MANIFESTremains the source for workflow identity, triggers, gates, helpers, report sections, subagents, and declared write boundaries.buildRepoIndex()/ route map remain the source for ownership and truth-doc mapping.runCheck()/ diagnostics remain the source for repository truth health.buildImpactSet()remains the source for branch-diff effects when--baseis provided.buildContextPack()remains the source for bounded workflow context and write paths.- New
workflow statusandworkflow instructionscommands should compose the above into an agent-facing contract.
This is OpenSpec-inspired ergonomics, not OpenSpec behavior. Truthmark workflow state is about routes, truth docs, evidence, health, and allowed writes — not proposals, specs, design docs, tasks, archive/apply, or artifact completion by file existence.
Implementation principles
- Compose first, refactor later. Build the workflow-state API from current data sources before reorganizing generated-surface internals.
- Version the agent contract early. Use a schema version such as
truthmark-workflow/v0so generated agent surfaces can rely on it without pretending it is final. - Keep JSON stable and prose generated from data. Agent surfaces should teach hosts to call the CLI instead of embedding stale workflow logic.
- Make write boundaries machine-readable. Every workflow status should say whether it is read-only and exactly what it may write.
- Keep OpenSpec non-goals visible in code review. No
changes/, proposal/spec/task DAGs, archive/apply semantics, arbitrary workflow schemas, or required pre-implementation planning artifacts.
Pass overview
| Pass | Name | Outcome | Can ship independently? |
|---|---|---|---|
| 0 | Baseline contract and guardrails | Document and test the non-OpenSpec boundary before code changes | Yes |
| 1 | Workflow state core | New typed WorkflowState builder composes manifest/check/index/impact/context |
Yes, internal only |
| 2 | Agent-facing CLI | truthmark workflow status/instructions --json expose the state contract |
Yes |
| 3 | Generated playbooks consume the contract | Host surfaces call the new CLI and receive operational playbooks | Yes |
| 4 | Compact truth health scorecard | check --json gets a tiny diagnostic triage index; workflow-state exposure is deferred |
Yes |
| 5 | Preview/Explore wording hardening | Keep truthmark-preview; improve read-only discovery instructions without new JSON |
Yes |
| 6 | Lightweight Sync intent checklist | Add a pre-write intent section to Sync instructions/reports; no typed plan engine yet | Yes |
| 7 | Platform surface adapter refactor | Deferred internal maintainability refactor after behavior stabilizes | No — explicitly deferred |
Pass 0: Baseline Contract And Guardrails
Objective
Before adding features, make the intended product boundary explicit so later implementation passes do not drift into OpenSpec-lite.
Files
- Modify:
docs/truth/contracts.mdor the current canonical CLI/workflow contract truth doc if routing points elsewhere. - Modify:
docs/truthmark/truth/**/*.mdonly if existing routed truth docs already own CLI/workflow behavior. - Modify:
tests/cli/help.test.tsfor absence checks if new commands are not yet implemented. - Create:
tests/workflow-state/non-goals.test.tsif a new test directory is acceptable, otherwise place absence tests in the closest existing CLI/workflow test file.
Tasks
Task 0.1: Record the closed product decision
Objective: Make the OpenSpec-learning boundary explicit in canonical truth.
Steps:
- Find the routed truth owner for CLI/workflow contracts:
- Inspect
docs/truthmark/routes/areas.mdand child area files when present. - Identify the truth doc that owns
src/cli/**,src/agents/workflow-manifest.ts, and generated surfaces.
- Inspect
- Add a dated decision:
- Truthmark may add agent-readable workflow status/instructions/action-context behavior.
- Truthmark must not add OpenSpec-style proposal/spec/design/task lifecycle artifacts.
- Truthmark must not add arbitrary workflow DAG schemas or archive/apply semantics.
- Keep the language product-scoped: Truthmark is a repository-truth governance layer, not an application feature.
Verification:
npm run check
npx tsx src/cli/main.ts check --json
npx tsx src/cli/main.ts index --json
Expected: no new errors. Existing unrelated review diagnostics may be reported separately.
Task 0.2: Add absence tests for future-only OpenSpec concepts
Objective: Prevent accidental exposure of OpenSpec-like lifecycle surface while implementing the improvements.
Test examples:
- CLI help does not mention
proposal,spec delta,archive,apply,changes, ortasksas Truthmark lifecycle commands. - Default config does not include arbitrary workflow schemas or artifact DAG configuration.
- Generated workflow surfaces do not instruct agents to create
truthmark/changes/*directories.
Files:
- Modify:
tests/cli/help.test.ts - Modify:
tests/init/init.test.ts - Modify:
tests/templates/generated-surfaces.test.ts
Verification:
npx vitest run tests/cli/help.test.ts tests/init/init.test.ts tests/templates/generated-surfaces.test.ts
Expected: tests pass and protect the non-goals before feature work starts.
Pass 1: Workflow State Core
Objective
Create an internal typed workflow-state builder that composes existing Truthmark data into one agent-readable model. Do not expose new CLI commands yet unless needed for tests.
Architecture
Add a new internal module, for example:
buildWorkflowState(cwd, options): Promise<WorkflowState>
The builder should be a composition layer, not a new workflow engine.
Proposed files
- Create:
src/workflow-state/types.ts - Create:
src/workflow-state/build.ts - Create:
src/workflow-state/action-context.ts - Create:
tests/workflow-state/build.test.ts - Modify:
src/context-pack/types.tsonly if existing context pack types need to expose richer action constraints. - Modify:
src/context-pack/build.tsonly if write-path derivation should be shared rather than duplicated.
Proposed type shape
export type WorkflowStateSchemaVersion = "truthmark-workflow/v0";
export type WorkflowApplicabilityState =
| "applicable"
| "not_applicable"
| "blocked"
| "ambiguous";
export type WorkflowActionMode =
| "read-only"
| "truth-doc-write"
| "route-write"
| "code-write"
| "portal-write";
export type WorkflowActionContext = {
mode: WorkflowActionMode;
sourceOfTruth: "repository";
allowedWritePaths: string[];
forbiddenWritePaths: string[];
stopConditions: string[];
requiredEvidence: string[];
helperValidationCommands: string[];
writeLeaseRequired: boolean;
};
export type WorkflowState = {
schemaVersion: WorkflowStateSchemaVersion;
workflow: TruthmarkWorkflowId;
base: string | null;
applicability: {
state: WorkflowApplicabilityState;
reasons: string[];
};
changedFiles: Array<{ path: string; status?: string }>;
affectedRoutes: Array<{
id?: string;
name?: string;
sourcePath?: string;
codeSurface: string[];
truthDocs: string[];
}>;
targetTruthDocs: string[];
actionContext: WorkflowActionContext;
checks: {
required: string[];
recommended: string[];
helpers: string[];
};
diagnostics: Diagnostic[];
nextSteps: string[];
reportSections: string[];
};
Tasks
Task 1.1: Add workflow-state types
Objective: Define the contract in one place before implementation.
Files:
- Create:
src/workflow-state/types.ts - Test:
tests/workflow-state/build.test.ts
Test first:
Add a compile-level or runtime shape test that imports the public types and asserts a minimal WorkflowState object can be constructed with schemaVersion: "truthmark-workflow/v0".
Verification:
npx vitest run tests/workflow-state/build.test.ts
npm run typecheck
Expected before implementation: type/import failure. Expected after implementation: pass.
Task 1.2: Implement actionContext mapping from the manifest
Objective: Convert each fixed Truthmark workflow into a machine-readable action policy.
Files:
- Create:
src/workflow-state/action-context.ts - Test:
tests/workflow-state/build.test.ts
Rules:
truthmark-previewandtruthmark-checkareread-onlyand have emptyallowedWritePaths.truthmark-syncistruth-doc-writewith route/truth-doc allowed writes from context/index data.truthmark-documentistruth-doc-writeorroute-writedepending on route updates required; start withtruth-doc-writeunless a later route-specific distinction is implemented.truthmark-structureisroute-writewith route files and starter truth docs only.truthmark-realizeiscode-writeand must forbid truth docs/routing.truthmark-portalisportal-writeand must only allow the configured portal output when enabled.
Test cases:
- Read-only workflows return no allowed writes.
- Realize forbids Truthmark route/truth paths.
- Sync includes helper validation commands from manifest helpers.
- Missing/invalid config produces blocked or empty write boundaries, not permissive defaults.
Verification:
npx vitest run tests/workflow-state/build.test.ts -t "action context"
Task 1.3: Implement buildWorkflowState() composition
Objective: Build state from existing Truthmark systems.
Files:
- Create:
src/workflow-state/build.ts - Modify:
src/context-pack/build.tsonly if shared helpers are needed. - Test:
tests/workflow-state/build.test.ts
Implementation outline:
- Load manifest entry from
TRUTHMARK_WORKFLOW_MANIFEST. - Build repo index with
buildRepoIndex(cwd). - Load config through the same path used by context/check.
- If
baseis provided, callbuildImpactSet(rootDir, { base }). - For supported workflows, call
buildContextPack(rootDir, { workflow, base })or a shared internal write-path helper. - Merge diagnostics from config/index/impact/context.
- Derive
applicabilityfrom manifest triggers, config presence, base presence, changed-file availability, and route ambiguity diagnostics. - Produce
nextStepsfrom blockers and manifest gates.
Important: Do not invent OpenSpec-style ready/blocked artifact semantics. Applicability means “can this Truthmark workflow safely run now?” not “which artifact is next?”
Verification:
npx vitest run tests/workflow-state/build.test.ts
npm run typecheck
Task 1.4: Add fixture coverage for missing config and ambiguous routing
Objective: Ensure workflow state is fail-closed.
Files:
- Modify:
tests/helpers/temp-repo.tsor existing repo fixture helper. - Modify:
tests/workflow-state/build.test.ts
Test cases:
- Missing
.truthmark/config.ymlmakes Sync not applicable or blocked. - No changed files with
--basemakes Sync not applicable. - Unmapped changed functional code produces an ambiguity/blocker reason.
- Context-pack warnings are preserved as diagnostics.
Verification:
npx vitest run tests/workflow-state/build.test.ts
Pass 2: Agent-Facing CLI Contract
Objective
Expose the workflow-state layer through stable JSON commands that agents can call before acting.
Proposed CLI
truthmark workflow status --workflow truthmark-sync --base main --json
truthmark workflow instructions --workflow truthmark-sync --base main --json
Support legacy/short workflow aliases deliberately if needed:
truth-sync->truthmark-synctruth-document->truthmark-documenttruth-realize->truthmark-realize
If aliases are supported, add tests and document them. Do not add aliases accidentally.
Files
- Modify:
src/cli/program.ts - Modify:
src/cli/handlers.ts - Create:
src/workflow-state/instructions.ts - Modify:
src/output/render.tsonly if special rendering is needed; prefer normalCommandResultJSON. - Test:
tests/cli/workflow.test.ts - Test:
tests/integration/agent-workflow-contract.test.ts
Tasks
Task 2.1: Add CLI parser for workflow status
Objective: Wire the status command to buildWorkflowState().
Expected command result:
{
command: "workflow status",
summary: "Truthmark workflow status completed for truthmark-sync.",
diagnostics,
data: { workflowState }
}
Test first:
Add a subprocess test using tests/helpers/run-cli.ts or the existing CLI helper:
npx tsx src/cli/main.ts workflow status --workflow truthmark-sync --json
Expected before implementation: command not found. Expected after implementation: JSON command envelope with data.workflowState.schemaVersion === "truthmark-workflow/v0".
Verification:
npx vitest run tests/cli/workflow.test.ts -t "workflow status"
Task 2.2: Add CLI parser for workflow instructions
Objective: Give agents a workflow playbook and command sequence derived from the same state.
Instruction output should include:
- workflow id and display name
- first commands to run
- required reads
- allowed writes
- forbidden writes
- stop conditions
- helper validator commands
- report sections
- final report shape
- source state summary
Test first:
Assert workflow instructions --workflow truthmark-sync --json includes:
data.instructions.schemaVersiondata.instructions.commandSequencedata.instructions.actionContextdata.instructions.reportTemplate.sections
Verification:
npx vitest run tests/cli/workflow.test.ts -t "workflow instructions"
Task 2.3: Document the Agent-Compatible CLI Contract
Objective: Make the human/agent command split explicit.
Files:
- Modify:
docs/truth/contracts.mdor routed CLI contract truth doc. - Optionally modify:
README.mdonly with a compact conceptual pointer, not a long command inventory.
Content:
- Human/setup commands:
config,init. - Agent/context commands:
check,index,impact,context,validate,workflow status,workflow instructions. - JSON command envelope guarantee:
command,summary,diagnostics,data. schemaVersionguarantees for nested workflow state.- Stable vs experimental fields.
Verification:
npm run check
npx tsx src/cli/main.ts check --json
npx tsx src/cli/main.ts index --json
Task 2.4: Black-box test built CLI output
Objective: Prevent source-only CLI tests from passing while built/package output is broken.
Files:
- Modify:
tests/cli/build-artifact.test.tsor add a workflow-specific built artifact test.
Test:
- Run build before executing
dist. - Execute
node dist/main.js workflow status --workflow truthmark-check --jsonfrom a temp project or temp cwd. - Assert the JSON command envelope exists and does not depend on repo-root-only assets.
Verification:
npm run build
npx vitest run tests/cli/build-artifact.test.ts
Pass 3: Generated Playbooks Consume The Workflow Contract
Objective
Update generated agent surfaces so they call truthmark workflow status/instructions --json before acting, rather than relying only on embedded prose.
This is the direct transfer of OpenSpec's strongest behavior: generated skills/commands teach agents to ask the local CLI for current state.
Files
- Modify:
src/templates/workflow-surfaces.ts - Modify:
src/templates/generated-surfaces.ts - Modify:
src/agents/workflow-manifest.tsonly if manifest fields need extra playbook metadata. - Test:
tests/templates/generated-surfaces.test.ts - Test:
tests/init/init.test.ts - Test:
tests/agents/instructions.test.ts - Test:
tests/integration/agent-workflow-contract.test.ts
Required generated-surface behavior
For each workflow skill/command/prompt surface, add an operational first step:
truthmark workflow status --workflow <workflow-id> [--base <ref>] --json
truthmark workflow instructions --workflow <workflow-id> [--base <ref>] --json
Generated prose must say:
- stop if status says blocked or not applicable unless the user explicitly changes scope;
- obey
actionContext.allowedWritePathsandactionContext.forbiddenWritePaths; - use helper validator commands when present;
- do not edit generated surfaces manually;
- do not create OpenSpec-style change/spec/task artifacts.
Tasks
Task 3.1: Add renderer tests for CLI-first workflow instructions
Objective: Pin the new generated-surface contract before changing renderer output.
Tests:
- Codex/OpenCode/Claude/GitHub Copilot/Gemini generated workflow surfaces mention
truthmark workflow status. - They mention
truthmark workflow instructions. - They mention
actionContextor equivalent write-boundary JSON. - They do not instruct creation of proposal/spec/task/change lifecycle artifacts.
Verification:
npx vitest run tests/templates/generated-surfaces.test.ts tests/agents/instructions.test.ts
Task 3.2: Update workflow surface rendering
Objective: Render the CLI-first operational playbook across all host surfaces.
Implementation notes:
- Prefer shared renderer functions in
src/templates/workflow-surfaces.tsto avoid platform drift. - Preserve platform-specific syntax/frontmatter.
- Do not list every generated file path in README-style docs.
- Do not hard-require optional repository files such as
.truthmark/config.ymlunless the generated surface is only emitted after proving the file exists.
Verification:
npx vitest run tests/templates/generated-surfaces.test.ts
npx vitest run tests/init/init.test.ts
Task 3.3: Refresh generated surfaces and inspect diffs
Objective: Ensure real generated outputs match renderer tests.
Commands:
npx tsx src/cli/main.ts init --json
npm run check
npx tsx src/cli/main.ts check --json
npx tsx src/cli/main.ts index --json
Manual inspection:
- Generated bodies include CLI-first workflow status/instructions calls.
- Managed blocks are preserved.
- Generated outputs do not claim helper success unless the agent is instructed to run a validator and check
data.validation.ok: true. - No generated output implies Truthmark is an application feature rather than workflow/tooling scaffolding.
Pass 4: Compact Truth Health Scorecard
Objective
Add a small scorecard layer to check --json so humans and agents can triage repository-truth health quickly without reading every raw diagnostic first.
This is intentionally narrower than the original Pass 4 idea. The scorecard is not a second checker, not a grade, not a workflow-state payload, and not a new command. It is a compact index over the existing diagnostics returned by check --json.
Product decision
Implement Pass 4 as check-only:
- Add
data.scorecardtotruthmark check --json. - Do not add
data.workflowState.scorecardin this pass. - Do not update generated playbooks in this pass.
- Keep raw diagnostics authoritative.
- Keep JSON compact enough that routine checks do not become expensive to read or paste.
Reason: workflow instructions currently embeds full workflowState; adding fields there directly increases agent token load. Workflow-state scorecard exposure should wait until there is evidence agents need it inside workflow status/instructions.
Proposed dimensions
Use stable IDs only in runtime JSON; labels/remediation can live in docs/constants.
routing-coverageownership-clarityevidence-supportbranch-freshnessgenerated-surface-freshnesstruth-doc-structuredecision-rationale-preservation
Compact type shape
export type TruthHealthScorecard = {
schemaVersion: "truthmark-scorecard/v0";
dimensions: Array<{
id: TruthHealthDimensionId;
status: "pass" | "warn" | "fail" | "not-run";
diagnosticIndexes: number[];
evidence?: string[]; // optional, capped, non-pass only
}>;
};
Rules:
diagnosticIndexespoint into the raw diagnostics returned with the same command result.evidenceis optional and should be capped to 1-2 short snippets for non-pass dimensions.- Do not emit full diagnostic text, source excerpts, labels, or remediation paragraphs in every dimension.
branch-freshnessisnot-runwhen no--basewas supplied.
Files
- Create:
src/checks/scorecard.ts - Modify:
src/checks/check.ts - Test:
tests/checks/scorecard.test.ts - Modify:
tests/checks/check.test.ts - Modify: the routed check/validation truth doc, likely
docs/truthmark/truth/contracts.mdafter route confirmation.
Do not modify src/workflow-state/**, src/templates/**, generated platform surfaces, or report validators for this pass.
Tasks
Task 4.1: Add compact scorecard mapper tests
Objective: Prove the scorecard is a compact triage index over existing diagnostics.
Tests:
- Shape includes
schemaVersion: "truthmark-scorecard/v0"and the seven dimension IDs. - Runtime dimensions include
id,status,diagnosticIndexes, and optional cappedevidenceonly. - Error diagnostics map to
fail; non-error mapped diagnostics map towarn. - No mapped diagnostics after a relevant check ran maps to
pass. - Missing base maps branch freshness to
not-run. diagnosticIndexesremain stable when one diagnostic maps to multiple dimensions.
Verification:
npx vitest run tests/checks/scorecard.test.ts
Task 4.2: Implement the pure scorecard mapper
Objective: Add the minimum implementation needed for the tests.
Implementation constraints:
- Use diagnostic category first.
- Use message/data predicates only when a category is too coarse.
- No filesystem writes, Git commands, OpenSpec runtime artifacts, external calls, or LLM judgment.
- Keep optional evidence short and capped.
Verification:
npx vitest run tests/checks/scorecard.test.ts
npm run typecheck
Task 4.3: Include compact scorecard in check --json
Objective: Add data.scorecard without changing the existing diagnostic contract.
Expected JSON excerpt:
{
"data": {
"scorecard": {
"schemaVersion": "truthmark-scorecard/v0",
"dimensions": [
{ "id": "branch-freshness", "status": "not-run", "diagnosticIndexes": [] }
]
}
}
}
Must preserve:
- top-level
diagnostics data.branchScope- optional
data.impactSet data.truthVisibility
Verification:
npx vitest run tests/checks/check.test.ts tests/checks/scorecard.test.ts
npx tsx src/cli/main.ts check --json
Task 4.4: Update routed check-output truth docs only
Objective: Document the new check JSON contract without implying workflow-state support.
Docs:
- Confirm routing through
.truthmark/config.ymlanddocs/truthmark/routes/areas.md. - Update the routed validation/check contract doc.
- Say raw diagnostics remain authoritative.
- Say workflow-state scorecard exposure is deferred if needed to prevent ambiguity.
Verification:
npx tsx src/cli/main.ts check --json
npx tsx src/cli/main.ts index --json
Pass 5: Preview / Truth Explore Wording Hardening
Objective
Make the existing truthmark-preview workflow read as a safe “Truth Explore” stance for agents: inspect ownership, likely evidence, ambiguity, and recommended next workflow without writing anything.
This pass should be mostly generated-instruction and workflow-copy refinement. Do not add a new workflow ID and do not add a broad exploration JSON object yet.
Product decision
Keep the manifest id as truthmark-preview. Use “Truth Explore” only as user-facing wording inside Preview instructions if helpful.
Do not add this proposed object in the first pass:
exploration?: {
owningRoutes: string[];
owningTruthDocs: string[];
evidenceToInspect: string[];
likelyTruthImpacts: string[];
ambiguityWarnings: string[];
recommendedWorkflows: string[];
};
Reason: most of those fields duplicate existing workflow-state concepts or require agent judgment. Large path arrays and speculative “likely impacts” would add token cost without enough new correctness.
Files
- Modify:
src/agents/workflow-manifest.tsonly if Preview manifest wording/report sections need tightening. - Modify:
src/workflow-state/instructions.tsif generated instructions should call Preview “Truth Explore”. - Modify:
src/templates/workflow-surfaces.tsonly for wording emitted to generated surfaces. - Modify focused Preview/generated-surface tests that already cover Preview text.
Do not add a new workflow id, new CLI command, or new workflow-state JSON object.
Tasks
Task 5.1: Tighten Preview/Explore instruction wording
Objective: Make Preview clearly safe and read-only.
Instruction requirements:
- Say Preview/Explore is read-only.
- Tell agents to call
truthmark workflow status --workflow truthmark-preview --json. - Tell agents to inspect only enough checkout evidence to answer ownership/ambiguity/next-workflow questions.
- Tell agents to report the recommended next workflow instead of executing Sync/Document/Structure/Realize.
- Do not tell agents to edit docs, routes, code, or generated surfaces.
Verification:
npx vitest run tests/agents/truth-preview.test.ts tests/templates/generated-surfaces.test.ts
Task 5.2: Preserve existing workflow-state contract
Objective: Ensure the wording improvement does not introduce new JSON fields or broaden write permissions.
Checks:
truthmark-previewremains the manifest id.- Preview action context remains read-only.
- No
explorationobject is added. - Generated surfaces do not imply automatic follow-on writes.
Verification:
npx vitest run tests/workflow-state/build.test.ts -t "preview"
npx tsx src/cli/main.ts workflow status --workflow truthmark-preview --json
Pass 6: Lightweight Sync Intent Checklist
Objective
Before truth-doc writes, make agents state a reviewable Sync intent: changed code reviewed, affected routes, target truth docs, intended update, evidence to verify, no-update-needed rationale, and blockers.
This borrows OpenSpec's “reviewable intent” value without creating persistent change objects or a typed Sync Plan engine.
Product decision
Start with a checklist embedded in Sync instructions and reports, not a src/sync/plan.ts builder.
Do not create this typed object in the first pass:
export type TruthSyncPlan = {
schemaVersion: "truthmark-sync-plan/v0";
changedCodeReviewed: string[];
affectedRoutes: string[];
targetTruthDocs: string[];
staleClaims: Array<...>;
proposedUpdates: string[];
noUpdateNeededRationale: string[];
};
Reason: staleClaims and proposedUpdates require agent judgment and checkout inspection. A generated skeleton could look authoritative while incomplete, and it would duplicate the final Sync report.
Non-goal
Do not create truthmark/changes/*, proposal files, task files, sync-plan files, lifecycle objects, or arbitrary workflow DAGs. The Sync intent is transient report content.
Files
- Modify:
src/workflow-state/instructions.ts - Modify:
src/templates/workflow-surfaces.ts - Modify:
src/agents/workflow-manifest.tsif report sections/templates are centralized there. - Modify:
tests/agents/truth-sync.test.ts - Modify:
tests/templates/generated-surfaces.test.ts - Modify report validator tests only if the validator already recognizes report sections and the change is intentionally optional.
Do not create src/sync/plan.ts in this pass.
Proposed report section
## Sync Intent
- Changed code reviewed:
- Affected route/truth owner:
- Target truth docs:
- Intended update:
- Evidence to verify:
- No-update-needed rationale:
- Blockers:
Tasks
Task 6.1: Add Sync Intent to generated Sync instructions
Objective: Require agents to pause before truth-doc writes and summarize intent.
Instruction behavior:
- Run workflow status/instructions first.
- Fill the Sync Intent section before editing truth docs.
- If route ownership is ambiguous, block and recommend Truth Structure instead of guessing.
- Only edit allowed truth docs/routes after the intent is clear.
- Validate final report with
truthmark validate sync-report <report-file> --jsonwhen applicable.
Verification:
npx vitest run tests/agents/truth-sync.test.ts tests/templates/generated-surfaces.test.ts
Task 6.2: Keep validator changes optional during migration
Objective: Avoid breaking existing reports before all generated surfaces are refreshed.
Decision: The Sync Intent section should be encouraged/recognized in this pass, not required by the validator unless all generated templates and tests are updated in the same change.
Verification:
npx vitest run tests/sync/report.test.ts tests/cli/validate.test.ts
Pass 7: Deferred Platform Surface Adapter Refactor
Objective
Defer platform adapter refactoring out of the V2 value path. It is internal maintainability work and should happen only after Passes 4-6 behavior is stable and generated-output parity tests are strong enough to catch prompt drift.
Deferred rationale
Truthmark supports many host-native surfaces, and current rendering is centralized. An adapter registry may help later, but it does not directly improve repository-truth correctness now. Refactoring Codex, OpenCode, Claude Code, Copilot, and Gemini surfaces at once creates broad churn and subtle prompt-regression risk.
Do not implement in V2
Do not create these files as part of the current V2 pass sequence:
src/templates/platform-adapters/types.tssrc/templates/platform-adapters/registry.tssrc/templates/platform-adapters/codex.tssrc/templates/platform-adapters/opencode.tssrc/templates/platform-adapters/claude.tssrc/templates/platform-adapters/copilot.tssrc/templates/platform-adapters/gemini.ts
Future acceptance criteria before reopening
Only reopen this pass when:
- Generated behavior from Passes 4-6 is stable.
- Parity/snapshot tests prove generated body content, frontmatter, helper manifests, diagnostic categorization, and host-native paths do not drift.
- The first adapter is a no-op wrapper around one existing platform renderer.
- Platforms migrate one at a time.
- Generated output is byte-for-byte or semantically equivalent before old central branches are removed.
Cross-pass acceptance criteria
A pass is ready to merge only when:
- It preserves Truthmark's fixed repository-truth workflow model.
- It does not add OpenSpec proposal/spec/design/task lifecycle objects.
- JSON output uses the standard command envelope:
command,summary,diagnostics,data. - New nested JSON contracts have
schemaVersionfields. - Read-only workflows are machine-readably read-only.
- Write workflows include allowed writes, forbidden writes, stop conditions, and helper validator commands where applicable.
- Generated surfaces instruct agents to call the CLI and obey the returned state.
- Generated surfaces do not hard-require optional repo-specific files unless proven/configured.
- Tests cover source-tree and built CLI behavior where CLI surface changes.
- Truthmark check/index are run after docs or generated-surface changes.
Recommended implementation order
- Pass 0 first, because it prevents mission drift.
- Pass 1 next, because all later behavior needs the internal state model.
- Pass 2 next, because generated surfaces need a real CLI contract to call.
- Pass 3 next, because it lets agents benefit from the new contract.
- Pass 4 next, but only as a compact
check --jsonscorecard; defer workflow-state exposure. - Pass 5 next as Preview/Explore wording hardening, with no new JSON object.
- Pass 6 next as a lightweight Sync Intent checklist, with no typed plan engine yet.
- Pass 7 is deferred out of the V2 value path until generated behavior is stable and parity tests justify the refactor.
Defer explicitly
Do not implement these unless a later product decision says otherwise:
- arbitrary workflow schema files;
- artifact dependency DAGs;
truthmark/changes/*;- proposal/spec/design/task generation;
- archive/apply semantics;
- multi-repo planning homes;
- Truthmark-owned implementation task execution;
- required pre-code planning artifacts.
Final verification bundle
For each completed pass, run the narrow focused tests first. For a full pass completion, run:
npm run check
npx tsx src/cli/main.ts check --json
npx tsx src/cli/main.ts index --json
git diff --check
For CLI contract passes, also run:
npm run build
node dist/main.js workflow status --workflow truthmark-check --json
node dist/main.js workflow instructions --workflow truthmark-check --json
For generated-surface passes, also run:
npx tsx src/cli/main.ts init --json
npx vitest run tests/templates/generated-surfaces.test.ts tests/init/init.test.ts tests/integration/agent-workflow-contract.test.ts
Bottom line
The improvement path is not “copy OpenSpec.” The improvement path is:
- Make Truthmark's existing governance state computable.
- Expose it through stable JSON commands for agents.
- Teach generated host-native surfaces to consume that contract.
- Improve human review with compact scorecards and lightweight Sync intent checklists.
- Refactor platform rendering only after behavior is stable and the adapter refactor has a separate maintainability justification.
This gives Truthmark OpenSpec's best workflow ergonomics while keeping Truthmark focused on repository truth, route ownership, evidence-backed claims, branch-scoped freshness, safe write boundaries, and Git-reviewable local operation.