Skip to content

Commit a93944f

Browse files
Merge pull request #101 from autogrammar/fix/ticket-085-participant-document-boundary
fix(ticket-085): isolate participant documentation
2 parents afdbebe + 5befbc9 commit a93944f

8 files changed

Lines changed: 118 additions & 13 deletions

File tree

TODO.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
## Active tickets
44

55
- [ ] [`ticket-085`](project/ticket-085/README.md) — scope documentation
6-
acceptance criteria to their governed source ticket. Current state:
6+
acceptance criteria to their governed source ticket and keep participant
7+
Markdown in the communication lane only. Current state:
78
`IN_PROGRESS / PUBLICATION`.
89
- [ ] [`ticket-083`](project/ticket-083/README.md) — keep workspace comparison
910
artifacts bounded and outside analysed repository state; live `PLF-8091`

project/ticket-085/README.md

Lines changed: 21 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

project/ticket-085/ai-codex-logs.txt

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

project/ticket-085/ai-codex.md

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

project/ticket-085/changelog.md

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

project/ticket-085/intent.json

Lines changed: 11 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/extractors/docs-deterministic.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,17 +98,27 @@ export async function extractDocumentationBaseline(
9898
const resolver = createMarkdownPathResolver(root);
9999

100100
for (const file of options.files) {
101+
const relative = relativePosix(root, file);
102+
// Governed participant files are the canonical communication channel and
103+
// are extracted by project-communication. Reading the same bytes again as
104+
// generic documentation creates two records with different heuristic
105+
// polarity, which can turn one statement into a blocking self-conflict.
106+
if (isGovernedParticipantDocument(relative)) continue;
101107
try {
102108
const body = await readText(file, config.maxFileBytes);
103109
records.push(...convertDocument(root, file, body, await primePathMapper(resolver, body)));
104110
} catch (error) {
105-
warnings.push(`${relativePosix(root, file)}: ${error instanceof Error ? error.message : String(error)}`);
111+
warnings.push(`${relative}: ${error instanceof Error ? error.message : String(error)}`);
106112
}
107113
}
108114

109115
return { records, warnings };
110116
}
111117

118+
function isGovernedParticipantDocument(relativePath: string): boolean {
119+
return /^project\/ticket-[0-9]+\/(?:ai|user)-[^/]+\.md$/i.test(relativePath);
120+
}
121+
112122
/**
113123
* Documentation prose names files exactly the way TODO and CHANGELOG do, and
114124
* until now was the one Markdown converter that kept the shorthand. On

test/docs.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,39 @@ test('governed ticket documentation keeps acceptance criteria local to its sourc
7070
.every((record) => !record.statement.target.tickets.includes('AC-01')));
7171
});
7272

73+
test('governed participant communication is not duplicated as documentation', async () => {
74+
const root = await fs.mkdtemp(path.join(os.tmpdir(), 't2c-docs-participant-boundary-'));
75+
const ticket = path.join(root, 'project', 'ticket-118');
76+
const participant = path.join(ticket, 'ai-codex.md');
77+
const readme = path.join(ticket, 'README.md');
78+
await fs.mkdir(ticket, { recursive: true });
79+
await fs.writeFile(participant, [
80+
'---',
81+
'participant-id: agent:codex',
82+
'participant: codex',
83+
'role: agent',
84+
'ticket: ticket-118',
85+
'---',
86+
'# Participant',
87+
'',
88+
'Control must reject transport authority and must not bypass `subactor`.',
89+
].join('\n'));
90+
await fs.writeFile(readme, [
91+
'# Ticket 118',
92+
'',
93+
'- Control must reject transport authority in `config/adopt.json`.',
94+
].join('\n'));
95+
96+
const result = await extractDocumentationBaseline({
97+
root,
98+
files: [participant, readme],
99+
}, makeConfig(root));
100+
101+
assert.equal(result.warnings.length, 0);
102+
assert.ok(result.records.length > 0);
103+
assert.ok(result.records.every((record) => record.source.path === 'project/ticket-118/README.md'));
104+
});
105+
73106
test('deterministic documentation preserves Polish prohibition polarity', async () => {
74107
const root = await fs.mkdtemp(path.join(os.tmpdir(), 't2c-docs-prohibition-'));
75108
const readme = path.join(root, 'README.md');

0 commit comments

Comments
 (0)