Repository navigation
fix(cli): validate the qa setup catalog root - #405
Conversation
Fleet review (glmflash)Lens: adversarial. The slice's core claim holds: setup now validates the existing canonical root before probing or writing, reuses the exact canonicality rule qa run depends on (canonicalProfileRoot: every component a real directory, no symlinks, via Lstat), never creates the tree on refusal (test asserts it), and pins the issue #324 repro end to end with a relative setup+run pair. I attacked the validation boundary and the setup/run agreement and found no blocking defect: the refusal paths are loud, the probe-order guarantee is proven by refusingPi, and the macOS /tmp policy is documented. Four non-blocking observations remain, two of them questions about the boundary this slice intentionally draws. Suggestion (2)
Question (2)
Verdict: ready to merge |
Post-merge QA (glm)Slice 4/8: qa setup now validates the catalog root through the same agreement qa run depends on (existing root, no symlinks, catalog.json present and regular) before probing models or writing, so a typo is refused without materializing a tree no run reads. Relative setup and run addresses the same profile source, pinned end-to-end by TestQASetupAndRunAgreeOnARelativeCatalog, and the refusingPi fixture proves the runtime is never probed before validation. Docs document the macOS /tmp canonical-path requirement. Nothing found that breaks what landed. Suggestion (1)
Verdict: clean |
Post-merge QA (deepseek)Lens: evidence + test design. Setup and run now agree on the same profile source: qa setup resolves the path with filepath.Abs before writing, validates the existing root, and refuses before probing models, which the refusingPi resolver proves directly (calls must stay 0). The relative-path end-to-end test reproduces the issue's example. One product question is left open: the slice makes an existing CLI surface stricter than the linked issue asked for, and the only place that decision is recorded is the operating guide. Question (1)
Verdict: clean |
Linked Issue
Refs #324
Umbrella: #401
PR Type
type:featureFeaturetype:bugBug fixtype:docsDocumentationtype:refactorRefactoringtype:choreMaintenancetype:breaking-changeBreaking changeSummary
Validate the existing canonical catalog root and catalog.json before qa setup probes or writes. Relative setup and run address the same profile source; invalid roots create no tree.
Changes
This is slice 4/8, 162 authored changed lines. Code, focused tests and applicable operating documentation stay together. Exact reviewed source commit:
47ab76063bcf8f23c88e6504ef7c65a595e013a5. Delivery head48aa19a7b343470ae2a527beddecefb475ea7414has the identical complete source tree.Focused Tests
Each cumulative prepared slice passed
go test ./internal/cli ./internal/qapi ./internal/qaroute ./internal/installobserve -count=1,go vet ./...and whitespace checks. Final candidate additionally passedgo test ./... -count=1,go vet ./...,go test -race ./...and all 15 repository Python policy tests on a byte-verified canonical clean snapshot. Independent source-agreement, typed-admission and final security verification passed with no severe blockers; final verification observed 19 named tests plus four package suites/vet.Native assessment of this exact slice: medium native tier, reviewDue=false (under_budget); no new native review started. Security-affecting slices retained explicit high-risk escalation and independent verification rather than treating assessment as proof. Parser's separately requested native review completed approved and acknowledged.
Runtime Harness
Disposable public CLI fixtures, no real provider calls. Rejections pin no launch/write effects, route identity and safe profile tokens. macOS /tmp is a symlink and intentionally refused: canonical snapshot cwd passed unchanged guards. No credentials changed.
Rollback
Revert this slice. Revert any dependent later slice first; no stored-data migration.
Chain Dependencies / Out of Scope
Sequential verified-main strategy: merged #404 -> [current slice 4/8] -> remaining slices. This PR targets main only after its predecessor lands, so its diff contains only this work unit. Do not close the umbrella from this intermediate slice.
Known acceptance limit: #329's literal transient/persistent causal distinction is NOT established by stage reporting and remains open. Defensive untyped branches, a currently unreachable non_nan_route mapping and a brittle wording assertion were disclosed as nonblocking verifier advisories, not silently fixed. Provider transport #345 and lifecycle #373 are out of scope.
Checklist
status:approved.type:*label is applied.