openvibers/openvibe.blog Commits
Patch notes: a large diff is not a feature (#136)
Changes
@@@ -70,13 +70,14 @@ function intentOf(entry) {const slug = String(trailer[1]).toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 40);const known = INTENTS.some(([key]) => key === slug) || ['docs', 'chore'].includes(slug) ? slug : `ws:${slug || 'workstream'}`;const face = /^\s*Player-facing\s*:\s*yes/im.test(body);-- return { intent: known, kind: face ? 'feature' : entry.major ? 'feature' : 'fix', explicit: true };++ return { intent: known, kind: face ? 'feature' : 'fix', explicit: true };}const subject = normaliseSubject(entry);if (DOCS.test(subject)) return { intent: 'docs', kind: 'chore' };for (const [key, re, kind] of INTENTS) if (re.test(subject)) return { intent: key, kind };if (CHORE.test(subject)) return { intent: 'chore', kind: 'chore' };-- if (entry.major) return { intent: 'other', kind: 'feature' };++ // A large diff is not a feature (devblog §3.2 step 6): only the subject decides whether a change with no++ // workstream has a surface a reader can see.return { intent: 'other', kind: USER_FACING.test(subject) ? 'feature' : 'internal' };}@@@ -36,6 +36,8 @@ const entry = (service, sha, subject, body = null) => ({assert.strictEqual(intentOf({ service: 'network', repo: 'OpenVibers/OpenVibe.Network', subject: 'The site switcher follows the account (#430)' }).kind, 'feature');assert.strictEqual(intentOf({ service: 'bench', repo: 'OpenVibers/OpenVibe.Bench', subject: 'Generation: a token cap per showcase kind (#17)' }).kind, 'internal');assert.strictEqual(intentOf({ service: 'codes', repo: 'OpenVibers/OpenVibe.Codes', subject: 'engine/: the agent engine, ported from the portal (C1) (#159)' }).kind, 'internal');++ assert.strictEqual(intentOf({ service: 'blog', repo: 'OpenVibers/OpenVibe.Blog', subject: 'Patch notes v2: commits become stories, and a person publishes them (#131)', major: 1 }).kind, 'internal', 'a large diff is not a feature');++ assert.strictEqual(intentOf({ service: 'blog', repo: 'OpenVibers/OpenVibe.Blog', subject: 'patch notes: one-off changes get a line, and the full list is not prose (#134)', major: 1 }).kind, 'internal');});await check('a product name in a sourced line is not the writer\'s slop; the story still is', async () => {
@@ -70,13 +70,14 @@ function intentOf(entry) {
@@ -70,13 +70,14 @@ function intentOf(entry) {
const slug = String(trailer[1]).toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 40);
const slug = String(trailer[1]).toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 40);
const known = INTENTS.some(([key]) => key === slug) || ['docs', 'chore'].includes(slug) ? slug : `ws:${slug || 'workstream'}`;
const known = INTENTS.some(([key]) => key === slug) || ['docs', 'chore'].includes(slug) ? slug : `ws:${slug || 'workstream'}`;
const face = /^\s*Player-facing\s*:\s*yes/im.test(body);
const face = /^\s*Player-facing\s*:\s*yes/im.test(body);
- return { intent: known, kind: face ? 'feature' : entry.major ? 'feature' : 'fix', explicit: true };
+ return { intent: known, kind: face ? 'feature' : 'fix', explicit: true };
}
}
const subject = normaliseSubject(entry);
const subject = normaliseSubject(entry);
if (DOCS.test(subject)) return { intent: 'docs', kind: 'chore' };
if (DOCS.test(subject)) return { intent: 'docs', kind: 'chore' };
for (const [key, re, kind] of INTENTS) if (re.test(subject)) return { intent: key, kind };
for (const [key, re, kind] of INTENTS) if (re.test(subject)) return { intent: key, kind };
if (CHORE.test(subject)) return { intent: 'chore', kind: 'chore' };
if (CHORE.test(subject)) return { intent: 'chore', kind: 'chore' };
- if (entry.major) return { intent: 'other', kind: 'feature' };
+ // A large diff is not a feature (devblog §3.2 step 6): only the subject decides whether a change with no
+ // workstream has a surface a reader can see.
return { intent: 'other', kind: USER_FACING.test(subject) ? 'feature' : 'internal' };
return { intent: 'other', kind: USER_FACING.test(subject) ? 'feature' : 'internal' };
}
}
@@ -36,6 +36,8 @@ const entry = (service, sha, subject, body = null) => ({
@@ -36,6 +36,8 @@ const entry = (service, sha, subject, body = null) => ({
assert.strictEqual(intentOf({ service: 'network', repo: 'OpenVibers/OpenVibe.Network', subject: 'The site switcher follows the account (#430)' }).kind, 'feature');
assert.strictEqual(intentOf({ service: 'network', repo: 'OpenVibers/OpenVibe.Network', subject: 'The site switcher follows the account (#430)' }).kind, 'feature');
assert.strictEqual(intentOf({ service: 'bench', repo: 'OpenVibers/OpenVibe.Bench', subject: 'Generation: a token cap per showcase kind (#17)' }).kind, 'internal');
assert.strictEqual(intentOf({ service: 'bench', repo: 'OpenVibers/OpenVibe.Bench', subject: 'Generation: a token cap per showcase kind (#17)' }).kind, 'internal');
assert.strictEqual(intentOf({ service: 'codes', repo: 'OpenVibers/OpenVibe.Codes', subject: 'engine/: the agent engine, ported from the portal (C1) (#159)' }).kind, 'internal');
assert.strictEqual(intentOf({ service: 'codes', repo: 'OpenVibers/OpenVibe.Codes', subject: 'engine/: the agent engine, ported from the portal (C1) (#159)' }).kind, 'internal');
+ assert.strictEqual(intentOf({ service: 'blog', repo: 'OpenVibers/OpenVibe.Blog', subject: 'Patch notes v2: commits become stories, and a person publishes them (#131)', major: 1 }).kind, 'internal', 'a large diff is not a feature');
+ assert.strictEqual(intentOf({ service: 'blog', repo: 'OpenVibers/OpenVibe.Blog', subject: 'patch notes: one-off changes get a line, and the full list is not prose (#134)', major: 1 }).kind, 'internal');
});
});
await check('a product name in a sourced line is not the writer\'s slop; the story still is', async () => {
await check('a product name in a sourced line is not the writer\'s slop; the story still is', async () => {