fix: keep repo-rules maintainer-local

This commit is contained in:
MerlinH
2026-08-23 23:33:41 +00:00
parent 4d3cf2922d
commit eab58413bb
14 changed files with 48 additions and 27 deletions
+1
View File
@@ -1 +1,2 @@
*.ts text diff
*.md text eol=lf
+2 -2
View File
@@ -7,7 +7,7 @@ Agent-specific:
- Use repository onboarding or docs-map files only when present and needed for unclear or cross-area routing.
<!-- repo-rules:start -->
<!-- Generated from docs/repo/ai/repo-rules.md by `npm run render:repo-rules`. Edit the source doc, not this block. -->
<!-- Generated from docs/repo/ai/repo-rules.md by `node --import tsx scripts/render-repo-rules.ts`. Edit the source doc, not this block. -->
## Authority
@@ -63,7 +63,7 @@ Agents inspect the active checkout directly. There is no daemon, database, remot
`AGENTS.md` and `CLAUDE.md` carry two generated regions, and neither is hand-edited:
- the `truthmark:start` / `truthmark:end` comment markers wrap the Truthmark workflow surface, refreshed by `truthmark init`
- the `repo-rules:start` / `repo-rules:end` comment markers wrap this file's always-on section, rendered by `npm run render:repo-rules`
- the `repo-rules:start` / `repo-rules:end` comment markers wrap this file's always-on section, rendered locally with `node --import tsx scripts/render-repo-rules.ts`
Marker names appear here without their comment syntax on purpose: a literal marker inside the rendered region would duplicate it in the instruction files and make the managed block unparseable.
+2 -2
View File
@@ -7,7 +7,7 @@ Agent-specific:
- Use repository onboarding or docs-map files only when present and needed for unclear or cross-area routing.
<!-- repo-rules:start -->
<!-- Generated from docs/repo/ai/repo-rules.md by `npm run render:repo-rules`. Edit the source doc, not this block. -->
<!-- Generated from docs/repo/ai/repo-rules.md by `node --import tsx scripts/render-repo-rules.ts`. Edit the source doc, not this block. -->
## Authority
@@ -63,7 +63,7 @@ Agents inspect the active checkout directly. There is no daemon, database, remot
`AGENTS.md` and `CLAUDE.md` carry two generated regions, and neither is hand-edited:
- the `truthmark:start` / `truthmark:end` comment markers wrap the Truthmark workflow surface, refreshed by `truthmark init`
- the `repo-rules:start` / `repo-rules:end` comment markers wrap this file's always-on section, rendered by `npm run render:repo-rules`
- the `repo-rules:start` / `repo-rules:end` comment markers wrap this file's always-on section, rendered locally with `node --import tsx scripts/render-repo-rules.ts`
Marker names appear here without their comment syntax on purpose: a literal marker inside the rendered region would duplicate it in the instruction files and make the managed block unparseable.
@@ -6,7 +6,7 @@ Version action: none
- Removed `github-copilot` from `.truthmark/config.yml`, let the init lifecycle prune the 29 generated surfaces it owned, and deleted the leftover `.github/copilot-instructions.md`. Copilot remains a supported platform of the product; only this repository's installation changed.
- Narrowed the checked-in path lists in `tests/templates/generated-surfaces.test.ts` to the platforms this repository installs. The `allPlatforms` render assertions keep full Copilot coverage.
- Added a generated `repo-rules:start` / `repo-rules:end` region to `AGENTS.md` and `CLAUDE.md`, rendered from the always-on section of `docs/repo/ai/repo-rules.md` by `npm run render:repo-rules`, so repository authority, documentation scope, product boundary, the numbered rules, and the completion gate survive context compaction.
- Added a generated `repo-rules:start` / `repo-rules:end` region to `AGENTS.md` and `CLAUDE.md`, rendered from the always-on section of `docs/repo/ai/repo-rules.md` by the local `node --import tsx scripts/render-repo-rules.ts` command, so repository authority, documentation scope, product boundary, the numbered rules, and the completion gate survive context compaction.
- Added `scripts/repo-rules-block.ts` and `scripts/render-repo-rules.ts`, plus `tests/repo-rules-block.test.ts` covering source sync, cross-file equality, marker ordering, link rewriting, malformed-marker rejection, managed-block round-trip, and idempotence.
- Rewrote the Instruction Surface Boundary rule to describe the two-region model, since the previous wording forbade the preamble duplication this change introduces.
- Included `scripts/**/*.ts` in `tsconfig.json` so the new repo-local tooling is typechecked.
+1 -1
View File
@@ -5,7 +5,7 @@ doc_type: agent-guide
last_reviewed: 2026-05-16
source_of_truth:
- repo-rules.md
- ../README.md
- ../../../README.md
---
# Agent Onboarding
+3 -3
View File
@@ -4,8 +4,8 @@ scope: repo-local
doc_type: agent-rules
last_reviewed: 2026-08-23
source_of_truth:
- ../../AGENTS.md
- ../README.md
- ../../../AGENTS.md
- ../../../README.md
- ../architecture/product-boundary.md
---
@@ -69,7 +69,7 @@ Agents inspect the active checkout directly. There is no daemon, database, remot
`AGENTS.md` and `CLAUDE.md` carry two generated regions, and neither is hand-edited:
- the `truthmark:start` / `truthmark:end` comment markers wrap the Truthmark workflow surface, refreshed by `truthmark init`
- the `repo-rules:start` / `repo-rules:end` comment markers wrap this file's always-on section, rendered by `npm run render:repo-rules`
- the `repo-rules:start` / `repo-rules:end` comment markers wrap this file's always-on section, rendered locally with `node --import tsx scripts/render-repo-rules.ts`
Marker names appear here without their comment syntax on purpose: a literal marker inside the rendered region would duplicate it in the instruction files and make the managed block unparseable.
+5 -5
View File
@@ -4,11 +4,11 @@ scope: repo-local
doc_type: architecture
last_reviewed: 2026-07-30
source_of_truth:
- ../../README.md
- ../truthmark/product/capabilities/agent-native-workflow-injection.md
- ../truthmark/product/capabilities/lane-separated-truth.md
- ../truthmark/engineering/architecture/overview.md
- ../truthmark/engineering/workflows/installed-workflow-runtime.md
- ../../../README.md
- ../../truthmark/product/capabilities/agent-native-workflow-injection.md
- ../../truthmark/product/capabilities/lane-separated-truth.md
- ../../truthmark/engineering/architecture/overview.md
- ../../truthmark/engineering/workflows/installed-workflow-runtime.md
---
# Truthmark Product Boundary
+1 -1
View File
@@ -4,7 +4,7 @@ scope: repo-local
doc_type: standard
last_reviewed: 2026-07-30
source_of_truth:
- ../README.md
- ../../../README.md
- documentation-governance.md
---
@@ -4,7 +4,7 @@ scope: repo-local
doc_type: standard
last_reviewed: 2026-07-30
source_of_truth:
- ../README.md
- ../../../README.md
- ../ai/repo-rules.md
---
@@ -4,7 +4,7 @@ scope: repo-local
doc_type: guide
last_reviewed: 2026-05-09
source_of_truth:
- ../README.md
- ../../../README.md
- documentation-governance.md
- testing-and-verification.md
---
@@ -4,8 +4,8 @@ scope: repo-local
doc_type: standard
last_reviewed: 2026-05-13
source_of_truth:
- ../../package.json
- ../truthmark/engineering/contracts/config-route-and-check-contracts.md
- ../../../package.json
- ../../truthmark/engineering/contracts/config-route-and-check-contracts.md
- versioning.md
---
+2 -2
View File
@@ -4,8 +4,8 @@ scope: repo-local
doc_type: standard
last_reviewed: 2026-05-16
source_of_truth:
- ../../package.json
- ../../package-lock.json
- ../../../package.json
- ../../../package-lock.json
- change-notes.md
- https://semver.org/
---
-1
View File
@@ -55,7 +55,6 @@
"format:check": "prettier --check eslint.config.js package.json package-lock.json tests/package-files.test.ts tsconfig.json",
"lint": "eslint .",
"package:check": "node --import tsx --test --test-concurrency=1 tests/package-files.test.ts",
"render:repo-rules": "tsx scripts/render-repo-rules.ts",
"release:check": "npm run lint && npm run format:check && npm run typecheck && npm run test && npm run build && npm run package:check && npm audit --omit=dev",
"test": "node --import tsx --test --test-concurrency=1 \"tests/**/*.test.ts\"",
"test:watch": "node --watch --import tsx --test --test-concurrency=1 \"tests/**/*.test.ts\"",
+26 -5
View File
@@ -16,10 +16,19 @@ export const INSTRUCTION_FILES = ["AGENTS.md", "CLAUDE.md"];
const ALWAYS_ON_START = "<!-- always-on:start -->";
const ALWAYS_ON_END = "<!-- always-on:end -->";
const GENERATED_NOTICE = `<!-- Generated from ${REPO_RULES_SOURCE} by \`npm run render:repo-rules\`. Edit the source doc, not this block. -->`;
const GENERATED_NOTICE = `<!-- Generated from ${REPO_RULES_SOURCE} by \`node --import tsx scripts/render-repo-rules.ts\`. Edit the source doc, not this block. -->`;
const sourceDir = path.posix.dirname(REPO_RULES_SOURCE);
const normalizeLineEndings = (content: string): string =>
content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
const lineEndingFor = (content: string): "\n" | "\r\n" =>
content.includes("\r\n") ? "\r\n" : "\n";
const withLineEnding = (content: string, lineEnding: "\n" | "\r\n"): string =>
normalizeLineEndings(content).replace(/\n/g, lineEnding);
/**
* Rewrites links that were relative to the source doc so they resolve from the
* repository root, where the instruction files live.
@@ -101,17 +110,29 @@ export const upsertRepoRulesBlock = (
const current = extractRepoRulesBlock(existingContent);
if (current !== null) {
return existingContent.replace(current, block);
if (normalizeLineEndings(current) === normalizeLineEndings(block)) {
return existingContent;
}
return existingContent.replace(
current,
withLineEnding(block, lineEndingFor(existingContent)),
);
}
const lineEnding = lineEndingFor(existingContent);
const renderedBlock = withLineEnding(block, lineEnding);
const truthmarkStart = existingContent.indexOf("<!-- truthmark:start -->");
if (truthmarkStart === -1) {
return `${existingContent.replace(/\n+$/u, "")}\n\n${block}\n`;
return `${existingContent.replace(/(?:\r\n|\r|\n)+$/u, "")}${lineEnding}${lineEnding}${renderedBlock}${lineEnding}`;
}
const before = existingContent.slice(0, truthmarkStart).replace(/\n+$/u, "");
const before = existingContent
.slice(0, truthmarkStart)
.replace(/(?:\r\n|\r|\n)+$/u, "");
const after = existingContent.slice(truthmarkStart);
return `${before}\n\n${block}\n\n${after}`;
return `${before}${lineEnding}${lineEnding}${renderedBlock}${lineEnding}${lineEnding}${after}`;
};