Repository navigation
TODO #2
Copy link
Copy link
Labels
bugSomething isn't workingSomething isn't workingdocumentationImprovements or additions to documentationImprovements or additions to documentationenhancementNew feature or requestNew feature or request
Description
User report of this issue
Last updated: 2026-01-22
Bugs
- Fix
-tophelp text (https://github.com/Asynkron/asynkron.quickdup/blob/main/cmd/quickdup/main.go) - Fix
-min-scorehelp text (https://github.com/Asynkron/asynkron.quickdup/blob/main/cmd/quickdup/main.go)
Docs
- Align README scoring text with
Score()(https://github.com/Asynkron/asynkron.quickdup/blob/main/cmd/quickdup/strategy_wordindent.go) - Align README
.quickdup/*filenames with actual outputs (https://github.com/Asynkron/asynkron.quickdup/blob/main/README.md) - Document caching scope (
word-indentonly today) (https://github.com/Asynkron/asynkron.quickdup/blob/main/cmd/quickdup/cache.go)
Features
- Add
--versionoutput (https://github.com/Asynkron/asynkron.quickdup/blob/main/cmd/quickdup/main.go) (PR #7) - Inject build version via GoReleaser
ldflags(https://github.com/asynkron/asynkron.quickdup/blob/main/.goreleaser.yaml) (PR #8)
Tests
- Add unit tests for scoring + ignore parsing (https://github.com/Asynkron/asynkron.quickdup/tree/main/cmd/quickdup) (PR #9)
Investigation
Delivery strictness: full - the complete outcome crosses CLI control flow, build-time release metadata, strategy-specific persisted filenames, documentation, and regression tests, and the repository's canonical quality-evidence producer is currently unavailable.
Current Evidence
- The clean task worktree is at
c700991(origin/main, tagv0.6.0). go run ./cmd/quickdup -hshows the already-correct-topwording (blended rank) and the replacement-min-rankwording (score + complexity); there is no remaining-min-scoreflag to repair.go run ./cmd/quickdup --versionexits withflag provided but not defined: -version. No version symbol/resolver exists in the currentcmd/quickduppackage..goreleaser.yamlcurrently uses only-s -w; it does not inject a release tag intomain.version.- Runtime paths are strategy-specific:
<strategy>-results.jsonincmd/quickdup/main.go,<strategy>-ignore.jsoninpkg/quickdup/filter.go, and<strategy>-cache.gobinpkg/quickdup/cache.go. Cache load/save deliberately supports onlyword-indent. README still names genericresults.json,cache.gob, andignore.jsonin its explanatory sections and does not explain the exact score formula. - Current tests contain only limited score assertions and no focused ignore parsing or cache/ignore filename coverage. Historical implementation commits exist on unmerged branches, but they target the pre-
pkg/quickduplayout and must be ported rather than cherry-picked. - Semantic source evidence confirms
cmd/quickdup.maincallspkg/quickdup.LoadIgnoredHashes, and both indent strategies reach the sharedscoreIndentShapeimplementation.
Blast Radius
cmd/quickdup/main.go- preserve the corrected rank help, add early--versionhandling, and make-no-cachehelp explicit about theword-indentscope.cmd/quickdup/version.go- new main-package version value and deterministic resolution for release, module-build, VCS-revision, and development builds.cmd/quickdup/version_test.go- focused version-resolution regression coverage..goreleaser.yaml- inject the release tag into the exactmain.versionsymbol while preserving strip flags.README.md- align score/rank semantics, strategy-specific result/cache/ignore filenames, and cache scope with current source.pkg/quickdup/filter.go- make ignore-hash parsing explicit and testable if needed to preserve documented raw, bracketed CLI, and0xforms and a safe empty result for missing/invalid files.pkg/quickdup/filter_test.go- new ignore file creation, filename, valid-variant, and invalid-input coverage.pkg/quickdup/strategy_score_test.go- new focused scoring coverage adapted to the shared strategy implementations.pkg/quickdup/cache_test.go- new strategy-specific filename and word-indent-only cache coverage carried forward from the issue comment.
Dependencies
- fk1 - repository canonical quality evidence is unavailable because
.faktorial/main-verify.jsonand declared producers are missing; implementation can be prepared, but the required finalrun-qualitygate cannot complete until that machine-owned repair lands.
User Stories
Story 1: As a QuickDup CLI operator, I want accurate help, version output, and documented output-state paths, so that I can invoke the tool and manage its generated files without guessing.
Story 2: As a QuickDup release maintainer, I want GoReleaser binaries to report their release tag and the behavior contract to be regression-tested, so that published artifacts are identifiable and completed maintenance work does not silently regress.
Approach
- Keep the current
-min-rankand-topbehavior; do not reintroduce obsolete-min-score. Add aversionflag that returns before scan setup or timeout behavior. Put resolution in a smallcmd/quickdup/version.gosurface withdevas the source default, optional Go build-info/VCS fallback, and an ldflags-overridablemain.version. - Update GoReleaser ldflags to retain
-s -wand add-X main.version={{.Tag}}. Exercise the resolver independently so local/development and injected release identities remain deterministic. - Treat current production code as the documentation source of truth. Document the indent-strategy score as the effective unique-word count after imbalance penalty, multiplied by
max(2*similarity-1, 0)^3, plus the integer pattern-length bonus; state separately that rank adds positive indentation complexity. Document<strategy>-results.json,<strategy>-ignore.json, and that onlyword-indentreads/writes<strategy>-cache.gob. - Port the intended tests into the current package boundaries. Cover word-only, word-indent, normalized-indent, and inlineable scoring; missing/invalid and raw/bracketed/
0xignore hashes; strategy-specific ignore/cache paths; and the non-cacheable strategies. Avoid copying old concrete entry layouts that were removed by the library split. - After
fk1restores repository-owned quality evidence, commit the coherent change and request Faktorial's canonicalrun-qualityverification. Do not substitute agent-run unit tests for that gate.
Risks
- The historical branches modify the old monolithic
cmd/quickduppackage; cherry-picking them would undo or conflict with the current library extraction. - GoReleaser injection silently fails if the symbol path or variable name differs from
main.version; version tests alone do not prove the release YAML wiring. - The default strategy is
normalized-indent, while caching currently exists only forword-indent; broad cache wording would remain misleading even if the filename were corrected. - Score tests can become implementation snapshots. Assert the documented behavior at meaningful boundary cases while preserving strategy-specific semantics.
- Tests touching package globals such as
ActiveStrategy,CommentPrefix, or build-info hooks must restore state and must not use unsafe parallel execution.
Additional quality gates
- Canonical quality evidence - Do not advance to review until
fk1restores declared repository producers and Faktorial accepts complete build/test evidence fromrun-quality.
| Requested behavior | Risk lane | Lane evidence | Required proof or judgment | Buyer consequence if missing | Stop or downgrade trigger |
|---|---|---|---|---|---|
| Restore the complete issue #2 CLI, release, docs, and regression contract | full | Current main rejects --version, release ldflags omit the version, documentation contradicts persisted paths, and canonical evidence configuration is missing |
Accepted repository run-quality evidence after fk1, plus source/config review of the version injection and documentation contract |
Users can receive unidentifiable releases, misleading file guidance, or silently regressed parsing/scoring behavior | Stop before review while fk1 is unresolved or evidence is missing/invalid; return to build on any behavior, test, or config mismatch |
Recommended Labels
- bug
- documentation
- enhancement
Acceptance Criteria (Refined)
- AC-1: CLI help continues to describe
-topas ranking by blended rank and-min-rankas the score-plus-complexity threshold; the obsolete-min-scoreflag is not reintroduced. - AC-2:
quickdup --versionprints exactly onequickdup <identity>line and exits successfully before scanning, creating.quickdupstate, or starting timeout work. - AC-3: Development/module builds have a deterministic non-empty fallback identity, and a build with
-X main.version=vX.Y.Zreports that injected identity. - AC-4: GoReleaser preserves its existing stripping flags and injects
{{.Tag}}into the samemain.versionsymbol consumed by the CLI. - AC-5: README accurately describes the current scoring curve and imbalance/length terms, distinguishes score from blended rank, and matches the current 0.75 similarity default.
- AC-6: README and CLI help identify
<strategy>-results.json,<strategy>-ignore.json, andword-indent-cache.gobbehavior accurately, without implying that the defaultnormalized-indentstrategy is cached. - AC-7: Focused tests cover scoring for all current strategies and ignore parsing/file creation for raw, bracketed,
0x, invalid, and missing inputs using the currentpkg/quickdupAPIs. - AC-8: Focused tests cover strategy-specific cache/ignore filenames and prove that cache persistence is skipped for non-
word-indentstrategies. - AC-9: After
fk1completes, the committed change receives accepted canonicalrun-qualitybuild/test evidence before review.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingdocumentationImprovements or additions to documentationImprovements or additions to documentationenhancementNew feature or requestNew feature or request
Activity
rogeralsing commentedon Jan 22, 2026
Update: PR #5 covers the README filename alignment and now includes unit tests for strategy-specific cache/ignore filenames.
faktorial-ai commentedon Jul 16, 2026
Build Update
Committed
9392977(Restore QuickDup CLI maintenance contract).What changed
--versionhandling before scan globals, timeout work, or filesystem state, with exactquickdup <identity>output and deterministic injected, module, VCS, and development identities incmd/quickdup/version.go.-s -wflags and added-X main.version={{.Tag}}against the symbol consumed by the CLI.0xhexadecimal forms, reject malformed values, and return a safe empty map for missing or invalid files. Runtime output now names the strategy-specific ignore file.<strategy>-results.json,<strategy>-ignore.json, and word-indent-onlyword-indent-cache.gob. The obsolete-min-scoreflag remains absent.Evidence and verification
flag.Parseand beforequickdup.Debugor timeout setup..goreleaser.yamlcontains-s -w -X main.version={{.Tag}}; documentation scans found all canonical filenames and no-min-scoreoccurrence.git diff --cached --checkpassed before commit; the post-commit worktree was clean and one commit ahead oforigin/main.run-qualityis requested for the committed branch.GET /api/quickdupreview signal returned HTTP 503; feedback was recorded for taskgh2. This did not block the source/config proofs or canonical handoff.Durable artifacts and runtime notes
No ADR or prevention rule was required because this restores an existing CLI contract without a new architecture or policy decision. No Faktorial runtime notes or compliance-specific artifacts were present; no generated assets were created.
Material skills
Skill: golang-cli
Why used: Preserve the existing standard-library flag CLI while adding early version output and linker-injected release identity.
Artifact:
cmd/quickdup/version.go,cmd/quickdup/main.go,.goreleaser.yamlOutcome: applied
Verification/follow-up: Faktorial
run-qualitymust verify the committed binary/test contract.Skill: golang-testing
Why used: Shape focused regressions as named behavioral cases against the current package split without unsafe parallel global mutation.
Artifact:
cmd/quickdup/version_test.go,pkg/quickdup/filter_test.go,pkg/quickdup/cache_test.go,pkg/quickdup/strategy_score_test.goOutcome: applied
Verification/follow-up: Tests are intentionally delegated to Faktorial's canonical gate.
Skill: golang-documentation
Why used: Keep README and CLI help concise and source-accurate for scoring, rank, persisted filenames, and cache scope.
Artifact:
README.md,cmd/quickdup/main.go,cmd/quickdup/output.goOutcome: applied
Verification/follow-up: Review should compare the prose and help strings with the current strategy/cache implementations.
faktorial-ai commentedon Jul 16, 2026
Build Update
Focused verification repair
.faktorial/main-verify.jsonwas absent.fk1is complete and its commitd6310cdreceived accepted canonical evidence (1/1 commands passed) for the repository-owned adapter.5fda452on top of the original gh2 implementation commit9392977. The adapter declaresmain-verify.v2, runs the repository-native Go evidence producer, emits one requiredtest-results.v1envelope, and includes focused adapter conformance coverage.Static evidence
python3 -m json.tool .faktorial/main-verify.jsonpassed.git diff --check origin/main...HEADpassed.origin/agent-go/task-gh2.Durable artifacts and runtime notes
The repository quality adapter is the required durable verification artifact. No ADR or prevention rule was added because the adapter implements the already-established Faktorial evidence contract and was independently delivered and accepted by
fk1. No Faktorial runtime notes or compliance-specific context were present, and no generated assets were created.Material skills
Skill: golang-continuous-integration
Why used: Diagnose the missing repository quality gate and reuse the repository-owned, already-verified evidence producer instead of creating a competing pipeline.
Artifact:
.faktorial/main-verify.json,scripts/quality_evidence.py,scripts/test_quality_evidence.pyOutcome: applied
Verification/follow-up: Faktorial
run-qualitymust execute the committed adapter and review the complete gh2 change.faktorial-ai commentedon Jul 16, 2026
Build Update
Focused verification repair
TestWordIndentCacheUsesStrategySpecificFile:LoadCache()returned nil afterSaveCache().WordIndentEntryto embed the unexportedindentEntry.encoding/gobtherefore had no serializable fields for that value;SaveCacheignored the encode error and left an unreadable cache file.4ee1539(Fix word-indent cache serialization).What changed
GobEncode/GobDecodemethods backed by a private wire struct, preserving the existing exportedFileCache/CachedFileAPI and keepingindentEntryinternal.newIndentEntry, restoring the derived hash bytes that pattern detection consumes.Static evidence and verification
CachedFile.Entries []WordIndentEntryand the unexported embeddedindentEntry; pre-split history showed the entry previously exposed serializable fields directly.newIndentEntry, and the derived-hash regression assertion.gofmtandgit diff --checkpassed; the post-commit worktree was clean and HEAD was4ee1539, one commit ahead oforigin/agent-go/task-gh2.run-qualityis requested for the committed branch.Durable artifacts and runtime notes
No ADR, prevention rule, compliance artifact, generated asset, or runtime note was required: this is a backward-incompatible cache-format repair for derived local state, explicitly invalidated by the cache version. The committed repository quality adapter remains the durable verification artifact.
Material skills
Skill: golang-troubleshooting
Why used: Trace the single deterministic verifier failure through cache save/load and the library-split type history.
Artifact:
pkg/quickdup/cache.goOutcome: applied
Verification/follow-up: Faktorial
run-qualitymust execute the cache regression and full repository evidence.Skill: golang-safety
Why used: Restore derived hash state during decode while keeping the internal entry representation encapsulated.
Artifact:
pkg/quickdup/cache.goOutcome: applied
Verification/follow-up: Canonical tests must confirm loaded entries retain behavior, not only persisted display fields.
Skill: golang-testing
Why used: Strengthen the existing behavioral regression around the complete cache round trip without adding a parallel or implementation-only test surface.
Artifact:
pkg/quickdup/cache_test.goOutcome: applied
Verification/follow-up: Test execution is intentionally delegated to Faktorial's canonical gate.
faktorial-ai commentedon Jul 16, 2026
Review Cache
{ "version": 1, "task_id": "gh2", "pr": 12, "base_ref": "origin/main", "review_commit": "4ee1539388ed827c5ff415cea26735040d29c2c7", "entries": [ { "path": ".faktorial/main-verify.json", "status": "ok", "blob": "8a76d31db6b3f4f566f87be97451e28c5fc65b93", "diff": "1164eee191ed74584c4c6cfe02bbc53c9065f17cb2f0cead4cd8a74e9503b57f", "checked": [ "evidence" ], "note": "Declares the accepted Go evidence producer and required schema." }, { "path": ".gitignore", "status": "ok", "blob": "045fc62b66b8b64cf51bd2f920f7e84271495507", "diff": "90570bfd4f6b5c5938791d6428e043dc95d6f7e7141c3d8b32ae0e0dd217e59c", "checked": [ "scope" ], "note": "Ignores Python bytecode generated by the evidence tooling." }, { "path": ".goreleaser.yaml", "status": "ok", "blob": "02eff4655676e1321089cb7b757dbbc65212df0c", "diff": "ef70de7c6545d88c97caddcbe8ebbfea8345d1f1bd58e84d5fa6cba6425f434d", "checked": [ "release" ], "note": "Preserves -s -w and injects the tag into main.version." }, { "path": "README.md", "status": "ok", "blob": "812f55979904fb2a5de5dcbe5aeaa5e2723790bd", "diff": "9d587073dbec9f5d96432e3f10ff81b7e71a0703e1f04cf058a51f700bcc07fd", "checked": [ "docs" ], "note": "Matches scoring, rank, defaults, strategy filenames, and cache scope." }, { "path": "cmd/quickdup/main.go", "status": "ok", "blob": "37b8cfca2832d376133aa3995ef09a53ff309e58", "diff": "b348b742f224d1748d82d8bb715acdba025bc5284305c4e0bca09127ba0cbfd4", "checked": [ "cli", "help" ], "note": "Version exits immediately after parsing and help retains the required rank wording." }, { "path": "cmd/quickdup/output.go", "status": "ok", "blob": "3dbc6ce31ef472c22556e23a38387edc6b13c0e8", "diff": "d11ca0445fb6ba85fbe97456a148a6a18d6104e8db3e1ec245fa36a50f08fcff", "checked": [ "paths" ], "note": "Reports the strategy-specific ignore filename." }, { "path": "cmd/quickdup/version.go", "status": "ok", "blob": "4448ba8170b55bda6b2ee0dffb6e9f0b31e680a8", "diff": "7342882167d27b0ce1f7030d6fad65ef225bda0e53a231cb507e435d15fe4924", "checked": [ "version" ], "note": "Provides injected, module, VCS, and deterministic development identities." }, { "path": "cmd/quickdup/version_test.go", "status": "ok", "blob": "9c36bcf7bc4c7996f8461e2f005a60ba75f130eb", "diff": "5159c2775056adeff8deb6918f6d3959fff5f9f846e830498e5a57d751e2e9a6", "checked": [ "tests" ], "note": "Covers identity precedence, fallbacks, restoration, and exact one-line output." }, { "path": "pkg/quickdup/cache.go", "status": "ok", "blob": "233a1c2fb745d0009cd40878d44ea0633d815424", "diff": "571a4f597a1fd11ead8759d45260dbb2ce8c7795dedadea67d40bc59ac5dea01", "checked": [ "cache", "safety" ], "note": "Version 2 gob round trips internal entries and reconstructs derived hash bytes." }, { "path": "pkg/quickdup/cache_test.go", "status": "ok", "blob": "072617f3df698b5a69bcf836a4e82509367b954b", "diff": "d02f651093ad9aa68c351ce599dae043af633a089cda0aa7fffb31ccf5dba338", "checked": [ "tests" ], "note": "Covers the word-indent round trip and all non-cacheable strategies." }, { "path": "pkg/quickdup/filter.go", "status": "ok", "blob": "1d5078a3fbc98fbe80c730a6616fd88461b9edf2", "diff": "e6c0b4c6ab2b695d04129d60c2e69d456e1b1ddde7d4a2d7d6640709276ccf09", "checked": [ "ignore" ], "note": "Parses documented hash forms and safely handles missing or invalid files." }, { "path": "pkg/quickdup/filter_test.go", "status": "ok", "blob": "2bcd64f910f798819bfedad4e151f5aa86cd21b0", "diff": "62b571d5d0b02cf75f7dddbb1d3f6913743f434773a47f56593d220b8ca03f5e", "checked": [ "tests" ], "note": "Covers raw, bracketed, prefixed, invalid, missing, and filename behavior." }, { "path": "pkg/quickdup/strategy_score_test.go", "status": "ok", "blob": "6720c437141768f22070ee4a943b72d88f6dacd1", "diff": "8703f3b2774cefc32fc002f1b1bee477777e0e8b361d8df1d69250270fc9e052", "checked": [ "score" ], "note": "Covers all four strategies at meaningful scoring boundaries." }, { "path": "pkg/quickdup/types.go", "status": "ok", "blob": "81a91059940022c0a657fa6f6ab06cf1672c9a92", "diff": "b3152ad42d13421153d8284985e8e42192307d25bfbdec91a693e61b082e7c45", "checked": [ "docs" ], "note": "Updates the ignore-file contract comment to the strategy-specific shape." }, { "path": "scripts/quality_evidence.py", "status": "ok", "blob": "15c06d47742868f3c2ae475eb5752ece430284dc", "diff": "252f49b7c7a7d8dc3fdec9107a75e61cb52bfdd02db017bfad47a091640bde63", "checked": [ "evidence" ], "note": "Runs uncached Go tests and atomically translates exact terminal evidence." }, { "path": "scripts/test_quality_evidence.py", "status": "ok", "blob": "48905801a0cda53a40dd4ed88927cb36b9dd0654", "diff": "aa1a1bf7916e2695d009cc3acdc4351bbac7d1ab1c1c2552e312aefb9c33c551", "checked": [ "contract" ], "note": "Covers config alignment, translation failures, and evidence-set conformance." } ] }Agent: issue #2 (#12)
faktorial-ai commentedon Jul 16, 2026
Delivery Summary
Why this was built
QuickDup's maintenance contract had drifted after the library split: operators could not identify a running binary with
--version, release builds did not report their tag, and the documented scoring, generated filenames, and cache scope no longer matched runtime behavior.Problem it solves
Operators can now identify the exact QuickDup build before any scan begins, understand how score differs from blended rank, and reliably find strategy-specific result and ignore files. The delivery also prevents
word-indentcache files from becoming unreadable because internal entry fields were not serializable.What changed
The CLI now prints exactly
quickdup <identity>and exits before timeout or filesystem setup, resolving identity from release injection, module/VCS metadata, or a deterministic development fallback. GoReleaser injects the release tag while retaining stripped binaries. Help and README guidance now match the 0.75 similarity default, the score-plus-complexity rank model, strategy-specific result/ignore filenames, and the fact that onlyword-indentis cached. Ignore parsing accepts the documented raw, bracketed, and0xhash forms while safely handling missing or malformed files. Cache persistence now uses a version 2 wire format that round-trips internal entries and reconstructs their derived hash bytes. Focused regressions cover version behavior, all four scoring strategies, ignore handling, and cache eligibility/round-tripping; canonical evidence passed all 43 recorded tests.Visual explanation
The implementation kept the existing rank flags and strategy model intact, then added two bounded paths around them. Version reporting is an early-exit control path so asking for identity cannot create scan state. Normal scans continue through the selected strategy, but persisted state is named per strategy and cache I/O is explicitly gated to
word-indent. Because caches are derived local data, the serialization repair intentionally bumps the format instead of attempting to read structurally broken cache entries.flowchart LR A["quickdup --version"] --> B["Resolve release, module, VCS, or dev identity"] B --> C["Print one line and exit before scan or state"] D["Run selected duplicate strategy"] --> E["Score matches and add indentation complexity to rank"] E --> F["Write strategy-specific results and ignore state"] D --> G{"word-indent strategy?"} G -- Yes --> H["Use version 2 cache and restore derived hash bytes"] G -- No --> I["Skip cache persistence"] J["Focused regressions and canonical gate: 43/43 passed"] --> C J --> F J --> H