@crossplatformai/skills
Version:
Reusable Agent Skills for CrossPlatform.ai projects.
544 lines (491 loc) • 15 kB
JavaScript
import { createHash } from 'node:crypto';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import process from 'node:process';
import { pathToFileURL } from 'node:url';
const MODES = new Set(['portable', 'managed']);
const TIERS = new Set([1, 2, 3]);
const SECTION_ALIASES = {
objective: /\b(objective|evidence|goal|intent|context|problem|brief|why)\b/i,
outcomes:
/\b(outcomes?|proof|acceptance|success|done|results?|verification)\b/i,
scope: /\b(scope|boundar(?:y|ies)|non-goals?|included|excluded|edges?)\b/i,
risks: /\b(risks?|rules?|constraints?|assumptions?|guardrails?)\b/i,
execution:
/\b(execution|implementation|quality|qa|validation|tests?|commands?|delivery|how|establish)\b/i,
};
const MANAGED_IDENTITIES = [
'userConfirmedIntent',
'repositoryVerifiedFacts',
'primaryPlannerRecommendations',
'unresolvedQuestionsDisposition',
'uxImpact',
'dxImpact',
'experienceEvidence',
'scopeAndNonGoals',
'constraintsAndRepositoryRules',
'risksAndResolvedAssumptions',
'recommendationProvenance',
'noUnresolvedImplementationDecision',
'uxDxClaimToProofMapping',
];
/** @typedef {'portable' | 'managed'} AdmissionMode */
/** @typedef {1 | 2 | 3} RiskTier */
/** @typedef {{ code: string, message: string }} Diagnostic */
/**
* Normalize transport-only differences while preserving substantive Markdown.
*
* @param {string} input
*/
export function normalizeTransport(input) {
const lines = input
.replace(/^\uFEFF/, '')
.replace(/\r\n?/g, '\n')
.split('\n')
.map((line) => line.replace(/[\t ]+$/u, ''));
while (lines[0] === '') lines.shift();
while (lines.at(-1) === '') lines.pop();
return `${lines.join('\n')}\n`;
}
/**
* @param {string} input
*/
export function digestInput(input) {
return `sha256:${createHash('sha256').update(normalizeTransport(input)).digest('hex')}`;
}
/**
* @param {string} value
*/
function isPlaceholder(value) {
const compact = value
.replace(/^[-*+]\s+/gmu, '')
.replace(/[`*_#]/gu, '')
.trim();
return (
compact.length < 8 ||
/^(?:n\/?a|none|unknown|tbd|todo|pending|unchanged|not collected)[.!]?$/iu.test(
compact,
)
);
}
/**
* @param {string} input
*/
function collectSections(input) {
/** @type {Array<{ heading: string, body: string }>} */
const sections = [];
let heading = '';
/** @type {string[]} */
let body = [];
const push = () => {
if (heading) sections.push({ heading, body: body.join('\n').trim() });
};
for (const line of input.split('\n')) {
const markdownHeading = line.match(/^#{1,6}\s+(.+?)\s*#*$/u);
const labelHeading = line.match(
/^\s*(?:\*\*)?([A-Za-z][A-Za-z /&-]{2,60})(?:\*\*)?\s*:\s*$/u,
);
if (markdownHeading || labelHeading) {
push();
heading = (markdownHeading?.[1] ?? labelHeading?.[1] ?? '').trim();
body = [];
continue;
}
body.push(line);
}
push();
return sections;
}
/**
* @param {string} input
*/
function sectionCoverage(input) {
const sections = collectSections(input);
/** @type {Record<keyof typeof SECTION_ALIASES, boolean>} */
const coverage = {
objective: false,
outcomes: false,
scope: false,
risks: false,
execution: false,
};
for (const section of sections) {
for (const [identity, alias] of Object.entries(SECTION_ALIASES)) {
if (alias.test(section.heading) && !isPlaceholder(section.body)) {
coverage[/** @type {keyof typeof SECTION_ALIASES} */ (identity)] = true;
}
}
}
coverage.objective ||=
/^\s*(?:[-*]\s*)?(?:objective|goal|user intent)\s*:\s*\S.{7,}$/imu.test(
input,
);
coverage.outcomes ||=
/^\s*(?:[-*]\s*)?(?:acceptance criteria|outcome|done when|proof|success)\s*:\s*\S.{7,}$/imu.test(
input,
);
coverage.scope ||=
/^\s*(?:[-*]\s*)?(?:in scope|out of scope|scope(?: and non-goals?)?|non-goals?)\s*:\s*\S.{3,}$/imu.test(
input,
);
coverage.risks ||=
/^\s*(?:[-*]\s*)?(?:risks?|rules?|constraints?)\s*:\s*\S.{3,}$/imu.test(
input,
);
coverage.execution ||=
/^\s*(?:[-*]\s*)?(?:execution|qa|validation|commands?|implementation)\s*:\s*\S.{3,}$/imu.test(
input,
);
return coverage;
}
/**
* @param {string} input
* @param {AdmissionMode} mode
*/
function hasAuthorizingUserAuthority(input, mode) {
const explicitAuthority = input.split('\n').some((line) => {
if (!/(?:authorizing user|product owner)/iu.test(line)) return false;
if (
/(?:authorizing user|product owner).{0,40}\b(?:not approved|unapproved|missing|absent|denied|pending)\b/iu.test(
line,
) ||
/\b(?:not approved|unapproved|missing|absent|denied|pending)\b.{0,40}(?:authorizing user|product owner)/iu.test(
line,
)
) {
return false;
}
return /\b(?:approv(?:ed|al)|authoriz(?:ed|ation)|confirm(?:ed|ation)|granted)\b/iu.test(
line,
);
});
return (
explicitAuthority ||
(mode === 'managed' &&
/^\s*(?:[-*]\s*)?(?:approval )?authority source\s*(?::|-)\s*(?:fresh-context user launch|explicit same-window post-review approval|legacy preflight launch with an explicit implementation instruction|approved-plan launch)\b/imu.test(
input,
))
);
}
/**
* @param {string} input
*/
function hasUnresolvedProductDecision(input) {
return input
.split('\n')
.some((line) =>
/^\s*(?:[-*]\s*)?(?:(?:unresolved|open)\s+(?:product\s+)?(?:decision|question)s?|(?:product\s+)?decision status)\s*(?::|-)\s*(?!none\b|resolved\b|no\b)(?:\S)/iu.test(
line,
),
);
}
/**
* @param {string} input
* @param {RegExp} label
*/
function collectBoundaryItems(input, label) {
const items = new Set();
for (const line of input.split('\n')) {
const match = line.match(label);
if (!match?.[1]) continue;
for (const item of match[1].split(/[,;|]/u)) {
const normalized = item
.toLowerCase()
.replace(/[`*_]/gu, '')
.replace(/^(?:the|a|an)\s+/u, '')
.replace(/[^a-z0-9@/_. -]/gu, '')
.trim();
if (normalized.length >= 3) items.add(normalized);
}
}
return items;
}
/**
* @param {string} input
*/
function hasScopeOrRiskContradiction(input) {
if (
/^\s*(?:[-*]\s*)?(?:scope|risk|boundary)\s+(?:contradiction|conflict)(?:\s+status)?\s*(?::|-)\s*(?:yes|present|unresolved|open)\b/imu.test(
input,
)
) {
return true;
}
const included = collectBoundaryItems(
input,
/^\s*(?:[-*]\s*)?(?:in scope|included)\s*:\s*(.+)$/iu,
);
const excluded = collectBoundaryItems(
input,
/^\s*(?:[-*]\s*)?(?:out of scope|excluded|non-goals?)\s*:\s*(.+)$/iu,
);
return [...included].some((item) => excluded.has(item));
}
/**
* @param {string} input
*/
function hasUnmetExternalPrerequisite(input) {
return /^\s*(?:[-*]\s*)?(?:external\s+)?prerequisites?\s*(?::|-)\s*(?:unmet|missing|unavailable|blocked|pending)\b/imu.test(
input,
);
}
/**
* @param {string} input
*/
function hasUnavailableRequiredExecution(input) {
return (
/^\s*(?:[-*]\s*)?(?:required\s+)?(?:command execution|commands?|execution capability|tooling)\s*(?::|-)\s*(?:unavailable|missing|cannot run|blocked)\b/imu.test(
input,
) ||
/^\s*(?:[-*]\s*)?required\s+(?:command|tool)\b.{0,80}\b(?:unavailable|missing|cannot run)\b/imu.test(
input,
)
);
}
/**
* @param {string} input
*/
function hasFailedRequiredQa(input) {
return /^\s*(?:[-*]\s*)?(?:required\s+qa|qa\s+status|required\s+(?:checks?|tests?))\s*(?::|-)\s*(?:failed|failing|unavailable|blocked)\b/imu.test(
input,
);
}
/**
* @param {string} input
* @param {{ mode?: AdmissionMode, tier?: RiskTier }} [options]
*/
export function admitPacket(input, options = {}) {
const mode = options.mode ?? 'portable';
const tier = options.tier ?? 2;
const normalized = normalizeTransport(input);
const coverage = sectionCoverage(normalized);
/** @type {Diagnostic[]} */
const blockers = [];
/** @type {Diagnostic[]} */
const warnings = [];
/** @type {Diagnostic[]} */
const defaults = [];
if (!hasAuthorizingUserAuthority(normalized, mode)) {
blockers.push({
code: 'missing-authorizing-user-authority',
message:
'Record Authorizing User approval for this objective before Build.',
});
}
if (!coverage.objective) {
blockers.push({
code: 'missing-objective',
message:
'State the accepted objective and enough evidence to implement it.',
});
}
if (hasUnresolvedProductDecision(normalized)) {
blockers.push({
code: 'unresolved-product-decision',
message: 'Resolve the open product decision before Build.',
});
}
if (!coverage.outcomes) {
blockers.push({
code: 'missing-acceptance-outcomes',
message:
'Add observable acceptance outcomes and the proof that will establish them.',
});
}
if (!coverage.scope) {
blockers.push({
code: 'missing-material-boundaries',
message: 'State the material scope and boundaries for the objective.',
});
}
if (hasScopeOrRiskContradiction(normalized)) {
blockers.push({
code: 'contradictory-scope-or-risk',
message:
'Resolve contradictory scope, boundary, or risk statements before Build.',
});
}
if (hasUnmetExternalPrerequisite(normalized)) {
blockers.push({
code: 'unmet-external-prerequisite',
message:
'Satisfy or explicitly remove the current external prerequisite before Build.',
});
}
if (hasUnavailableRequiredExecution(normalized)) {
blockers.push({
code: 'required-execution-unavailable',
message:
'Restore the command capability required to implement or verify this objective.',
});
}
if (hasFailedRequiredQa(normalized)) {
blockers.push({
code: 'required-qa-failed',
message: 'Resolve the failed required QA before admission.',
});
}
const normalizedLabels = Object.entries(coverage)
.filter(([, present]) => present)
.map(([identity]) => identity);
if (normalizedLabels.length > 0 && normalizedLabels.length < 5) {
warnings.push({
code: 'compact-section-normalization',
message:
'Substantive content was normalized into the compact Post sections despite presentation differences.',
});
}
if (!coverage.risks) {
defaults.push({
code: 'no-additional-risk-rules',
message:
'No additional risk rule was declared; repository rules and stated boundaries apply.',
});
}
if (!coverage.execution) {
defaults.push({
code: 'adaptive-execution-and-qa',
message:
'Build selects implementation tactics and a proportionate final QA manifest from the completed diff.',
});
}
if (!/\broadmap\b/iu.test(normalized)) {
defaults.push({
code: 'no-roadmap-dependency',
message: 'No roadmap dependency is assumed for this objective.',
});
}
if (mode === 'managed') {
defaults.push({
code: 'managed-pbs-v1-identity-map',
message: `Normalize the compact packet to Workspace PBS v1 identities: ${MANAGED_IDENTITIES.join(', ')}.`,
});
}
return {
inputDigest: digestInput(normalized),
mode,
tier,
blockers,
warnings,
defaults,
};
}
/**
* @param {string[]} argv
*/
function parseArguments(argv) {
/** @type {{ file?: string, mode: AdmissionMode, tier: RiskTier, json: boolean, help: boolean }} */
const parsed = {
mode: 'portable',
tier: 2,
json: false,
help: false,
};
for (let index = 0; index < argv.length; index += 1) {
const argument = argv[index];
if (argument === '--json') {
parsed.json = true;
} else if (argument === '--help' || argument === '-h') {
parsed.help = true;
} else if (argument === '--file') {
const file = argv[index + 1];
if (!file || file.startsWith('--'))
throw new Error('--file requires a path');
parsed.file = file;
index += 1;
} else if (argument === '--mode') {
const mode = argv[index + 1];
if (!mode || !MODES.has(mode)) {
throw new Error('--mode must be portable or managed');
}
parsed.mode = /** @type {AdmissionMode} */ (mode);
index += 1;
} else if (argument === '--tier') {
const tier = Number(argv[index + 1]);
if (!TIERS.has(tier)) throw new Error('--tier must be 1, 2, or 3');
parsed.tier = /** @type {RiskTier} */ (tier);
index += 1;
} else {
throw new Error(`unknown argument: ${argument}`);
}
}
return parsed;
}
const USAGE = `Usage: pbs-admit [--file <path>] [--mode portable|managed] [--tier 1|2|3] [--json]
Reads a Post packet from --file or stdin. It performs no writes, Git operations, or network calls.`;
/**
* @param {ReturnType<typeof admitPacket>} result
*/
function formatHumanResult(result) {
const lines = [
result.blockers.length === 0
? 'PBS admission: accepted'
: 'PBS admission: blocked',
`Input digest: ${result.inputDigest}`,
`Mode: ${result.mode}`,
`Risk tier: ${result.tier}`,
];
for (const [label, diagnostics] of [
['Blockers', result.blockers],
['Warnings', result.warnings],
['Defaults', result.defaults],
]) {
lines.push(`${label}:`);
if (diagnostics.length === 0) {
lines.push('- none');
} else {
lines.push(
...diagnostics.map((item) => `- ${item.code}: ${item.message}`),
);
}
}
return lines.join('\n');
}
/**
* @param {string[]} argv
*/
export function run(argv) {
let parsed;
try {
parsed = parseArguments(argv);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
const wantsJson = argv.includes('--json');
process.stderr.write(
wantsJson
? `${JSON.stringify({ error: message })}\n`
: `${message}\n${USAGE}\n`,
);
return 2;
}
if (parsed.help) {
process.stdout.write(`${USAGE}\n`);
return 0;
}
let input;
try {
input = parsed.file
? readFileSync(resolve(parsed.file), 'utf8')
: readFileSync(0, 'utf8');
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
process.stderr.write(
parsed.json
? `${JSON.stringify({ error: `unable to read input: ${message}` })}\n`
: `unable to read input: ${message}\n`,
);
return 2;
}
const result = admitPacket(input, { mode: parsed.mode, tier: parsed.tier });
process.stdout.write(
parsed.json
? `${JSON.stringify(result)}\n`
: `${formatHumanResult(result)}\n`,
);
return result.blockers.length === 0 ? 0 : 1;
}
const isDirectExecution =
process.argv[1] &&
import.meta.url === pathToFileURL(resolve(process.argv[1])).href;
if (isDirectExecution) process.exitCode = run(process.argv.slice(2));