diff --git a/docs/SECURITY_AUDIT.md b/docs/SECURITY_AUDIT.md index ea882bc..b7598e4 100644 --- a/docs/SECURITY_AUDIT.md +++ b/docs/SECURITY_AUDIT.md @@ -163,10 +163,20 @@ important scanner counts in the tracker issue. The jscpd step is intentionally scoped to application and test source. It excludes documentation snippets, package manifests, generated translations, -public SVG assets, workflow YAML, and declarative backend schema JSON because -those reports produce metadata or asset repetition rather than actionable source -duplication. Keep exclusions narrow and create child issues for source-code -clusters that cross module ownership or make behavior harder to change safely. +public SVG assets and catalog output, workflow YAML, declarative backend schema +JSON, the generated migration baseline, and mirrored development migration +directories because those reports produce metadata or generated-source +repetition rather than actionable source duplication. Keep exclusions narrow +and create child issues for source-code clusters that cross module ownership or +make behavior harder to change safely. + +The 2026-08-02 full-workspace baseline covered 64 repositories and reported +1.82% duplicated lines before those generated-source exclusions. The reviewed +high-value clusters were catalog acceptance persistence, release publication +result assembly, and local WebUI JSON mutation wrappers. Similar Dataflow and +Workflow graph/governance code remains independently owned until its shared +contract is stable enough for Core; a raw similarity score is not grounds for a +module-to-module dependency. ## Image Freshness diff --git a/tools/checks/check-security-audit.sh b/tools/checks/check-security-audit.sh index 60ae309..5a4a3a3 100644 --- a/tools/checks/check-security-audit.sh +++ b/tools/checks/check-security-audit.sh @@ -851,6 +851,9 @@ run_jscpd() { "package.json" "**/generatedTranslations.ts" "**/docs/gitea-labels.json" + "**/docs/migration-release-baselines.json" + "**/public/catalogs/**" + "**/alembic/dev_versions/**" "**/*.md" "**/*.md:*" "*.md" diff --git a/tools/release/govoplan_release/publisher.py b/tools/release/govoplan_release/publisher.py index 5d66512..ed24cc1 100644 --- a/tools/release/govoplan_release/publisher.py +++ b/tools/release/govoplan_release/publisher.py @@ -484,31 +484,35 @@ def publish_catalog_candidate( ) ) + result_fields = { + "candidate_root": candidate_root, + "candidate_catalog": candidate_catalog, + "candidate_keyring": candidate_keyring, + "resolved_web_root": resolved_web_root, + "target_catalog": target_catalog, + "target_keyring": target_keyring, + "channel": channel, + "branch": effective_branch, + "tag_name": effective_tag_name, + "remote": remote, + "validation_valid": validation_valid, + "validation_error": validation_error, + "validation_warnings": validation_warnings, + "candidate_catalog_hash": candidate_catalog_hash, + "candidate_keyring_hash": candidate_keyring_hash, + "target_catalog_hash_before": target_catalog_hash_before, + "target_keyring_hash_before": target_keyring_hash_before, + "catalog_changed": catalog_changed, + "keyring_changed": keyring_changed, + } + if blockers: return result( status="blocked", applied=False, - candidate_root=candidate_root, - candidate_catalog=candidate_catalog, - candidate_keyring=candidate_keyring, - resolved_web_root=resolved_web_root, - target_catalog=target_catalog, - target_keyring=target_keyring, - channel=channel, - branch=effective_branch, - tag_name=effective_tag_name, - remote=remote, - validation_valid=validation_valid, - validation_error=validation_error, - validation_warnings=validation_warnings, - candidate_catalog_hash=candidate_catalog_hash, - candidate_keyring_hash=candidate_keyring_hash, - target_catalog_hash_before=target_catalog_hash_before, - target_keyring_hash_before=target_keyring_hash_before, - catalog_changed=catalog_changed, - keyring_changed=keyring_changed, steps=tuple(steps), notes=tuple([*notes, *blockers]), + **result_fields, ) if not apply: @@ -518,27 +522,9 @@ def publish_catalog_candidate( return result( status="ready", applied=False, - candidate_root=candidate_root, - candidate_catalog=candidate_catalog, - candidate_keyring=candidate_keyring, - resolved_web_root=resolved_web_root, - target_catalog=target_catalog, - target_keyring=target_keyring, - channel=channel, - branch=effective_branch, - tag_name=effective_tag_name, - remote=remote, - validation_valid=validation_valid, - validation_error=validation_error, - validation_warnings=validation_warnings, - candidate_catalog_hash=candidate_catalog_hash, - candidate_keyring_hash=candidate_keyring_hash, - target_catalog_hash_before=target_catalog_hash_before, - target_keyring_hash_before=target_keyring_hash_before, - catalog_changed=catalog_changed, - keyring_changed=keyring_changed, steps=tuple(steps), notes=tuple(notes), + **result_fields, ) directory_payloads = module_directory_payloads( @@ -615,11 +601,7 @@ def publish_catalog_candidate( publication_commit, ) _seal_git_metadata_file( - resolved_web_root - / ".git" - / "refs" - / "tags" - / effective_tag_name, + resolved_web_root / ".git" / "refs" / "tags" / effective_tag_name, label="website publication tag reference", ) publication_tag_object = git_text( @@ -704,30 +686,12 @@ def publish_catalog_candidate( return result( status="published" if push else "applied", applied=True, - candidate_root=candidate_root, - candidate_catalog=candidate_catalog, - candidate_keyring=candidate_keyring, - resolved_web_root=resolved_web_root, - target_catalog=target_catalog, - target_keyring=target_keyring, - channel=channel, - branch=effective_branch, - tag_name=effective_tag_name, - remote=remote, - validation_valid=validation_valid, - validation_error=validation_error, - validation_warnings=validation_warnings, - candidate_catalog_hash=candidate_catalog_hash, - candidate_keyring_hash=candidate_keyring_hash, - target_catalog_hash_before=target_catalog_hash_before, - target_keyring_hash_before=target_keyring_hash_before, - catalog_changed=catalog_changed, - keyring_changed=keyring_changed, publication_commit_sha=publication_commit, publication_tag_object_sha=publication_tag_object, publication_tag_commit_sha=publication_tag_commit, steps=tuple(completed_steps), notes=tuple(notes), + **result_fields, )