Repository navigation
[Bug]: Repository evidence accepts annotated tag object IDs as commit SHAs #1129
Description
Archify version or commit
dev at 500d4a65211ffe607fde6b3ce7505027b45bb59e (2026-10-27).
Installation method
Git clone
Diagram type
Architecture
Exact command
Save the JSON below as /tmp/archify-tag-revision.json, then run from the Archify repository root. The script replaces the zero-SHA placeholder with a generated local annotated tag object ID before invoking the CLI. The origin URL is synthetic; no public repository is contacted or modified.
set -eu
archify_repro_dir=$(mktemp -d)
git -C "$archify_repro_dir" init -q
git -C "$archify_repro_dir" config user.name 'Synthetic research'
git -C "$archify_repro_dir" config user.email 'research@example.invalid'
git -C "$archify_repro_dir" remote add origin https://github.com/example/evidence-repo.git
printf '# Guide\n\nUseful documented behavior.\n' > "$archify_repro_dir/README.md"
git -C "$archify_repro_dir" add README.md
git -C "$archify_repro_dir" -c commit.gpgsign=false commit -m 'Synthetic fixture' >/dev/null
archify_commit=$(git -C "$archify_repro_dir" rev-parse HEAD)
git -C "$archify_repro_dir" -c tag.gpgsign=false tag -a v1 -m 'Annotated tag fixture'
archify_tag=$(git -C "$archify_repro_dir" rev-parse refs/tags/v1)
git -C "$archify_repro_dir" cat-file -t "$archify_tag" # prints: tag
node - /tmp/archify-tag-revision.json "$archify_repro_dir/diagram.json" "$archify_tag" <<'JS'
const fs = require('node:fs');
const [input, output, revision] = process.argv.slice(2);
const diagram = JSON.parse(fs.readFileSync(input, 'utf8'));
diagram.meta.repository.revision = revision;
fs.writeFileSync(output, JSON.stringify(diagram));
JS
node archify/bin/archify.mjs deliver architecture "$archify_repro_dir/diagram.json" "$archify_repro_dir/diagram.html" --json --repo-root "$archify_repro_dir"
node - "$archify_repro_dir/diagram.html" <<'JS'
const fs = require('node:fs');
const html = fs.readFileSync(process.argv[2], 'utf8');
const evidence = JSON.parse(html.match(/<script id="archify-source-evidence-data" type="application\/json">([\s\S]*?)<\/script>/)[1]);
console.log(JSON.stringify({ verified: evidence.verified, revision: evidence.repository.revision, href: evidence.nodes.docs[0].href }, null, 2));
JSMinimal redacted JSON reproduction
{
"schema_version": 1,
"diagram_type": "architecture",
"meta": {
"title": "Repository source link",
"output": "diagram.html",
"repository": {
"url": "https://github.com/example/evidence-repo",
"revision": "0000000000000000000000000000000000000000"
}
},
"components": [
{
"id": "docs",
"type": "backend",
"label": "Docs",
"pos": [
80,
80
],
"size": [
160,
80
],
"sources": [
{
"path": "README.md",
"line": 1,
"end_line": 3
}
]
}
],
"connections": []
}Validation receipt or exact error
git cat-file -t prints tag. Delivery still exits 0; the receipt's evidence.verified is true and evidence.revision contains that tag object ID. The embedded HTML also retains it as repository.revision and in source links. Relevant extracted fields (generated SHA redacted):
{"verified":true,"revision":"<tag-object-sha>","href":"https://github.com/example/evidence-repo/blob/<tag-object-sha>/README.md#L1-L3"}Expected behavior
The input must identify a commit object, as required by the authoring contract and existing revision diagnostic. Proposed behavior: reject a tag object ID with an actionable diagnostic directing the author to its peeled commit SHA. This stricter rejection still needs maintainer scope agreement.
Actual behavior
The revision check uses cat-file -e <sha>^{commit}. Git peels an annotated tag for this check, but the verifier then keeps the original tag object ID. The authoring defaults require a 40-character commit. This is not the same as a lightweight tag whose resolved object ID is already a commit.
Supporting visual evidence
No screenshot is needed for the local Git object-type result. A separate public check on 2026-10-27 confirms the visible link consequence: Git's v2.50.0 annotated tag object 192a0a2c points to commit 16bd9f20; the tag-object README URL returned HTTP 404, while the commit README URL returned HTTP 200. This public comparison is separate from the synthetic local fixture.
Environment
macOS 27.0.1 arm64; Node.js v25.2.1; Git 2.55.0. Codex (GPT-6) assisted inspection, reproduction, and report drafting. This is a constructed case found during code inspection, not an observed production incident.
Proposed scope and related work
Keep the fix to validating the originally supplied object type, preserving no-fetch/no-replace controls and accepted commit identities. Do not silently replace the supplied identity. Related work modifies the same module: #1063 (Enterprise source links), #1119 (task-checklist evidence), and #413 (Atlas/internal source evidence). Their inspected heads retain the peeling check; sequencing questions are linked above. PR #1049 resolves Git refs for snapshot comparison elsewhere. No implementation has started.
Final checks
- I searched existing issues for the same problem.
- I removed access tokens, credentials, private repository contents, and personal or customer data.
Activity
[-][Bug]: repository evidence accepts annotated tag object IDs as commit revisions[/-][+][Bug]: Repository evidence accepts annotated tag object IDs as commit SHAs[/+]