feat(dry-run): tag-selection observability#85
Merged
Conversation
- Add FilterConfig::apply_with_report() returning Outcome { kept, report }
with per-stage attrition and Pareto-sorted drop attribution. apply()
delegates and re-checks min_tags. Existing callers stay drop-in.
- ResolvedMapping carries candidates: Option<usize> and filter_report:
Option<Report>. None on the exact-tag fast path.
- synchronize::run emits one INFO line per mapping with per-line targets:
"{source} -> {target}: {kept} of {N} tags => [t1, t2]".
- New src/cli/commands/dry_run.rs writer-based formatter renders linear
and include-path layouts with sample cap (5 by default, removed under
-v). System-exclude rows surface a hint pointing at include:.
- Default log format is text everywhere; --log-format json opts in.
Removed KUBERNETES_SERVICE_HOST auto-detection.
- Chart values.yaml gains logging.format (default text); _pod.tpl wires
--log-format. Existing chart-deployed installs switch from JSON to
text on upgrade; set logging.format: json to keep JSON output.
Dry-run output is the user's primary tool for confirming what will sync. Two gaps closed and one efficiency fix: - Surface min_tags status: when configured and unsatisfied, real-sync errors with BelowMinTags. The formatter now prints "min_tags: N (kept M, real sync will FAIL with BelowMinTags)" so the configuration can be fixed before running. - Show include-rescued tag names: include_kept moves from a count to a Vec<String> so operators can verify their include: patterns matched what they intended. Rescued tags also get a [via include] marker in the kept section. - Hot path: gate the report's Vec<String> materialization on track so the watch-mode loop pays no allocation for drop attribution. Cleanups: - Rename filter::Outcome -> Filtered; FilterReport.candidates -> candidate_count. - Extract partition_with_drop / push_drop_reason helpers for the glob and semver stages (single-pass kept + dropped). - Slim formatter signatures to take primitives (kept count, min_tags) instead of &ResolvedMapping + &FilterReport where only counts are needed. Tests: - New filter.rs tests cover min_tags round-trip, include-rescued names, and the single-pass attribution invariant. - New synchronize.rs E2E tests exercise the full path through select_filtered_tags + ResolvedMapping + dry_run::write_to, catching wire-up regressions. Chart and docs: - charts/ocync/templates/NOTES.txt prints the active log format and, when text, a one-time upgrade hint about the JSON->text default flip. - cli-reference.md gains a Dry-run output section explaining each rendered section and the -v sample-uncap interaction. - observability.md notes that -v also uncaps dry-run sample lists.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
{source} -> {target}: {kept} of {N} tags => [t1, t2]. Operators see at a glance which tags survived filtering and where they're going.--dry-runnow renders the full filter trace per mapping:source candidates,include path(rescued tag names with sample cap),pipelinestages with attrition,kepttags (with[via include]markers on rescued tags),droppedPareto-sorted by reason with samples, andmin_tagsstatus. Whenmin_tagsis configured but unsatisfied, the formatter prints(kept M, real sync will FAIL with BelowMinTags)so the configuration can be fixed before running.-vremoves the per-reason sample cap.texteverywhere (was JSON-by-default in Kubernetes viaKUBERNETES_SERVICE_HOSTauto-detection). The chart'slogging.formatvalue (defaulttext) drives--log-format, and a newtemplates/NOTES.txtshows a one-time upgrade hint when the default is in use. Setlogging.format: jsonto keep structured logs.apply_with_report()returningFiltered { kept, report }. The report carriescandidate_count,include_kept(rescued tag names), pipeline stages, Pareto-sorted drop reasons, andmin_tags. Hot-pathapply()skips drop attribution to avoid per-cycle allocations on the watch loop.partition_with_dropandpush_drop_reasonhelpers consolidate the per-stage single-pass tracking.Test plan
cargo fmt --checkcargo clippy --workspace --all-targets -- -D warningscargo test --workspace(1333 passed)cargo deny checknpm run --prefix docs buildhelm unittest charts/ocync(63 tests passed)helm install --dry-runconfirmsNOTES.txtrenders with the upgrade hint whenlogging.format=textand suppresses it whenlogging.format=jsonmin_tagsround-trip (configured/satisfied/absent), and the single-pass attribution invariantselect_filtered_tags->ResolvedMapping->dry_run::write_to, catching wire-up regressionsmin_tagsstatus (satisfied / FAIL / absent / blank-separator), include-rescue rendering and verbose-uncap, and the full mapping render with both[via include]markers and the FAIL warning