From c16190acf13e84c64db87979bd82bf712f54f539 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 00:57:22 -0700 Subject: [PATCH 01/15] feat(msdmd): collect org-wide repository map --- scripts/fetch-org-msdmd.mjs | 521 ++++++++++++++++++++++++++++++++++++ 1 file changed, 521 insertions(+) create mode 100644 scripts/fetch-org-msdmd.mjs diff --git a/scripts/fetch-org-msdmd.mjs b/scripts/fetch-org-msdmd.mjs new file mode 100644 index 0000000..ec5994b --- /dev/null +++ b/scripts/fetch-org-msdmd.mjs @@ -0,0 +1,521 @@ +import { execFileSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; +import { pathToFileURL } from 'node:url'; + +// === MODULE_BUILD === +// id: organization_msdmd_map_collector +// purpose: Join repo-owned msdmd collection points into one provenance-bearing organization map without transferring source authority to the website. +// entrypoint: npm run refresh:msdmd +// tests: tests/org-msdmd.test.mjs +// === END MODULE_BUILD === +// === BOUNDARIES === +// id: organization_msdmd_source_boundary +// network: reads only commit-pinned raw.githubusercontent.com collection files named _msdmd.ts; repository heads come from the prior GitHub metadata refresh +// storage: writes generated and last-known-good JSON snapshots only +// authority: repository collection points remain source authority; this module namespaces, resolves, aggregates, and displays their declared relations +// failure: missing, invalid, stale, and unresolved inputs remain explicit hmmm evidence and are never silently omitted +// === END BOUNDARIES === +// === CONTRACTS === +// id: organization_msdmd_exact_input_identity +// given: a repository head and collection file are consumed +// then: repository, exact head SHA, collection path, collection SHA-256, declared source commit, and match status remain in the output receipt +// class: evidence +// +// id: organization_msdmd_no_inferred_edges +// given: an msdmd edge target cannot be resolved exactly by local id, explicit repository identity, or globally unique declaration id +// then: the edge is retained unresolved rather than guessed +// class: safety +// +// id: organization_msdmd_reproducible_snapshot +// given: repository heads and collection bytes do not change +// then: the emitted JSON is byte-identical because no wall-clock build timestamp enters the artifact +// class: correctness +// === END CONTRACTS === +// Usage: run after `npm run refresh:github`. The generated artifact is consumed by /projects/map/ and copied to /assets/data/org-msdmd.json. + +const ORGANIZATION = 'The-Interdependency'; +const RAW_GITHUB_ORIGIN = 'https://raw.githubusercontent.com'; +const GENERATED_REPOS = 'src/_data/generated/repos.json'; +const GENERATED_OUT = 'src/_data/generated/orgMsdmd.json'; +const SNAPSHOT_OUT = 'src/_data/snapshots/org-msdmd.last-known-good.json'; +const COLLECTION_SUFFIX = '_msdmd.ts'; +const COLLECTION_MARKER = 'defineMsdmdCollection('; + +function sha256(value) { + return createHash('sha256').update(value).digest('hex'); +} + +function stableJson(value) { + return `${JSON.stringify(value, null, 2)}\n`; +} + +function rawGithubUrl(repo, commit, path) { + const parts = [ORGANIZATION, repo, commit, ...String(path).split('/')].map(encodeURIComponent); + return new URL(`/${parts.join('/')}`, RAW_GITHUB_ORIGIN); +} + +function getText(target) { + const url = target instanceof URL ? target : new URL(target); + if (url.protocol !== 'https:' || url.origin !== RAW_GITHUB_ORIGIN) { + throw new Error(`refusing non-raw-GitHub target: ${url.origin}`); + } + return execFileSync( + 'curl', + ['-fsSL', '--retry', '2', '--max-time', '20', url.href], + { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] } + ); +} + +export function stripComments(text) { + let out = ''; + let quote = ''; + for (let i = 0; i < text.length;) { + const ch = text[i]; + if (quote) { + out += ch; + if (ch === '\\' && i + 1 < text.length) { + out += text[i + 1]; + i += 2; + continue; + } + if (ch === quote) quote = ''; + i += 1; + continue; + } + if (ch === '"' || ch === "'") { + quote = ch; + out += ch; + i += 1; + continue; + } + if (ch === '/' && text[i + 1] === '/') { + i += 2; + while (i < text.length && text[i] !== '\n') i += 1; + continue; + } + if (ch === '/' && text[i + 1] === '*') { + const end = text.indexOf('*/', i + 2); + i = end < 0 ? text.length : end + 2; + continue; + } + out += ch; + i += 1; + } + return out; +} + +export function extractCollectionPayload(text) { + const start = text.indexOf(COLLECTION_MARKER); + if (start < 0) throw new Error('collection marker not found'); + const payloadStart = start + COLLECTION_MARKER.length; + let depth = 1; + let quote = ''; + for (let i = payloadStart; i < text.length; i += 1) { + const ch = text[i]; + if (quote) { + if (ch === '\\') { + i += 1; + continue; + } + if (ch === quote) quote = ''; + continue; + } + if (ch === '"' || ch === "'") { + quote = ch; + continue; + } + if (ch === '(') depth += 1; + if (ch === ')') { + depth -= 1; + if (depth === 0) return text.slice(payloadStart, i); + } + } + throw new Error('unterminated collection call'); +} + +function readQuoted(text, start) { + const quote = text[start]; + let value = ''; + for (let i = start + 1; i < text.length; i += 1) { + const ch = text[i]; + if (ch === quote) return { json: JSON.stringify(value), next: i + 1 }; + if (ch !== '\\') { + value += ch; + continue; + } + if (i + 1 >= text.length) throw new Error('unterminated string escape'); + const next = text[++i]; + const escapes = { n: '\n', r: '\r', t: '\t', b: '\b', f: '\f', v: '\v', '0': '\0' }; + if (next === 'u') { + const hex = text.slice(i + 1, i + 5); + if (!/^[0-9a-fA-F]{4}$/.test(hex)) throw new Error('invalid unicode escape'); + value += String.fromCharCode(Number.parseInt(hex, 16)); + i += 4; + } else if (next === 'x') { + const hex = text.slice(i + 1, i + 3); + if (!/^[0-9a-fA-F]{2}$/.test(hex)) throw new Error('invalid hex escape'); + value += String.fromCharCode(Number.parseInt(hex, 16)); + i += 2; + } else { + value += escapes[next] ?? next; + } + } + throw new Error('unterminated quoted string'); +} + +export function objectLiteralToJson(text) { + let out = ''; + for (let i = 0; i < text.length;) { + const ch = text[i]; + if (ch === '"' || ch === "'") { + const quoted = readQuoted(text, i); + out += quoted.json; + i = quoted.next; + continue; + } + const match = /^[A-Za-z_$][A-Za-z0-9_$]*/.exec(text.slice(i)); + if (match) { + const ident = match[0]; + let j = i + ident.length; + while (/\s/.test(text[j] || '')) j += 1; + out += text[j] === ':' ? JSON.stringify(ident) : ident; + i += ident.length; + continue; + } + out += ch; + i += 1; + } + return out.replace(/,\s*([}\]])/g, '$1'); +} + +export function parseCollectionText(text) { + const stripped = stripComments(String(text)).trim(); + if (stripped.startsWith('{')) return JSON.parse(stripped); + const payload = extractCollectionPayload(stripped).trim(); + try { + return JSON.parse(payload); + } catch { + return JSON.parse(objectLiteralToJson(payload)); + } +} + +function normalizeRepoName(value) { + const name = String(value || ''); + if (!/^[A-Za-z0-9_.-]{1,100}$/.test(name)) throw new Error(`invalid repository name: ${name}`); + return name; +} + +function normalizeDeclaration(repoName, declaration) { + const localId = String(declaration?.id || '').trim(); + if (!localId) return null; + return { + id: `${repoName}::${localId}`, + localId, + repo: repoName, + file: String(declaration?.file || 'hmmm'), + block: String(declaration?.block || 'hmmm'), + fields: declaration?.fields && typeof declaration.fields === 'object' ? declaration.fields : {} + }; +} + +function explicitRepoTarget(target, repoNames) { + if (repoNames.has(target)) return { repo: target, declaration: null }; + const full = new RegExp(`^${ORGANIZATION.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/([^@#:\\s/]+)(?:@[^#:\\s]+)?(?:#{1}|::)(.+)$`).exec(target); + if (full && repoNames.has(full[1])) return { repo: full[1], declaration: full[2].trim() || null }; + const fullRepo = new RegExp(`^${ORGANIZATION.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/([^@#:\\s/]+)(?:@[^#:\\s]+)?$`).exec(target); + if (fullRepo && repoNames.has(fullRepo[1])) return { repo: fullRepo[1], declaration: null }; + const scoped = /^([^:\s]+)::(.+)$/.exec(target); + if (scoped && repoNames.has(scoped[1])) return { repo: scoped[1], declaration: scoped[2].trim() || null }; + return null; +} + +function resolveEdgeTarget(sourceRepo, target, context) { + const raw = String(target || '').trim(); + if (!raw) return { resolution: 'unresolved', targetId: null, targetRepo: null }; + + const local = `${sourceRepo}::${raw}`; + if (context.declarationIds.has(local)) { + return { resolution: 'local-declaration', targetId: local, targetRepo: sourceRepo }; + } + + const explicit = explicitRepoTarget(raw, context.repoNames); + if (explicit) { + if (!explicit.declaration) { + return { resolution: 'explicit-repository', targetId: `repo:${explicit.repo}`, targetRepo: explicit.repo }; + } + const explicitId = `${explicit.repo}::${explicit.declaration}`; + if (context.declarationIds.has(explicitId)) { + return { resolution: 'explicit-declaration', targetId: explicitId, targetRepo: explicit.repo }; + } + return { resolution: 'unresolved', targetId: null, targetRepo: explicit.repo }; + } + + const global = context.globalIds.get(raw) || []; + if (global.length === 1) { + const [targetId] = global; + return { resolution: 'unique-global-declaration', targetId, targetRepo: targetId.split('::')[0] }; + } + return { resolution: 'unresolved', targetId: null, targetRepo: null }; +} + +function aggregateRepositoryEdges(edges) { + const grouped = new Map(); + for (const edge of edges) { + if (!edge.targetRepo || edge.targetRepo === edge.sourceRepo || edge.resolution === 'unresolved') continue; + const key = `${edge.sourceRepo}\u0000${edge.targetRepo}`; + const entry = grouped.get(key) || { + from: edge.sourceRepo, + to: edge.targetRepo, + count: 0, + kinds: new Set(), + sourceBlocks: new Set() + }; + entry.count += 1; + entry.kinds.add(edge.kind); + entry.sourceBlocks.add(edge.sourceBlock); + grouped.set(key, entry); + } + return [...grouped.values()] + .map(item => ({ + from: item.from, + to: item.to, + count: item.count, + kinds: [...item.kinds].sort(), + sourceBlocks: [...item.sourceBlocks].sort() + })) + .sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to)); +} + +export function buildOrgMap(repositoryInputs) { + const repoNames = new Set(repositoryInputs.map(item => item.name)); + const declarations = []; + const gaps = []; + const repositoryRows = []; + + for (const item of repositoryInputs) { + const hmmm = [...(item.hmmm || [])]; + const collection = item.collection || null; + const row = { + name: item.name, + slug: item.slug, + archived: Boolean(item.archived), + defaultBranch: item.defaultBranch || null, + headSha: item.headSha || null, + headCommittedAt: item.headCommittedAt || null, + collection: { + status: item.collectionStatus || 'missing', + path: item.collectionPath || `${item.name}${COLLECTION_SUFFIX}`, + sha256: item.collectionSha256 || null, + declaredRepo: collection?.repo || null, + declaredSourceCommit: collection?.source_commit || null, + sourceCommitMatchesHead: collection?.source_commit && item.headSha + ? collection.source_commit === item.headSha + : null, + error: item.collectionError || null + }, + counts: { declarations: 0, gaps: 0, edges: 0, resolvedEdges: 0, unresolvedEdges: 0, crossRepoEdges: 0 }, + blockCounts: {}, + hmmm + }; + + if (!collection) { + if (item.collectionStatus === 'invalid') hmmm.push('The repository collection point was present but could not be parsed.'); + else hmmm.push('No consumable repo-level msdmd collection point was found at the recorded head.'); + repositoryRows.push(row); + continue; + } + if (collection.repo && collection.repo !== item.name) { + hmmm.push(`Collection declares repo=${collection.repo}; consumed repository is ${item.name}.`); + } + if (row.collection.sourceCommitMatchesHead === false) { + hmmm.push('Collection-declared source_commit does not match the repository head consumed by this website build.'); + } + + for (const declaration of collection.declarations || []) { + const normalized = normalizeDeclaration(item.name, declaration); + if (!normalized) continue; + declarations.push(normalized); + row.counts.declarations += 1; + row.blockCounts[normalized.block] = (row.blockCounts[normalized.block] || 0) + 1; + } + for (const gap of collection.gaps || []) { + gaps.push({ + repo: item.name, + file: String(gap?.file || 'hmmm'), + missing: Array.isArray(gap?.missing) ? gap.missing.map(String) : [], + reason: gap?.reason ? String(gap.reason) : null + }); + row.counts.gaps += 1; + } + row._rawEdges = Array.isArray(collection.edges) ? collection.edges : []; + row.counts.edges = row._rawEdges.length; + repositoryRows.push(row); + } + + const declarationIds = new Set(declarations.map(item => item.id)); + const globalIds = new Map(); + for (const declaration of declarations) { + const values = globalIds.get(declaration.localId) || []; + values.push(declaration.id); + globalIds.set(declaration.localId, values); + } + const context = { repoNames, declarationIds, globalIds }; + const edges = []; + for (const row of repositoryRows) { + for (const edge of row._rawEdges || []) { + const sourceLocalId = String(edge?.from || edge?.source_id || 'hmmm'); + const sourceId = declarationIds.has(`${row.name}::${sourceLocalId}`) + ? `${row.name}::${sourceLocalId}` + : `${row.name}::${sourceLocalId}`; + const targetRaw = String(edge?.to || 'hmmm'); + const resolved = resolveEdgeTarget(row.name, targetRaw, context); + const normalized = { + sourceRepo: row.name, + sourceId, + sourceLocalId, + targetRaw, + targetId: resolved.targetId, + targetRepo: resolved.targetRepo, + resolution: resolved.resolution, + kind: String(edge?.kind || 'relation'), + sourceBlock: String(edge?.source_block || 'hmmm'), + sourceDeclarationId: String(edge?.source_id || sourceLocalId) + }; + edges.push(normalized); + if (normalized.resolution === 'unresolved') row.counts.unresolvedEdges += 1; + else row.counts.resolvedEdges += 1; + if (normalized.targetRepo && normalized.targetRepo !== row.name && normalized.resolution !== 'unresolved') { + row.counts.crossRepoEdges += 1; + } + } + delete row._rawEdges; + } + + const repositoryEdges = aggregateRepositoryEdges(edges); + const unresolvedEdges = edges.filter(edge => edge.resolution === 'unresolved'); + const collectionCount = repositoryRows.filter(repo => repo.collection.status === 'ok').length; + const invalidCollectionCount = repositoryRows.filter(repo => repo.collection.status === 'invalid').length; + const missingCollectionCount = repositoryRows.length - collectionCount - invalidCollectionCount; + const resolvedEdgeCount = edges.length - unresolvedEdges.length; + const latestHeadCommittedAt = repositoryRows + .map(repo => repo.headCommittedAt) + .filter(Boolean) + .sort() + .at(-1) || null; + const stateMaterial = repositoryRows + .map(repo => ({ + repo: repo.name, + headSha: repo.headSha, + collectionStatus: repo.collection.status, + collectionSha256: repo.collection.sha256 + })) + .sort((a, b) => a.repo.localeCompare(b.repo)); + + return { + schema: 'interdependency.org-msdmd-map/0.1.0', + organization: ORGANIZATION, + fallback: false, + sourceSnapshot: { + policy: 'current default-branch heads recorded by refresh:github; collection bytes fetched at those exact SHAs', + latestHeadCommittedAt, + stateDigest: sha256(JSON.stringify(stateMaterial)) + }, + summary: { + repositoryCount: repositoryRows.length, + collectionCount, + missingCollectionCount, + invalidCollectionCount, + declarationCount: declarations.length, + gapCount: gaps.length, + edgeCount: edges.length, + resolvedEdgeCount, + crossRepoEdgeCount: repositoryEdges.reduce((sum, edge) => sum + edge.count, 0), + crossRepoPairCount: repositoryEdges.length, + unresolvedEdgeCount: unresolvedEdges.length + }, + repositories: repositoryRows.sort((a, b) => a.name.localeCompare(b.name)), + declarations: declarations.sort((a, b) => a.repo.localeCompare(b.repo) || a.file.localeCompare(b.file) || a.block.localeCompare(b.block) || a.localId.localeCompare(b.localId)), + gaps: gaps.sort((a, b) => a.repo.localeCompare(b.repo) || a.file.localeCompare(b.file)), + edges: edges.sort((a, b) => a.sourceRepo.localeCompare(b.sourceRepo) || a.sourceId.localeCompare(b.sourceId) || a.kind.localeCompare(b.kind) || a.targetRaw.localeCompare(b.targetRaw)), + repositoryEdges, + unresolvedEdges: unresolvedEdges.sort((a, b) => a.sourceRepo.localeCompare(b.sourceRepo) || a.sourceId.localeCompare(b.sourceId) || a.targetRaw.localeCompare(b.targetRaw)), + hmmm: [ + 'An unresolved edge means the source repository declared a target that cannot be exactly identified from current repo collection identities; the website does not guess the relation.', + 'Missing collection points remain visible until the source repository publishes one.' + ] + }; +} + +async function fetchRepositoryInputs(repositories) { + const inputs = []; + for (const repo of repositories) { + const name = normalizeRepoName(repo.name); + const collectionPath = `${name}${COLLECTION_SUFFIX}`; + const base = { + name, + slug: repo.slug || name.toLowerCase().replace(/[^a-z0-9]+/g, '-'), + archived: repo.archived, + defaultBranch: repo.default_branch, + headSha: repo.head_sha || null, + headCommittedAt: repo.head_committed_at || null, + collectionPath, + hmmm: [] + }; + if (!base.headSha) { + inputs.push({ ...base, collectionStatus: 'missing', collectionError: 'exact default-branch head unavailable' }); + continue; + } + try { + const text = getText(rawGithubUrl(name, base.headSha, collectionPath)); + const collection = parseCollectionText(text); + inputs.push({ + ...base, + collectionStatus: 'ok', + collectionSha256: sha256(Buffer.from(text, 'utf8')), + collection + }); + } catch (error) { + const stderr = String(error?.stderr || ''); + const status = /404|not found/i.test(stderr) ? 'missing' : 'invalid'; + inputs.push({ + ...base, + collectionStatus: status, + collectionError: status === 'missing' ? 'collection point absent at consumed head' : String(error?.message || error) + }); + } + } + return inputs; +} + +async function main() { + await mkdir('src/_data/generated', { recursive: true }); + await mkdir('src/_data/snapshots', { recursive: true }); + + if (process.env.OFFLINE === '1') { + const fallback = JSON.parse(await readFile(SNAPSHOT_OUT, 'utf8')); + fallback.fallback = true; + fallback.hmmm = [...new Set([...(fallback.hmmm || []), 'OFFLINE=1: displaying the last-known-good org msdmd snapshot.'])]; + await writeFile(GENERATED_OUT, stableJson(fallback)); + console.log(`org-msdmd ${fallback.summary?.collectionCount || 0}/${fallback.summary?.repositoryCount || 0} fallback`); + return; + } + + try { + const repoData = JSON.parse(await readFile(GENERATED_REPOS, 'utf8')); + const inputs = await fetchRepositoryInputs(repoData.repositories || []); + const data = buildOrgMap(inputs); + await writeFile(GENERATED_OUT, stableJson(data)); + await writeFile(SNAPSHOT_OUT, stableJson(data)); + console.log(`org-msdmd ${data.summary.collectionCount}/${data.summary.repositoryCount} collections · ${data.summary.crossRepoPairCount} cross-repo pairs · ${data.summary.unresolvedEdgeCount} unresolved edges`); + } catch (error) { + const fallback = JSON.parse(await readFile(SNAPSHOT_OUT, 'utf8')); + fallback.fallback = true; + fallback.hmmm = [...new Set([...(fallback.hmmm || []), `Refresh failed; displaying last-known-good snapshot: ${String(error?.message || error)}`])]; + await writeFile(GENERATED_OUT, stableJson(fallback)); + console.log(`org-msdmd ${fallback.summary?.collectionCount || 0}/${fallback.summary?.repositoryCount || 0} fallback`); + } +} + +const invokedAsScript = process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href; +if (invokedAsScript) await main(); From 6493a86e62af1b0859a0b5333f4ae570ec4e744c Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 00:57:49 -0700 Subject: [PATCH 02/15] refactor(github): pin repository heads for downstream maps --- scripts/fetch-github-org.mjs | 53 ++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/scripts/fetch-github-org.mjs b/scripts/fetch-github-org.mjs index 8e58400..508f302 100644 --- a/scripts/fetch-github-org.mjs +++ b/scripts/fetch-github-org.mjs @@ -4,19 +4,21 @@ import yaml from 'js-yaml'; // === MODULE_BUILD === // id: organization_project_map -// purpose: Build public project pages from GitHub facts plus reviewed repository manifests or central overrides. +// purpose: Build public project pages from GitHub facts plus reviewed repository manifests or central overrides, recording exact default-branch heads for reproducible downstream consumers. // entrypoint: npm run refresh:github // tests: tests/repo-coverage.test.mjs, tests/offline-project-snapshot.test.mjs // === END MODULE_BUILD === // === BOUNDARIES === // id: github_public_metadata -// network: reads only allowlisted HTTPS GitHub API endpoints; optional token raises rate limits +// network: reads only allowlisted HTTPS GitHub API and raw.githubusercontent.com endpoints; optional token raises API rate limits // storage: writes generated and last-known-good JSON snapshots // failure: preserves last-known-good data with fallback=true, including reviewed editorial fields // === END BOUNDARIES === +// Usage: run `npm run refresh:github`; the generated repo snapshot records each exact default-branch head so later collectors can fetch commit-pinned source without repeating GitHub API lookups. const org = 'The-Interdependency'; const githubApiOrigin = 'https://api.github.com'; +const rawGithubOrigin = 'https://raw.githubusercontent.com'; const headers = ['-H', 'Accept: application/vnd.github+json', '-H', 'X-GitHub-Api-Version: 2022-11-28']; if (process.env.GITHUB_TOKEN) headers.push('-H', `Authorization: Bearer ${process.env.GITHUB_TOKEN}`); @@ -26,6 +28,11 @@ function githubApiUrl(pathname, search = {}) { return url; } +function rawGithubUrl(repoName, commit, path) { + const parts = [org, repoName, commit, ...String(path).split('/')].map(encodeURIComponent); + return new URL(`/${parts.join('/')}`, rawGithubOrigin); +} + function getJson(target) { const url = target instanceof URL ? target : new URL(target); if (url.protocol !== 'https:' || url.origin !== githubApiOrigin) { @@ -38,19 +45,45 @@ function getJson(target) { )); } +function getText(target) { + const url = target instanceof URL ? target : new URL(target); + if (url.protocol !== 'https:' || url.origin !== rawGithubOrigin) { + throw new Error(`refusing non-raw-GitHub target: ${url.origin}`); + } + return execFileSync( + 'curl', + ['-fsSL', '--retry', '2', '--max-time', '20', url.href], + { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] } + ); +} + function normalizeRepoName(value) { const name = String(value || ''); if (!/^[A-Za-z0-9_.-]{1,100}$/.test(name)) throw new Error(`invalid GitHub repository name: ${name}`); return name; } -function getManifest(repoName) { +function getHead(repoName, defaultBranch) { try { + if (!defaultBranch) return { sha: null, committed_at: null }; const safeRepo = normalizeRepoName(repoName); const response = getJson(githubApiUrl( - `/repos/${encodeURIComponent(org)}/${encodeURIComponent(safeRepo)}/contents/.interdependency/project.yml` + `/repos/${encodeURIComponent(org)}/${encodeURIComponent(safeRepo)}/commits/${encodeURIComponent(defaultBranch)}` )); - return yaml.load(Buffer.from(response.content || '', 'base64').toString('utf8')) || null; + return { + sha: response.sha || null, + committed_at: response.commit?.committer?.date || response.commit?.author?.date || null + }; + } catch { + return { sha: null, committed_at: null }; + } +} + +function getManifest(repoName, headSha) { + try { + if (!headSha) return null; + const safeRepo = normalizeRepoName(repoName); + return yaml.load(getText(rawGithubUrl(safeRepo, headSha, '.interdependency/project.yml'))) || null; } catch { return null; } @@ -91,7 +124,10 @@ try { const repositories = rawRepos.map(repo => { const repoName = normalizeRepoName(repo.name); - const manifest = fallback ? null : getManifest(repoName); + const head = fallback + ? { sha: repo.head_sha || null, committed_at: repo.head_committed_at || null } + : getHead(repoName, repo.default_branch); + const manifest = fallback ? null : getManifest(repoName, head.sha); const inheritedEditorial = fallback ? { category: repo.category, status: repo.status, @@ -113,6 +149,9 @@ const repositories = rawRepos.map(repo => { if (!editorial.status && !hmmm.includes('Project maturity has not been explicitly declared.')) { hmmm.push('Project maturity has not been explicitly declared.'); } + if (!fallback && !head.sha) { + hmmm.push('Exact default-branch head was unavailable during this snapshot; commit-pinned downstream collection is suspended for this repository.'); + } return { name: repoName, slug: repoName.toLowerCase().replace(/[^a-z0-9]+/g, '-'), @@ -127,6 +166,8 @@ const repositories = rawRepos.map(repo => { archived: Boolean(repo.archived), fork: Boolean(repo.fork), default_branch: repo.default_branch || null, + head_sha: head.sha, + head_committed_at: head.committed_at, topics: Array.isArray(repo.topics) ? repo.topics : [], license: repo.license?.spdx_id || repo.license || null, language: repo.language || null, From 2c4699628fbfb63e76783bcb7d52514b0dcfafe8 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 00:58:20 -0700 Subject: [PATCH 03/15] feat(msdmd): add organization map presentation --- src/assets/css/org-map.css | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/assets/css/org-map.css diff --git a/src/assets/css/org-map.css b/src/assets/css/org-map.css new file mode 100644 index 0000000..8e8fcab --- /dev/null +++ b/src/assets/css/org-map.css @@ -0,0 +1,39 @@ +/* Usage: loaded by the base layout; styles activate only on /projects/map/ markup and keep the static fallback readable without JavaScript. */ +.org-map-shell { margin: 2rem 0 3.5rem; } +.org-map-frame { position: relative; min-height: 34rem; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); background: radial-gradient(circle at 50% 50%, rgba(155, 135, 245, .11), rgba(16, 24, 42, .9) 42%, rgba(9, 13, 24, .98) 78%); } +.org-map-frame svg { display: block; width: 100%; min-height: 34rem; } +.org-map-edge { stroke: rgba(174, 187, 210, .36); vector-effect: non-scaling-stroke; } +.org-map-edge[data-kind~="requires"] { stroke: var(--cyan); } +.org-map-edge[data-kind~="claims_proves"] { stroke: #9ce2b9; } +.org-map-node circle { fill: var(--night-raised); stroke: var(--violet); stroke-width: 2; vector-effect: non-scaling-stroke; } +.org-map-node[data-status="missing"] circle { stroke: var(--amber); stroke-dasharray: 5 4; } +.org-map-node[data-status="invalid"] circle { stroke: var(--scarlet); } +.org-map-node[data-archived="true"] { opacity: .55; } +.org-map-node text { fill: var(--starlight); font: 700 15px/1 ui-monospace, SFMono-Regular, Consolas, monospace; pointer-events: none; paint-order: stroke; stroke: var(--night); stroke-width: 4px; stroke-linejoin: round; } +.org-map-node:hover circle, .org-map-node:focus circle { fill: var(--night-soft); stroke: var(--cyan); stroke-width: 3; } +.org-map-detail { position: absolute; left: 1rem; bottom: 1rem; z-index: 2; max-width: min(31rem, calc(100% - 2rem)); padding: .8rem 1rem; border: 1px solid var(--line); border-radius: .75rem; background: rgba(9, 13, 24, .94); box-shadow: var(--shadow); } +.org-map-detail strong { display: block; color: var(--starlight); } +.org-map-detail span { color: var(--silver); font-size: .9rem; } +.org-map-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: .75rem; margin: 1.25rem 0 2rem; } +.org-map-stat { padding: .85rem 1rem; border: 1px solid var(--line); border-radius: .75rem; background: rgba(16,24,42,.72); } +.org-map-stat strong { display: block; color: var(--starlight); font: 800 1.55rem/1.2 ui-monospace, monospace; } +.org-map-stat span { color: var(--silver); font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; } +.org-map-repo-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); } +.org-map-repo-card dl { display: grid; grid-template-columns: auto 1fr; gap: .2rem .7rem; margin: .8rem 0 0; font-size: .86rem; } +.org-map-repo-card dt { color: var(--silver); } +.org-map-repo-card dd { margin: 0; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; } +.org-map-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); } +.org-map-table { width: 100%; border-collapse: collapse; min-width: 42rem; } +.org-map-table th, .org-map-table td { padding: .7rem .8rem; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; } +.org-map-table th { color: var(--cyan); font: 800 .74rem/1.3 ui-monospace, monospace; text-transform: uppercase; letter-spacing: .06em; } +.org-map-table td { color: var(--silver); } +.org-map-table tr:last-child td { border-bottom: 0; } +.org-map-receipts { display: grid; gap: .6rem; padding: 0; list-style: none; } +.org-map-receipts li { padding: .75rem .9rem; border: 1px solid var(--line); border-radius: .7rem; background: rgba(16,24,42,.62); } +.org-map-receipts code { overflow-wrap: anywhere; } +.org-map-unresolved { display: grid; gap: .45rem; padding-left: 1.2rem; } +.org-map-unresolved code { overflow-wrap: anywhere; } +@media (max-width: 680px) { + .org-map-frame, .org-map-frame svg { min-height: 28rem; } + .org-map-detail { position: static; max-width: none; margin: 0; border-width: 1px 0 0; border-radius: 0; box-shadow: none; } +} From 783a9fc526735af8b3734fe7b51ec84cadec8b30 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 00:58:36 -0700 Subject: [PATCH 04/15] feat(msdmd): render organization relation map --- src/assets/js/org-map.js | 136 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 src/assets/js/org-map.js diff --git a/src/assets/js/org-map.js b/src/assets/js/org-map.js new file mode 100644 index 0000000..781dcce --- /dev/null +++ b/src/assets/js/org-map.js @@ -0,0 +1,136 @@ +// === MODULE_BUILD === +// id: organization_msdmd_map_renderer +// purpose: Render the generated repository-level msdmd relation graph as an accessible SVG enhancement while preserving the complete static fallback below it. +// entrypoint: base layout deferred script; activates only when [data-org-map] exists +// tests: tests/org-msdmd.test.mjs, tests/generated-site.test.mjs +// === END MODULE_BUILD === +// === BOUNDARIES === +// id: organization_msdmd_map_renderer_boundary +// network: fetches only the same-origin generated /assets/data/org-msdmd.json artifact +// storage: none +// failure: leaves the complete server-rendered repository, relation, unresolved-edge, and provenance lists intact +// === END BOUNDARIES === +// Usage: no direct invocation is needed. The /projects/map/ page supplies data-source and an accessible static fallback; this script adds only the visual graph. + +const SVG_NS = 'http://www.w3.org/2000/svg'; + +function svgElement(name, attributes = {}) { + const element = document.createElementNS(SVG_NS, name); + for (const [key, value] of Object.entries(attributes)) element.setAttribute(key, String(value)); + return element; +} + +function shortName(value, limit = 18) { + const text = String(value || 'hmmm'); + return text.length <= limit ? text : `${text.slice(0, limit - 1)}…`; +} + +function positionsFor(repositories) { + const rows = [...repositories].sort((a, b) => a.name.localeCompare(b.name)); + const centerX = 500; + const centerY = 350; + const split = rows.length > 18 ? Math.ceil(rows.length * 0.62) : rows.length; + return new Map(rows.map((repo, index) => { + const outer = index < split; + const ringRows = outer ? rows.slice(0, split) : rows.slice(split); + const ringIndex = outer ? index : index - split; + const radius = outer ? 285 : 175; + const angle = (-Math.PI / 2) + (2 * Math.PI * ringIndex / Math.max(1, ringRows.length)); + return [repo.name, { + x: centerX + Math.cos(angle) * radius, + y: centerY + Math.sin(angle) * radius + }]; + })); +} + +function updateDetail(detail, repo) { + detail.replaceChildren(); + const strong = document.createElement('strong'); + strong.textContent = repo.name; + const span = document.createElement('span'); + const collection = repo.collection?.status || 'hmmm'; + const counts = repo.counts || {}; + span.textContent = `${collection} collection · ${counts.declarations || 0} declarations · ${counts.edges || 0} edges · ${counts.gaps || 0} gaps`; + detail.append(strong, span); +} + +export function renderOrganizationMap(root, data) { + const frame = root.querySelector('[data-org-map-frame]'); + const detail = root.querySelector('[data-org-map-detail]'); + if (!frame || !detail || !Array.isArray(data?.repositories)) return; + + const positions = positionsFor(data.repositories); + const byName = new Map(data.repositories.map(repo => [repo.name, repo])); + const svg = svgElement('svg', { + viewBox: '0 0 1000 700', + role: 'img', + 'aria-label': 'Repository relationship map generated from msdmd declarations' + }); + + const edgeLayer = svgElement('g', { 'aria-hidden': 'true' }); + for (const edge of data.repositoryEdges || []) { + const from = positions.get(edge.from); + const to = positions.get(edge.to); + if (!from || !to) continue; + const line = svgElement('line', { + x1: from.x, + y1: from.y, + x2: to.x, + y2: to.y, + class: 'org-map-edge', + 'data-kind': (edge.kinds || []).join(' '), + 'stroke-width': Math.min(6, 1 + Math.log2((edge.count || 1) + 1)) + }); + edgeLayer.append(line); + } + svg.append(edgeLayer); + + const nodeLayer = svgElement('g'); + for (const repo of data.repositories) { + const point = positions.get(repo.name); + if (!point) continue; + const link = svgElement('a', { + href: `/projects/${repo.slug}/`, + class: 'org-map-node', + 'data-status': repo.collection?.status || 'hmmm', + 'data-archived': Boolean(repo.archived), + 'aria-label': `${repo.name}: ${repo.collection?.status || 'hmmm'} msdmd collection` + }); + const radius = Math.min(21, 8 + Math.sqrt(repo.counts?.declarations || 0)); + link.append(svgElement('circle', { cx: point.x, cy: point.y, r: radius })); + const label = svgElement('text', { + x: point.x, + y: point.y + radius + 19, + 'text-anchor': 'middle' + }); + label.textContent = shortName(repo.name); + link.append(label); + link.addEventListener('mouseenter', () => updateDetail(detail, repo)); + link.addEventListener('focus', () => updateDetail(detail, repo)); + nodeLayer.append(link); + } + svg.append(nodeLayer); + + frame.prepend(svg); + const first = [...byName.values()].sort((a, b) => a.name.localeCompare(b.name))[0]; + if (first) updateDetail(detail, first); +} + +async function activate() { + const root = document.querySelector('[data-org-map]'); + if (!root) return; + const source = root.getAttribute('data-source'); + if (!source) return; + try { + const response = await fetch(source, { credentials: 'same-origin' }); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + renderOrganizationMap(root, await response.json()); + } catch (error) { + const detail = root.querySelector('[data-org-map-detail]'); + if (detail) { + detail.textContent = `Visual enhancement unavailable; the complete static map remains below. ${String(error?.message || error)}`; + } + } +} + +activate(); From 15fb0b274a6a63dadcd978fabd7c9fe607eb5cce Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 00:58:57 -0700 Subject: [PATCH 05/15] feat(msdmd): publish organization repository map --- src/projects/map/index.njk | 106 +++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/projects/map/index.njk diff --git a/src/projects/map/index.njk b/src/projects/map/index.njk new file mode 100644 index 0000000..1ea2368 --- /dev/null +++ b/src/projects/map/index.njk @@ -0,0 +1,106 @@ +--- +layout: layouts/base.njk +title: Organization map +description: A build-time, provenance-bearing relationship map generated from repository-owned msdmd collection points. +--- +{% set map = generated.orgMsdmd %} +
+

Repository-owned msdmd → organization-scale integration

+

Organization map

+

Repositories describe themselves. This website joins those commit-pinned descriptions and displays the resulting relations without becoming a second source of repository canon.

+
+ {{ map.summary.collectionCount }}/{{ map.summary.repositoryCount }} collections + {{ map.summary.declarationCount }} declarations + {{ map.summary.crossRepoPairCount }} cross-repo pairs + {% if map.summary.unresolvedEdgeCount %}{{ map.summary.unresolvedEdgeCount }} unresolved edges{% endif %} + {% if map.fallback %}last-known-good snapshot{% endif %} +
+
+ +
+

Generated view

+

Relations currently visible

+

The graphic shows repository-level relations only when an msdmd edge resolves exactly across repository boundaries. Missing collections and unresolved targets remain visible rather than being inferred.

+
+
{{ map.summary.repositoryCount }}repositories
+
{{ map.summary.collectionCount }}collections
+
{{ map.summary.edgeCount }}declared edges
+
{{ map.summary.resolvedEdgeCount }}resolved edges
+
{{ map.summary.gapCount }}coverage gaps
+
{{ map.summary.unresolvedEdgeCount }}hmmm edges
+
+
+
+
JavaScript adds the visual graph here. The complete static evidence remains below.
+
+
+
+ +
+

Static fallback · complete repository surface

+

Repository evidence

+ +
+ +
+

Exact cross-repository resolution

+

Cross-repo relations

+ {% if map.repositoryEdges.length %} +
+ + + + {% for edge in map.repositoryEdges %}{% endfor %} + +
FromToRelationsDeclarations
{{ edge.from }}{{ edge.to }}{{ edge.kinds | join(', ') }}{{ edge.count }}
+
+ {% else %} +

hmmm

No current msdmd edge resolves exactly across repository boundaries. The repositories remain mapped individually; the website will not invent cross-repo edges from naming similarity or editorial familiarity.

+ {% endif %} +
+ +
+

Resolution boundary

+

Unresolved edges

+ {% if map.unresolvedEdges.length %} +
+ {{ map.unresolvedEdges.length }} declared targets remain unresolved +
    + {% for edge in map.unresolvedEdges %}
  1. {{ edge.sourceId }} —{{ edge.kind }}→ {{ edge.targetRaw }}
  2. {% endfor %} +
+
+ {% else %}

No unresolved declared targets in this snapshot.

{% endif %} +
+ +
+

Build receipt

+

Consumed source identities

+

The snapshot identity is {{ map.sourceSnapshot.stateDigest }}. Its source time is the latest consumed repository head time, {{ map.sourceSnapshot.latestHeadCommittedAt or 'hmmm' }}. Rebuilding against unchanged heads and collection bytes produces the same JSON.

+
    + {% for repo in map.repositories %} +
  • {{ repo.name }} · head {{ repo.headSha or 'hmmm' }} · collection {{ repo.collection.path }} · SHA-256 {{ repo.collection.sha256 or 'hmmm' }}{% if repo.collection.declaredSourceCommit %} · declared source {{ repo.collection.declaredSourceCommit }}{% endif %}{% if repo.collection.sourceCommitMatchesHead == false %} · source-commit mismatch{% endif %}
  • + {% endfor %} +
+
+ +
+

hmmm

+ {% for item in map.hmmm %}

{{ item }}

{% endfor %} +
From ce263d315d651e4d9e8d9fbdbdedc4874ba523c7 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 00:59:09 -0700 Subject: [PATCH 06/15] feat(msdmd): load organization map enhancement --- src/_includes/layouts/base.njk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/_includes/layouts/base.njk b/src/_includes/layouts/base.njk index 788b5b9..7fed671 100644 --- a/src/_includes/layouts/base.njk +++ b/src/_includes/layouts/base.njk @@ -13,7 +13,9 @@ + + From e403ad07e386519875a7bb75c43136d08a209afa Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 00:59:27 -0700 Subject: [PATCH 07/15] feat(msdmd): publish generated organization map data --- .eleventy.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.eleventy.js b/.eleventy.js index f019fb1..34a5356 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -20,6 +20,12 @@ import { installMathRenderer } from './scripts/markdown-math.mjs'; // then: the website publishes the generated presentation view without becoming a second source of repo canon // class: evidence // since: 2026-08-14 +// +// id: website_org_msdmd_has_one_public_projection_copy +// given: commit-pinned repo-owned msdmd collections are joined into the generated organization map +// then: the website publishes that generated evidence artifact unchanged and uses it for the visual map without becoming repository metadata authority +// class: evidence +// since: 2026-08-16 // === END CONTRACTS === // Usage: run `npm run build`; Eleventy emits the static site, copies root machine instructions, and preserves dependency-free public reading paths. @@ -30,6 +36,7 @@ export default function configureEleventy(eleventyConfig) { 'src/assets': 'assets', 'src/_data/gonol_relationship_display.json': 'assets/data/gonol-relationship-display-v1.json', 'src/_data/generated/sitrep.json': 'assets/data/sitrep.json', + 'src/_data/generated/orgMsdmd.json': 'assets/data/org-msdmd.json', 'CNAME': 'CNAME', 'llms.txt': 'llms.txt', 'artifacts/four-cuts-1.html': 'artifacts/four-cuts/index.html', From 25f22a621bd89846b68c977a47977971847e10f3 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 00:59:38 -0700 Subject: [PATCH 08/15] feat(msdmd): wire organization map refresh and tests --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5b3775b..fa4d117 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,10 @@ "type": "module", "scripts": { "dev": "npm run refresh:data && eleventy --serve", - "refresh:data": "npm run refresh:canon && npm run refresh:github && npm run refresh:sitrep && npm run refresh:textbook && npm run refresh:works", + "refresh:data": "npm run refresh:canon && npm run refresh:github && npm run refresh:msdmd && npm run refresh:sitrep && npm run refresh:textbook && npm run refresh:works", "refresh:canon": "node scripts/fetch-canon.mjs && node scripts/parse-canon.mjs", "refresh:github": "node scripts/fetch-github-org.mjs", + "refresh:msdmd": "node scripts/fetch-org-msdmd.mjs", "refresh:sitrep": "node scripts/fetch-sitrep.mjs", "refresh:textbook": "node scripts/fetch-textbook.mjs", "research:enrich": "node scripts/enrich-citations.mjs", @@ -20,7 +21,7 @@ "validate": "node scripts/validate-content.mjs && node scripts/verify-generated-routes.mjs && node scripts/verify-article-canon.mjs", "build": "npm run validate && eleventy && pagefind --site _site && node scripts/write-build-info.mjs", "pretest": "node scripts/prepare-tests.mjs", - "test": "node --test tests/aicontext.test.mjs tests/edcm-mathematics.test.mjs tests/gonol-relationships.test.mjs tests/post-merge-reconciliation.test.mjs tests/llms-build.test.mjs tests/canon-parser.test.mjs tests/canon-integrity.test.mjs tests/textbook-integrity.test.mjs tests/math-rendering.test.mjs tests/narratives.test.mjs tests/offline-project-snapshot.test.mjs tests/repo-coverage.test.mjs tests/research-ledger.test.mjs tests/works-registry.test.mjs tests/site-contract.test.mjs tests/sitrep.test.mjs", + "test": "node --test tests/aicontext.test.mjs tests/edcm-mathematics.test.mjs tests/gonol-relationships.test.mjs tests/org-msdmd.test.mjs tests/post-merge-reconciliation.test.mjs tests/llms-build.test.mjs tests/canon-parser.test.mjs tests/canon-integrity.test.mjs tests/textbook-integrity.test.mjs tests/math-rendering.test.mjs tests/narratives.test.mjs tests/offline-project-snapshot.test.mjs tests/repo-coverage.test.mjs tests/research-ledger.test.mjs tests/works-registry.test.mjs tests/site-contract.test.mjs tests/sitrep.test.mjs", "test:generated": "node --test tests/generated-site.test.mjs tests/human-ui-generated.test.mjs tests/textbook-generated.test.mjs tests/math-generated.test.mjs && node tests/links.test.mjs", "test:browser": "playwright test", "test:e2e": "playwright test tests/site.spec.mjs", From 0fdb04ce12a6510a2058a3606719eb9943ab4f4a Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 00:59:56 -0700 Subject: [PATCH 09/15] test(msdmd): cover organization map collection and resolution --- tests/org-msdmd.test.mjs | 84 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/org-msdmd.test.mjs diff --git a/tests/org-msdmd.test.mjs b/tests/org-msdmd.test.mjs new file mode 100644 index 0000000..18f1837 --- /dev/null +++ b/tests/org-msdmd.test.mjs @@ -0,0 +1,84 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { buildOrgMap, parseCollectionText } from '../scripts/fetch-org-msdmd.mjs'; + +// Usage: `node --test tests/org-msdmd.test.mjs`; all fixtures are local and perform no network requests. + +test('parses generated and hand-authored msdmd collection points without evaluation', () => { + const generated = ` + import { defineMsdmdCollection } from './collection'; + export default defineMsdmdCollection({"repo":"alpha","declarations":[],"gaps":[],"edges":[]}); + // ratios: ignored + `; + assert.deepEqual(parseCollectionText(generated), { + repo: 'alpha', declarations: [], gaps: [], edges: [] + }); + + const handAuthored = ` + export default defineMsdmdCollection({ + repo: 'alpha', + declarations: [{ file: 'src/a.py', block: 'DEPENDENCIES', id: 'alpha_dep', fields: { requires: 'beta::beta_cap', }, }], + gaps: [], + edges: [{ from: 'alpha_dep', to: 'beta::beta_cap', kind: 'requires', source_block: 'DEPENDENCIES', source_id: 'alpha_dep', }], + }); + // ratios: trailing source seal + `; + const parsed = parseCollectionText(handAuthored); + assert.equal(parsed.repo, 'alpha'); + assert.equal(parsed.declarations[0].fields.requires, 'beta::beta_cap'); + assert.equal(parsed.edges[0].kind, 'requires'); +}); + +test('resolves only exact cross-repo targets and retains unresolved edges', () => { + const inputs = [ + { + name: 'alpha', slug: 'alpha', defaultBranch: 'main', headSha: 'a'.repeat(40), headCommittedAt: '2026-08-15T00:00:00Z', + collectionStatus: 'ok', collectionPath: 'alpha_msdmd.ts', collectionSha256: '1'.repeat(64), + collection: { + repo: 'alpha', source_commit: 'a'.repeat(40), gaps: [], + declarations: [{ file: 'src/a.py', block: 'DEPENDENCIES', id: 'alpha_dep', fields: {} }], + edges: [ + { from: 'alpha_dep', to: 'beta::beta_cap', kind: 'requires', source_block: 'DEPENDENCIES', source_id: 'alpha_dep' }, + { from: 'alpha_dep', to: 'looks-like-something', kind: 'requires', source_block: 'DEPENDENCIES', source_id: 'alpha_dep' } + ] + } + }, + { + name: 'beta', slug: 'beta', defaultBranch: 'main', headSha: 'b'.repeat(40), headCommittedAt: '2026-08-16T00:00:00Z', + collectionStatus: 'ok', collectionPath: 'beta_msdmd.ts', collectionSha256: '2'.repeat(64), + collection: { + repo: 'beta', source_commit: 'b'.repeat(40), gaps: [], edges: [], + declarations: [{ file: 'src/b.py', block: 'CAPABILITIES', id: 'beta_cap', fields: {} }] + } + }, + { + name: 'gamma', slug: 'gamma', defaultBranch: 'main', headSha: 'c'.repeat(40), headCommittedAt: '2026-08-14T00:00:00Z', + collectionStatus: 'missing', collectionPath: 'gamma_msdmd.ts', collectionError: 'collection point absent at consumed head' + } + ]; + + const first = buildOrgMap(inputs); + const second = buildOrgMap(inputs); + assert.equal(JSON.stringify(first), JSON.stringify(second), 'same inputs must emit byte-equivalent data'); + assert.equal(first.summary.repositoryCount, 3); + assert.equal(first.summary.collectionCount, 2); + assert.equal(first.summary.missingCollectionCount, 1); + assert.equal(first.summary.crossRepoPairCount, 1); + assert.equal(first.summary.unresolvedEdgeCount, 1); + assert.deepEqual(first.repositoryEdges[0], { + from: 'alpha', to: 'beta', count: 1, kinds: ['requires'], sourceBlocks: ['DEPENDENCIES'] + }); + assert.equal(first.unresolvedEdges[0].targetRaw, 'looks-like-something'); + assert.match(first.repositories.find(repo => repo.name === 'gamma').hmmm[0], /No consumable repo-level msdmd collection point/); +}); + +test('flags collection source commit drift without rejecting the source bytes', () => { + const data = buildOrgMap([{ + name: 'alpha', slug: 'alpha', defaultBranch: 'main', headSha: 'a'.repeat(40), headCommittedAt: '2026-08-16T00:00:00Z', + collectionStatus: 'ok', collectionPath: 'alpha_msdmd.ts', collectionSha256: '3'.repeat(64), + collection: { repo: 'alpha', source_commit: 'b'.repeat(40), declarations: [], gaps: [], edges: [] } + }]); + const repo = data.repositories[0]; + assert.equal(repo.collection.sourceCommitMatchesHead, false); + assert.ok(repo.hmmm.some(item => /does not match/.test(item))); +}); From b5b148dd0ac667f79a21f832360764b67d02179c Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 01:00:03 -0700 Subject: [PATCH 10/15] feat(msdmd): link project index to generated organization map --- src/projects/index.njk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/projects/index.njk b/src/projects/index.njk index c457490..9393dc9 100644 --- a/src/projects/index.njk +++ b/src/projects/index.njk @@ -3,5 +3,5 @@ layout: layouts/base.njk title: Projects description: A generated map of every public repository in The Interdependency organization, grouped by function and status. --- -

Build-time organization map

Projects

Every public repository receives a page. GitHub facts update automatically at build time; reviewed manifests supply purpose, maturity, relations, and primary artifacts. Missing editorial knowledge remains visible as hmmm.

{{ generated.repos.publicRepoCount }} public repos{% if generated.repos.fallback %}last-known-good snapshot{% endif %}
+

Build-time organization map

Projects

Every public repository receives a page. GitHub facts update automatically at build time; reviewed manifests supply purpose, maturity, relations, and primary artifacts. Missing editorial knowledge remains visible as hmmm.

{{ generated.repos.publicRepoCount }} public repos{% if generated.repos.fallback %}last-known-good snapshot{% endif %}
{% for category in generated.repos.categories %}

Project constellation

{{ category }}

{% for repo in generated.repos.repositories %}{% if repo.category == category %}
{{ repo.status }}{% if repo.archived %}archived{% endif %}

{{ repo.name }}

{{ repo.description or 'No public summary supplied.' }}

{% endif %}{% endfor %}
{% endfor %} From aee80d4a3ee261787f65a903fa305efba73a695a Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 01:02:17 -0700 Subject: [PATCH 11/15] chore(msdmd): add honest bootstrap fallback snapshot --- .../snapshots/org-msdmd.last-known-good.json | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/_data/snapshots/org-msdmd.last-known-good.json diff --git a/src/_data/snapshots/org-msdmd.last-known-good.json b/src/_data/snapshots/org-msdmd.last-known-good.json new file mode 100644 index 0000000..2c195a8 --- /dev/null +++ b/src/_data/snapshots/org-msdmd.last-known-good.json @@ -0,0 +1,35 @@ +{ + "schema": "interdependency.org-msdmd-map/0.1.0", + "organization": "The-Interdependency", + "fallback": true, + "sourceSnapshot": { + "policy": "bootstrap fallback only; no repository collection evidence has been consumed in this checked-in snapshot", + "latestHeadCommittedAt": null, + "stateDigest": "hmmm-bootstrap-no-source-evidence" + }, + "summary": { + "repositoryCount": 0, + "collectionCount": 0, + "missingCollectionCount": 0, + "invalidCollectionCount": 0, + "declarationCount": 0, + "gapCount": 0, + "edgeCount": 0, + "resolvedEdgeCount": 0, + "crossRepoEdgeCount": 0, + "crossRepoPairCount": 0, + "unresolvedEdgeCount": 0 + }, + "repositories": [], + "declarations": [], + "gaps": [], + "edges": [], + "repositoryEdges": [], + "unresolvedEdges": [], + "hmmm": [ + "Bootstrap fallback: this checked-in artifact contains no repository collection evidence and must not be mistaken for an organization-state measurement.", + "A successful online refresh replaces this file in the build workspace with a commit-pinned last-known-good snapshot.", + "An unresolved edge means the source repository declared a target that cannot be exactly identified from current repo collection identities; the website does not guess the relation.", + "Missing collection points remain visible until the source repository publishes one." + ] +} From 125b211c0d10b643eb6a9ebce29ef34437b4887c Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 01:05:28 -0700 Subject: [PATCH 12/15] fix(msdmd): distinguish opaque targets from unresolved relations --- scripts/fetch-org-msdmd.mjs | 69 ++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/scripts/fetch-org-msdmd.mjs b/scripts/fetch-org-msdmd.mjs index ec5994b..796bb6b 100644 --- a/scripts/fetch-org-msdmd.mjs +++ b/scripts/fetch-org-msdmd.mjs @@ -14,7 +14,7 @@ import { pathToFileURL } from 'node:url'; // network: reads only commit-pinned raw.githubusercontent.com collection files named _msdmd.ts; repository heads come from the prior GitHub metadata refresh // storage: writes generated and last-known-good JSON snapshots only // authority: repository collection points remain source authority; this module namespaces, resolves, aggregates, and displays their declared relations -// failure: missing, invalid, stale, and unresolved inputs remain explicit hmmm evidence and are never silently omitted +// failure: missing, invalid, stale, ambiguous, and broken explicit inputs remain visible; ordinary owner/file/route/tool/external targets remain valid opaque relations rather than being mislabeled hmmm // === END BOUNDARIES === // === CONTRACTS === // id: organization_msdmd_exact_input_identity @@ -22,9 +22,9 @@ import { pathToFileURL } from 'node:url'; // then: repository, exact head SHA, collection path, collection SHA-256, declared source commit, and match status remain in the output receipt // class: evidence // -// id: organization_msdmd_no_inferred_edges -// given: an msdmd edge target cannot be resolved exactly by local id, explicit repository identity, or globally unique declaration id -// then: the edge is retained unresolved rather than guessed +// id: organization_msdmd_target_kinds_remain_distinct +// given: an msdmd edge target is not a repository or declaration identity +// then: retain it as an opaque external target; only empty, ambiguous declaration, or broken explicit declaration references become unresolved hmmm // class: safety // // id: organization_msdmd_reproducible_snapshot @@ -41,6 +41,7 @@ const GENERATED_OUT = 'src/_data/generated/orgMsdmd.json'; const SNAPSHOT_OUT = 'src/_data/snapshots/org-msdmd.last-known-good.json'; const COLLECTION_SUFFIX = '_msdmd.ts'; const COLLECTION_MARKER = 'defineMsdmdCollection('; +const HMMM_RESOLUTIONS = new Set(['empty-target', 'ambiguous-declaration', 'broken-explicit-declaration']); function sha256(value) { return createHash('sha256').update(value).digest('hex'); @@ -206,6 +207,11 @@ function normalizeRepoName(value) { return name; } +function collectionRepoMatches(value, repoName) { + if (!value) return true; + return value === repoName || value === `${ORGANIZATION}/${repoName}`; +} + function normalizeDeclaration(repoName, declaration) { const localId = String(declaration?.id || '').trim(); if (!localId) return null; @@ -221,9 +227,10 @@ function normalizeDeclaration(repoName, declaration) { function explicitRepoTarget(target, repoNames) { if (repoNames.has(target)) return { repo: target, declaration: null }; - const full = new RegExp(`^${ORGANIZATION.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/([^@#:\\s/]+)(?:@[^#:\\s]+)?(?:#{1}|::)(.+)$`).exec(target); + const escapedOrg = ORGANIZATION.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const full = new RegExp(`^${escapedOrg}/([^@#:\\s/]+)(?:@[^#:\\s]+)?(?:#{1}|::)(.+)$`).exec(target); if (full && repoNames.has(full[1])) return { repo: full[1], declaration: full[2].trim() || null }; - const fullRepo = new RegExp(`^${ORGANIZATION.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/([^@#:\\s/]+)(?:@[^#:\\s]+)?$`).exec(target); + const fullRepo = new RegExp(`^${escapedOrg}/([^@#:\\s/]+)(?:@[^#:\\s]+)?$`).exec(target); if (fullRepo && repoNames.has(fullRepo[1])) return { repo: fullRepo[1], declaration: null }; const scoped = /^([^:\s]+)::(.+)$/.exec(target); if (scoped && repoNames.has(scoped[1])) return { repo: scoped[1], declaration: scoped[2].trim() || null }; @@ -232,7 +239,7 @@ function explicitRepoTarget(target, repoNames) { function resolveEdgeTarget(sourceRepo, target, context) { const raw = String(target || '').trim(); - if (!raw) return { resolution: 'unresolved', targetId: null, targetRepo: null }; + if (!raw) return { resolution: 'empty-target', targetId: null, targetRepo: null }; const local = `${sourceRepo}::${raw}`; if (context.declarationIds.has(local)) { @@ -248,7 +255,7 @@ function resolveEdgeTarget(sourceRepo, target, context) { if (context.declarationIds.has(explicitId)) { return { resolution: 'explicit-declaration', targetId: explicitId, targetRepo: explicit.repo }; } - return { resolution: 'unresolved', targetId: null, targetRepo: explicit.repo }; + return { resolution: 'broken-explicit-declaration', targetId: null, targetRepo: explicit.repo }; } const global = context.globalIds.get(raw) || []; @@ -256,13 +263,20 @@ function resolveEdgeTarget(sourceRepo, target, context) { const [targetId] = global; return { resolution: 'unique-global-declaration', targetId, targetRepo: targetId.split('::')[0] }; } - return { resolution: 'unresolved', targetId: null, targetRepo: null }; + if (global.length > 1) { + return { resolution: 'ambiguous-declaration', targetId: null, targetRepo: null }; + } + return { resolution: 'external-target', targetId: null, targetRepo: null }; +} + +function isHmmmResolution(value) { + return HMMM_RESOLUTIONS.has(value); } function aggregateRepositoryEdges(edges) { const grouped = new Map(); for (const edge of edges) { - if (!edge.targetRepo || edge.targetRepo === edge.sourceRepo || edge.resolution === 'unresolved') continue; + if (!edge.targetRepo || edge.targetRepo === edge.sourceRepo || isHmmmResolution(edge.resolution)) continue; const key = `${edge.sourceRepo}\u0000${edge.targetRepo}`; const entry = grouped.get(key) || { from: edge.sourceRepo, @@ -314,7 +328,15 @@ export function buildOrgMap(repositoryInputs) { : null, error: item.collectionError || null }, - counts: { declarations: 0, gaps: 0, edges: 0, resolvedEdges: 0, unresolvedEdges: 0, crossRepoEdges: 0 }, + counts: { + declarations: 0, + gaps: 0, + edges: 0, + resolvedEdges: 0, + externalTargets: 0, + unresolvedEdges: 0, + crossRepoEdges: 0 + }, blockCounts: {}, hmmm }; @@ -325,7 +347,7 @@ export function buildOrgMap(repositoryInputs) { repositoryRows.push(row); continue; } - if (collection.repo && collection.repo !== item.name) { + if (!collectionRepoMatches(collection.repo, item.name)) { hmmm.push(`Collection declares repo=${collection.repo}; consumed repository is ${item.name}.`); } if (row.collection.sourceCommitMatchesHead === false) { @@ -365,10 +387,8 @@ export function buildOrgMap(repositoryInputs) { for (const row of repositoryRows) { for (const edge of row._rawEdges || []) { const sourceLocalId = String(edge?.from || edge?.source_id || 'hmmm'); - const sourceId = declarationIds.has(`${row.name}::${sourceLocalId}`) - ? `${row.name}::${sourceLocalId}` - : `${row.name}::${sourceLocalId}`; - const targetRaw = String(edge?.to || 'hmmm'); + const sourceId = `${row.name}::${sourceLocalId}`; + const targetRaw = String(edge?.to || ''); const resolved = resolveEdgeTarget(row.name, targetRaw, context); const normalized = { sourceRepo: row.name, @@ -383,9 +403,10 @@ export function buildOrgMap(repositoryInputs) { sourceDeclarationId: String(edge?.source_id || sourceLocalId) }; edges.push(normalized); - if (normalized.resolution === 'unresolved') row.counts.unresolvedEdges += 1; + if (isHmmmResolution(normalized.resolution)) row.counts.unresolvedEdges += 1; + else if (normalized.resolution === 'external-target') row.counts.externalTargets += 1; else row.counts.resolvedEdges += 1; - if (normalized.targetRepo && normalized.targetRepo !== row.name && normalized.resolution !== 'unresolved') { + if (normalized.targetRepo && normalized.targetRepo !== row.name && !isHmmmResolution(normalized.resolution)) { row.counts.crossRepoEdges += 1; } } @@ -393,11 +414,12 @@ export function buildOrgMap(repositoryInputs) { } const repositoryEdges = aggregateRepositoryEdges(edges); - const unresolvedEdges = edges.filter(edge => edge.resolution === 'unresolved'); + const unresolvedEdges = edges.filter(edge => isHmmmResolution(edge.resolution)); + const externalTargetCount = edges.filter(edge => edge.resolution === 'external-target').length; + const graphResolvedEdgeCount = edges.length - unresolvedEdges.length - externalTargetCount; const collectionCount = repositoryRows.filter(repo => repo.collection.status === 'ok').length; const invalidCollectionCount = repositoryRows.filter(repo => repo.collection.status === 'invalid').length; const missingCollectionCount = repositoryRows.length - collectionCount - invalidCollectionCount; - const resolvedEdgeCount = edges.length - unresolvedEdges.length; const latestHeadCommittedAt = repositoryRows .map(repo => repo.headCommittedAt) .filter(Boolean) @@ -429,7 +451,8 @@ export function buildOrgMap(repositoryInputs) { declarationCount: declarations.length, gapCount: gaps.length, edgeCount: edges.length, - resolvedEdgeCount, + resolvedEdgeCount: graphResolvedEdgeCount, + externalTargetCount, crossRepoEdgeCount: repositoryEdges.reduce((sum, edge) => sum + edge.count, 0), crossRepoPairCount: repositoryEdges.length, unresolvedEdgeCount: unresolvedEdges.length @@ -441,7 +464,7 @@ export function buildOrgMap(repositoryInputs) { repositoryEdges, unresolvedEdges: unresolvedEdges.sort((a, b) => a.sourceRepo.localeCompare(b.sourceRepo) || a.sourceId.localeCompare(b.sourceId) || a.targetRaw.localeCompare(b.targetRaw)), hmmm: [ - 'An unresolved edge means the source repository declared a target that cannot be exactly identified from current repo collection identities; the website does not guess the relation.', + 'Only empty, ambiguous declaration, and broken explicit declaration references are unresolved. Ordinary owners, routes, files, tools, capability names, and external systems remain valid opaque targets.', 'Missing collection points remain visible until the source repository publishes one.' ] }; @@ -507,7 +530,7 @@ async function main() { const data = buildOrgMap(inputs); await writeFile(GENERATED_OUT, stableJson(data)); await writeFile(SNAPSHOT_OUT, stableJson(data)); - console.log(`org-msdmd ${data.summary.collectionCount}/${data.summary.repositoryCount} collections · ${data.summary.crossRepoPairCount} cross-repo pairs · ${data.summary.unresolvedEdgeCount} unresolved edges`); + console.log(`org-msdmd ${data.summary.collectionCount}/${data.summary.repositoryCount} collections · ${data.summary.crossRepoPairCount} cross-repo pairs · ${data.summary.externalTargetCount} opaque targets · ${data.summary.unresolvedEdgeCount} hmmm edges`); } catch (error) { const fallback = JSON.parse(await readFile(SNAPSHOT_OUT, 'utf8')); fallback.fallback = true; From 4ef635c330b0c2a9469b3f8b1ee57db0e3bbd977 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 01:06:10 -0700 Subject: [PATCH 13/15] test(msdmd): preserve opaque target distinction --- tests/org-msdmd.test.mjs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/org-msdmd.test.mjs b/tests/org-msdmd.test.mjs index 18f1837..c093902 100644 --- a/tests/org-msdmd.test.mjs +++ b/tests/org-msdmd.test.mjs @@ -29,7 +29,7 @@ test('parses generated and hand-authored msdmd collection points without evaluat assert.equal(parsed.edges[0].kind, 'requires'); }); -test('resolves only exact cross-repo targets and retains unresolved edges', () => { +test('resolves exact graph targets, preserves opaque targets, and isolates true hmmm edges', () => { const inputs = [ { name: 'alpha', slug: 'alpha', defaultBranch: 'main', headSha: 'a'.repeat(40), headCommittedAt: '2026-08-15T00:00:00Z', @@ -39,7 +39,8 @@ test('resolves only exact cross-repo targets and retains unresolved edges', () = declarations: [{ file: 'src/a.py', block: 'DEPENDENCIES', id: 'alpha_dep', fields: {} }], edges: [ { from: 'alpha_dep', to: 'beta::beta_cap', kind: 'requires', source_block: 'DEPENDENCIES', source_id: 'alpha_dep' }, - { from: 'alpha_dep', to: 'looks-like-something', kind: 'requires', source_block: 'DEPENDENCIES', source_id: 'alpha_dep' } + { from: 'alpha_dep', to: 'node', kind: 'requires', source_block: 'DEPENDENCIES', source_id: 'alpha_dep' }, + { from: 'alpha_dep', to: 'The-Interdependency/beta#missing_cap', kind: 'requires', source_block: 'DEPENDENCIES', source_id: 'alpha_dep' } ] } }, @@ -47,7 +48,7 @@ test('resolves only exact cross-repo targets and retains unresolved edges', () = name: 'beta', slug: 'beta', defaultBranch: 'main', headSha: 'b'.repeat(40), headCommittedAt: '2026-08-16T00:00:00Z', collectionStatus: 'ok', collectionPath: 'beta_msdmd.ts', collectionSha256: '2'.repeat(64), collection: { - repo: 'beta', source_commit: 'b'.repeat(40), gaps: [], edges: [], + repo: 'The-Interdependency/beta', source_commit: 'b'.repeat(40), gaps: [], edges: [], declarations: [{ file: 'src/b.py', block: 'CAPABILITIES', id: 'beta_cap', fields: {} }] } }, @@ -64,12 +65,17 @@ test('resolves only exact cross-repo targets and retains unresolved edges', () = assert.equal(first.summary.collectionCount, 2); assert.equal(first.summary.missingCollectionCount, 1); assert.equal(first.summary.crossRepoPairCount, 1); + assert.equal(first.summary.externalTargetCount, 1); assert.equal(first.summary.unresolvedEdgeCount, 1); assert.deepEqual(first.repositoryEdges[0], { from: 'alpha', to: 'beta', count: 1, kinds: ['requires'], sourceBlocks: ['DEPENDENCIES'] }); - assert.equal(first.unresolvedEdges[0].targetRaw, 'looks-like-something'); + const opaque = first.edges.find(edge => edge.targetRaw === 'node'); + assert.equal(opaque.resolution, 'external-target'); + assert.equal(first.unresolvedEdges[0].targetRaw, 'The-Interdependency/beta#missing_cap'); + assert.equal(first.unresolvedEdges[0].resolution, 'broken-explicit-declaration'); assert.match(first.repositories.find(repo => repo.name === 'gamma').hmmm[0], /No consumable repo-level msdmd collection point/); + assert.equal(first.repositories.find(repo => repo.name === 'beta').hmmm.length, 0, 'full-name repo identity is accepted'); }); test('flags collection source commit drift without rejecting the source bytes', () => { From 68c41eb4c97db740f7986e7b7ef2422170d90365 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 01:06:26 -0700 Subject: [PATCH 14/15] fix(msdmd): display opaque targets separately from hmmm --- src/projects/map/index.njk | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/projects/map/index.njk b/src/projects/map/index.njk index 1ea2368..8602802 100644 --- a/src/projects/map/index.njk +++ b/src/projects/map/index.njk @@ -12,7 +12,7 @@ description: A build-time, provenance-bearing relationship map generated from re {{ map.summary.collectionCount }}/{{ map.summary.repositoryCount }} collections {{ map.summary.declarationCount }} declarations {{ map.summary.crossRepoPairCount }} cross-repo pairs - {% if map.summary.unresolvedEdgeCount %}{{ map.summary.unresolvedEdgeCount }} unresolved edges{% endif %} + {% if map.summary.unresolvedEdgeCount %}{{ map.summary.unresolvedEdgeCount }} hmmm edges{% endif %} {% if map.fallback %}last-known-good snapshot{% endif %} @@ -20,12 +20,13 @@ description: A build-time, provenance-bearing relationship map generated from re

Generated view

Relations currently visible

-

The graphic shows repository-level relations only when an msdmd edge resolves exactly across repository boundaries. Missing collections and unresolved targets remain visible rather than being inferred.

+

The graphic shows repository-level relations only when an msdmd edge resolves to a repository or declaration identity. Owners, routes, files, tools, capability names, and external systems remain valid opaque targets; only genuinely broken or ambiguous graph references become hmmm.

{{ map.summary.repositoryCount }}repositories
{{ map.summary.collectionCount }}collections
{{ map.summary.edgeCount }}declared edges
-
{{ map.summary.resolvedEdgeCount }}resolved edges
+
{{ map.summary.resolvedEdgeCount }}graph-resolved
+
{{ map.summary.externalTargetCount or 0 }}opaque targets
{{ map.summary.gapCount }}coverage gaps
{{ map.summary.unresolvedEdgeCount }}hmmm edges
@@ -50,9 +51,10 @@ description: A build-time, provenance-bearing relationship map generated from re
declarations
{{ repo.counts.declarations }}
edges
{{ repo.counts.edges }}
+
opaque
{{ repo.counts.externalTargets or 0 }}
gaps
{{ repo.counts.gaps }}
cross-repo
{{ repo.counts.crossRepoEdges }}
-
unresolved
{{ repo.counts.unresolvedEdges }}
+
hmmm
{{ repo.counts.unresolvedEdges }}
{% endfor %} @@ -78,15 +80,15 @@ description: A build-time, provenance-bearing relationship map generated from re

Resolution boundary

-

Unresolved edges

+

hmmm edges

{% if map.unresolvedEdges.length %}
- {{ map.unresolvedEdges.length }} declared targets remain unresolved + {{ map.unresolvedEdges.length }} declared graph targets remain genuinely unresolved
    - {% for edge in map.unresolvedEdges %}
  1. {{ edge.sourceId }} —{{ edge.kind }}→ {{ edge.targetRaw }}
  2. {% endfor %} + {% for edge in map.unresolvedEdges %}
  3. {{ edge.sourceId }} —{{ edge.kind }}→ {{ edge.targetRaw or 'hmmm' }} · {{ edge.resolution }}
  4. {% endfor %}
- {% else %}

No unresolved declared targets in this snapshot.

{% endif %} + {% else %}

No broken or ambiguous graph targets in this snapshot. Opaque non-graph targets remain represented in the machine artifact.

{% endif %}
From c19f8294e417a26e49f1a7d251a2ddb3b06f3aee Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Sun, 16 Aug 2026 01:06:37 -0700 Subject: [PATCH 15/15] chore(msdmd): align bootstrap target distinctions --- src/_data/snapshots/org-msdmd.last-known-good.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_data/snapshots/org-msdmd.last-known-good.json b/src/_data/snapshots/org-msdmd.last-known-good.json index 2c195a8..c0c4bd3 100644 --- a/src/_data/snapshots/org-msdmd.last-known-good.json +++ b/src/_data/snapshots/org-msdmd.last-known-good.json @@ -16,6 +16,7 @@ "gapCount": 0, "edgeCount": 0, "resolvedEdgeCount": 0, + "externalTargetCount": 0, "crossRepoEdgeCount": 0, "crossRepoPairCount": 0, "unresolvedEdgeCount": 0 @@ -29,7 +30,7 @@ "hmmm": [ "Bootstrap fallback: this checked-in artifact contains no repository collection evidence and must not be mistaken for an organization-state measurement.", "A successful online refresh replaces this file in the build workspace with a commit-pinned last-known-good snapshot.", - "An unresolved edge means the source repository declared a target that cannot be exactly identified from current repo collection identities; the website does not guess the relation.", + "Only empty, ambiguous declaration, and broken explicit declaration references are unresolved. Ordinary owners, routes, files, tools, capability names, and external systems remain valid opaque targets.", "Missing collection points remain visible until the source repository publishes one." ] }