From 7e60fbce686bf8fbb65944393f677f9e34599ab3 Mon Sep 17 00:00:00 2001 From: Merlin's Cat Date: Mon, 22 Jun 2026 03:28:02 +1000 Subject: [PATCH] chore: prepare Truthmark 2.2.5 (#26) Co-authored-by: MerlinH --- .../truthmark-sync/support/report-template.md | 23 +-- .antigravity/rules/truthmark-sync.md | 23 +-- .claude/agents/truth-claim-verifier.md | 2 +- .claude/agents/truth-doc-reviewer.md | 2 +- .claude/agents/truth-route-auditor.md | 2 +- .../truthmark-sync/support/report-template.md | 23 +-- .codex/agents/truth-claim-verifier.toml | 2 +- .codex/agents/truth-doc-reviewer.toml | 2 +- .codex/agents/truth-route-auditor.toml | 2 +- .cursor/skills/truthmark-check/SKILL.md | 21 +++ .../truthmark-check/support/procedure.md} | 45 +----- .../support/report-template.md | 27 ++++ .cursor/skills/truthmark-document/SKILL.md | 22 +++ .../truthmark-document/support/procedure.md} | 52 +----- .../support/report-template.md | 34 ++++ .cursor/skills/truthmark-realize/SKILL.md | 22 +++ .../truthmark-realize/support/procedure.md} | 37 +---- .../support/report-template.md | 19 +++ .cursor/skills/truthmark-structure/SKILL.md | 22 +++ .../truthmark-structure/support/procedure.md} | 56 +------ .../support/report-template.md | 38 +++++ .cursor/skills/truthmark-sync/SKILL.md | 23 +++ .../truthmark-sync/support/procedure.md} | 69 +------- .../truthmark-sync/support/report-template.md | 52 ++++++ .github/agents/truth-claim-verifier.md | 2 +- .github/agents/truth-doc-reviewer.md | 2 +- .github/agents/truth-route-auditor.md | 2 +- .../truthmark-sync/support/report-template.md | 23 +-- .opencode/agents/truth-claim-verifier.md | 2 +- .opencode/agents/truth-doc-reviewer.md | 2 +- .opencode/agents/truth-route-auditor.md | 2 +- .../truthmark-sync/support/report-template.md | 23 +-- changes/2026-06-21-version-2-2-5.md | 21 +++ docs/truthmark/engineering/README.md | 3 +- .../engineering/architecture/overview.md | 3 +- .../behaviors/check-diagnostics.md | 34 +++- .../behaviors/init-and-scaffold.md | 28 +++- .../contracts/generated-host-surfaces.md | 68 +++++--- .../repository/bootstrap-routing.md | 9 +- .../repository/repository-intelligence.md | 65 ++++++-- .../workflows/installed-workflow-runtime.md | 46 ++++-- .../agent-native-workflow-injection.md | 73 +++++++-- .../capabilities/lane-separated-truth.md | 11 +- docs/user-guide.md | 6 +- package-lock.json | 4 +- package.json | 2 +- src/agents/truth-check.ts | 2 +- src/agents/truth-document.ts | 2 +- src/agents/truth-structure.ts | 2 +- src/agents/truth-sync.ts | 31 ++-- src/agents/truthmark-portal.ts | 2 +- src/agents/workflow-helper-validation.ts | 13 ++ src/checks/generated-surfaces.ts | 43 ++++- src/init/init.ts | 10 +- src/sync/classify.ts | 1 + src/templates/generated-surfaces.ts | 80 +++++----- src/templates/workflow-surfaces.ts | 149 +++++------------- src/workflow-state/build.ts | 92 ++++++++++- tests/agents/instructions.test.ts | 2 +- tests/agents/truth-check.test.ts | 4 +- tests/agents/truth-document.test.ts | 43 +++-- tests/agents/truth-sync.test.ts | 47 +++--- tests/checks/check.test.ts | 8 +- tests/cli/validate.test.ts | 33 ++++ tests/init/init-instructions.test.ts | 12 +- .../agent-workflow-contract.test.ts | 7 +- tests/package-files.test.ts | 4 +- tests/templates/generated-surfaces.test.ts | 78 +++++++-- tests/workflow-state/build.test.ts | 8 +- 69 files changed, 1088 insertions(+), 636 deletions(-) create mode 100644 .cursor/skills/truthmark-check/SKILL.md rename .cursor/{rules/truthmark-check.mdc => skills/truthmark-check/support/procedure.md} (80%) create mode 100644 .cursor/skills/truthmark-check/support/report-template.md create mode 100644 .cursor/skills/truthmark-document/SKILL.md rename .cursor/{rules/truthmark-document.mdc => skills/truthmark-document/support/procedure.md} (85%) create mode 100644 .cursor/skills/truthmark-document/support/report-template.md create mode 100644 .cursor/skills/truthmark-realize/SKILL.md rename .cursor/{rules/truthmark-realize.mdc => skills/truthmark-realize/support/procedure.md} (68%) create mode 100644 .cursor/skills/truthmark-realize/support/report-template.md create mode 100644 .cursor/skills/truthmark-structure/SKILL.md rename .cursor/{rules/truthmark-structure.mdc => skills/truthmark-structure/support/procedure.md} (80%) create mode 100644 .cursor/skills/truthmark-structure/support/report-template.md create mode 100644 .cursor/skills/truthmark-sync/SKILL.md rename .cursor/{rules/truthmark-sync.mdc => skills/truthmark-sync/support/procedure.md} (75%) create mode 100644 .cursor/skills/truthmark-sync/support/report-template.md create mode 100644 changes/2026-06-21-version-2-2-5.md diff --git a/.agents/skills/truthmark-sync/support/report-template.md b/.agents/skills/truthmark-sync/support/report-template.md index 57c92fc..d682cc5 100644 --- a/.agents/skills/truthmark-sync/support/report-template.md +++ b/.agents/skills/truthmark-sync/support/report-template.md @@ -11,26 +11,26 @@ Changed code reviewed: Sync Intent: - Changed code reviewed: src/auth/session.ts -- Affected route/truth owner: docs/truthmark/routes/areas.md -- Target truth docs: docs/truthmark/engineering/repository/bootstrap-routing.md +- Affected route/truth owner: docs/truthmark/routes/areas/authentication.md +- Target truth docs: docs/truthmark/engineering/behaviors/session-timeout.md - Intended update: Update session timeout behavior. -- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 - User-provided decisions/rationale: User rationale: session timeout behavior changed for internal implementation consistency - No-update-needed rationale: not applicable; mapped truth is stale - Blockers: none Ownership reviewed: -- docs/truthmark/routes/areas.md +- docs/truthmark/routes/areas/authentication.md Truth docs updated: -- docs/truthmark/engineering/repository/bootstrap-routing.md +- docs/truthmark/engineering/behaviors/session-timeout.md Decision/rationale captured: -- Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale. +- Placed user rationale in the bounded authentication behavior truth doc under Engineering Decisions/Rationale. Evidence checked: -- Claim: Session timeout behavior is documented in the mapped repository truth doc. - Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Claim: Session timeout behavior is documented in the bounded authentication behavior truth doc. + Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 Result: supported Notes: @@ -41,11 +41,12 @@ Blocked report example: Truth Sync: blocked Reason: -- routing repair is not allowed +- Changed code maps only to the provisional bootstrap route. Files requiring manual review: -- docs/truthmark/routes/areas.md +- src/auth/** +- docs/truthmark/routes/areas/repository.md Next action: -- update routing metadata and rerun Truth Sync +- Run Truth Structure for src/auth/** before updating behavior truth. ``` diff --git a/.antigravity/rules/truthmark-sync.md b/.antigravity/rules/truthmark-sync.md index 6ac4501..d44e168 100644 --- a/.antigravity/rules/truthmark-sync.md +++ b/.antigravity/rules/truthmark-sync.md @@ -86,26 +86,26 @@ Changed code reviewed: Sync Intent: - Changed code reviewed: src/auth/session.ts -- Affected route/truth owner: docs/truthmark/routes/areas.md -- Target truth docs: docs/truthmark/engineering/repository/bootstrap-routing.md +- Affected route/truth owner: docs/truthmark/routes/areas/authentication.md +- Target truth docs: docs/truthmark/engineering/behaviors/session-timeout.md - Intended update: Update session timeout behavior. -- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 - User-provided decisions/rationale: User rationale: session timeout behavior changed for internal implementation consistency - No-update-needed rationale: not applicable; mapped truth is stale - Blockers: none Ownership reviewed: -- docs/truthmark/routes/areas.md +- docs/truthmark/routes/areas/authentication.md Truth docs updated: -- docs/truthmark/engineering/repository/bootstrap-routing.md +- docs/truthmark/engineering/behaviors/session-timeout.md Decision/rationale captured: -- Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale. +- Placed user rationale in the bounded authentication behavior truth doc under Engineering Decisions/Rationale. Evidence checked: -- Claim: Session timeout behavior is documented in the mapped repository truth doc. - Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Claim: Session timeout behavior is documented in the bounded authentication behavior truth doc. + Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 Result: supported Notes: @@ -116,11 +116,12 @@ Blocked report example: Truth Sync: blocked Reason: -- routing repair is not allowed +- Changed code maps only to the provisional bootstrap route. Files requiring manual review: -- docs/truthmark/routes/areas.md +- src/auth/** +- docs/truthmark/routes/areas/repository.md Next action: -- update routing metadata and rerun Truth Sync +- Run Truth Structure for src/auth/** before updating behavior truth. ``` diff --git a/.claude/agents/truth-claim-verifier.md b/.claude/agents/truth-claim-verifier.md index 326f90f..1168164 100644 --- a/.claude/agents/truth-claim-verifier.md +++ b/.claude/agents/truth-claim-verifier.md @@ -16,6 +16,6 @@ For every checked claim, classify the result as supported | narrowed | removed | Do not edit files, stage changes, or invent missing behavior. Return JSON only with keys: scope, filesReviewed, claimsChecked, evidence, unsupportedClaims, confidence, recommendedWorkflow, notes. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. diff --git a/.claude/agents/truth-doc-reviewer.md b/.claude/agents/truth-doc-reviewer.md index 758d460..bc3b3d8 100644 --- a/.claude/agents/truth-doc-reviewer.md +++ b/.claude/agents/truth-doc-reviewer.md @@ -15,6 +15,6 @@ Do not edit files, stage changes, or rewrite docs. Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes. recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. diff --git a/.claude/agents/truth-route-auditor.md b/.claude/agents/truth-route-auditor.md index 0f09eae..5a4713b 100644 --- a/.claude/agents/truth-route-auditor.md +++ b/.claude/agents/truth-route-auditor.md @@ -23,6 +23,6 @@ Do not edit files, stage changes, or propose broad rewrites. Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes. recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. diff --git a/.claude/skills/truthmark-sync/support/report-template.md b/.claude/skills/truthmark-sync/support/report-template.md index 57c92fc..d682cc5 100644 --- a/.claude/skills/truthmark-sync/support/report-template.md +++ b/.claude/skills/truthmark-sync/support/report-template.md @@ -11,26 +11,26 @@ Changed code reviewed: Sync Intent: - Changed code reviewed: src/auth/session.ts -- Affected route/truth owner: docs/truthmark/routes/areas.md -- Target truth docs: docs/truthmark/engineering/repository/bootstrap-routing.md +- Affected route/truth owner: docs/truthmark/routes/areas/authentication.md +- Target truth docs: docs/truthmark/engineering/behaviors/session-timeout.md - Intended update: Update session timeout behavior. -- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 - User-provided decisions/rationale: User rationale: session timeout behavior changed for internal implementation consistency - No-update-needed rationale: not applicable; mapped truth is stale - Blockers: none Ownership reviewed: -- docs/truthmark/routes/areas.md +- docs/truthmark/routes/areas/authentication.md Truth docs updated: -- docs/truthmark/engineering/repository/bootstrap-routing.md +- docs/truthmark/engineering/behaviors/session-timeout.md Decision/rationale captured: -- Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale. +- Placed user rationale in the bounded authentication behavior truth doc under Engineering Decisions/Rationale. Evidence checked: -- Claim: Session timeout behavior is documented in the mapped repository truth doc. - Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Claim: Session timeout behavior is documented in the bounded authentication behavior truth doc. + Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 Result: supported Notes: @@ -41,11 +41,12 @@ Blocked report example: Truth Sync: blocked Reason: -- routing repair is not allowed +- Changed code maps only to the provisional bootstrap route. Files requiring manual review: -- docs/truthmark/routes/areas.md +- src/auth/** +- docs/truthmark/routes/areas/repository.md Next action: -- update routing metadata and rerun Truth Sync +- Run Truth Structure for src/auth/** before updating behavior truth. ``` diff --git a/.codex/agents/truth-claim-verifier.toml b/.codex/agents/truth-claim-verifier.toml index 5387031..429f677 100644 --- a/.codex/agents/truth-claim-verifier.toml +++ b/.codex/agents/truth-claim-verifier.toml @@ -12,7 +12,7 @@ For every checked claim, classify the result as supported | narrowed | removed | Do not edit files, stage changes, or invent missing behavior. Return JSON only with keys: scope, filesReviewed, claimsChecked, evidence, unsupportedClaims, confidence, recommendedWorkflow, notes. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. """ diff --git a/.codex/agents/truth-doc-reviewer.toml b/.codex/agents/truth-doc-reviewer.toml index 7755da1..b8cae62 100644 --- a/.codex/agents/truth-doc-reviewer.toml +++ b/.codex/agents/truth-doc-reviewer.toml @@ -11,7 +11,7 @@ Do not edit files, stage changes, or rewrite docs. Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes. recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. """ diff --git a/.codex/agents/truth-route-auditor.toml b/.codex/agents/truth-route-auditor.toml index df85c58..ef56782 100644 --- a/.codex/agents/truth-route-auditor.toml +++ b/.codex/agents/truth-route-auditor.toml @@ -19,7 +19,7 @@ Do not edit files, stage changes, or propose broad rewrites. Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes. recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. """ diff --git a/.cursor/skills/truthmark-check/SKILL.md b/.cursor/skills/truthmark-check/SKILL.md new file mode 100644 index 0000000..df2ec94 --- /dev/null +++ b/.cursor/skills/truthmark-check/SKILL.md @@ -0,0 +1,21 @@ +--- +name: truthmark-check +description: Use when the user asks to audit repository truth health, routing, ownership, or canonical docs. Not for normal lint/test/typecheck/code-review verification, finish-time Sync, or silently rewriting docs. +argument-hint: Optional area, doc path, or audit focus +user-invocable: true +--- + +# Truthmark Check + +Use this skill to audit repository truth health. + +Use as a Cursor Agent Skill. Cursor discovers project skills under `.cursor/skills/`, selects them from the description when relevant, and supports manual `/` invocation. + +Quick procedure: +- Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists. +- Inspect .truthmark/config.yml and configured route files (docs/truthmark/routes/areas.md; docs/truthmark/routes/areas/) only when they exist; then inspect canonical docs and relevant implementation directly. +- Report issues and suggested fixes; do not silently rewrite unrelated files. + +Progressive disclosure: +- support/procedure.md — read before edits or detailed auditing; contains core review questions +- support/report-template.md — read before the final report diff --git a/.cursor/rules/truthmark-check.mdc b/.cursor/skills/truthmark-check/support/procedure.md similarity index 80% rename from .cursor/rules/truthmark-check.mdc rename to .cursor/skills/truthmark-check/support/procedure.md index fdfaf96..9c5779f 100644 --- a/.cursor/rules/truthmark-check.mdc +++ b/.cursor/skills/truthmark-check/support/procedure.md @@ -1,24 +1,7 @@ ---- -description: Use when the user asks to audit repository truth health, routing, ownership, or canonical docs. Not for normal lint/test/typecheck/code-review verification, finish-time Sync, or silently rewriting docs. -alwaysApply: false ---- - -# Truthmark Check +# Truthmark Check Procedure Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. -This rule is the Cursor entrypoint for Truthmark Check. - -Do not invoke another Truthmark command from here. - -Manual invocation: @truthmark-check - -If skill entrypoints are unavailable, use the host's direct evidence-first manual fallback procedure. - -Description: Use when the user asks to audit repository truth health, routing, ownership, or canonical docs. Not for normal lint/test/typecheck/code-review verification, finish-time Sync, or silently rewriting docs. - -## Procedure - # Truthmark Check Use this skill to audit repository truth health. @@ -69,29 +52,3 @@ Truthmark hierarchy hints: Decision truth lives in the canonical doc it governs; date active decisions inline when added or changed. Do not create separate active-decision ADR/planning logs; replace the active decision and let Git history carry the audit trail. Product decisions belong in product truth; engineering, architecture, contract, workflow, and operational decisions belong in engineering truth. - -## Report Template - -Report completion in this shape: - -```md -Truth Check: completed - -Files reviewed: -- docs/truthmark/routes/areas.md - -Issues found: -- none - -Fixes suggested: -- none - -Evidence checked: -- Finding: The root route index is present and maps repository truth owners. - Evidence: docs/truthmark/routes/areas.md:1 - Suggested fix: none - Confidence: high - -Validation: -- truthmark check -``` diff --git a/.cursor/skills/truthmark-check/support/report-template.md b/.cursor/skills/truthmark-check/support/report-template.md new file mode 100644 index 0000000..c03f1c8 --- /dev/null +++ b/.cursor/skills/truthmark-check/support/report-template.md @@ -0,0 +1,27 @@ +# Truthmark Check Report Template + +Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. + +Report completion in this shape: + +```md +Truth Check: completed + +Files reviewed: +- docs/truthmark/routes/areas.md + +Issues found: +- none + +Fixes suggested: +- none + +Evidence checked: +- Finding: The root route index is present and maps repository truth owners. + Evidence: docs/truthmark/routes/areas.md:1 + Suggested fix: none + Confidence: high + +Validation: +- truthmark check +``` diff --git a/.cursor/skills/truthmark-document/SKILL.md b/.cursor/skills/truthmark-document/SKILL.md new file mode 100644 index 0000000..60f5ba4 --- /dev/null +++ b/.cursor/skills/truthmark-document/SKILL.md @@ -0,0 +1,22 @@ +--- +name: truthmark-document +description: Use when the user asks to document existing implemented behavior, or Sync, Check, or Structure finds implemented behavior missing canonical truth. Not for functional-code changes, doc-first implementation, or topology repair that needs Structure. +argument-hint: Optional implemented behavior, API endpoint, route, controller, package, or truth-doc area to document +user-invocable: true +--- + +# Truthmark Document + +Use this skill to document existing implemented behavior when no functional-code changes are required for the task. + +Use as a Cursor Agent Skill. Cursor discovers project skills under `.cursor/skills/`, selects them from the description when relevant, and supports manual `/` invocation. + +Quick procedure: +- Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists. +- Inspect .truthmark/config.yml and configured route files (docs/truthmark/routes/areas.md; docs/truthmark/routes/areas/) only when they exist; then inspect existing canonical docs, implementation code, and tests directly. +- Document current implemented behavior; do not invent future behavior. +- May write canonical truth docs and truth routing files only; must not write functional code. + +Progressive disclosure: +- support/procedure.md — read before edits or detailed auditing; contains core review questions +- support/report-template.md — read before the final report diff --git a/.cursor/rules/truthmark-document.mdc b/.cursor/skills/truthmark-document/support/procedure.md similarity index 85% rename from .cursor/rules/truthmark-document.mdc rename to .cursor/skills/truthmark-document/support/procedure.md index d64ca3b..eecba04 100644 --- a/.cursor/rules/truthmark-document.mdc +++ b/.cursor/skills/truthmark-document/support/procedure.md @@ -1,24 +1,7 @@ ---- -description: Use when the user asks to document existing implemented behavior, or Sync, Check, or Structure finds implemented behavior missing canonical truth. Not for functional-code changes, doc-first implementation, or topology repair that needs Structure. -alwaysApply: false ---- - -# Truthmark Document +# Truthmark Document Procedure Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. -This rule is the Cursor entrypoint for Truthmark Document. - -Do not invoke another Truthmark command from here. - -Manual invocation: @truthmark-document - -If skill entrypoints are unavailable, use the host's direct evidence-first manual fallback procedure. - -Description: Use when the user asks to document existing implemented behavior, or Sync, Check, or Structure finds implemented behavior missing canonical truth. Not for functional-code changes, doc-first implementation, or topology repair that needs Structure. - -## Procedure - # Truthmark Document Use this skill to document existing implemented behavior when no functional-code changes are required for the task. @@ -102,36 +85,3 @@ Parent post-document verification: - stop on functional code, generated host surfaces, or unrelated diffs caused by document work - for each write lease, validate the worker report against the actual worker diff, allowedWrites, forbiddenWrites, identity fields, filesChanged, offLeaseChanges, blockers, and expected report fields before accepting it - verify the final report records ownership review, structure requirement, restructure, routing update, or manual handoff reason when applicable - -## Report Template - -Report completion in this shape: -```md -Truth Document: completed - -Implementation reviewed: -- src/routing/area-resolver.ts - -Ownership reviewed: -- docs/truthmark/routes/areas.md - -Truth docs created: -- docs/truthmark/engineering/contracts/routing.md - -Truth docs updated: -- docs/truthmark/engineering/behaviors/check-diagnostics.md - -Truth docs restructured: -- docs/truthmark/engineering/behaviors/check-diagnostics.md - -Routing updated: -- docs/truthmark/routes/areas.md - -Evidence checked: -- Claim: Route resolution behavior is documented in the contracts truth doc. - Evidence: src/routing/area-resolver.ts:14 / docs/truthmark/routes/areas.md:9 - Result: supported - -Notes: -- Documented routing and behavior from route handlers and tests. -``` diff --git a/.cursor/skills/truthmark-document/support/report-template.md b/.cursor/skills/truthmark-document/support/report-template.md new file mode 100644 index 0000000..29677aa --- /dev/null +++ b/.cursor/skills/truthmark-document/support/report-template.md @@ -0,0 +1,34 @@ +# Truthmark Document Report Template + +Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. + +Report completion in this shape: +```md +Truth Document: completed + +Implementation reviewed: +- src/routing/area-resolver.ts + +Ownership reviewed: +- docs/truthmark/routes/areas.md + +Truth docs created: +- docs/truthmark/engineering/contracts/routing.md + +Truth docs updated: +- docs/truthmark/engineering/behaviors/check-diagnostics.md + +Truth docs restructured: +- docs/truthmark/engineering/behaviors/check-diagnostics.md + +Routing updated: +- docs/truthmark/routes/areas.md + +Evidence checked: +- Claim: Route resolution behavior is documented in the contracts truth doc. + Evidence: src/routing/area-resolver.ts:14 / docs/truthmark/routes/areas.md:9 + Result: supported + +Notes: +- Documented routing and behavior from route handlers and tests. +``` diff --git a/.cursor/skills/truthmark-realize/SKILL.md b/.cursor/skills/truthmark-realize/SKILL.md new file mode 100644 index 0000000..c798f7d --- /dev/null +++ b/.cursor/skills/truthmark-realize/SKILL.md @@ -0,0 +1,22 @@ +--- +name: truthmark-realize +description: Use when the user explicitly asks to realize Truthmark truth docs into code, including /truthmark-realize, $truthmark-realize, or /truthmark:realize. Not for syncing docs after code changes, documenting existing code, topology repair, or truth audits. +argument-hint: Optional truth doc path, area, or desired code behavior to realize +user-invocable: true +--- + +# Truthmark Realize + +Use this skill only when the user explicitly asks to realize truth docs into code. + +Use as a Cursor Agent Skill. Cursor discovers project skills under `.cursor/skills/`, selects them from the description when relevant, and supports manual `/` invocation. + +Quick procedure: +- Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists. +- Read the source truth docs, inspect .truthmark/config.yml and configured route files (docs/truthmark/routes/areas.md; docs/truthmark/routes/areas/) only when they exist, then inspect tests and relevant functional code directly. +- Truth docs lead; code follows. +- may write functional code only; must not edit truth docs or truth routing while realizing those docs. + +Progressive disclosure: +- support/procedure.md — read before edits or detailed auditing; contains core review questions +- support/report-template.md — read before the final report diff --git a/.cursor/rules/truthmark-realize.mdc b/.cursor/skills/truthmark-realize/support/procedure.md similarity index 68% rename from .cursor/rules/truthmark-realize.mdc rename to .cursor/skills/truthmark-realize/support/procedure.md index 363e46e..f6b3200 100644 --- a/.cursor/rules/truthmark-realize.mdc +++ b/.cursor/skills/truthmark-realize/support/procedure.md @@ -1,24 +1,7 @@ ---- -description: Use when the user explicitly asks to realize Truthmark truth docs into code, including /truthmark-realize, $truthmark-realize, or /truthmark:realize. Not for syncing docs after code changes, documenting existing code, topology repair, or truth audits. -alwaysApply: false ---- - -# Truthmark Realize +# Truthmark Realize Procedure Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. -This rule is the Cursor entrypoint for Truthmark Realize. - -Do not invoke another Truthmark command from here. - -Manual invocation: @truthmark-realize - -If skill entrypoints are unavailable, use the host's direct evidence-first manual fallback procedure. - -Description: Use when the user explicitly asks to realize Truthmark truth docs into code, including /truthmark-realize, $truthmark-realize, or /truthmark:realize. Not for syncing docs after code changes, documenting existing code, topology repair, or truth audits. - -## Procedure - # Truthmark Realize Use this skill only when the user explicitly asks to realize truth docs into code. @@ -56,21 +39,3 @@ Read and write boundaries: - may read truth docs, routing docs, and relevant functional code - may write functional code only - must not edit truth docs or truth routing while realizing those docs - -## Report Template - -Report completion in this shape: - -```md -Truth Realize: completed - -Truth docs used: -- docs/truthmark/product/capabilities/authentication-session.md -- docs/truthmark/engineering/behaviors/authentication-session.md - -Code updated: -- src/auth/session.ts - -Verification: -- npm test -- auth -``` diff --git a/.cursor/skills/truthmark-realize/support/report-template.md b/.cursor/skills/truthmark-realize/support/report-template.md new file mode 100644 index 0000000..730b19e --- /dev/null +++ b/.cursor/skills/truthmark-realize/support/report-template.md @@ -0,0 +1,19 @@ +# Truthmark Realize Report Template + +Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. + +Report completion in this shape: + +```md +Truth Realize: completed + +Truth docs used: +- docs/truthmark/product/capabilities/authentication-session.md +- docs/truthmark/engineering/behaviors/authentication-session.md + +Code updated: +- src/auth/session.ts + +Verification: +- npm test -- auth +``` diff --git a/.cursor/skills/truthmark-structure/SKILL.md b/.cursor/skills/truthmark-structure/SKILL.md new file mode 100644 index 0000000..9674a43 --- /dev/null +++ b/.cursor/skills/truthmark-structure/SKILL.md @@ -0,0 +1,22 @@ +--- +name: truthmark-structure +description: Use when routing or truth ownership is missing, stale, broad, overloaded, catch-all, unrouteable, mixed-owner, needs split/repair, or needs new area setup. Not for documenting implemented behavior, syncing a code diff, or realizing docs into code. +argument-hint: Optional area, directory, or routing concern +user-invocable: true +--- + +# Truthmark Structure + +Use this skill to design or repair Truthmark area structure. + +Use as a Cursor Agent Skill. Cursor discovers project skills under `.cursor/skills/`, selects them from the description when relevant, and supports manual `/` invocation. + +Quick procedure: +- Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists. +- Inspect .truthmark/config.yml and configured route files (docs/truthmark/routes/areas.md; docs/truthmark/routes/areas/) only when they exist; then inspect current docs and relevant code directly. +- Define areas by product or behavior ownership, not by mechanical directory mirroring. +- Do not edit functional code. + +Progressive disclosure: +- support/procedure.md — read before edits or detailed auditing; contains core review questions +- support/report-template.md — read before the final report diff --git a/.cursor/rules/truthmark-structure.mdc b/.cursor/skills/truthmark-structure/support/procedure.md similarity index 80% rename from .cursor/rules/truthmark-structure.mdc rename to .cursor/skills/truthmark-structure/support/procedure.md index 95cb42d..16f39e5 100644 --- a/.cursor/rules/truthmark-structure.mdc +++ b/.cursor/skills/truthmark-structure/support/procedure.md @@ -1,24 +1,7 @@ ---- -description: Use when routing or truth ownership is missing, stale, broad, overloaded, catch-all, unrouteable, mixed-owner, needs split/repair, or needs new area setup. Not for documenting implemented behavior, syncing a code diff, or realizing docs into code. -alwaysApply: false ---- - -# Truthmark Structure +# Truthmark Structure Procedure Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. -This rule is the Cursor entrypoint for Truthmark Structure. - -Do not invoke another Truthmark command from here. - -Manual invocation: @truthmark-structure - -If skill entrypoints are unavailable, use the host's direct evidence-first manual fallback procedure. - -Description: Use when routing or truth ownership is missing, stale, broad, overloaded, catch-all, unrouteable, mixed-owner, needs split/repair, or needs new area setup. Not for documenting implemented behavior, syncing a code diff, or realizing docs into code. - -## Procedure - Use this skill to design or repair Truthmark area structure. Truth Structure is agent-native: @@ -116,40 +99,3 @@ Truthmark hierarchy hints: Decision truth lives in the canonical doc it governs; date active decisions inline when added or changed. Do not create separate active-decision ADR/planning logs; replace the active decision and let Git history carry the audit trail. Product decisions belong in product truth; engineering, architecture, contract, workflow, and operational decisions belong in engineering truth. - -## Report Template - -Report completion in this shape: -```md -Truth Structure: completed -Topology reviewed: -- controllers: src/auth/** -- product docs root: docs/truthmark/product -- engineering docs root: docs/truthmark/engineering -- route files: docs/truthmark/routes/areas.md -Areas reviewed: -- src/auth/** -Routing updated: -- docs/truthmark/routes/areas.md -Initial truth boundary: -- Area: Authentication -- Code: src/auth/** -- Product owner: docs/truthmark/product/capabilities/authentication-session.md -- Engineering owner: docs/truthmark/engineering/behaviors/authentication-session.md -- Scope: session behavior only -Truth docs created: -- docs/truthmark/product/capabilities/authentication-session.md -- docs/truthmark/engineering/behaviors/authentication-session.md -Truth docs split: -- docs/truthmark/truth/authentication/README.md -> docs/truthmark/product/capabilities/authentication-session.md and docs/truthmark/engineering/behaviors/authentication-session.md -Truth docs restructured: -- docs/truthmark/truth/authentication/README.md -Evidence checked: -- Claim: Session behavior belongs to a dedicated Authentication truth owner. - Evidence: src/auth/** / docs/truthmark/routes/areas.md:7 - Result: supported -Topology decisions: -- Added an Authentication area because session behavior has a distinct code surface and truth owner. -Notes: -- Added an Authentication area for session behavior. -``` diff --git a/.cursor/skills/truthmark-structure/support/report-template.md b/.cursor/skills/truthmark-structure/support/report-template.md new file mode 100644 index 0000000..d615580 --- /dev/null +++ b/.cursor/skills/truthmark-structure/support/report-template.md @@ -0,0 +1,38 @@ +# Truthmark Structure Report Template + +Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. + +Report completion in this shape: +```md +Truth Structure: completed +Topology reviewed: +- controllers: src/auth/** +- product docs root: docs/truthmark/product +- engineering docs root: docs/truthmark/engineering +- route files: docs/truthmark/routes/areas.md +Areas reviewed: +- src/auth/** +Routing updated: +- docs/truthmark/routes/areas.md +Initial truth boundary: +- Area: Authentication +- Code: src/auth/** +- Product owner: docs/truthmark/product/capabilities/authentication-session.md +- Engineering owner: docs/truthmark/engineering/behaviors/authentication-session.md +- Scope: session behavior only +Truth docs created: +- docs/truthmark/product/capabilities/authentication-session.md +- docs/truthmark/engineering/behaviors/authentication-session.md +Truth docs split: +- docs/truthmark/truth/authentication/README.md -> docs/truthmark/product/capabilities/authentication-session.md and docs/truthmark/engineering/behaviors/authentication-session.md +Truth docs restructured: +- docs/truthmark/truth/authentication/README.md +Evidence checked: +- Claim: Session behavior belongs to a dedicated Authentication truth owner. + Evidence: src/auth/** / docs/truthmark/routes/areas.md:7 + Result: supported +Topology decisions: +- Added an Authentication area because session behavior has a distinct code surface and truth owner. +Notes: +- Added an Authentication area for session behavior. +``` diff --git a/.cursor/skills/truthmark-sync/SKILL.md b/.cursor/skills/truthmark-sync/SKILL.md new file mode 100644 index 0000000..883829f --- /dev/null +++ b/.cursor/skills/truthmark-sync/SKILL.md @@ -0,0 +1,23 @@ +--- +name: truthmark-sync +description: Use automatically at finish-time after functional code changes, or explicit /truthmark-sync, $truthmark-sync, or /truthmark:sync. Skip docs-only, formatting-only, behavior-preserving renames, missing config, and no-code changes. Not for doc-first realization or manual topology design. +argument-hint: Optional changed-code area, truth-doc area, or sync focus +user-invocable: true +--- + +# Truthmark Sync + +Use this skill automatically before finishing when functional code changed since the last successful Truth Sync. Also run it immediately when the user explicitly invokes Truth Sync. + +Use as a Cursor Agent Skill. Cursor discovers project skills under `.cursor/skills/`, selects them from the description when relevant, and supports manual `/` invocation. + +Quick procedure: +- Follow repository instruction files that exist in this checkout; do not assume any optional policy path exists. +- Skip docs-only, formatting-only, behavior-preserving renames with no truth impact, missing config, and no-code changes. +- Inspect .truthmark/config.yml and configured route files (docs/truthmark/routes/areas.md; docs/truthmark/routes/areas/) only when they exist; then inspect relevant canonical docs directly. +- direct checkout inspection is the canonical path; do not require the truthmark binary. +- May write canonical truth docs and truth routing files only; must not rewrite functional code. + +Progressive disclosure: +- support/procedure.md — read before edits or detailed auditing; contains core review questions +- support/report-template.md — read before the final report diff --git a/.cursor/rules/truthmark-sync.mdc b/.cursor/skills/truthmark-sync/support/procedure.md similarity index 75% rename from .cursor/rules/truthmark-sync.mdc rename to .cursor/skills/truthmark-sync/support/procedure.md index 750d1e3..29f5a3c 100644 --- a/.cursor/rules/truthmark-sync.mdc +++ b/.cursor/skills/truthmark-sync/support/procedure.md @@ -1,24 +1,7 @@ ---- -description: Use automatically at finish-time after functional code changes, or explicit /truthmark-sync, $truthmark-sync, or /truthmark:sync. Skip docs-only, formatting-only, behavior-preserving renames, missing config, and no-code changes. Not for doc-first realization or manual topology design. -alwaysApply: false ---- - -# Truthmark Sync +# Truthmark Sync Procedure Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. -This rule is the Cursor entrypoint for Truthmark Sync. - -Do not invoke another Truthmark command from here. - -Manual invocation: @truthmark-sync - -If skill entrypoints are unavailable, use the host's direct evidence-first manual fallback procedure. - -Description: Use automatically at finish-time after functional code changes, or explicit /truthmark-sync, $truthmark-sync, or /truthmark:sync. Skip docs-only, formatting-only, behavior-preserving renames, missing config, and no-code changes. Not for doc-first realization or manual topology design. - -## Procedure - Use this skill automatically before finishing when functional code changed since the last successful Truth Sync. Also run it immediately when the user explicitly invokes Truth Sync. Explicit invocation runs immediately when the user directly requests this workflow. Later functional-code changes need a fresh finish-time review, and an earlier explicit run satisfies the finish-time review only if no later functional-code changes occur. Skip when changes are documentation-only, formatting-only, clearly behavior-preserving renames with no truth impact, when no Truthmark config exists yet, or when there are no functional code changes. @@ -79,53 +62,3 @@ Parent post-sync verification: - verify the updated docs correspond to reviewed checkout evidence, changed-code impact, or a recorded stale-truth correction made within the sync write lease - verify the final report records ownership review, structure requirement, split, restructure, or manual handoff reason when the ownership review applies - manual handoff outcomes must preserve the working tree as-is: no rollback, no post-block cleanup edits, and manual-review reporting of any remaining files - -## Report Template - -Report completion in this shape: -```md -Truth Sync: completed - -Changed code reviewed: -- src/auth/session.ts - -Sync Intent: -- Changed code reviewed: src/auth/session.ts -- Affected route/truth owner: docs/truthmark/routes/areas.md -- Target truth docs: docs/truthmark/engineering/repository/bootstrap-routing.md -- Intended update: Update session timeout behavior. -- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 -- User-provided decisions/rationale: User rationale: session timeout behavior changed for internal implementation consistency -- No-update-needed rationale: not applicable; mapped truth is stale -- Blockers: none - -Ownership reviewed: -- docs/truthmark/routes/areas.md - -Truth docs updated: -- docs/truthmark/engineering/repository/bootstrap-routing.md - -Decision/rationale captured: -- Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale. - -Evidence checked: -- Claim: Session timeout behavior is documented in the mapped repository truth doc. - Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 - Result: supported - -Notes: -- Updated session timeout behavior. -``` -Blocked report example: -```md -Truth Sync: blocked - -Reason: -- routing repair is not allowed - -Files requiring manual review: -- docs/truthmark/routes/areas.md - -Next action: -- update routing metadata and rerun Truth Sync -``` diff --git a/.cursor/skills/truthmark-sync/support/report-template.md b/.cursor/skills/truthmark-sync/support/report-template.md new file mode 100644 index 0000000..d682cc5 --- /dev/null +++ b/.cursor/skills/truthmark-sync/support/report-template.md @@ -0,0 +1,52 @@ +# Truthmark Sync Report Template + +Truthmark-managed generated file. Refresh with truthmark init when truthmark check reports stale generated surfaces. + +Report completion in this shape: +```md +Truth Sync: completed + +Changed code reviewed: +- src/auth/session.ts + +Sync Intent: +- Changed code reviewed: src/auth/session.ts +- Affected route/truth owner: docs/truthmark/routes/areas/authentication.md +- Target truth docs: docs/truthmark/engineering/behaviors/session-timeout.md +- Intended update: Update session timeout behavior. +- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 +- User-provided decisions/rationale: User rationale: session timeout behavior changed for internal implementation consistency +- No-update-needed rationale: not applicable; mapped truth is stale +- Blockers: none + +Ownership reviewed: +- docs/truthmark/routes/areas/authentication.md + +Truth docs updated: +- docs/truthmark/engineering/behaviors/session-timeout.md + +Decision/rationale captured: +- Placed user rationale in the bounded authentication behavior truth doc under Engineering Decisions/Rationale. + +Evidence checked: +- Claim: Session timeout behavior is documented in the bounded authentication behavior truth doc. + Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 + Result: supported + +Notes: +- Updated session timeout behavior. +``` +Blocked report example: +```md +Truth Sync: blocked + +Reason: +- Changed code maps only to the provisional bootstrap route. + +Files requiring manual review: +- src/auth/** +- docs/truthmark/routes/areas/repository.md + +Next action: +- Run Truth Structure for src/auth/** before updating behavior truth. +``` diff --git a/.github/agents/truth-claim-verifier.md b/.github/agents/truth-claim-verifier.md index e693b62..2758044 100644 --- a/.github/agents/truth-claim-verifier.md +++ b/.github/agents/truth-claim-verifier.md @@ -14,6 +14,6 @@ For every checked claim, classify the result as supported | narrowed | removed | Do not edit files, stage changes, or invent missing behavior. Return JSON only with keys: scope, filesReviewed, claimsChecked, evidence, unsupportedClaims, confidence, recommendedWorkflow, notes. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. diff --git a/.github/agents/truth-doc-reviewer.md b/.github/agents/truth-doc-reviewer.md index 3bfd9bd..220de97 100644 --- a/.github/agents/truth-doc-reviewer.md +++ b/.github/agents/truth-doc-reviewer.md @@ -13,6 +13,6 @@ Do not edit files, stage changes, or rewrite docs. Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes. recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. diff --git a/.github/agents/truth-route-auditor.md b/.github/agents/truth-route-auditor.md index 3505ecc..cbde262 100644 --- a/.github/agents/truth-route-auditor.md +++ b/.github/agents/truth-route-auditor.md @@ -21,6 +21,6 @@ Do not edit files, stage changes, or propose broad rewrites. Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes. recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. diff --git a/.github/skills/truthmark-sync/support/report-template.md b/.github/skills/truthmark-sync/support/report-template.md index 57c92fc..d682cc5 100644 --- a/.github/skills/truthmark-sync/support/report-template.md +++ b/.github/skills/truthmark-sync/support/report-template.md @@ -11,26 +11,26 @@ Changed code reviewed: Sync Intent: - Changed code reviewed: src/auth/session.ts -- Affected route/truth owner: docs/truthmark/routes/areas.md -- Target truth docs: docs/truthmark/engineering/repository/bootstrap-routing.md +- Affected route/truth owner: docs/truthmark/routes/areas/authentication.md +- Target truth docs: docs/truthmark/engineering/behaviors/session-timeout.md - Intended update: Update session timeout behavior. -- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 - User-provided decisions/rationale: User rationale: session timeout behavior changed for internal implementation consistency - No-update-needed rationale: not applicable; mapped truth is stale - Blockers: none Ownership reviewed: -- docs/truthmark/routes/areas.md +- docs/truthmark/routes/areas/authentication.md Truth docs updated: -- docs/truthmark/engineering/repository/bootstrap-routing.md +- docs/truthmark/engineering/behaviors/session-timeout.md Decision/rationale captured: -- Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale. +- Placed user rationale in the bounded authentication behavior truth doc under Engineering Decisions/Rationale. Evidence checked: -- Claim: Session timeout behavior is documented in the mapped repository truth doc. - Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Claim: Session timeout behavior is documented in the bounded authentication behavior truth doc. + Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 Result: supported Notes: @@ -41,11 +41,12 @@ Blocked report example: Truth Sync: blocked Reason: -- routing repair is not allowed +- Changed code maps only to the provisional bootstrap route. Files requiring manual review: -- docs/truthmark/routes/areas.md +- src/auth/** +- docs/truthmark/routes/areas/repository.md Next action: -- update routing metadata and rerun Truth Sync +- Run Truth Structure for src/auth/** before updating behavior truth. ``` diff --git a/.opencode/agents/truth-claim-verifier.md b/.opencode/agents/truth-claim-verifier.md index d4c97cb..48c66c1 100644 --- a/.opencode/agents/truth-claim-verifier.md +++ b/.opencode/agents/truth-claim-verifier.md @@ -28,6 +28,6 @@ For every checked claim, classify the result as supported | narrowed | removed | Do not edit files, stage changes, or invent missing behavior. Return JSON only with keys: scope, filesReviewed, claimsChecked, evidence, unsupportedClaims, confidence, recommendedWorkflow, notes. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. diff --git a/.opencode/agents/truth-doc-reviewer.md b/.opencode/agents/truth-doc-reviewer.md index 50d3b16..6818431 100644 --- a/.opencode/agents/truth-doc-reviewer.md +++ b/.opencode/agents/truth-doc-reviewer.md @@ -27,6 +27,6 @@ Do not edit files, stage changes, or rewrite docs. Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes. recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. diff --git a/.opencode/agents/truth-route-auditor.md b/.opencode/agents/truth-route-auditor.md index 2c50d84..4047877 100644 --- a/.opencode/agents/truth-route-auditor.md +++ b/.opencode/agents/truth-route-auditor.md @@ -35,6 +35,6 @@ Do not edit files, stage changes, or propose broad rewrites. Return JSON only with keys: scope, filesReviewed, findings, evidence, confidence, recommendedWorkflow, notes. recommendedWorkflow must be one of: none, truthmark-document, truthmark-structure. Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes. diff --git a/.opencode/skills/truthmark-sync/support/report-template.md b/.opencode/skills/truthmark-sync/support/report-template.md index 57c92fc..d682cc5 100644 --- a/.opencode/skills/truthmark-sync/support/report-template.md +++ b/.opencode/skills/truthmark-sync/support/report-template.md @@ -11,26 +11,26 @@ Changed code reviewed: Sync Intent: - Changed code reviewed: src/auth/session.ts -- Affected route/truth owner: docs/truthmark/routes/areas.md -- Target truth docs: docs/truthmark/engineering/repository/bootstrap-routing.md +- Affected route/truth owner: docs/truthmark/routes/areas/authentication.md +- Target truth docs: docs/truthmark/engineering/behaviors/session-timeout.md - Intended update: Update session timeout behavior. -- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Evidence to verify: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 - User-provided decisions/rationale: User rationale: session timeout behavior changed for internal implementation consistency - No-update-needed rationale: not applicable; mapped truth is stale - Blockers: none Ownership reviewed: -- docs/truthmark/routes/areas.md +- docs/truthmark/routes/areas/authentication.md Truth docs updated: -- docs/truthmark/engineering/repository/bootstrap-routing.md +- docs/truthmark/engineering/behaviors/session-timeout.md Decision/rationale captured: -- Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale. +- Placed user rationale in the bounded authentication behavior truth doc under Engineering Decisions/Rationale. Evidence checked: -- Claim: Session timeout behavior is documented in the mapped repository truth doc. - Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas.md:11 +- Claim: Session timeout behavior is documented in the bounded authentication behavior truth doc. + Evidence: src/auth/session.ts:12 / docs/truthmark/routes/areas/authentication.md:11 Result: supported Notes: @@ -41,11 +41,12 @@ Blocked report example: Truth Sync: blocked Reason: -- routing repair is not allowed +- Changed code maps only to the provisional bootstrap route. Files requiring manual review: -- docs/truthmark/routes/areas.md +- src/auth/** +- docs/truthmark/routes/areas/repository.md Next action: -- update routing metadata and rerun Truth Sync +- Run Truth Structure for src/auth/** before updating behavior truth. ``` diff --git a/changes/2026-06-21-version-2-2-5.md b/changes/2026-06-21-version-2-2-5.md new file mode 100644 index 0000000..cbeb15f --- /dev/null +++ b/changes/2026-06-21-version-2-2-5.md @@ -0,0 +1,21 @@ +# Version 2.2.5 + +Previous version: 2.2.4 +New version: 2.2.5 +Diff basis: release/2.2.4..HEAD plus working tree +Version action: patch +SemVer rationale: This release is a backward-compatible patch that corrects generated workflow surfaces, validation/report examples, and generated-surface diagnostics without changing public CLI command shape. + +Release payload: +- Move generated Cursor workflow support from large `.cursor/rules` files to native Cursor Agent Skill packages under `.cursor/skills/truthmark-*` with colocated support resources. +- Keep retired Gemini surfaces as manual-cleanup diagnostics while allowing `truthmark init` to auto-remove non-Gemini retired generated surfaces. +- Prevent Truth Sync reports and examples from treating provisional `bootstrap-routing.md` as a completed behavior-update target. +- Narrow Sync `candidateStaleTruthDocs` to signal-backed candidates instead of every indexed truth doc outside the impact set. + +User-facing release text: +- Cursor installs now receive Truthmark workflows as Agent Skills under `.cursor/skills/truthmark-*`, while generated-surface checks and Sync validation avoid stale or over-broad workflow guidance. + +Verification: +- `npx vitest run tests/agents/instructions.test.ts tests/agents/prompts.test.ts tests/agents/truth-check.test.ts tests/agents/truth-document.test.ts tests/agents/truth-sync.test.ts tests/templates/generated-surfaces.test.ts` passed. +- `npx tsx src/cli/main.ts check --json` passed with no diagnostics after regenerating surfaces. +- `npm run release:check` passed: lint, format, typecheck, 337 tests, build, package check, and audit. diff --git a/docs/truthmark/engineering/README.md b/docs/truthmark/engineering/README.md index 528c4e9..d4f479f 100644 --- a/docs/truthmark/engineering/README.md +++ b/docs/truthmark/engineering/README.md @@ -8,7 +8,8 @@ last_reviewed: 2026-06-14 This directory is an index for current truth docs organized by the configured Truthmark hierarchy. -Engineering truth owns current realization, contracts, architecture, workflows, operations, and tests. Engineering lane docs describe how the repository currently implements and operates the behavior. +- Engineering truth owns current realization, contracts, architecture, workflows, operations, and tests. +- Engineering lane docs describe how the repository currently implements and operates the behavior. README.md files are indexes, not Truth Sync targets. Keep engineering truth in bounded behavior, contract, architecture, workflow, operations, and test docs. diff --git a/docs/truthmark/engineering/architecture/overview.md b/docs/truthmark/engineering/architecture/overview.md index bcd2e3e..403f4ad 100644 --- a/docs/truthmark/engineering/architecture/overview.md +++ b/docs/truthmark/engineering/architecture/overview.md @@ -22,7 +22,8 @@ It turns checkout evidence, route metadata, and source renderers into committed ## Current Implementation Behavior -Truthmark is a local CLI and generated-surface renderer. It reads checkout files, normalizes configuration, parses route files, emits diagnostics, and writes configured workflow surfaces during init. +- Truthmark is a local CLI and generated-surface renderer. +- It reads checkout files, normalizes configuration, parses route files, emits diagnostics, and writes configured workflow surfaces during init. ## Boundaries diff --git a/docs/truthmark/engineering/behaviors/check-diagnostics.md b/docs/truthmark/engineering/behaviors/check-diagnostics.md index 597c9c2..c276f73 100644 --- a/docs/truthmark/engineering/behaviors/check-diagnostics.md +++ b/docs/truthmark/engineering/behaviors/check-diagnostics.md @@ -16,11 +16,27 @@ It covers route coverage, lane shape, lane drift, traceability, frontmatter, gen ## Current Implementation Behavior -`truthmark check` combines config, area routing, frontmatter, link, lane-shape, lane-drift, traceability, generated-surface, source-traceability, and freshness diagnostics. Missing product links for engineering behavior, workflow, and contract docs are review diagnostics only when the same routed area includes product truth evidence. Cross-lane route metadata is route-local: product `realized_by` links and engineering `realizes` links must target existing opposite-lane truth docs, but they do not have to be reciprocated by the target entry. Repeated route entries for the same truth document, kind, and lane merge their `realized_by`, `realizes`, and `depends_on` metadata before traceability validation; conflicting duplicate kinds or lanes are area-index errors. +- `truthmark check` combines config, area routing, frontmatter, link, lane-shape, lane-drift, traceability, generated-surface, source-traceability, and freshness diagnostics. +- Missing product links for engineering behavior, workflow, and contract docs are review diagnostics only when the same routed area includes product truth evidence. +- Cross-lane route metadata is route-local. + - Product `realized_by` links and engineering `realizes` links must target existing opposite-lane truth docs. + - Relationship links do not have to be reciprocated by the target entry. +- Repeated route entries for the same truth document, kind, and lane merge their `realized_by`, `realizes`, and `depends_on` metadata before traceability validation. +- Conflicting duplicate kinds or lanes are area-index errors. -Frontmatter diagnostics reject relationship metadata fields `realized_by`, `realizes`, and `depends_on` when they appear in truth document frontmatter. Relationship authority stays in fenced route YAML entries. +- Frontmatter diagnostics reject relationship metadata fields `realized_by`, `realizes`, and `depends_on` when they appear in truth document frontmatter. +- Relationship authority stays in fenced route YAML entries. -Product truth doc structure validation enforces the `product-capability` shape. Product capability docs require capability sections for the capability promise, users and value, capability scope including boundary constraints and adjacent systems, current product behavior, acceptance criteria, product decisions, engineering realization links, and non-goals. +- Product truth doc structure validation enforces the `product-capability` shape. +- Product capability docs require capability sections for: + - capability promise + - users and value + - capability scope, including boundary constraints and adjacent systems + - current product behavior + - acceptance criteria + - product decisions + - engineering realization links + - non-goals ## Core Rules @@ -50,10 +66,14 @@ Product truth doc structure validation enforces the `product-capability` shape. ## Engineering Decisions -- Decision (2026-06-14): Wrong-lane content is a lane-drift diagnostic; missing product links for engineering behavior, workflow, and contract docs are review diagnostics only when routed area evidence indicates product truth context. -- Decision (2026-06-14): Downstream injected/default product truth supports `product-capability` only; boundary material belongs inside capability scope, acceptance criteria, and non-goals. -- Decision (2026-06-15): Duplicate route entries with the same path, kind, and lane are an additive relationship model; divergent relationship arrays merge instead of erroring so area-local route entries do not have to repeat the full relationship closure. -- Decision (2026-06-15): `realized_by` and `realizes` route metadata is route-local navigation metadata, not a canonical global graph, so check validates target existence and lane compatibility without requiring reciprocal edges. +- Decision (2026-06-14): Wrong-lane content is a lane-drift diagnostic. + - Missing product links for engineering behavior, workflow, and contract docs are review diagnostics only when routed area evidence indicates product truth context. +- Decision (2026-06-14): Downstream injected/default product truth supports `product-capability` only. + - Boundary material belongs inside capability scope, acceptance criteria, and non-goals. +- Decision (2026-06-15): Duplicate route entries with the same path, kind, and lane are an additive relationship model. + - Divergent relationship arrays merge instead of erroring so area-local route entries do not have to repeat the full relationship closure. +- Decision (2026-06-15): `realized_by` and `realizes` route metadata is route-local navigation metadata, not a canonical global graph. + - Check validates target existence and lane compatibility without requiring reciprocal edges. ## Rationale diff --git a/docs/truthmark/engineering/behaviors/init-and-scaffold.md b/docs/truthmark/engineering/behaviors/init-and-scaffold.md index 9b3f964..5fdc9f6 100644 --- a/docs/truthmark/engineering/behaviors/init-and-scaffold.md +++ b/docs/truthmark/engineering/behaviors/init-and-scaffold.md @@ -1,7 +1,7 @@ --- status: active truth_kind: engineering-behavior -last_reviewed: 2026-06-20 +last_reviewed: 2026-06-21 --- # Init And Scaffold @@ -44,7 +44,20 @@ Generated truth-doc frontmatter includes `truth_kind`. Generated truth-doc frontmatter does not include `doc_type` or `truth_lane`. -`truthmark init` also removes retired generated-surface artifacts (for example `truthmark-preview` package files, retired Preview prompt/command adapters, and legacy `helper-manifest.yml`/`support/helper-policy.md`) when those paths are no longer part of current generated output. +`truthmark init` removes auto-removable retired generated-surface artifacts when those paths are no longer part of current generated output. + +Auto-removable retired artifacts include: + +- `truthmark-preview` package files +- retired non-Gemini Preview adapters +- legacy `helper-manifest.yml` and `support/helper-policy.md` files + +Init leaves retired Gemini surfaces in place for manual cleanup: + +- `GEMINI.md` +- `.gemini/**` + +Those files may contain user-owned instructions alongside old Truthmark injections. Generated truth-doc templates keep kind-specific and section-specific authoring comments in the template files. @@ -86,7 +99,8 @@ Capability docs own: - `truthmark init` creates or refreshes workspace scaffold files. - It renders current templates and generated host surfaces from source renderers. -- It removes retired generated-surface artifacts that are no longer part of current generated output. +- It removes retired non-Gemini generated-surface artifacts that are no longer part of current generated output. +- It leaves retired Gemini surfaces for manual cleanup. ## Contracts @@ -102,8 +116,11 @@ Capability docs own: - Decision (2026-06-14): New scaffold targets do not create `docs/truthmark/truth` as the canonical target root. - Decision (2026-06-14): Editable template filenames match `truth_kind` values directly so generated docs do not point agents at legacy `*-doc.md` names. - Decision (2026-06-14): Init scaffolds routes, templates, product truth, and engineering truth at fixed workspace-derived paths rather than accepting route or template roots from config. -- Decision (2026-06-17): The default broad `repository` route is provisional bootstrap state; init creates a compact `bootstrap-routing.md` workflow handoff instead of a catch-all behavior overview so agents run Truth Structure before normal Sync on real touched code. -- Decision (2026-06-18): Fresh configs omit `platforms` by default. Truthmark does not infer Codex, OpenCode, or any other host from a fresh checkout; host-native workflow surfaces require explicit platform configuration. +- Decision (2026-06-17): The default broad `repository` route is provisional bootstrap state. + - Init creates a compact `bootstrap-routing.md` workflow handoff instead of a catch-all behavior overview so agents run Truth Structure before normal Sync on real touched code. +- Decision (2026-06-18): Fresh configs omit `platforms` by default. + - Truthmark does not infer Codex, OpenCode, or any other host from a fresh checkout; host-native workflow surfaces require explicit platform configuration. +- Decision (2026-06-21): Init does not delete retired Gemini surfaces automatically; users remove stale injected Gemini guidance manually after reviewing `GEMINI.md` and `.gemini/**`. ## Rationale @@ -116,6 +133,7 @@ Keeping templates kind-specific and moving global prose style into workflow guid - Init does not infer a preferred agent host. - Init does not create behavior truth for unknown code ownership beyond the provisional bootstrap routing handoff. - Init does not maintain a legacy `docs/truthmark/truth` tree. +- Init does not delete retired Gemini instruction files automatically. ## Maintenance Notes diff --git a/docs/truthmark/engineering/contracts/generated-host-surfaces.md b/docs/truthmark/engineering/contracts/generated-host-surfaces.md index 45bcafc..f5a853f 100644 --- a/docs/truthmark/engineering/contracts/generated-host-surfaces.md +++ b/docs/truthmark/engineering/contracts/generated-host-surfaces.md @@ -1,7 +1,7 @@ --- status: active truth_kind: engineering-contract -last_reviewed: 2026-06-20 +last_reviewed: 2026-06-21 --- # Generated Host Surfaces @@ -18,25 +18,37 @@ It covers configured platform output paths, generated workflow files, managed in Truthmark renders workflow surfaces only for configured platforms. Legacy package artifacts and retired Preview adapters are explicitly retired. -- `truthmark init` removes obsolete generated files that are no longer in `renderGeneratedSurfaces(...)`, including `truthmark-preview` package contents, retired Preview prompt/command adapters, and legacy `helper-manifest.yml` and `support/helper-policy.md` files under host skill roots. +- `truthmark init` removes obsolete generated files that are no longer in `renderGeneratedSurfaces(...)`. + - Removed obsolete files include `truthmark-preview` package contents. + - Removed obsolete files include retired non-Gemini Preview adapters. + - Removed obsolete files include legacy `helper-manifest.yml` and `support/helper-policy.md` files under host skill roots. - `truthmark check` reports missing, stale, or obsolete generated surfaces when render outputs and committed files differ. + - Stale Gemini surfaces are reported for manual cleanup rather than deleted by init. -When `platforms` is omitted, fresh config does not assume a host platform; `truthmark init` still maintains instruction targets, but host-specific skill/prompt/command surfaces are opt-in through explicit `platforms` entries. -Host skill packages carry canonical workflow entrypoints plus support files for full procedures, report templates, and subagent/lease guidance when the workflow uses subagents; generated helper manifest and helper policy files are intentionally not emitted. -GitHub Copilot prompt files are lightweight workflow adapters for supported generated workflows: they point to the current host entrypoint and tell the agent not to invoke another Truthmark command from inside that entrypoint. -Antigravity and Cursor rule files are flat rule surfaces that inline the workflow procedure and report template, omit the duplicate quick-procedure block, and do not reference package-local `support/` files that those hosts do not consume. -Truth Preview is not generated as a skill package, prompt file, or command file for any host. +- When `platforms` is omitted, fresh config does not assume a host platform. +- `truthmark init` still maintains instruction targets, but host-specific skill/prompt/command surfaces are opt-in through explicit `platforms` entries. +- Host skill packages carry canonical workflow entrypoints plus support files for full procedures, report templates, and subagent/lease guidance when the workflow uses subagents. +- Generated helper manifest and helper policy files are intentionally not emitted. +- GitHub Copilot prompt files are lightweight workflow adapters for supported generated workflows. + - They point to the current host entrypoint. + - They tell the agent not to invoke another Truthmark command from inside that entrypoint. +- Cursor Agent Skills are generated as native project skill packages under `.cursor/skills/truthmark-*` with package-local support files. +- Cursor Rules remain supported by Cursor as a platform concept. +- Truthmark does not use `.cursor/rules` for its workflow surface because the Agent Skills directory is the better current native workflow representation. +- Truth Preview is not generated as a skill package, prompt file, or command file for any host. ## Contract Surface -- Codex, OpenCode, Claude Code, GitHub Copilot, Antigravity, and Cursor skills/prompts/rules/agents +- Codex, OpenCode, Claude Code, GitHub Copilot, Cursor, and Antigravity skills/prompts/rules/agents - `AGENTS.md`, `CLAUDE.md`, and `.github/copilot-instructions.md` managed blocks ## Platform Implementation References -- Antigravity support renders workflow rule files under `.antigravity/rules/truthmark-*.md`; implementation reference: Antigravity documentation entrypoint at . -- Cursor support renders project rules under `.cursor/rules/truthmark-*.mdc` with Cursor frontmatter; implementation reference: Cursor Rules documentation at . -- Gemini CLI support is retired. `GEMINI.md` and `.gemini/**` are treated as obsolete generated surfaces for cleanup and check diagnostics, not active host implementations. +- Antigravity support renders workflow rule files under `.antigravity/rules/truthmark-*.md`. + - Implementation reference: Antigravity documentation entrypoint at . +- Cursor support renders Agent Skill project packages under `.cursor/skills/truthmark-*` with package-local `SKILL.md` and `support/` resources. + - Implementation reference: Cursor Agent Skills documentation at . +- Gemini CLI support is retired. `GEMINI.md` and `.gemini/**` are obsolete generated surfaces for check diagnostics and manual cleanup, not active host implementations. ## Inputs @@ -46,7 +58,7 @@ Truth Preview is not generated as a skill package, prompt file, or command file ## Outputs -- Host-native workflow skill packages, compact prompt adapters, and flat Antigravity/Cursor rule surfaces +- Host-native workflow skill packages, compact prompt adapters, and flat Antigravity rule surfaces - No generated Truth Preview skill package, prompt, or command - Procedure, report-template, and subagent/lease support files only when a workflow needs them - Managed instruction blocks with non-versioned refresh guidance @@ -54,7 +66,7 @@ Truth Preview is not generated as a skill package, prompt file, or command file ## Errors And Diagnostics - `truthmark check` reports missing, stale, or obsolete generated surfaces. -- `truthmark init` removes retired managed artifacts when they are no longer rendered. +- `truthmark init` removes retired non-Gemini managed artifacts when they are no longer rendered; retired Gemini files are left for manual cleanup. - Generated-surface freshness uses rendered-content comparison rather than package-version markers. ## Compatibility Rules @@ -65,7 +77,8 @@ Truth Preview is not generated as a skill package, prompt file, or command file ## Versioning And Migration -- Retired generated files are removed during init instead of remaining as stale runtime guidance. +- Retired non-Gemini generated files are removed during init instead of remaining as stale runtime guidance. +- Retired Gemini files are diagnosed but not deleted automatically because repositories may have user-owned Gemini instructions beside old Truthmark injections. - Generated surfaces use non-versioned refresh wording; package versions are not runtime authority. ## Product Truth Links @@ -75,16 +88,31 @@ Truth Preview is not generated as a skill package, prompt file, or command file ## Engineering Decisions - Decision (2026-06-14): Generated surfaces must preserve Truthmark as a workflow injector, not a runtime authority. -- Decision (2026-06-15): GitHub Copilot prompt files stay compact workflow adapters; Antigravity and Cursor rules are flat rendered rule bodies that carry procedure/report content directly. -- Decision (2026-06-20): Runtime surfaces must not carry redundant host-switch or support-file overhead. Cross-host invocation lists belong in human-facing docs or platform-reference contracts, native `SKILL.md` quick procedures do not repeat support-file read instructions already listed under Progressive disclosure, and flat Antigravity/Cursor rules do not reference nonexistent `support/` files. +- Decision (2026-06-15): GitHub Copilot prompt files stay compact workflow adapters; Antigravity rules are flat rendered rule bodies that carry procedure/report content directly. +- Decision (2026-06-21): Cursor support uses Agent Skill project packages under `.cursor/skills/truthmark-*`, not large dynamic `.cursor/rules` files. + - Cursor's current Agent Skills surface supplies description-based selection plus package-local support resources, so it is the single native Cursor workflow representation Truthmark uses. +- Decision (2026-06-20): Runtime surfaces must not carry redundant host-switch or support-file overhead. + - Cross-host invocation lists belong in human-facing docs or platform-reference contracts. + - Native `SKILL.md` quick procedures do not repeat support-file read instructions already listed under Progressive disclosure. + - Flat Antigravity rules do not reference nonexistent `support/` files. - Decision (2026-06-18): Fresh configs do not assume Codex, OpenCode, or any other host platform. Host-specific surfaces are opt-in through explicit `platforms` entries. -- Decision (2026-06-18): Generated helper manifest and helper policy files are removed; optional validation commands remain in workflow metadata and report validation accepts manual fallback evidence. -- Decision (2026-06-20): Truth Preview generated host surfaces are retired. Truthmark no longer emits Preview skill packages, Copilot prompts, Antigravity rules, or Cursor rules; preview-like route/workflow selection remains internal advisory behavior rather than an installed workflow surface. -- Decision (2026-06-18): Truth Sync keeps bounded topology repair in the finish-time path; Sync runs or applies Truth Structure-style repair when safe and scoped, and hands off only unsafe or ambiguous topology work. +- Decision (2026-06-18): Generated helper manifest and helper policy files are removed. + - Optional validation commands remain in workflow metadata. + - Report validation accepts manual fallback evidence. +- Decision (2026-06-20): Truth Preview generated host surfaces are retired. + - Truthmark no longer emits Preview skill packages, Copilot prompts, Antigravity rules, or Cursor rules. + - Preview-like route/workflow selection remains internal advisory behavior rather than an installed workflow surface. +- Decision (2026-06-18): Truth Sync keeps bounded topology repair in the finish-time path. + - Sync runs or applies Truth Structure-style repair when safe and scoped. + - Sync hands off only unsafe or ambiguous topology work. +- Decision (2026-06-21): Init does not delete retired Gemini surfaces automatically. + - Check diagnostics identify obsolete `GEMINI.md` and `.gemini/**` files so users can remove stale injected Gemini guidance themselves. ## Rationale -Host-native skill packages preserve progressive disclosure for agents that package skill directories. Compact prompt adapters avoid duplicating full workflow bodies, while flat Antigravity/Cursor rules inline only the procedure/report body those rule hosts can load directly. +- Host-native skill packages preserve progressive disclosure for agents that package skill directories. +- Compact prompt adapters avoid duplicating full workflow bodies, while flat Antigravity rules inline only the procedure/report body that rule host can load directly. +- Cursor now uses Agent Skill packages because that current native Cursor surface supports description-based selection and package-local resources. ## Non-Goals diff --git a/docs/truthmark/engineering/repository/bootstrap-routing.md b/docs/truthmark/engineering/repository/bootstrap-routing.md index 47f201e..2d12bb7 100644 --- a/docs/truthmark/engineering/repository/bootstrap-routing.md +++ b/docs/truthmark/engineering/repository/bootstrap-routing.md @@ -19,7 +19,8 @@ It does not own implementation behavior under that code surface. ## Current Implementation Behavior -The scaffold creates this provisional bootstrap handoff only when a default broad route needs a canonical owner. Agents use it as a signal to run Truth Structure and create bounded routes before normal Truth Sync, not as a place to accumulate implementation claims. +- The scaffold creates this provisional bootstrap handoff only when a default broad route needs a canonical owner. +- Agents use it as a signal to run Truth Structure and create bounded routes before normal Truth Sync, not as a place to accumulate implementation claims. ## Product Truth Links @@ -39,7 +40,8 @@ The scaffold creates this provisional bootstrap handoff only when a default broa ## Execution Model -Run Truth Structure before normal Truth Sync when real code changes touch only this broad route. Truth Structure should create or repair bounded areas first; Truth Sync should then update the bounded owner docs. +- Run Truth Structure before normal Truth Sync when real code changes touch only this broad route. +- Truth Structure should create or repair bounded areas first; Truth Sync should then update the bounded owner docs. ## Steps @@ -64,7 +66,8 @@ If ownership cannot be inferred safely, stop and report manual-review files inst ## Rationale -Scoped ownership keeps agent context close to affected files and prevents broad default docs from absorbing unrelated behavior. This preserves agent-native truth maintenance without adding a token-heavy discovery layer. +- Scoped ownership keeps agent context close to affected files and prevents broad default docs from absorbing unrelated behavior. +- This preserves agent-native truth maintenance without adding a token-heavy discovery layer. ## Non-Goals diff --git a/docs/truthmark/engineering/repository/repository-intelligence.md b/docs/truthmark/engineering/repository/repository-intelligence.md index f5b658e..fbe530f 100644 --- a/docs/truthmark/engineering/repository/repository-intelligence.md +++ b/docs/truthmark/engineering/repository/repository-intelligence.md @@ -1,7 +1,7 @@ --- status: active truth_kind: engineering-behavior -last_reviewed: 2026-06-20 +last_reviewed: 2026-06-21 --- # Repository Intelligence @@ -16,17 +16,52 @@ It covers RepoIndex, RouteMap, ImpactSet, evidence validation, freshness, and Wo ## Current Implementation Behavior -RepoIndex and RouteMap are derived from the active checkout. They preserve repository metadata, discovered files, truth docs, test files, route lane metadata, and route-local relationship metadata. RouteMap emits duplicate truth document entries with the same path, kind, and lane as one relationship view whose `realized_by`, `realizes`, and `depends_on` metadata is merged by unique sorted set. RepoIndex derives truth-doc lane and doc type from `truth_kind` when canonical truth docs omit explicit `truth_lane` and `doc_type` frontmatter. +- RepoIndex and RouteMap are derived from the active checkout. +- They preserve repository metadata, discovered files, truth docs, test files, route lane metadata, and route-local relationship metadata. +- RouteMap emits duplicate truth document entries with the same path, kind, and lane as one relationship view whose `realized_by`, `realizes`, and `depends_on` metadata is merged by unique sorted set. +- RepoIndex derives truth-doc lane and doc type from `truth_kind` when canonical truth docs omit explicit `truth_lane` and `doc_type` frontmatter. -Repository intelligence is language-neutral workflow context, not a language-semantic code index. Truthmark does not maintain import graphs, export lists, public-symbol tables, or language-specific symbol validation. Agents inspect source code directly; these artifacts guide routing, context selection, verification planning, and write boundaries without overriding source files, route files, truth docs, or workflow write boundaries. +- Repository intelligence is language-neutral workflow context, not a language-semantic code index. +- Truthmark does not maintain import graphs, export lists, public-symbol tables, or language-specific symbol validation. +- Agents inspect source code directly. +- These artifacts guide routing, context selection, verification planning, and write boundaries without overriding source files, route files, truth docs, or workflow write boundaries. -ImpactSet remains the branch-diff routing handoff for changed files, affected routes, affected truth docs, affected tests, and diagnostics. It derives affected routes from route code surfaces and truth-doc ownership, derives affected tests from changed test paths and path/name hints, and reports diagnostics for unmapped functional-code changes. It does not report TypeScript public-symbol changes or use TypeScript/JavaScript import parsing to infer affected tests. +- ImpactSet remains the branch-diff routing handoff for changed files, affected routes, affected truth docs, affected tests, and diagnostics. +- It derives affected routes from route code surfaces and truth-doc ownership, derives affected tests from changed test paths and path/name hints, and reports diagnostics for unmapped functional-code changes. +- It does not report TypeScript public-symbol changes or use TypeScript/JavaScript import parsing to infer affected tests. -WorkflowState is the workflow-scoped advisory handoff for helper readiness, a workflow card, write-boundary suggestions, target truth docs, optional helper commands, review checklist, compact affected-test guidance, diagnostics, next steps, and 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. 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. Sync action context separates `primaryTruthDocs`, `candidateStaleTruthDocs`, and `routeFiles`: agents start with impacted route owners, while indexed canonical truth docs outside the impact set remain candidate stale-truth repair targets that require checkout evidence and a recorded reason before being touched. The standalone ContextPack handoff is retired; agents use workflow status plus impact as optional guidance and continue with direct checkout inspection when helpers are skipped or unavailable. These outputs do not emit source-file or truth-doc body contents. +- WorkflowState is the workflow-scoped advisory handoff for: + - helper readiness + - a workflow card + - write-boundary suggestions + - target truth docs + - optional helper commands + - review checklist + - compact affected-test guidance + - diagnostics + - 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. +- 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. +- Sync action context separates `primaryTruthDocs`, `candidateStaleTruthDocs`, and `routeFiles`. +- Agents start with impacted route owners. +- Stale candidates are included only when a concrete signal exists. +- Stale-candidate signals include freshness diagnostics naming a truth doc. +- Stale-candidate signals include route relationships through `realized_by`, `realizes`, or `depends_on`. +- Stale-candidate signals include truth docs whose `source_of_truth` references changed files. +- Stale-candidate signals include changed route metadata and changed linked counterpart docs. +- When no signal exists, `candidateStaleTruthDocs` is empty; agents may still inspect another document when direct checkout evidence reveals a stale claim. +- The standalone ContextPack handoff is retired. +- Agents use workflow status plus impact as optional guidance and continue with direct checkout inspection when helpers are skipped or unavailable. +- These outputs do not emit source-file or truth-doc body contents. -Evidence validation checks repository containment, referenced file or glob existence, line spans, and `sha256:` content hashes. Evidence `symbol` metadata, when present in an evidence YAML block, is non-normative metadata and is not validated through TypeScript-specific parsing. +- Evidence validation checks repository containment, referenced file or glob existence, line spans, and `sha256:` content hashes. +- Evidence `symbol` metadata, when present in an evidence YAML block, is non-normative metadata and is not validated through TypeScript-specific parsing. -Generated-surface diagnostics are checkout-derived repository intelligence for the installed workflow runtime. `truthmark check` compares rendered generated surfaces with committed files and reports missing or stale generated host-native skill package files so skill-directory resources stay colocated with `SKILL.md`. +- Generated-surface diagnostics are checkout-derived repository intelligence for the installed workflow runtime. +- `truthmark check` compares rendered generated surfaces with committed files and reports missing or stale generated host-native skill package files so skill-directory resources stay colocated with `SKILL.md`. ## Core Rules @@ -54,11 +89,19 @@ Generated-surface diagnostics are checkout-derived repository intelligence for t - Decision (2026-06-14): Repository intelligence is derived context, not hidden memory or off-repo authority. - Decision (2026-06-15): Repository intelligence is a language-neutral workflow helper, not a semantic code index; TypeScript-specific import/export/public-symbol analysis is not part of the public contract. -- Decision (2026-06-15): The standalone ContextPack handoff is retired; agents use `truthmark workflow status --workflow [--base ] --json` for optional workflow-scoped guidance and `truthmark impact --base --json` for branch-diff routing. -- Decision (2026-06-16): `workflow status` is status/debug/handoff only; Truthmark does not expose a `workflow instructions` command and generated workflows must remain usable from committed repository files without live CLI preflight. -- Decision (2026-06-17): WorkflowState presents optional helper output as an advisory workflow card with affected files, likely route owners, suggested truth docs, open questions, skipped helper status, `reviewChecklist`, and `evidencePrompts`; it does not expose retired enforcement-shaped names such as `checks.required`, the old gate alias, or `requiredEvidence`. +- Decision (2026-06-15): The standalone ContextPack handoff is retired. + - Agents use `truthmark workflow status --workflow [--base ] --json` for optional workflow-scoped guidance and `truthmark impact --base --json` for branch-diff routing. +- Decision (2026-06-16): `workflow status` is status/debug/handoff only. + - Truthmark does not expose a `workflow instructions` command and generated workflows must remain usable from committed repository files without live CLI preflight. +- Decision (2026-06-17): WorkflowState presents optional helper output as an advisory workflow card. + - The advisory card includes affected files, likely route owners, suggested truth docs, open questions, skipped helper status, `reviewChecklist`, and `evidencePrompts`. + - It does not expose retired enforcement-shaped names such as `checks.required`, the old gate alias, or `requiredEvidence`. - Decision (2026-06-16): Sync Intent is a transient report-section checklist exposed through workflow/report surfaces and WorkflowState report sections; it is not repository-intelligence state or a persisted plan. -- Decision (2026-06-17): Generated-surface freshness includes host-native package diagnostics; these diagnostics are review output and do not add hooks, live services, duplicate workflow packages, or mandatory workflow preflight execution. +- Decision (2026-06-17): Generated-surface freshness includes host-native package diagnostics. + - These diagnostics are review output and do not add hooks, live services, duplicate workflow packages, or mandatory workflow preflight execution. +- 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. ## Rationale diff --git a/docs/truthmark/engineering/workflows/installed-workflow-runtime.md b/docs/truthmark/engineering/workflows/installed-workflow-runtime.md index dcde38c..00a34cb 100644 --- a/docs/truthmark/engineering/workflows/installed-workflow-runtime.md +++ b/docs/truthmark/engineering/workflows/installed-workflow-runtime.md @@ -1,7 +1,7 @@ --- status: active truth_kind: engineering-workflow -last_reviewed: 2026-06-20 +last_reviewed: 2026-06-21 --- # Installed Workflow Runtime @@ -50,12 +50,18 @@ GitHub Copilot prompts and top-level managed instruction blocks stay thin: - They point to host-native workflow entrypoints when a host skill package exists. - They do not embed full workflow bodies or cross-host invocation lists. -Antigravity and Cursor rule files are flat host rule surfaces: +Antigravity rule files remain flat host rule surfaces: -- They inline the workflow procedure and report template because those hosts do not consume the package-local `support/` directory model. +- They inline the workflow procedure and report template because that host does not consume the package-local `support/` directory model. - They omit the duplicate quick-procedure block and do not reference nonexistent `support/` files. - They keep only host-local invocation framing and do not embed cross-host invocation lists. +Cursor Agent Skills are generated as project skill packages under `.cursor/skills/truthmark-*`: + +- They use Cursor's current Agent Skills model rather than `.cursor/rules` dynamic rule files. +- `SKILL.md` carries the description that lets Cursor select the workflow automatically when relevant and supports manual `/` invocation. +- Package-local `support/procedure.md`, `support/report-template.md`, and any lease guidance stay colocated with the Cursor skill. + Generated-surface checks report missing or stale configured host-native skill package files. Workflow manifest entries use review-oriented questions that surface as a WorkflowState `reviewChecklist`. @@ -131,6 +137,12 @@ Truth Sync generated procedures and report templates include a transient Sync In - no-update-needed rationale - blockers +Truth Sync successful report examples target bounded behavior ownership rather than the provisional bootstrap handoff: + +- The successful session-timeout example uses a bounded authentication route and `engineering/behaviors/session-timeout.md`. +- The provisional `bootstrap-routing.md` document is represented only as a blocked topology case that tells agents to run Truth Structure before updating behavior truth. +- `truthmark validate sync-report` rejects completed reports that list `bootstrap-routing.md` as an updated or target truth doc. + Optional CLI repository-intelligence helpers are compact advisory cards: - `workflow status` reports affected files, likely route owners, suggested truth docs, open questions, skipped helper status, and compact write-boundary suggestions. @@ -185,17 +197,30 @@ Committed workflow files are the runtime contract. The CLI installs and validate ## Engineering Decisions - Decision (2026-06-14): Product and engineering truth remain separate generated-workflow lanes for truth creation, structure, audit, and cross-lane ownership checks. -- Decision (2026-06-17): Routine code-first Truth Sync uses a product-truth decision instead of a full lane-classification gate; product truth is opt-in for externally visible promises, product boundaries, APIs, acceptance criteria, or explicit user/product evidence. +- Decision (2026-06-17): Routine code-first Truth Sync uses a product-truth decision instead of a full lane-classification gate. + - Product truth is opt-in for externally visible promises, product boundaries, APIs, acceptance criteria, or explicit user/product evidence. - Decision (2026-06-15): Optional workflow handoff helpers use `workflow status --json` and `impact --json`; generated surfaces must not direct agents to a standalone ContextPack command. -- Decision (2026-06-16): `truthmark workflow instructions` is intentionally absent; committed host-native workflow files and direct checkout inspection are the runtime contract, while `workflow status` remains an optional compact helper. -- Decision (2026-06-17): Workflow status presents optional helper output as advisory workflow cards with review checklists, evidence prompts, open questions, and skipped-helper status; generated workflows still run from committed host-native files and direct checkout inspection when helpers are unavailable. +- Decision (2026-06-16): `truthmark workflow instructions` is intentionally absent. + - Committed host-native workflow files and direct checkout inspection are the runtime contract, while `workflow status` remains an optional compact helper. +- Decision (2026-06-17): Workflow status presents optional helper output as advisory workflow cards with review checklists, evidence prompts, open questions, and skipped-helper status. + - Generated workflows still run from committed host-native files and direct checkout inspection when helpers are unavailable. - Decision (2026-06-16): Truth Sync uses a transient Sync Intent checklist in generated procedures and report templates before truth writes; it is not a persistent plan object or lifecycle artifact. -- Decision (2026-06-18): Truth Sync treats user-provided decision rationale from the current task conversation as first-class sync input. The workflow records that context in Sync Intent, routes it to the correct product or engineering truth section when supported, and reports where it was placed, skipped because none was provided, or handed off for manual review. -- Decision (2026-06-17): Source manifest/renderers are the workflow-generation authority; configured host skill directories are native generated packages with colocated resources. Truthmark does not emit a separate `.truthmark/agent/` workflow copy when no host surface consumes it. +- Decision (2026-06-18): Truth Sync treats user-provided decision rationale from the current task conversation as first-class sync input. + - The workflow records that context in Sync Intent, routes it to the correct product or engineering truth section when supported, and reports where it was placed, skipped because none was provided, or handed off for manual review. +- Decision (2026-06-17): Source manifest/renderers are the workflow-generation authority; configured host skill directories are native generated packages with colocated resources. + - Truthmark does not emit a separate `.truthmark/agent/` workflow copy when no host surface consumes it. - Decision (2026-06-18): Fresh configs do not assume Codex, OpenCode, or any other host platform. Host-specific surfaces are generated only for explicit `platforms` entries. - Decision (2026-06-18): Generated helper manifest and helper policy files are retired. Validation helpers remain as optional workflow metadata and explicit `truthmark validate ...` commands, not package support files. -- Decision (2026-06-20): Truth Preview generated host surfaces are retired. The repository no longer emits Preview skill packages, Copilot prompts, Antigravity rules, or Cursor rules; route/workflow preview remains an internal read-only selection behavior rather than an installed workflow surface. -- Decision (2026-06-18): Truth Sync retains bounded topology repair. Missing, stale, broad, overloaded, or catch-all route ownership is repaired inside Sync when safe and scoped to the changed functional code; only unsafe, ambiguous, or out-of-scope topology repair is handed off manually to Truth Structure. +- Decision (2026-06-20): Truth Preview generated host surfaces are retired. + - The repository no longer emits Preview skill packages, Copilot prompts, Antigravity rules, or Cursor rules. + - Route/workflow preview remains an internal read-only selection behavior rather than an installed workflow surface. +- Decision (2026-06-18): Truth Sync retains bounded topology repair. + - Missing, stale, broad, overloaded, or catch-all route ownership is repaired inside Sync when safe and scoped to the changed functional code. + - Only unsafe, ambiguous, or out-of-scope topology repair is handed off manually to Truth Structure. +- Decision (2026-06-21): Truth Sync report examples and validation must not accept `bootstrap-routing.md` as a completed behavior-update target. + - Bootstrap-only mappings are blocked topology handoffs until Truth Structure assigns a bounded owner. +- Decision (2026-06-21): Cursor workflow generation uses Agent Skill project packages under `.cursor/skills/truthmark-*`, not dynamic `.cursor/rules` files. + - Agent Skills are the single current native Cursor workflow representation because they provide description-based selection plus package-local resources. ## Rationale @@ -216,6 +241,7 @@ Update this doc when workflow manifest fields, generated surface paths, optional - ../../../../src/agents/instructions.ts - ../../../../src/agents/prompts.ts - ../../../../src/agents/workflow-manifest.ts +- ../../../../src/agents/workflow-helper-validation.ts - ../../../../src/agents/truth-sync.ts - ../../../../src/sync/report.ts - ../../../../src/agents/shared.ts diff --git a/docs/truthmark/product/capabilities/agent-native-workflow-injection.md b/docs/truthmark/product/capabilities/agent-native-workflow-injection.md index 5aafd48..2ceb6ce 100644 --- a/docs/truthmark/product/capabilities/agent-native-workflow-injection.md +++ b/docs/truthmark/product/capabilities/agent-native-workflow-injection.md @@ -8,7 +8,9 @@ last_reviewed: 2026-06-20 ## Capability Promise -Truthmark gives configured AI hosts explicit, committed workflow surfaces for Structure, Document, Sync, Realize, and Check. Portal surfaces are generated only when Portal is enabled. Truth Preview generated host surfaces are retired; preview-like route/workflow selection remains internal advisory behavior rather than an installed workflow surface. +- Truthmark gives configured AI hosts explicit, committed workflow surfaces for Structure, Document, Sync, Realize, and Check. +- Portal surfaces are generated only when Portal is enabled. +- Truth Preview generated host surfaces are retired; preview-like route/workflow selection remains internal advisory behavior rather than an installed workflow surface. ## Users And Value @@ -16,35 +18,84 @@ Repository maintainers and agents can follow the checked-in workflow contract wi ## Capability Scope -This capability covers generated host-native workflow files, managed instruction blocks, bounded write rules, compact optional validation commands, workflow status/impact guidance, and direct-checkout fallback behavior. +This capability covers: + +- generated host-native workflow files +- managed instruction blocks +- bounded write rules +- compact optional validation commands +- workflow status/impact guidance +- direct-checkout fallback behavior ## Current Product Behavior -Supported surfaces include Codex, OpenCode, Claude Code, GitHub Copilot, Antigravity, and Cursor workflow files generated from the source templates and manifest when those platforms are configured. Fresh configs do not assume a host platform; host-specific surfaces are opt-in through `.truthmark/config.yml` `platforms`. Host skill directories are generated as native skill packages for Structure, Document, Sync, Realize, Check, and Portal when enabled: `SKILL.md` plus colocated procedure/report support files and subagent or lease guidance where the workflow uses them. Antigravity and Cursor rule files are flat host rule surfaces that inline the procedure and report template, omit duplicate quick-procedure summaries, and do not reference package-local support files those hosts do not consume. Generated helper manifests and helper policy files are intentionally not emitted; validation helpers remain optional commands and report validators allow manual fallback evidence. Compact prompt, command, and top-level instruction surfaces may point into host-native packages, but configured skill directories are not adapter-only pointer folders because some hosts package and progressively disclose resources from the skill directory itself. Truth Preview is not generated as a skill package, prompt file, or command file for any host. Truthmark does not add a separate `.truthmark/agent/` workflow copy unless a host surface actually consumes it; the checked-in host-native packages are the runtime workflow surfaces. Agents may use `truthmark workflow status --workflow [--base ] --json` and `truthmark impact --base --json` as optional compact helpers for advisory workflow cards, affected files, likely route owners, suggested truth docs, review checklists, evidence prompts, open questions, skipped helper status, and diagnostics; these helpers do not provide file-content packets and are not sources of truth. Truth Sync status separates impacted `primaryTruthDocs`, `candidateStaleTruthDocs`, and `routeFiles` so agents start with affected route owners while preserving evidence-backed stale repository-truth correction beyond the initially affected route set. +- Supported surfaces include Codex, OpenCode, Claude Code, GitHub Copilot, Antigravity, and Cursor workflow files generated from the source templates and manifest when those platforms are configured. +- Fresh configs do not assume a host platform; host-specific surfaces are opt-in through `.truthmark/config.yml` `platforms`. +- Host skill directories are generated as native skill packages for Structure, Document, Sync, Realize, Check, and Portal when enabled. + - They include `SKILL.md` plus colocated procedure/report support files. + - They include subagent or lease guidance where the workflow uses them. +- Antigravity rule files are flat host rule surfaces. + - They inline the procedure and report template. + - They omit duplicate quick-procedure summaries. + - They do not reference package-local support files that Antigravity does not consume. +- Cursor uses Agent Skill project packages under `.cursor/skills/truthmark-*`. +- Cursor Rules remain a platform surface, but Truthmark uses Agent Skills as its single current native Cursor workflow representation because they provide description-based selection and package-local support resources. +- Generated helper manifests and helper policy files are intentionally not emitted; validation helpers remain optional commands and report validators allow manual fallback evidence. +- Compact prompt, command, and top-level instruction surfaces may point into host-native packages. +- Configured skill directories are not adapter-only pointer folders. +- Some hosts package and progressively disclose resources from the skill directory itself. +- Truth Preview is not generated as a skill package, prompt file, or command file for any host. +- Truthmark does not add a separate `.truthmark/agent/` workflow copy unless a host surface actually consumes it. +- The checked-in host-native packages are the runtime workflow surfaces. +- Agents may use optional compact helpers for workflow guidance: + - `truthmark workflow status --workflow [--base ] --json` + - `truthmark impact --base --json` +- Optional helpers can expose advisory workflow cards, affected files, likely route owners, suggested truth docs, review checklists, evidence prompts, open questions, skipped helper status, and diagnostics. +- These helpers do not provide file-content packets and are not sources of truth. +- Truth Sync status separates impacted `primaryTruthDocs`, `candidateStaleTruthDocs`, and `routeFiles`. +- Agents start with affected route owners. +- Evidence-backed stale repository-truth correction remains available beyond the initially affected route set. ## Acceptance Criteria - Each configured platform receives host-native workflow entrypoints. - Fresh config defaults do not generate host-specific surfaces unless platforms are explicitly configured. - Each configured host skill directory receives the workflow support files needed for native skill resource packaging, without generated helper manifests or helper policy files. -- Flat Antigravity and Cursor rule surfaces inline procedure/report content without duplicate quick-procedure summaries, nonexistent support-file references, or cross-host invocation matrices. +- Flat Antigravity rule surfaces inline procedure/report content without duplicate quick-procedure summaries, nonexistent support-file references, or cross-host invocation matrices. +- Cursor Agent Skill packages under `.cursor/skills/truthmark-*` include package-local support resources and are the only generated Cursor workflow surface. - Generated surfaces preserve workflow boundaries, direct-checkout fallback, and bounded Sync-owned topology repair. - Truth Preview generated host surfaces are retired; preview-like routing selection remains internal, read-only advisory behavior rather than an installed workflow package, prompt, or command. - Routine code-first Truth Sync defaults internal implementation changes to engineering truth unless a user-visible promise, capability boundary, API contract, acceptance criterion, or explicit user/product evidence changed. -- Truth Sync carries user-provided decision rationale, constraints, tradeoffs, rejection reasons, and scope boundaries from the current task conversation into Sync Intent, routes them to the correct truth lane when supported, and reports placement, skip, or manual handoff. +- Truth Sync carries user-provided decision rationale, constraints, tradeoffs, rejection reasons, and scope boundaries from the current task conversation into Sync Intent. +- Truth Sync routes supported context to the correct truth lane. +- Truth Sync reports placement, skip, or manual handoff. - Workflows that create, structure, or audit truth docs still preserve product and engineering truth as separate lanes. ## Product Decisions - Decision (2026-06-14): Workflow surfaces remain committed repository files; optional CLI helpers validate after relevant work and do not orchestrate workflow execution. - Decision (2026-06-15): Agent-facing repository-intelligence handoff uses workflow status plus impact instead of a standalone ContextPack command. -- Decision (2026-06-17): Optional workflow status presents helper output as advisory workflow cards with review checklists, evidence prompts, open questions, and skipped-helper status; direct checkout inspection remains the fallback when helpers are skipped, unavailable, or unnecessary. -- Decision (2026-06-17): Host skill directories are product-owned native packages, not adapter-only pointers. Justification: agent skill systems may discover and package the skill directory as the resource boundary, so `SKILL.md` must be colocated with procedure, report-template, and lease resources needed for progressive disclosure. Compact adapters may point to host-native packages, but removing those colocated resources from configured skill folders would make workflow behavior depend on manual cross-repository reads and could fail in hosts or sandboxes that package only the skill directory. A separate `.truthmark/agent/` workflow copy is not generated unless a host surface actually consumes it, because otherwise it is duplicate repository documentation rather than runtime surface. -- Decision (2026-06-18): Truth Sync exposes conversation-provided decision rationale as a visible workflow input and report outcome, without transcript ingestion, hidden memory, required hooks, persistent inbox files, mandatory ADRs, or extra proposal artifacts. -- Decision (2026-06-18): Fresh installs do not assume Codex, OpenCode, or any other host platform; maintainers opt into Codex, OpenCode, Claude Code, GitHub Copilot, Antigravity, or Cursor surfaces by listing them in `platforms`. +- Decision (2026-06-17): Optional workflow status presents helper output as advisory workflow cards with review checklists, evidence prompts, open questions, and skipped-helper status. + - Direct checkout inspection remains the fallback when helpers are skipped, unavailable, or unnecessary. +- Decision (2026-06-17): Host skill directories are product-owned native packages, not adapter-only pointers. + - Agent skill systems may discover and package the skill directory as the resource boundary. + - `SKILL.md` must be colocated with procedure, report-template, and lease resources needed for progressive disclosure. + - Compact adapters may point to host-native packages. + - Removing colocated resources from configured skill folders would make workflow behavior depend on manual cross-repository reads. + - Removing colocated resources could fail in hosts or sandboxes that package only the skill directory. + - A separate `.truthmark/agent/` workflow copy is not generated unless a host surface actually consumes it, because otherwise it is duplicate repository documentation rather than runtime surface. +- Decision (2026-06-18): Truth Sync exposes conversation-provided decision rationale as a visible workflow input and report outcome. + - It does not use transcript ingestion, hidden memory, required hooks, persistent inbox files, mandatory ADRs, or extra proposal artifacts. +- Decision (2026-06-18): Fresh installs do not assume Codex, OpenCode, or any other host platform. + - Maintainers opt into Codex, OpenCode, Claude Code, GitHub Copilot, Antigravity, or Cursor surfaces by listing them in `platforms`. - Decision (2026-06-18): Generated helper manifest and helper policy files are removed from skill packages; optional validation remains available through explicit CLI validation commands and manual fallback checks. -- Decision (2026-06-20): Truth Preview generated host surfaces are retired. Truthmark no longer emits Preview skill packages, Copilot prompts, Antigravity rules, or Cursor rules; preview-like route/workflow selection remains internal advisory behavior rather than an installed workflow surface. -- Decision (2026-06-18): Finish-time Truth Sync retains bounded topology repair. Safe repairs happen inside Sync before normal truth syncing; manual Truth Structure handoff is only for unsafe, ambiguous, or out-of-scope topology changes. +- Decision (2026-06-20): Truth Preview generated host surfaces are retired. + - Truthmark no longer emits Preview skill packages, Copilot prompts, Antigravity rules, or Cursor rules. + - Preview-like route/workflow selection remains internal advisory behavior rather than an installed workflow surface. +- Decision (2026-06-18): Finish-time Truth Sync retains bounded topology repair. + - Safe repairs happen inside Sync before normal truth syncing; manual Truth Structure handoff is only for unsafe, ambiguous, or out-of-scope topology changes. +- Decision (2026-06-21): Cursor uses Agent Skill project packages under `.cursor/skills/truthmark-*`, not dynamic `.cursor/rules` files. + - Cursor Agent Skills are the single current native Cursor workflow representation for Truthmark because they support description-based selection plus package-local support resources. ## Engineering Realization Links diff --git a/docs/truthmark/product/capabilities/lane-separated-truth.md b/docs/truthmark/product/capabilities/lane-separated-truth.md index 1c6e17d..d72eab3 100644 --- a/docs/truthmark/product/capabilities/lane-separated-truth.md +++ b/docs/truthmark/product/capabilities/lane-separated-truth.md @@ -16,11 +16,15 @@ Maintainers can review product promises and implementation realization without e ## Capability Scope -Product truth belongs under `docs/truthmark/product`; engineering truth belongs under `docs/truthmark/engineering`. Downstream product truth uses `product-capability` only. Product boundary, scope, adjacent-system, and non-goal guidance lives inside capability docs instead of a separate downstream boundary kind. Relationships between lanes are traceability edges, not content inheritance. +- Product truth belongs under `docs/truthmark/product`; engineering truth belongs under `docs/truthmark/engineering`. +- Downstream product truth uses `product-capability` only. +- Product boundary, scope, adjacent-system, and non-goal guidance lives inside capability docs instead of a separate downstream boundary kind. +- Relationships between lanes are traceability edges, not content inheritance. ## Current Product Behavior -Route metadata supports explicit `lane`, `realized_by`, `realizes`, and `depends_on` fields for route-local traceability. Product-path kind inference returns `product-capability`, and init scaffolds `product-capability.md` without scaffolding a downstream `product-boundary` template. +- Route metadata supports explicit `lane`, `realized_by`, `realizes`, and `depends_on` fields for route-local traceability. +- Product-path kind inference returns `product-capability`, and init scaffolds `product-capability.md` without scaffolding a downstream `product-boundary` template. ## Acceptance Criteria @@ -36,7 +40,8 @@ Route metadata supports explicit `lane`, `realized_by`, `realizes`, and `depends - Decision (2026-06-14): Product docs may cite code directly as evidence for current product behavior, but detailed mechanics stay in engineering docs. - Decision (2026-06-14): Missing product links for user-visible engineering docs are review diagnostics, not hard errors. - Decision (2026-06-14): Downstream product truth supports `product-capability` only; product boundary guidance belongs inside capability scope, acceptance criteria, and non-goals. -- Decision (2026-06-15): Route `realized_by` and `realizes` relationships are local navigation metadata, not a single global doc graph; validation requires existing opposite-lane targets without requiring reciprocal declarations. +- Decision (2026-06-15): Route `realized_by` and `realizes` relationships are local navigation metadata, not a single global doc graph. + - Validation requires existing opposite-lane targets without requiring reciprocal declarations. ## Engineering Realization Links diff --git a/docs/user-guide.md b/docs/user-guide.md index f760e93..7a9d957 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -62,7 +62,7 @@ truthmark init | `github-copilot` | Agent skills, prompt commands, custom agents, and managed instructions | `/truthmark-*` in supported Copilot IDEs; `@truth-*` custom agents in Copilot CLI | | `opencode` | Skill packages and verifier agents | `/skill truthmark-*` | | `antigravity` | Project rule files for Truthmark workflows | `@truthmark-*` | -| `cursor` | Project rule files under `.cursor/rules` | `@truthmark-*` | +| `cursor` | Agent Skill project packages under `.cursor/skills` | selected by description or invoked with `/` in Cursor Agent chat | Unknown platform names are config errors. @@ -120,7 +120,7 @@ Use Truth Document when the implementation already exists but the repository tru /truthmark-document document the implemented session timeout behavior across src/auth/session.ts, src/auth/middleware.ts, and tests/auth/session.test.ts ``` -Give it the feature name, code paths, test paths, or desired truth-doc area. On OpenCode-style hosts, call the same workflow as `/skill truthmark-document ...`; on Antigravity or Cursor, use `@truthmark-document ...`. +Give it the feature name, code paths, test paths, or desired truth-doc area. On OpenCode-style hosts, call the same workflow as `/skill truthmark-document ...`; on Antigravity, use `@truthmark-document ...`; in Cursor, use `/truthmark-document ...` or let the Agent Skill be selected by description. Start with Truth Document for one bounded feature or area at a time. @@ -170,7 +170,7 @@ Most maintainers start with three commands. | `truthmark init` | Install or refresh configured workflow surfaces from the reviewed config. | | `truthmark check` | Validate configuration, authority, routing, decision-bearing docs, frontmatter, internal links, branch scope, generated surfaces, freshness, and coverage diagnostics. | -Optional repository-intelligence helpers generate derived review material for the active checkout, such as RepoIndex, RouteMap, ImpactSet, and compact WorkflowState/action-context JSON. Validation helpers are exposed as optional workflow metadata and explicit `truthmark validate ... --json` commands; they are accelerators, not bundled repo-local helper manifest or policy files and not sources of truth. Standalone Copilot prompts and Antigravity/Cursor rules use the same CLI validator contract when the installed runner is available, and otherwise report a visible skipped helper status with manual validation. +Optional repository-intelligence helpers generate derived review material for the active checkout, such as RepoIndex, RouteMap, ImpactSet, and compact WorkflowState/action-context JSON. Validation helpers are exposed as optional workflow metadata and explicit `truthmark validate ... --json` commands; they are accelerators, not bundled repo-local helper manifest or policy files and not sources of truth. Standalone Copilot prompts, Antigravity rules, and Cursor Agent Skills use the same CLI validator contract when the installed runner is available, and otherwise report a visible skipped helper status with manual validation. They are not sources of truth. diff --git a/package-lock.json b/package-lock.json index bfff0ff..8e9735f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "truthmark", - "version": "2.2.4", + "version": "2.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "truthmark", - "version": "2.2.4", + "version": "2.2.5", "license": "MIT", "dependencies": { "ajv": "^8.17.1", diff --git a/package.json b/package.json index 5965b1c..1e0b6b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "truthmark", - "version": "2.2.4", + "version": "2.2.5", "description": "Git-native, branch-scoped truth workflow installer for local AI coding agents.", "license": "MIT", "type": "module", diff --git a/src/agents/truth-check.ts b/src/agents/truth-check.ts index ead37a5..67ce3bb 100644 --- a/src/agents/truth-check.ts +++ b/src/agents/truth-check.ts @@ -20,7 +20,7 @@ const renderMarkdownExample = (content: string): string => { }; export const TRUTH_CHECK_EXPLICIT_INVOCATIONS = - "OpenCode /skill truthmark-check; Codex /truthmark-check or $truthmark-check; Claude Code /truthmark-check; GitHub Copilot /truthmark-check; Antigravity @truthmark-check; Cursor @truthmark-check."; + "OpenCode /skill truthmark-check; Codex /truthmark-check or $truthmark-check; Claude Code /truthmark-check; GitHub Copilot /truthmark-check; Antigravity @truthmark-check; Cursor /truthmark-check."; export const renderTruthCheckReportExample = ( config: TruthmarkConfig = defaultAgentConfig(), diff --git a/src/agents/truth-document.ts b/src/agents/truth-document.ts index fa4e633..d589438 100644 --- a/src/agents/truth-document.ts +++ b/src/agents/truth-document.ts @@ -29,7 +29,7 @@ const renderMarkdownExample = (content: string): string => { }; export const TRUTH_DOCUMENT_EXPLICIT_INVOCATIONS = - "OpenCode /skill truthmark-document; Codex /truthmark-document or $truthmark-document; Claude Code /truthmark-document; GitHub Copilot /truthmark-document; Antigravity @truthmark-document; Cursor @truthmark-document."; + "OpenCode /skill truthmark-document; Codex /truthmark-document or $truthmark-document; Claude Code /truthmark-document; GitHub Copilot /truthmark-document; Antigravity @truthmark-document; Cursor /truthmark-document."; export const renderTruthDocumentReportExample = ( config: TruthmarkConfig = defaultAgentConfig(), diff --git a/src/agents/truth-structure.ts b/src/agents/truth-structure.ts index fb9ff08..950e0f7 100644 --- a/src/agents/truth-structure.ts +++ b/src/agents/truth-structure.ts @@ -23,7 +23,7 @@ const renderMarkdownExample = (content: string): string => { }; export const TRUTH_STRUCTURE_EXPLICIT_INVOCATIONS = - "OpenCode /skill truthmark-structure; Codex /truthmark-structure or $truthmark-structure; Claude Code /truthmark-structure; GitHub Copilot /truthmark-structure; Antigravity @truthmark-structure; Cursor @truthmark-structure."; + "OpenCode /skill truthmark-structure; Codex /truthmark-structure or $truthmark-structure; Claude Code /truthmark-structure; GitHub Copilot /truthmark-structure; Antigravity @truthmark-structure; Cursor /truthmark-structure."; export const renderTruthStructureReportExample = ( config: TruthmarkConfig = defaultAgentConfig(), diff --git a/src/agents/truth-sync.ts b/src/agents/truth-sync.ts index 7f146d1..7bbacdf 100644 --- a/src/agents/truth-sync.ts +++ b/src/agents/truth-sync.ts @@ -17,7 +17,7 @@ import { import { getTruthmarkWorkflow } from "./workflow-manifest.js"; export const TRUTH_SYNC_EXPLICIT_INVOCATIONS = - "OpenCode /skill truthmark-sync; Codex /truthmark-sync or $truthmark-sync; Claude Code /truthmark-sync; GitHub Copilot /truthmark-sync; Antigravity @truthmark-sync; Cursor @truthmark-sync."; + "OpenCode /skill truthmark-sync; Codex /truthmark-sync or $truthmark-sync; Claude Code /truthmark-sync; GitHub Copilot /truthmark-sync; Antigravity @truthmark-sync; Cursor /truthmark-sync."; const renderMarkdownExample = (content: string): string => { return ["```md", content, "```"].join("\n"); @@ -191,14 +191,14 @@ ${renderMarkdownExample( changedCode: ["src/auth/session.ts"], syncIntent: { changedCodeReviewed: ["src/auth/session.ts"], - affectedRouteOrTruthOwner: [config.truthmark.paths.routesIndex], - targetTruthDocs: [ - `${engineeringTruthRoot}/repository/bootstrap-routing.md`, + affectedRouteOrTruthOwner: [ + `${config.truthmark.paths.routeAreasRoot}/authentication.md`, ], + targetTruthDocs: [`${engineeringTruthRoot}/behaviors/session-timeout.md`], intendedUpdate: ["Update session timeout behavior."], evidenceToVerify: [ "src/auth/session.ts:12", - `${config.truthmark.paths.routesIndex}:11`, + `${config.truthmark.paths.routeAreasRoot}/authentication.md:11`, ], userProvidedDecisionRationale: [ "User rationale: session timeout behavior changed for internal implementation consistency", @@ -206,23 +206,21 @@ ${renderMarkdownExample( noUpdateNeededRationale: ["not applicable; mapped truth is stale"], blockers: ["none"], }, - ownershipReviewed: [config.truthmark.paths.routesIndex], - truthDocsUpdated: [ - `${engineeringTruthRoot}/repository/bootstrap-routing.md`, - ], + ownershipReviewed: [`${config.truthmark.paths.routeAreasRoot}/authentication.md`], + truthDocsUpdated: [`${engineeringTruthRoot}/behaviors/session-timeout.md`], evidenceChecked: [ { claim: - "Session timeout behavior is documented in the mapped repository truth doc.", + "Session timeout behavior is documented in the bounded authentication behavior truth doc.", evidence: [ "src/auth/session.ts:12", - `${config.truthmark.paths.routesIndex}:11`, + `${config.truthmark.paths.routeAreasRoot}/authentication.md:11`, ], result: "supported", }, ], decisionRationaleCaptured: [ - "Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale.", + "Placed user rationale in the bounded authentication behavior truth doc under Engineering Decisions/Rationale.", ], notes: ["Updated session timeout behavior."], }), @@ -230,9 +228,12 @@ ${renderMarkdownExample( Blocked report example: ${renderMarkdownExample( renderTruthSyncBlockedReport({ - reason: "routing repair is unsafe or ambiguous", - manualReviewFiles: [config.truthmark.paths.routesIndex], - nextAction: "run Truth Structure with the listed files before rerunning Truth Sync", + reason: "Changed code maps only to the provisional bootstrap route.", + manualReviewFiles: [ + "src/auth/**", + `${config.truthmark.paths.routeAreasRoot}/${config.truthmark.routes.defaultArea}.md`, + ], + nextAction: "Run Truth Structure for src/auth/** before updating behavior truth.", }), )}`; }; diff --git a/src/agents/truthmark-portal.ts b/src/agents/truthmark-portal.ts index fa9d528..2a65cd3 100644 --- a/src/agents/truthmark-portal.ts +++ b/src/agents/truthmark-portal.ts @@ -3,7 +3,7 @@ import { defaultAgentConfig, renderHierarchySummary } from "./shared.js"; import { getTruthmarkWorkflow } from "./workflow-manifest.js"; export const TRUTHMARK_PORTAL_EXPLICIT_INVOCATIONS = - "OpenCode /skill truthmark-portal; Codex /truthmark-portal or $truthmark-portal; Claude Code /truthmark-portal; GitHub Copilot /truthmark-portal; Antigravity @truthmark-portal; Cursor @truthmark-portal."; + "OpenCode /skill truthmark-portal; Codex /truthmark-portal or $truthmark-portal; Claude Code /truthmark-portal; GitHub Copilot /truthmark-portal; Antigravity @truthmark-portal; Cursor /truthmark-portal."; export const renderTruthmarkPortalProcedureBody = ( config: TruthmarkConfig = defaultAgentConfig(), diff --git a/src/agents/workflow-helper-validation.ts b/src/agents/workflow-helper-validation.ts index 219f0ae..6c9e813 100644 --- a/src/agents/workflow-helper-validation.ts +++ b/src/agents/workflow-helper-validation.ts @@ -195,6 +195,17 @@ export const validateTruthSyncReportText = (text: string): WorkflowHelperValidat ); } + const completedTargets = [ + ...report.truthDocsUpdated, + ...(report.syncIntent?.targetTruthDocs ?? []), + ]; + const bootstrapTargets = completedTargets.filter(isBootstrapRoutingDocPath); + if (bootstrapTargets.length > 0) { + errors.push( + `bootstrap-routing.md is a provisional topology handoff, not a completed behavior-update target: ${bootstrapTargets.join(", ")}`, + ); + } + if (report.syncIntent !== undefined) { checks.push("Sync Intent"); } @@ -265,6 +276,8 @@ export const validateTruthDocumentReportText = (text: string): WorkflowHelperVal const cleanPathValue = (value: string): string => value.trim().replace(/^["']|["']$/gu, ""); const normalizePath = (value: string): string => cleanPathValue(value).replace(/^\.\//u, ""); +const isBootstrapRoutingDocPath = (value: string): boolean => + normalizePath(value).endsWith("/bootstrap-routing.md"); const windowsDriveAbsolutePattern = /^[A-Za-z]:[\\/]/u; const uncPathPattern = /^[/\\]{2}[^/\\]+[/\\]+[^/\\]+/u; diff --git a/src/checks/generated-surfaces.ts b/src/checks/generated-surfaces.ts index d468757..75c6377 100644 --- a/src/checks/generated-surfaces.ts +++ b/src/checks/generated-surfaces.ts @@ -51,6 +51,7 @@ const GENERATED_HOST_SKILL_ROOTS = [ ".opencode/skills", ".claude/skills", ".github/skills", + ".cursor/skills", ] as const; const RETIRED_SKILL_HELPER_PATHS = [ @@ -63,10 +64,31 @@ const RETIRED_PACKAGE_DIRECTORIES = ["truthmark-preview"] as const; const RETIRED_GENERATED_SURFACE_PATHS = [ "GEMINI.md", ".github/prompts/truthmark-preview.prompt.md", + ".cursor/rules/truthmark-structure.mdc", + ".cursor/rules/truthmark-document.mdc", + ".cursor/rules/truthmark-sync.mdc", + ".cursor/rules/truthmark-realize.mdc", + ".cursor/rules/truthmark-check.mdc", + ".cursor/rules/truthmark-portal.mdc", ] as const; const RETIRED_GENERATED_SURFACE_ROOTS = [".gemini"] as const; +const isRetiredGeminiSurfacePath = (filePath: string): boolean => + filePath === "GEMINI.md" || filePath.startsWith(".gemini/"); + +const obsoleteGeneratedSurfaceMessage = (surfacePath: string): string => { + if (isRetiredGeminiSurfacePath(surfacePath)) { + return `Generated surface ${surfacePath} is obsolete; remove stale Gemini instructions manually if they are no longer wanted.`; + } + + return `Generated surface ${surfacePath} is obsolete; rerun truthmark init.`; +}; + +type RetiredSurfaceCollectionOptions = { + includeGeminiSurfaces?: boolean; +}; + const pathExists = async (absolutePath: string): Promise => { try { await fs.access(absolutePath); @@ -116,10 +138,16 @@ const listDirectoryFiles = async ( const collectRetiredGeneratedSurfaces = async ( rootDir: string, expectedSurfacePaths: Set, + options: RetiredSurfaceCollectionOptions = {}, ): Promise => { const legacyCandidates = new Set(); + const includeGeminiSurfaces = options.includeGeminiSurfaces ?? true; for (const retiredPath of RETIRED_GENERATED_SURFACE_PATHS) { + if (!includeGeminiSurfaces && isRetiredGeminiSurfacePath(retiredPath)) { + continue; + } + const absoluteRetiredPath = resolveRepoPath(rootDir, retiredPath); if ( @@ -131,6 +159,10 @@ const collectRetiredGeneratedSurfaces = async ( } for (const retiredRoot of RETIRED_GENERATED_SURFACE_ROOTS) { + if (!includeGeminiSurfaces && isRetiredGeminiSurfacePath(`${retiredRoot}/`)) { + continue; + } + const absoluteRetiredRoot = resolveRepoPath(rootDir, retiredRoot); if (!(await pathExists(absoluteRetiredRoot))) { @@ -245,7 +277,7 @@ export const checkGeneratedSurfaces = async ( diagnostics.push({ category: "generated-surface", severity: "review", - message: `Generated surface ${surfacePath} is obsolete; rerun truthmark init.`, + message: obsoleteGeneratedSurfaceMessage(surfacePath), file: surfacePath, }); } @@ -259,3 +291,12 @@ export const findRetiredGeneratedSurfaces = async ( ): Promise => { return collectRetiredGeneratedSurfaces(rootDir, expectedSurfacePaths); }; + +export const findAutoRemovableRetiredGeneratedSurfaces = async ( + rootDir: string, + expectedSurfacePaths: Set, +): Promise => { + return collectRetiredGeneratedSurfaces(rootDir, expectedSurfacePaths, { + includeGeminiSurfaces: false, + }); +}; diff --git a/src/init/init.ts b/src/init/init.ts index af8f8ad..aa1fbce 100644 --- a/src/init/init.ts +++ b/src/init/init.ts @@ -6,7 +6,7 @@ import type { CommandResult, DiagnosticCategory } from "../output/diagnostic.js" import { getGitRepository } from "../git/repository.js"; import { resolveRepoPath, type FileWriteResult, writeRepoFile } from "../fs/paths.js"; import { scaffoldHierarchy } from "./hierarchy.js"; -import { findRetiredGeneratedSurfaces } from "../checks/generated-surfaces.js"; +import { findAutoRemovableRetiredGeneratedSurfaces } from "../checks/generated-surfaces.js"; import { renderAgentsBlock, TRUTHMARK_BLOCK_END, TRUTHMARK_BLOCK_START } from "../templates/agents-block.js"; import { renderGeneratedSurfaces, type GeneratedSurface } from "../templates/generated-surfaces.js"; @@ -164,7 +164,8 @@ const diagnosticCategoryForPath = ( filePath.startsWith(".opencode/skills/truthmark-realize/") || filePath.startsWith(".agents/skills/truthmark-realize/") || filePath.startsWith(".antigravity/rules/truthmark-realize") || - filePath.startsWith(".cursor/rules/truthmark-realize") + filePath.startsWith(".cursor/rules/truthmark-realize") || + filePath.startsWith(".cursor/skills/truthmark-realize/") ) { return "realization"; } @@ -181,7 +182,8 @@ const diagnosticCategoryForPath = ( filePath.startsWith(".opencode/agents/") || filePath.startsWith(".codex/agents/") || filePath.startsWith(".antigravity/rules/truthmark-") || - filePath.startsWith(".cursor/rules/truthmark-") + filePath.startsWith(".cursor/rules/truthmark-") || + filePath.startsWith(".cursor/skills/truthmark-") ) { return "truth-sync"; } @@ -265,7 +267,7 @@ export const runInit = async (cwd: string): Promise => { results.push(await writePlatformFile(rootDir, file)); } - const obsoleteSurfacePaths = await findRetiredGeneratedSurfaces( + const obsoleteSurfacePaths = await findAutoRemovableRetiredGeneratedSurfaces( rootDir, expectedSurfacePaths, ); diff --git a/src/sync/classify.ts b/src/sync/classify.ts index c89a3a3..74fd43f 100644 --- a/src/sync/classify.ts +++ b/src/sync/classify.ts @@ -169,6 +169,7 @@ export const classifyPath = ( normalizedPath.startsWith(".opencode/") || normalizedPath.startsWith(".antigravity/rules/truthmark-") || normalizedPath.startsWith(".cursor/rules/truthmark-") || + normalizedPath.startsWith(".cursor/skills/truthmark-") || normalizedPath === ".github/copilot-instructions.md" || normalizedPath.startsWith(".github/agents/truth-") || normalizedPath.startsWith(".github/prompts/truthmark-") || diff --git a/src/templates/generated-surfaces.ts b/src/templates/generated-surfaces.ts index e852132..f7c08cd 100644 --- a/src/templates/generated-surfaces.ts +++ b/src/templates/generated-surfaces.ts @@ -25,12 +25,6 @@ import { renderTruthmarkAntigravityRealizeRule, renderTruthmarkAntigravityStructureRule, renderTruthmarkAntigravitySyncRule, - renderTruthmarkCursorCheckRule, - renderTruthmarkCursorDocumentRule, - renderTruthmarkCursorPortalRule, - renderTruthmarkCursorRealizeRule, - renderTruthmarkCursorStructureRule, - renderTruthmarkCursorSyncRule, renderTruthmarkSkillPackage, renderTruthmarkCheckSkillMetadata, renderTruthmarkOpenCodeClaimVerifierAgent, @@ -55,12 +49,12 @@ import { TRUTHMARK_ANTIGRAVITY_REALIZE_RULE_PATH, TRUTHMARK_ANTIGRAVITY_STRUCTURE_RULE_PATH, TRUTHMARK_ANTIGRAVITY_SYNC_RULE_PATH, - TRUTHMARK_CURSOR_CHECK_RULE_PATH, - TRUTHMARK_CURSOR_DOCUMENT_RULE_PATH, - TRUTHMARK_CURSOR_PORTAL_RULE_PATH, - TRUTHMARK_CURSOR_REALIZE_RULE_PATH, - TRUTHMARK_CURSOR_STRUCTURE_RULE_PATH, - TRUTHMARK_CURSOR_SYNC_RULE_PATH, + TRUTHMARK_CURSOR_CHECK_SKILL_PATH, + TRUTHMARK_CURSOR_DOCUMENT_SKILL_PATH, + TRUTHMARK_CURSOR_PORTAL_SKILL_PATH, + TRUTHMARK_CURSOR_REALIZE_SKILL_PATH, + TRUTHMARK_CURSOR_STRUCTURE_SKILL_PATH, + TRUTHMARK_CURSOR_SYNC_SKILL_PATH, TRUTHMARK_COPILOT_CLAIM_VERIFIER_AGENT_PATH, TRUTHMARK_COPILOT_CHECK_PROMPT_PATH, TRUTHMARK_COPILOT_DOCUMENT_PROMPT_PATH, @@ -444,33 +438,47 @@ const antigravityFiles = (config: TruthmarkConfig): GeneratedSurface[] => { const cursorFiles = (config: TruthmarkConfig): GeneratedSurface[] => { const files: GeneratedSurface[] = [ - { - path: TRUTHMARK_CURSOR_STRUCTURE_RULE_PATH, - content: renderTruthmarkCursorStructureRule(config), - }, - { - path: TRUTHMARK_CURSOR_DOCUMENT_RULE_PATH, - content: renderTruthmarkCursorDocumentRule(config), - }, - { - path: TRUTHMARK_CURSOR_SYNC_RULE_PATH, - content: renderTruthmarkCursorSyncRule(config), - }, - { - path: TRUTHMARK_CURSOR_CHECK_RULE_PATH, - content: renderTruthmarkCursorCheckRule(config), - }, - { - path: TRUTHMARK_CURSOR_REALIZE_RULE_PATH, - content: renderTruthmarkCursorRealizeRule(config), - }, + ...renderTruthmarkSkillPackage({ + skillPath: TRUTHMARK_CURSOR_STRUCTURE_SKILL_PATH, + workflowId: "truthmark-structure", + host: "cursor", + config, + }), + ...renderTruthmarkSkillPackage({ + skillPath: TRUTHMARK_CURSOR_DOCUMENT_SKILL_PATH, + workflowId: "truthmark-document", + host: "cursor", + config, + }), + ...renderTruthmarkSkillPackage({ + skillPath: TRUTHMARK_CURSOR_SYNC_SKILL_PATH, + workflowId: "truthmark-sync", + host: "cursor", + config, + }), + ...renderTruthmarkSkillPackage({ + skillPath: TRUTHMARK_CURSOR_CHECK_SKILL_PATH, + workflowId: "truthmark-check", + host: "cursor", + config, + }), + ...renderTruthmarkSkillPackage({ + skillPath: TRUTHMARK_CURSOR_REALIZE_SKILL_PATH, + workflowId: "truthmark-realize", + host: "cursor", + config, + }), ]; if (config.truthmark.generated.portal.enabled) { - files.push({ - path: TRUTHMARK_CURSOR_PORTAL_RULE_PATH, - content: renderTruthmarkCursorPortalRule(config), - }); + files.push( + ...renderTruthmarkSkillPackage({ + skillPath: TRUTHMARK_CURSOR_PORTAL_SKILL_PATH, + workflowId: "truthmark-portal", + host: "cursor", + config, + }), + ); } return files; diff --git a/src/templates/workflow-surfaces.ts b/src/templates/workflow-surfaces.ts index 2721c38..ab34125 100644 --- a/src/templates/workflow-surfaces.ts +++ b/src/templates/workflow-surfaces.ts @@ -133,23 +133,23 @@ export const TRUTHMARK_ANTIGRAVITY_CHECK_RULE_PATH = export const TRUTHMARK_ANTIGRAVITY_PORTAL_RULE_PATH = ".antigravity/rules/truthmark-portal.md"; -export const TRUTHMARK_CURSOR_STRUCTURE_RULE_PATH = - ".cursor/rules/truthmark-structure.mdc"; +export const TRUTHMARK_CURSOR_STRUCTURE_SKILL_PATH = + ".cursor/skills/truthmark-structure/SKILL.md"; -export const TRUTHMARK_CURSOR_DOCUMENT_RULE_PATH = - ".cursor/rules/truthmark-document.mdc"; +export const TRUTHMARK_CURSOR_DOCUMENT_SKILL_PATH = + ".cursor/skills/truthmark-document/SKILL.md"; -export const TRUTHMARK_CURSOR_SYNC_RULE_PATH = - ".cursor/rules/truthmark-sync.mdc"; +export const TRUTHMARK_CURSOR_SYNC_SKILL_PATH = + ".cursor/skills/truthmark-sync/SKILL.md"; -export const TRUTHMARK_CURSOR_REALIZE_RULE_PATH = - ".cursor/rules/truthmark-realize.mdc"; +export const TRUTHMARK_CURSOR_REALIZE_SKILL_PATH = + ".cursor/skills/truthmark-realize/SKILL.md"; -export const TRUTHMARK_CURSOR_CHECK_RULE_PATH = - ".cursor/rules/truthmark-check.mdc"; +export const TRUTHMARK_CURSOR_CHECK_SKILL_PATH = + ".cursor/skills/truthmark-check/SKILL.md"; -export const TRUTHMARK_CURSOR_PORTAL_RULE_PATH = - ".cursor/rules/truthmark-portal.mdc"; +export const TRUTHMARK_CURSOR_PORTAL_SKILL_PATH = + ".cursor/skills/truthmark-portal/SKILL.md"; export const TRUTHMARK_COPILOT_STRUCTURE_PROMPT_PATH = ".github/prompts/truthmark-structure.prompt.md"; @@ -241,7 +241,8 @@ type TruthmarkSkillPackageHost = | "codex" | "opencode" | "claude-code" - | "github-copilot"; + | "github-copilot" + | "cursor"; type TruthmarkSkillPackageFile = { path: string; @@ -374,14 +375,14 @@ const renderWorkflowReportTemplate = ( changedCode: ["src/auth/session.ts"], syncIntent: { changedCodeReviewed: ["src/auth/session.ts"], - affectedRouteOrTruthOwner: [config.truthmark.paths.routesIndex], - targetTruthDocs: [ - `${engineeringTruthRoot}/repository/bootstrap-routing.md`, + affectedRouteOrTruthOwner: [ + `${config.truthmark.paths.routeAreasRoot}/authentication.md`, ], + targetTruthDocs: [`${engineeringTruthRoot}/behaviors/session-timeout.md`], intendedUpdate: ["Update session timeout behavior."], evidenceToVerify: [ "src/auth/session.ts:12", - `${config.truthmark.paths.routesIndex}:11`, + `${config.truthmark.paths.routeAreasRoot}/authentication.md:11`, ], userProvidedDecisionRationale: [ "User rationale: session timeout behavior changed for internal implementation consistency", @@ -389,31 +390,34 @@ const renderWorkflowReportTemplate = ( noUpdateNeededRationale: ["not applicable; mapped truth is stale"], blockers: ["none"], }, - ownershipReviewed: [config.truthmark.paths.routesIndex], - truthDocsUpdated: [ - `${engineeringTruthRoot}/repository/bootstrap-routing.md`, + ownershipReviewed: [ + `${config.truthmark.paths.routeAreasRoot}/authentication.md`, ], + truthDocsUpdated: [`${engineeringTruthRoot}/behaviors/session-timeout.md`], evidenceChecked: [ { claim: - "Session timeout behavior is documented in the mapped repository truth doc.", + "Session timeout behavior is documented in the bounded authentication behavior truth doc.", evidence: [ "src/auth/session.ts:12", - `${config.truthmark.paths.routesIndex}:11`, + `${config.truthmark.paths.routeAreasRoot}/authentication.md:11`, ], result: "supported", }, ], decisionRationaleCaptured: [ - "Placed user rationale in the mapped engineering truth doc under Engineering Decisions/Rationale.", + "Placed user rationale in the bounded authentication behavior truth doc under Engineering Decisions/Rationale.", ], notes: ["Updated session timeout behavior."], }), )}\nBlocked report example:\n${renderMarkdownExample( renderTruthSyncBlockedReport({ - reason: "routing repair is not allowed", - manualReviewFiles: [config.truthmark.paths.routesIndex], - nextAction: "update routing metadata and rerun Truth Sync", + reason: "Changed code maps only to the provisional bootstrap route.", + manualReviewFiles: [ + "src/auth/**", + `${config.truthmark.paths.routeAreasRoot}/${config.truthmark.routes.defaultArea}.md`, + ], + nextAction: "Run Truth Structure for src/auth/** before updating behavior truth.", }), )}`; case "truthmark-realize": @@ -526,7 +530,9 @@ const renderWorkflowEntrypoint = ( const hostUsage = host === "github-copilot" ? "Use as a Copilot agent skill. Prompt files remain available under `.github/prompts/` for command-style invocation in supported Copilot IDEs." - : undefined; + : host === "cursor" + ? "Use as a Cursor Agent Skill. Cursor discovers project skills under `.cursor/skills/`, selects them from the description when relevant, and supports manual `/` invocation." + : undefined; return `--- name: ${workflowId} @@ -592,6 +598,8 @@ const renderWorkflowSubagentSupport = ( definition.parentRule, writeAgents, ); + case "cursor": + return undefined; } }; @@ -613,7 +621,11 @@ export const renderTruthmarkSkillPackage = ({ config, ); const subagents = renderWorkflowSubagentSupport(workflowId, host); - const supportFiles = workflowSupportFiles(workflowId); + const supportFiles = [ + "support/procedure.md", + "support/report-template.md", + ...(subagents !== undefined ? ["support/subagents-and-leases.md"] : []), + ]; const definition = WORKFLOW_PACKAGE_DEFINITIONS[workflowId]; const files: TruthmarkSkillPackageFile[] = [ { @@ -697,7 +709,7 @@ type TruthmarkSubagentProfile = { }; const READ_ONLY_SUBAGENT_CONTEXT_BOUNDARY = `Context boundary: -Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. +Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence. Use only the parent-assigned shard plus required checkout evidence files. Return findings only; the parent workflow owns repository-policy interpretation, final decisions, and all writes.`; @@ -1374,13 +1386,11 @@ const renderWorkflowRuleFile = ({ workflowId, hostName, ruleName, - includeCursorFrontmatter = false, config = defaultAgentConfig(), }: { workflowId: TruthmarkWorkflowId; hostName: string; ruleName: string; - includeCursorFrontmatter?: boolean; config?: TruthmarkConfig; }): string => { const workflow = getTruthmarkWorkflow(workflowId); @@ -1412,16 +1422,7 @@ ${procedure} ${reportTemplate} `; - if (!includeCursorFrontmatter) { - return body; - } - - return `--- -description: ${workflow.description} -alwaysApply: false ---- - -${body}`; + return body; }; const renderCopilotWorkflowPrompt = ( @@ -1501,72 +1502,6 @@ export const renderTruthmarkAntigravityPortalRule = ( config, }); -export const renderTruthmarkCursorStructureRule = ( - config: TruthmarkConfig = defaultAgentConfig(), -): string => - renderWorkflowRuleFile({ - workflowId: "truthmark-structure", - hostName: "Cursor", - ruleName: "truthmark-structure", - includeCursorFrontmatter: true, - config, - }); - -export const renderTruthmarkCursorDocumentRule = ( - config: TruthmarkConfig = defaultAgentConfig(), -): string => - renderWorkflowRuleFile({ - workflowId: "truthmark-document", - hostName: "Cursor", - ruleName: "truthmark-document", - includeCursorFrontmatter: true, - config, - }); - -export const renderTruthmarkCursorSyncRule = ( - config: TruthmarkConfig = defaultAgentConfig(), -): string => - renderWorkflowRuleFile({ - workflowId: "truthmark-sync", - hostName: "Cursor", - ruleName: "truthmark-sync", - includeCursorFrontmatter: true, - config, - }); - -export const renderTruthmarkCursorRealizeRule = ( - config: TruthmarkConfig = defaultAgentConfig(), -): string => - renderWorkflowRuleFile({ - workflowId: "truthmark-realize", - hostName: "Cursor", - ruleName: "truthmark-realize", - includeCursorFrontmatter: true, - config, - }); - -export const renderTruthmarkCursorCheckRule = ( - config: TruthmarkConfig = defaultAgentConfig(), -): string => - renderWorkflowRuleFile({ - workflowId: "truthmark-check", - hostName: "Cursor", - ruleName: "truthmark-check", - includeCursorFrontmatter: true, - config, - }); - -export const renderTruthmarkCursorPortalRule = ( - config: TruthmarkConfig = defaultAgentConfig(), -): string => - renderWorkflowRuleFile({ - workflowId: "truthmark-portal", - hostName: "Cursor", - ruleName: "truthmark-portal", - includeCursorFrontmatter: true, - config, - }); - export const renderTruthmarkCopilotStructurePrompt = ( config: TruthmarkConfig = defaultAgentConfig(), ): string => { diff --git a/src/workflow-state/build.ts b/src/workflow-state/build.ts index b904d97..c740654 100644 --- a/src/workflow-state/build.ts +++ b/src/workflow-state/build.ts @@ -1,4 +1,5 @@ import { execa } from "execa"; +import micromatch from "micromatch"; import { TRUTHMARK_WORKFLOW_MANIFEST, @@ -78,11 +79,89 @@ const routeFilesFor = (repoIndex: RepoIndex): string[] => uniqueSorted(repoIndex.routeMap.routes.map((route) => route.sourcePath)); const candidateStaleTruthDocsFor = ( - indexedTruthDocs: string[], + repoIndex: RepoIndex, primaryTruthDocs: string[], + impactSet: ImpactSet | null, + diagnostics: Diagnostic[], ): string[] => { + const indexedTruthDocs = new Set( + repoIndex.routeMap.routes.flatMap((route) => route.truthDocs), + ); const primary = new Set(primaryTruthDocs); - return indexedTruthDocs.filter((truthDoc) => !primary.has(truthDoc)); + const candidates = new Set(); + const changedPaths = new Set( + (impactSet?.changedFiles ?? []).flatMap((file) => [ + file.path, + ...(file.previousPath ? [file.previousPath] : []), + ]), + ); + const docEntries = new Map( + repoIndex.routeMap.routes + .flatMap((route) => route.truthDocumentEntries) + .map((entry) => [entry.path, entry]), + ); + + const addCandidate = (truthDoc: string): void => { + if (indexedTruthDocs.has(truthDoc) && !primary.has(truthDoc)) { + candidates.add(truthDoc); + } + }; + + const linkedTruthDocs = (truthDoc: string): string[] => { + const entry = docEntries.get(truthDoc); + return uniqueSorted([ + ...(entry?.realizedBy ?? []), + ...(entry?.realizes ?? []), + ...(entry?.dependsOn ?? []), + ...[...docEntries.values()] + .filter( + (candidate) => + candidate.realizedBy.includes(truthDoc) || + candidate.realizes.includes(truthDoc) || + candidate.dependsOn.includes(truthDoc), + ) + .map((candidate) => candidate.path), + ]); + }; + + for (const truthDoc of [...primary, ...changedPaths].filter((path) => + indexedTruthDocs.has(path), + )) { + for (const linkedTruthDoc of linkedTruthDocs(truthDoc)) { + addCandidate(linkedTruthDoc); + } + } + + for (const diagnostic of diagnostics) { + if (diagnostic.category === "freshness" && diagnostic.file) { + addCandidate(diagnostic.file); + } + } + + for (const route of repoIndex.routeMap.routes) { + if (changedPaths.has(route.sourcePath)) { + route.truthDocs.forEach(addCandidate); + } + } + + for (const doc of repoIndex.docs) { + if (!indexedTruthDocs.has(doc.path) || primary.has(doc.path)) { + continue; + } + + if ( + doc.sourceOfTruth.some((reference) => + [...changedPaths].some( + (changedPath) => + reference === changedPath || micromatch.isMatch(changedPath, reference), + ), + ) + ) { + candidates.add(doc.path); + } + } + + return uniqueSorted([...candidates]); }; const hasUnmappedFunctionalChange = (impactSet: ImpactSet | null): boolean => @@ -186,6 +265,7 @@ const contextDataFor = ( repoIndex: RepoIndex, config: Awaited>["config"], impactSet: ImpactSet | null, + diagnostics: Diagnostic[], ): WorkflowActionContextData => { if (!config) { return {}; @@ -198,7 +278,12 @@ const contextDataFor = ( const primaryTruthDocs = uniqueSorted(impactSet?.affectedTruthDocs ?? []); const candidateStaleTruthDocs = workflow === "truthmark-sync" - ? candidateStaleTruthDocsFor(indexedTruthDocs, primaryTruthDocs) + ? candidateStaleTruthDocsFor( + repoIndex, + primaryTruthDocs, + impactSet, + diagnostics, + ) : []; const truthDocs = workflow === "truthmark-sync" @@ -297,6 +382,7 @@ export const buildWorkflowState = async ( repoIndex, loadResult.config, impactSet, + diagnostics, ); return { diff --git a/tests/agents/instructions.test.ts b/tests/agents/instructions.test.ts index 20d7046..26c13dd 100644 --- a/tests/agents/instructions.test.ts +++ b/tests/agents/instructions.test.ts @@ -15,7 +15,7 @@ describe("renderTruthSyncInstructions", () => { expect(instructions).toContain("Automatic finish-time trigger"); expect(instructions).toContain("use the truthmark-sync skill before finishing"); expect(instructions).toContain( - "OpenCode /skill truthmark-sync; Codex /truthmark-sync or $truthmark-sync; Claude Code /truthmark-sync; GitHub Copilot /truthmark-sync; Antigravity @truthmark-sync; Cursor @truthmark-sync", + "OpenCode /skill truthmark-sync; Codex /truthmark-sync or $truthmark-sync; Claude Code /truthmark-sync; GitHub Copilot /truthmark-sync; Antigravity @truthmark-sync; Cursor /truthmark-sync", ); expect(instructions).toContain("staged, unstaged, and untracked functional code files"); expect(instructions).toContain("Run relevant tests before finishing"); diff --git a/tests/agents/truth-check.test.ts b/tests/agents/truth-check.test.ts index 8b0a344..df116e3 100644 --- a/tests/agents/truth-check.test.ts +++ b/tests/agents/truth-check.test.ts @@ -32,7 +32,7 @@ describe("renderTruthCheckSkillBody", () => { it("renders the agent-led truth audit workflow", () => { const skill = renderTruthCheckSkillBody(); - expect(TRUTH_CHECK_EXPLICIT_INVOCATIONS).toContain("Cursor @truthmark-check"); + expect(TRUTH_CHECK_EXPLICIT_INVOCATIONS).toContain("Cursor /truthmark-check"); expect(skill).toContain("name: truthmark-check"); expect(skill).toContain( "description: Use when the user asks to audit repository truth health, routing, ownership, or canonical docs.", @@ -84,7 +84,7 @@ describe("renderTruthCheckSkillBody", () => { describe("Truth Check generated surfaces", () => { const readOnlyContextBoundary = - "Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/rules, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence."; + "Do not preload AGENTS.md, CLAUDE.md, .github/copilot-instructions.md, .cursor/skills, .antigravity/rules, or repo-wide policy docs unless the parent explicitly assigns them as evidence."; it("renders Codex metadata and OpenCode skill content", () => { expect(renderTruthmarkCheckSkill()).toContain("name: truthmark-check"); diff --git a/tests/agents/truth-document.test.ts b/tests/agents/truth-document.test.ts index c6db817..505f277 100644 --- a/tests/agents/truth-document.test.ts +++ b/tests/agents/truth-document.test.ts @@ -13,7 +13,7 @@ import { renderTruthmarkDocumentLocalSkill, renderTruthmarkDocumentSkill, renderTruthmarkDocumentSkillMetadata, - renderTruthmarkCursorDocumentRule, + renderTruthmarkSkillPackage, } from "../../src/templates/workflow-surfaces.js"; describe("renderTruthDocumentSkillBody", () => { @@ -37,7 +37,7 @@ describe("renderTruthDocumentSkillBody", () => { it("renders the manual existing-implementation documentation workflow", () => { const skill = renderTruthDocumentSkillBody(); - expect(TRUTH_DOCUMENT_EXPLICIT_INVOCATIONS).toContain("Cursor @truthmark-document"); + expect(TRUTH_DOCUMENT_EXPLICIT_INVOCATIONS).toContain("Cursor /truthmark-document"); expect(skill).toContain("name: truthmark-document"); expect(skill).toContain("manual and implementation-first"); expect(skill).toContain("existing implemented behavior"); @@ -177,7 +177,7 @@ describe("Truth Document generated surfaces", () => { "Claude Code subagent mode:", ); expect(renderTruthmarkDocumentLocalSkill()).not.toContain("OpenCode /skill truthmark-document"); - expect(renderTruthmarkDocumentLocalSkill()).not.toContain("Cursor @truthmark-document"); + expect(renderTruthmarkDocumentLocalSkill()).not.toContain("Cursor /truthmark-document"); expect(renderTruthmarkDocumentSkillMetadata()).toContain( 'display_name: "Truthmark Document"', ); @@ -187,16 +187,29 @@ describe("Truth Document generated surfaces", () => { expect(renderTruthmarkDocumentSkillMetadata()).toContain( 'refresh_command: "truthmark init"', ); - expect(renderTruthmarkCursorDocumentRule()).toContain( - "This rule is the Cursor entrypoint for Truthmark Document.", - ); + const cursorDocumentPackage = renderTruthmarkSkillPackage({ + skillPath: ".cursor/skills/truthmark-document/SKILL.md", + workflowId: "truthmark-document", + host: "cursor", + }); + const cursorDocumentSkill = + cursorDocumentPackage.find((file) => file.path.endsWith("/SKILL.md"))?.content ?? ""; + const cursorDocumentProcedure = + cursorDocumentPackage.find((file) => file.path.endsWith("/support/procedure.md")) + ?.content ?? ""; + const cursorDocumentReportTemplate = + cursorDocumentPackage.find((file) => file.path.endsWith("/support/report-template.md")) + ?.content ?? ""; + + expect(cursorDocumentSkill).toContain("Use as a Cursor Agent Skill."); + expect(cursorDocumentSkill).toContain(".cursor/skills/"); + expect(cursorDocumentSkill).toContain("Progressive disclosure:"); + expect(cursorDocumentSkill).toContain("support/procedure.md"); + expect(cursorDocumentSkill).toContain("support/report-template.md"); expect(renderTruthmarkCopilotDocumentPrompt()).toContain( "This prompt is the GitHub Copilot entrypoint for Truthmark Document.", ); - for (const surface of [ - renderTruthmarkCursorDocumentRule(), - renderTruthmarkCopilotDocumentPrompt(), - ]) { + for (const surface of [renderTruthmarkCopilotDocumentPrompt()]) { expect(surface).toContain("Do not invoke another Truthmark command from here."); expect(surface).toContain( "If skill entrypoints are unavailable, use the host's direct evidence-first manual fallback procedure.", @@ -210,12 +223,8 @@ describe("Truth Document generated surfaces", () => { expect(renderTruthmarkCopilotDocumentPrompt()).toContain( "support/report-template.md", ); - expect(renderTruthmarkCursorDocumentRule()).not.toContain( - "support/procedure.md", - ); - expect(renderTruthmarkCursorDocumentRule()).not.toContain( - "support/report-template.md", - ); - expect(renderTruthmarkCursorDocumentRule()).not.toContain("Quick procedure:"); + expect(cursorDocumentProcedure).toContain("Truthmark Document Procedure"); + expect(cursorDocumentProcedure).not.toContain("Report completion in this shape:"); + expect(cursorDocumentReportTemplate).toContain("Report completion in this shape:"); }); }); diff --git a/tests/agents/truth-sync.test.ts b/tests/agents/truth-sync.test.ts index c97b9ff..f9ed606 100644 --- a/tests/agents/truth-sync.test.ts +++ b/tests/agents/truth-sync.test.ts @@ -13,7 +13,6 @@ import { } from "../../src/agents/truth-sync.js"; import { renderTruthmarkCopilotSyncPrompt, - renderTruthmarkCursorSyncRule, renderTruthmarkSyncClaudeSkill, renderTruthmarkSyncLocalSkill, renderTruthmarkSkillPackage, @@ -25,7 +24,7 @@ describe("renderTruthSyncWorkerPrompt", () => { it("renders the prepared-context worker contract and result shape", () => { const prompt = renderTruthSyncWorkerPrompt(); - expect(TRUTH_SYNC_EXPLICIT_INVOCATIONS).toContain("Cursor @truthmark-sync"); + expect(TRUTH_SYNC_EXPLICIT_INVOCATIONS).toContain("Cursor /truthmark-sync"); expect(prompt).toContain("parent provides the task focus"); expect(prompt).toContain("explicit write lease"); expect(prompt).toContain( @@ -158,9 +157,9 @@ describe("renderTruthSyncSkillBody", () => { const skillBody = renderTruthSyncSkillBody(config); expect(skillBody).toContain( - "docs/truthmark/engineering/repository/bootstrap-routing.md", + "docs/truthmark/engineering/behaviors/session-timeout.md", ); - expect(skillBody).toContain("docs/routes/index.md:11"); + expect(skillBody).toContain("docs/routes/areas/authentication.md:11"); expect(skillBody).toContain( "verify only truth docs and leased truth routing files changed", ); @@ -280,22 +279,30 @@ describe("Truth Sync generated metadata", () => { 'short_description: "Sync truth docs from functional code changes; skip docs-only/no-code changes"', ); expect(metadata).toContain("allow_implicit_invocation: true"); - expect(renderTruthmarkCursorSyncRule()).toContain( + const cursorSyncPackage = renderTruthmarkSkillPackage({ + skillPath: ".cursor/skills/truthmark-sync/SKILL.md", + workflowId: "truthmark-sync", + host: "cursor", + }); + const cursorSyncSkill = + cursorSyncPackage.find((file) => file.path.endsWith("/SKILL.md"))?.content ?? ""; + const cursorSyncProcedure = + cursorSyncPackage.find((file) => file.path.endsWith("/support/procedure.md")) + ?.content ?? ""; + + expect(cursorSyncSkill).toContain( 'description: Use automatically at finish-time after functional code changes', ); + expect(cursorSyncSkill).toContain("Use as a Cursor Agent Skill."); + expect(cursorSyncSkill).toContain("support/procedure.md"); + expect(cursorSyncSkill).toContain("support/report-template.md"); expect(renderTruthmarkCopilotSyncPrompt()).toContain( "description: 'Use automatically at finish-time after functional code changes", ); - expect(renderTruthmarkCursorSyncRule()).toContain( - "This rule is the Cursor entrypoint for Truthmark Sync.", - ); expect(renderTruthmarkCopilotSyncPrompt()).toContain( "This prompt is the GitHub Copilot entrypoint for Truthmark Sync.", ); - for (const surface of [ - renderTruthmarkCursorSyncRule(), - renderTruthmarkCopilotSyncPrompt(), - ]) { + for (const surface of [renderTruthmarkCopilotSyncPrompt()]) { expect(surface).toContain( "If skill entrypoints are unavailable, use the host's direct evidence-first manual fallback procedure.", ); @@ -311,11 +318,8 @@ describe("Truth Sync generated metadata", () => { expect(renderTruthmarkCopilotSyncPrompt()).toContain( "support/report-template.md", ); - expect(renderTruthmarkCursorSyncRule()).not.toContain("support/procedure.md"); - expect(renderTruthmarkCursorSyncRule()).not.toContain( - "support/report-template.md", - ); - expect(renderTruthmarkCursorSyncRule()).not.toContain("Quick procedure:"); + expect(cursorSyncProcedure).toContain("Truthmark Sync Procedure"); + expect(cursorSyncProcedure).not.toContain("Report completion in this shape:"); }); it("adds host-specific subagent guidance without changing generic surfaces", () => { @@ -356,7 +360,14 @@ describe("Truth Sync generated metadata", () => { expect(renderTruthmarkSyncLocalSkill()).not.toContain( "Claude Code subagent mode:", ); - expect(renderTruthmarkCursorSyncRule()).not.toContain( + const cursorSyncProcedure = + renderTruthmarkSkillPackage({ + skillPath: ".cursor/skills/truthmark-sync/SKILL.md", + workflowId: "truthmark-sync", + host: "cursor", + }).find((file) => file.path.endsWith("/support/procedure.md"))?.content ?? ""; + + expect(cursorSyncProcedure).not.toContain( "Codex subagent mode:", ); expect(renderTruthmarkCopilotSyncPrompt()).not.toContain( diff --git a/tests/checks/check.test.ts b/tests/checks/check.test.ts index b8b81ea..c3ddb68 100644 --- a/tests/checks/check.test.ts +++ b/tests/checks/check.test.ts @@ -958,7 +958,7 @@ Update truth when: } }); - it("reports stale generated Cursor rule surfaces when configured", async () => { + it("reports stale generated Cursor skill surfaces when configured", async () => { const repo = await createTempRepo(); try { @@ -986,8 +986,8 @@ ignore: [] ); await runInit(repo.rootDir); await repo.writeFile( - ".cursor/rules/truthmark-sync.mdc", - `${await repo.readFile(".cursor/rules/truthmark-sync.mdc")}\n# stale\n`, + ".cursor/skills/truthmark-sync/SKILL.md", + `${await repo.readFile(".cursor/skills/truthmark-sync/SKILL.md")}\n# stale\n`, ); const result = await runCheck(repo.rootDir); @@ -997,7 +997,7 @@ ignore: [] expect.objectContaining({ category: "generated-surface", severity: "review", - file: ".cursor/rules/truthmark-sync.mdc", + file: ".cursor/skills/truthmark-sync/SKILL.md", message: expect.stringContaining("stale"), }), ]), diff --git a/tests/cli/validate.test.ts b/tests/cli/validate.test.ts index 882200f..3061c43 100644 --- a/tests/cli/validate.test.ts +++ b/tests/cli/validate.test.ts @@ -126,6 +126,39 @@ describe("truthmark validate CLI helpers", () => { } }); + it("rejects bootstrap-routing as a completed behavior-update target", async () => { + const repo = await createTempRepo(); + try { + await repo.writeFile( + "report.md", + validSyncReportWithIntent + .replace( + "docs/truthmark/truth/init-and-scaffold.md", + "docs/truthmark/engineering/repository/bootstrap-routing.md", + ) + .replace( + "docs/truthmark/truth/init-and-scaffold.md", + "docs/truthmark/engineering/repository/bootstrap-routing.md", + ), + ); + + const result = await runCli(["validate", "sync-report", "report.md", "--json"], { + cwd: repo.rootDir, + }); + const output = JSON.parse(result.stdout) as { + data?: { validation?: { ok: boolean; errors?: string[] } }; + }; + + expect(result.exitCode).toBe(1); + expect(output.data?.validation?.ok).toBe(false); + expect(output.data?.validation?.errors?.join("\n")).toContain( + "bootstrap-routing.md is a provisional topology handoff", + ); + } finally { + await repo.cleanup(); + } + }); + it("validates document reports through the Truthmark CLI", async () => { const repo = await createTempRepo(); try { diff --git a/tests/init/init-instructions.test.ts b/tests/init/init-instructions.test.ts index 53a3ebc..30e7fd1 100644 --- a/tests/init/init-instructions.test.ts +++ b/tests/init/init-instructions.test.ts @@ -90,7 +90,7 @@ ignore: [] } }); - it("removes retired generated surfaces from older versions", async () => { + it("removes auto-removable retired generated surfaces but preserves stale Gemini surfaces", async () => { const repo = await createTempRepo(); try { @@ -140,17 +140,17 @@ ignore: [] ).rejects.toThrow(); await expect( fs.stat(`${repo.rootDir}/.gemini/commands/truthmark/preview.toml`), - ).rejects.toThrow(); - await expect(fs.stat(`${repo.rootDir}/GEMINI.md`)).rejects.toThrow(); + ).resolves.toBeDefined(); + await expect(fs.stat(`${repo.rootDir}/GEMINI.md`)).resolves.toBeDefined(); await expect( fs.stat(`${repo.rootDir}/.gemini/skills/truthmark-sync/SKILL.md`), - ).rejects.toThrow(); + ).resolves.toBeDefined(); await expect( fs.stat(`${repo.rootDir}/.gemini/agents/truth-doc-writer.md`), - ).rejects.toThrow(); + ).resolves.toBeDefined(); await expect( fs.stat(`${repo.rootDir}/.gemini/commands/truthmark/sync.toml`), - ).rejects.toThrow(); + ).resolves.toBeDefined(); await expect( fs.stat(`${repo.rootDir}/.agents/skills/truthmark-sync/helper-manifest.yml`), ).rejects.toThrow(); diff --git a/tests/integration/agent-workflow-contract.test.ts b/tests/integration/agent-workflow-contract.test.ts index 39483cb..11ad78f 100644 --- a/tests/integration/agent-workflow-contract.test.ts +++ b/tests/integration/agent-workflow-contract.test.ts @@ -76,8 +76,8 @@ describe("installed workflow contract", () => { const antigravitySyncRule = await repo.readFile( ".antigravity/rules/truthmark-sync.md", ); - const cursorSyncRule = await repo.readFile( - ".cursor/rules/truthmark-sync.mdc", + const cursorSyncSkill = await repo.readFile( + ".cursor/skills/truthmark-sync/SKILL.md", ); expect(agents.split("\n").length).toBeLessThanOrEqual(20); @@ -163,7 +163,8 @@ describe("installed workflow contract", () => { await expect(repo.readFile(".gemini/skills/truthmark-sync/SKILL.md")).rejects.toThrow(); await expect(repo.readFile(".gemini/commands/truthmark/sync.toml")).rejects.toThrow(); expect(antigravitySyncRule).toContain("This rule is the Antigravity entrypoint"); - expect(cursorSyncRule).toContain("This rule is the Cursor entrypoint"); + expect(cursorSyncSkill).toContain("Use as a Cursor Agent Skill."); + expect(cursorSyncSkill).toContain("support/procedure.md"); expect(checkSkill).toContain("name: truthmark-check"); expect(checkSkill).toContain("support/report-template.md"); expect(checkSkill).toContain("support/subagents-and-leases.md"); diff --git a/tests/package-files.test.ts b/tests/package-files.test.ts index 1eb14a1..85c45ae 100644 --- a/tests/package-files.test.ts +++ b/tests/package-files.test.ts @@ -87,9 +87,7 @@ describe("package and release integrity", () => { it("includes localized README files linked from the published README", async () => { const tarballPaths = (await readPackFiles()).map((file) => file.path); - expect(tarballPaths).toEqual( - expect.arrayContaining(localizedReadmeFiles), - ); + expect(tarballPaths).toEqual(expect.arrayContaining(localizedReadmeFiles)); }); it("publishes only expected files with intentional executable modes", async () => { diff --git a/tests/templates/generated-surfaces.test.ts b/tests/templates/generated-surfaces.test.ts index 18120a1..d1405aa 100644 --- a/tests/templates/generated-surfaces.test.ts +++ b/tests/templates/generated-surfaces.test.ts @@ -4,6 +4,7 @@ import { join } from "node:path"; import { describe, expect, it } from "vitest"; import { createDefaultConfig } from "../../src/config/defaults.js"; +import { renderTruthSyncSkillBody } from "../../src/agents/truth-sync.js"; import { renderAgentsBlock } from "../../src/templates/agents-block.js"; import { renderGeneratedSurfaces } from "../../src/templates/generated-surfaces.js"; @@ -24,7 +25,7 @@ const portalPaths = [ ".github/skills/truthmark-portal/SKILL.md", ".github/prompts/truthmark-portal.prompt.md", ".antigravity/rules/truthmark-portal.md", - ".cursor/rules/truthmark-portal.mdc", + ".cursor/skills/truthmark-portal/SKILL.md", ]; const readOnlyProcedurePaths = [ @@ -92,8 +93,7 @@ describe("Truthmark Portal generated surfaces", () => { (surface) => surface.path.endsWith("/SKILL.md") || surface.path.startsWith(".github/prompts/") || - surface.path.startsWith(".antigravity/rules/") || - surface.path.startsWith(".cursor/rules/"), + surface.path.startsWith(".antigravity/rules/"), ); const forbiddenText = [ "## Optional local CLI validation", @@ -209,7 +209,9 @@ describe("Truthmark Portal generated surfaces", () => { expect(byPath.has(".gemini/skills/truthmark-sync/SKILL.md")).toBe(false); expect(byPath.has(".gemini/commands/truthmark/sync.toml")).toBe(false); expect(byPath.has(".antigravity/rules/truthmark-sync.md")).toBe(true); - expect(byPath.has(".cursor/rules/truthmark-sync.mdc")).toBe(true); + expect(byPath.has(".cursor/skills/truthmark-sync/SKILL.md")).toBe(true); + expect(byPath.has(".cursor/skills/truthmark-sync/support/procedure.md")).toBe(true); + expect(byPath.has(".cursor/skills/truthmark-sync/support/report-template.md")).toBe(true); expect(byPath.has(".agents/skills/truthmark-preview/agents/openai.yaml")).toBe( false, ); @@ -250,6 +252,62 @@ describe("Truthmark Portal generated surfaces", () => { expect(claudeProcedure).not.toContain("truthmark:adapter-mode=expanded-adapter"); }); + it("does not teach Sync to update bootstrap routing as behavior truth", () => { + const config = createDefaultConfig(); + config.platforms = [...allPlatforms]; + const renderedSurfaces = renderGeneratedSurfaces(config); + const generatedSyncReportSurfaces = renderedSurfaces.filter( + (surface) => + surface.path.endsWith("truthmark-sync/support/report-template.md") || + surface.path === ".antigravity/rules/truthmark-sync.md" || + surface.path === ".cursor/skills/truthmark-sync/support/report-template.md", + ); + const checkedInSyncReportPaths = [ + ".agents/skills/truthmark-sync/support/report-template.md", + ".opencode/skills/truthmark-sync/support/report-template.md", + ".claude/skills/truthmark-sync/support/report-template.md", + ".github/skills/truthmark-sync/support/report-template.md", + ".antigravity/rules/truthmark-sync.md", + ".cursor/skills/truthmark-sync/support/report-template.md", + ]; + const surfacesToCheck = [ + { path: "renderTruthSyncSkillBody", content: renderTruthSyncSkillBody(config) }, + ...generatedSyncReportSurfaces, + ...checkedInSyncReportPaths.map((path) => ({ + path, + content: readFileSync(join(process.cwd(), path), "utf8"), + })), + ]; + + expect(generatedSyncReportSurfaces.length).toBeGreaterThan(0); + for (const surface of surfacesToCheck) { + expect(surface.content, surface.path).toContain( + "docs/truthmark/routes/areas/authentication.md", + ); + expect(surface.content, surface.path).toContain( + "docs/truthmark/engineering/behaviors/session-timeout.md", + ); + expect(surface.content, surface.path).toContain( + "Changed code maps only to the provisional bootstrap route.", + ); + expect(surface.content, surface.path).toContain( + "Run Truth Structure for src/auth/** before updating behavior truth.", + ); + expect(surface.content, surface.path).not.toContain( + "- Target truth docs: docs/truthmark/engineering/repository/bootstrap-routing.md", + ); + expect(surface.content, surface.path).not.toContain( + [ + "Truth docs updated:", + "- docs/truthmark/engineering/repository/bootstrap-routing.md", + ].join("\n"), + ); + expect(surface.content, surface.path).not.toContain( + "Session timeout behavior is documented in the mapped repository truth doc.", + ); + } + }); + it("omits Portal surfaces and AGENTS wording when disabled", () => { const config = createDefaultConfig(); const paths = renderGeneratedSurfaces(config).map( @@ -287,7 +345,9 @@ describe("Truthmark Portal generated surfaces", () => { byPath.get(".github/prompts/truthmark-portal.prompt.md") ?? ""; const antigravityRule = byPath.get(".antigravity/rules/truthmark-portal.md") ?? ""; - const cursorRule = byPath.get(".cursor/rules/truthmark-portal.mdc") ?? ""; + const cursorSkill = byPath.get(".cursor/skills/truthmark-portal/SKILL.md") ?? ""; + const cursorProcedure = + byPath.get(".cursor/skills/truthmark-portal/support/procedure.md") ?? ""; const agentsBlock = renderAgentsBlock(config); for (const text of [portalSkill, portalProcedure]) { @@ -309,10 +369,10 @@ describe("Truthmark Portal generated surfaces", () => { expect(antigravityRule).toContain( "This rule is the Antigravity entrypoint for Truthmark Portal.", ); - expect(cursorRule).toContain( - "This rule is the Cursor entrypoint for Truthmark Portal.", - ); - expect(cursorRule).toContain("alwaysApply: false"); + expect(cursorSkill).toContain("Use as a Cursor Agent Skill."); + expect(cursorSkill).toContain(".cursor/skills/"); + expect(cursorSkill).toContain("Progressive disclosure:"); + expect(cursorProcedure).toContain("manual-only"); expect(portalProcedure).toContain("replace the entire output directory"); expect(portalProcedure).toContain("fixed Portal output directory only"); diff --git a/tests/workflow-state/build.test.ts b/tests/workflow-state/build.test.ts index f42665a..774114b 100644 --- a/tests/workflow-state/build.test.ts +++ b/tests/workflow-state/build.test.ts @@ -278,7 +278,7 @@ describe("buildWorkflowState", () => { expect(JSON.stringify(state)).not.toContain('"content":'); }); - it("authorizes sync to correct any indexed truth docs and routing files", async () => { + it("authorizes sync to correct signal-linked truth docs and routing files", async () => { const repo = await setupConfiguredRepo({ includeUnrelatedRoute: true }); repos.push(repo); @@ -292,14 +292,14 @@ describe("buildWorkflowState", () => { ]); expect(state.targetTruthDocs).toEqual(["docs/truthmark/engineering/repository/bootstrap-routing.md"]); expect(state.actionContext.allowedWritePaths).toEqual( - expect.arrayContaining([ + [ "docs/truthmark/engineering/repository/bootstrap-routing.md", - "docs/truthmark/engineering/unrelated.md", "docs/truthmark/routes/areas.md", "docs/truthmark/routes/areas/repository.md", "docs/truthmark/routes/areas/unrelated.md", - ]), + ], ); + expect(state.actionContext.candidateStaleTruthDocs).toEqual([]); }); it("does not expose a legacy ContextPack opt-in path", async () => {