From 981c0b74fa1c16945809c82db97d24af3d3aa2dd Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:37:09 +0200 Subject: [PATCH 1/8] Define public materials review process Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- docs/legal/PUBLIC-MATERIALS-REVIEW.md | 95 +++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 docs/legal/PUBLIC-MATERIALS-REVIEW.md diff --git a/docs/legal/PUBLIC-MATERIALS-REVIEW.md b/docs/legal/PUBLIC-MATERIALS-REVIEW.md new file mode 100644 index 00000000..2f28394a --- /dev/null +++ b/docs/legal/PUBLIC-MATERIALS-REVIEW.md @@ -0,0 +1,95 @@ +# Public materials, third-party names and asset review + +## Purpose + +This process controls SightAdapt materials that mention third-party products, display third-party names or assets, make compatibility statements, or discuss protected content and digital-rights management (DRM). + +The authoritative notice is `THIRD-PARTY-NAMES-AND-DRM-NOTICE.txt`. `release/public-materials.json` records the exact maintained surfaces and their reviewed Git blob identities. Internal review is a maintainer risk control, not legal advice, trademark clearance or permission from a third party. + +## Maintained versus planned surfaces + +A surface is `maintained` only when it is listed in the registry with: + +- an exact source or evidence path; +- an immutable Git blob SHA; +- a review date and reviewer; +- the third-party names and compatibility claims it contains; +- every third-party asset and its documented use basis, or an explicit empty asset list; +- an `approved` review result. + +A future website page, GitHub Release, store listing, directory entry, mirror, social profile, announcement, screenshot or video remains `planned` until its implementation adds exact evidence and passes `tools/verify-public-materials.ps1`. + +## Compatibility statements + +Use narrow factual wording such as: + +- `works with user-selected Windows applications`; +- `tested with `; +- `compatible with supported application windows`; +- `uses Windows Magnification API`; +- `applies an overlay to an application selected by the user`. + +A named statement must identify the tested version when practical and state relevant limits. Do not use `official integration`, `partner`, `approved by`, `certified by`, `endorsed by`, `supported by` or similar wording unless a current written relationship authorizes that exact statement. + +## Screenshots, logos and other assets + +Prefer SightAdapt-controlled interfaces, project-owned sample content and the canonical SightAdapt brand assets. A material must not include a third-party logo, branded icon, screenshot dominated by third-party trade dress, certification badge or promotional asset unless the registry records: + +- the owner or source; +- the exact asset path and Git blob SHA or archived evidence; +- the use basis or permission record; +- the approved purpose and surface; +- the review date and reviewer. + +Locally displayed application icons and file metadata are identification data, not SightAdapt brand assets. Do not reuse them in project-controlled marketing without a separate recorded review. + +## About window + +The current About window was reviewed as an application-owned surface. It contains SightAdapt's own product identity, version, publisher, website, repository and license. It does not contain a named third-party application, third-party logo, partnership statement or endorsement claim. A change to About content or assets requires a registry update and review. + +## Protected content and DRM + +SightAdapt is not intended to decrypt, unlock, evade, bypass or interfere with DRM, authentication, licensing, encryption, capture prevention or another access control. Protected content may remain blank, unavailable, unchanged or unfilterable. Do not publish troubleshooting or compatibility material that describes bypassing those restrictions. + +## Publication workflow + +Before publishing or materially updating a controlled surface: + +1. add or update its registry entry; +2. record every named third party, compatibility statement and asset; +3. archive the final text or asset in the repository where practical; +4. record the exact Git blob SHA or other immutable evidence; +5. run `tools/verify-public-materials.ps1` and its negative tests; +6. obtain the maintainer review recorded in the registry; +7. publish only the reviewed bytes or text; +8. record the public URL and publication date when the channel becomes active. + +A public account requiring private credentials is managed interactively, but its final public text and assets must still be represented by repository evidence. + +## Objection or correction procedure + +When a rights holder or platform objects to a name, mark, screenshot, compatibility statement or asset: + +1. preserve the objection privately when it contains personal or confidential information; +2. archive or hash the affected public material and record its URL and date; +3. pause new publication or promotion of the disputed material; +4. create or update a GitHub Issue with a non-confidential summary; +5. remove, neutralize or replace the material when continued use is not supported by the recorded basis; +6. update the registry, notice and dependent surfaces; +7. rerun the public-material and release-package gates; +8. record the maintainer decision and any conditions before republication. + +Do not send automated legal notices or claim that the internal review determines trademark rights. + +## Re-review triggers + +Repeat review when: + +- a new public surface is activated; +- a named product/version compatibility claim is added or changed; +- a third-party logo, icon, screenshot, badge or trade dress is proposed; +- an endorsement, partnership or certification is proposed; +- protected-content behavior changes; +- the SightAdapt trademark-risk record changes; +- a third party objects; +- a source path or pinned Git blob SHA changes. From 54970e230d23cf2b23f558d2fa339ceaeecb7af1 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:38:28 +0200 Subject: [PATCH 2/8] Register reviewed public materials Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- release/public-materials.json | 299 ++++++++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 release/public-materials.json diff --git a/release/public-materials.json b/release/public-materials.json new file mode 100644 index 00000000..7e46524a --- /dev/null +++ b/release/public-materials.json @@ -0,0 +1,299 @@ +{ + "schemaVersion": 1, + "reviewedAt": "2026-07-31", + "decisionOwner": "KeyffMS / aiteracja.pl", + "decisionIssue": 92, + "reviewType": "internal-maintainer-risk-control", + "limitations": [ + "This record is not legal advice, trademark clearance or third-party permission.", + "Only exact maintained surfaces listed below are approved by this record.", + "Planned or externally managed surfaces require their own final-text and asset review before activation." + ], + "authoritativeNotice": { + "path": "THIRD-PARTY-NAMES-AND-DRM-NOTICE.txt", + "gitBlobSha": "d71f384508d2e2abdf3b78f85516f01d9b0cf799", + "approvedSummary": "Third-party product names and trademarks are the property of their respective owners and are used only to identify applications selected or configured by the user. SightAdapt is not affiliated with, sponsored by or endorsed by Microsoft or those owners unless an explicit written relationship is identified. SightAdapt does not circumvent DRM or other access controls, and protected content may remain unavailable or unfilterable." + }, + "reviewAuthorities": [ + { + "path": "docs/legal/THIRD-PARTY-NAMES-AFFILIATION-AND-DRM.md", + "gitBlobSha": "97565d113169afbb2a363e37fc8371927f3b7eaa" + }, + { + "path": "docs/legal/TRADEMARK-CLEARANCE-2026-07-27.md", + "gitBlobSha": "cee7ebf580597c7273e40b6807418bb3953e6ce4" + }, + { + "path": "docs/legal/PUBLIC-MATERIALS-REVIEW.md", + "gitBlobSha": "2f28394af42df60e7c0149b77fd8a76037feb2e0" + } + ], + "maintainedSurfaces": [ + { + "id": "repository-readme", + "kind": "repository-document", + "status": "approved", + "reviewedAt": "2026-07-31", + "reviewer": "KeyffMS / aiteracja.pl", + "sourceEvidence": [ + { + "path": "README.md", + "gitBlobSha": "7176f70d577039464dad56fc93866f1d13d17431" + } + ], + "namedThirdParties": [ + { + "name": "Microsoft", + "purpose": "platform and no-endorsement identification" + }, + { + "name": "Windows", + "purpose": "supported operating-system identification" + }, + { + "name": ".NET", + "purpose": "runtime identification" + } + ], + "compatibilityClaims": [ + { + "wording": "works with user-selected Windows applications", + "limitations": "Compatibility depends on application framework, privilege level, protected content, remote sessions and graphics behavior." + } + ], + "thirdPartyAssets": [] + }, + { + "id": "binary-third-party-names-notice", + "kind": "binary-legal-document", + "status": "approved", + "reviewedAt": "2026-07-31", + "reviewer": "KeyffMS / aiteracja.pl", + "sourceEvidence": [ + { + "path": "THIRD-PARTY-NAMES-AND-DRM-NOTICE.txt", + "gitBlobSha": "d71f384508d2e2abdf3b78f85516f01d9b0cf799" + } + ], + "namedThirdParties": [ + { + "name": "Microsoft", + "purpose": "platform, runtime and no-endorsement identification" + }, + { + "name": "Windows", + "purpose": "operating-system platform identification" + }, + { + "name": ".NET", + "purpose": "runtime component identification" + } + ], + "compatibilityClaims": [ + { + "wording": "uses Windows Magnification API", + "limitations": "Protected surfaces and application-specific graphics behavior may remain unavailable or unfilterable." + } + ], + "thirdPartyAssets": [] + }, + { + "id": "repository-third-party-policy", + "kind": "repository-policy", + "status": "approved", + "reviewedAt": "2026-07-31", + "reviewer": "KeyffMS / aiteracja.pl", + "sourceEvidence": [ + { + "path": "docs/legal/THIRD-PARTY-NAMES-AFFILIATION-AND-DRM.md", + "gitBlobSha": "97565d113169afbb2a363e37fc8371927f3b7eaa" + }, + { + "path": "docs/legal/TRADEMARK-CLEARANCE-2026-07-27.md", + "gitBlobSha": "cee7ebf580597c7273e40b6807418bb3953e6ce4" + }, + { + "path": "docs/legal/PUBLIC-MATERIALS-REVIEW.md", + "gitBlobSha": "2f28394af42df60e7c0149b77fd8a76037feb2e0" + } + ], + "namedThirdParties": [ + { + "name": "Microsoft", + "purpose": "no-affiliation and platform identification" + } + ], + "compatibilityClaims": [], + "thirdPartyAssets": [] + }, + { + "id": "release-description-template", + "kind": "release-template", + "status": "approved", + "reviewedAt": "2026-07-31", + "reviewer": "KeyffMS / aiteracja.pl", + "sourceEvidence": [ + { + "path": "docs/RELEASING.md", + "gitBlobSha": "04483e8ea7765a15ec5b1afef474624d54cc237e" + } + ], + "namedThirdParties": [ + { + "name": "Microsoft", + "purpose": "required no-endorsement wording when compatibility is discussed" + } + ], + "compatibilityClaims": [ + { + "wording": "tested with ", + "limitations": "The final release text must replace the placeholder with a real tested product and version and record limitations." + } + ], + "thirdPartyAssets": [] + }, + { + "id": "application-about-window", + "kind": "application-ui", + "status": "approved", + "reviewedAt": "2026-07-31", + "reviewer": "KeyffMS / aiteracja.pl", + "sourceEvidence": [ + { + "path": "docs/legal/THIRD-PARTY-NAMES-AFFILIATION-AND-DRM.md", + "gitBlobSha": "97565d113169afbb2a363e37fc8371927f3b7eaa", + "evidence": "About-window and current materials review" + } + ], + "namedThirdParties": [], + "compatibilityClaims": [], + "thirdPartyAssets": [] + }, + { + "id": "repository-brand-assets", + "kind": "project-owned-assets", + "status": "approved", + "reviewedAt": "2026-07-31", + "reviewer": "KeyffMS / aiteracja.pl", + "sourceEvidence": [ + { + "path": "assets/brand/sightadapt-mark.svg", + "gitBlobSha": "55269ec937abcf5515d807972d2cd2e75a4d01a7" + }, + { + "path": "assets/brand/sightadapt-lockup-dark.svg", + "gitBlobSha": "2b21023079ec57f1a6e993239616e72c3cb1a980" + }, + { + "path": "assets/brand/sightadapt-lockup-light.svg", + "gitBlobSha": "23156a2bac047acfafca3b71e0b3d754b8e8a600" + } + ], + "namedThirdParties": [], + "compatibilityClaims": [], + "thirdPartyAssets": [], + "projectOwnedAssets": [ + "assets/brand/sightadapt-mark.svg", + "assets/brand/sightadapt-lockup-dark.svg", + "assets/brand/sightadapt-lockup-light.svg" + ] + } + ], + "plannedSurfaces": [ + { + "id": "aiteracja-product-site", + "kind": "website", + "status": "planned", + "trackingIssues": [100, 103, 124], + "activationRequirements": [ + "Archive or version the final public text and assets.", + "Record the public URL, publication date and exact evidence.", + "Add the approved notice or a stable direct link.", + "Pass the public-materials verifier before publication." + ] + }, + { + "id": "github-release", + "kind": "release-listing", + "status": "planned", + "trackingIssues": [98], + "activationRequirements": [ + "Register final release text, screenshots and assets.", + "Use the approved no-affiliation and DRM wording when compatibility is discussed." + ] + }, + { + "id": "github-pages-site", + "kind": "website-origin", + "status": "planned", + "trackingIssues": [99, 103], + "activationRequirements": [ + "Register final built pages and public assets.", + "Keep legal and compatibility text synchronized with repository authorities." + ] + }, + { + "id": "winget-listing", + "kind": "store-package-listing", + "status": "planned", + "trackingIssues": [107], + "activationRequirements": [ + "Register the final manifest text and public URLs.", + "Do not imply Microsoft endorsement or certification." + ] + }, + { + "id": "open-hub-listing", + "kind": "directory-listing", + "status": "planned", + "trackingIssues": [108], + "activationRequirements": [ + "Register final description, icon and links." + ] + }, + { + "id": "sourceforge-listing-or-mirror", + "kind": "directory-or-mirror", + "status": "planned", + "trackingIssues": [109], + "activationRequirements": [ + "Register final description and assets.", + "Preserve the approved notice with mirrored packages." + ] + }, + { + "id": "public-social-profiles", + "kind": "social-profile", + "status": "planned", + "trackingIssues": [110], + "activationRequirements": [ + "Register each maintained profile URL, biography and assets." + ] + }, + { + "id": "product-hunt-listing", + "kind": "launch-listing", + "status": "planned", + "trackingIssues": [111], + "activationRequirements": [ + "Register final listing copy and screenshots.", + "Review every named compatibility claim and visible third-party asset." + ] + }, + { + "id": "community-announcements", + "kind": "announcement-set", + "status": "planned", + "trackingIssues": [112], + "activationRequirements": [ + "Register the canonical announcement package and final publication URLs.", + "Record corrections when claims or downloads change." + ] + } + ], + "objectionProcedure": { + "path": "docs/legal/PUBLIC-MATERIALS-REVIEW.md", + "gitBlobSha": "2f28394af42df60e7c0149b77fd8a76037feb2e0", + "section": "Objection or correction procedure" + } +} From b2b7ed7479e2f4f0b64130f2b6b01aa0c00986c6 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:39:21 +0200 Subject: [PATCH 3/8] Add public materials verification Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- tools/verify-public-materials.ps1 | 228 ++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 tools/verify-public-materials.ps1 diff --git a/tools/verify-public-materials.ps1 b/tools/verify-public-materials.ps1 new file mode 100644 index 00000000..bcaf6df5 --- /dev/null +++ b/tools/verify-public-materials.ps1 @@ -0,0 +1,228 @@ +[CmdletBinding()] +param( + [string]$RegistryPath = + (Join-Path $PSScriptRoot '..\release\public-materials.json') +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$root = Split-Path -Parent $PSScriptRoot +$registryFullPath = (Resolve-Path -LiteralPath $RegistryPath).Path +$registry = Get-Content -LiteralPath $registryFullPath -Raw | ConvertFrom-Json +$failures = [System.Collections.Generic.List[string]]::new() + +function Add-Failure([string]$Message) { + $failures.Add($Message) +} + +function Test-Date([string]$Value) { + return $Value -match '^\d{4}-\d{2}-\d{2}$' +} + +function Test-GitBlobEvidence($Evidence, [string]$Context) { + $path = [string]$Evidence.path + $expected = ([string]$Evidence.gitBlobSha).ToLowerInvariant() + + if ([string]::IsNullOrWhiteSpace($path)) { + Add-Failure "$Context has an empty evidence path." + return + } + if ($expected -notmatch '^[0-9a-f]{40}$') { + Add-Failure "$Context evidence '$path' has an invalid Git blob SHA '$expected'." + return + } + + $fullPath = Join-Path $root $path + if (-not [System.IO.File]::Exists($fullPath)) { + Add-Failure "$Context evidence file '$path' does not exist." + return + } + + $actualOutput = & git -C $root hash-object -- $path 2>&1 + if ($LASTEXITCODE -ne 0) { + Add-Failure "$Context evidence '$path' could not be hashed by Git: $($actualOutput -join ' ')" + return + } + $actual = ([string]($actualOutput | Select-Object -Last 1)).Trim().ToLowerInvariant() + if ($actual -ne $expected) { + Add-Failure "$Context evidence '$path' has Git blob '$actual'; reviewed blob is '$expected'." + } +} + +if ([int]$registry.schemaVersion -ne 1) { + Add-Failure "Unsupported public-material registry schema '$($registry.schemaVersion)'." +} +if (-not (Test-Date ([string]$registry.reviewedAt))) { + Add-Failure 'The registry review date must use YYYY-MM-DD.' +} +if ([string]::IsNullOrWhiteSpace([string]$registry.decisionOwner)) { + Add-Failure 'The registry requires a decision owner.' +} +if ([int]$registry.decisionIssue -ne 92) { + Add-Failure "The registry decision issue must be #92, not '$($registry.decisionIssue)'." +} +if ([string]$registry.reviewType -ne 'internal-maintainer-risk-control') { + Add-Failure 'The registry must identify the review as an internal maintainer risk control.' +} + +Test-GitBlobEvidence $registry.authoritativeNotice 'Authoritative notice' +$noticePath = Join-Path $root ([string]$registry.authoritativeNotice.path) +if ([System.IO.File]::Exists($noticePath)) { + $notice = Get-Content -LiteralPath $noticePath -Raw + foreach ($requiredText in @( + 'property of their respective owners', + 'only to identify an application selected or configured by the user', + 'not affiliated with, sponsored by, certified by or endorsed by Microsoft', + 'not intended to circumvent', + 'Protected or DRM-controlled content may remain unavailable')) { + if (-not $notice.Contains($requiredText, [StringComparison]::Ordinal)) { + Add-Failure "The authoritative notice is missing required wording: '$requiredText'." + } + } +} + +$summary = [string]$registry.authoritativeNotice.approvedSummary +foreach ($requiredText in @( + 'property of their respective owners', + 'only to identify applications selected or configured by the user', + 'not affiliated with, sponsored by or endorsed by Microsoft', + 'does not circumvent DRM or other access controls', + 'protected content may remain unavailable or unfilterable')) { + if (-not $summary.Contains($requiredText, [StringComparison]::OrdinalIgnoreCase)) { + Add-Failure "The approved reusable summary is missing: '$requiredText'." + } +} + +foreach ($authority in @($registry.reviewAuthorities)) { + Test-GitBlobEvidence $authority 'Review authority' +} +Test-GitBlobEvidence $registry.objectionProcedure 'Objection procedure' + +$knownMaintained = @( + 'repository-readme', + 'binary-third-party-names-notice', + 'repository-third-party-policy', + 'release-description-template', + 'application-about-window', + 'repository-brand-assets' +) +$seenIds = @{} +$allowedClaimPrefixes = @( + 'works with ', + 'tested with ', + 'compatible with ', + 'uses ', + 'applies an overlay to ' +) +$prohibitedClaimPattern = '(?i)\b(official integration|partnered? with|approved by|certified by|endorsed by|supported by|authorized by)\b' + +foreach ($surface in @($registry.maintainedSurfaces)) { + $id = [string]$surface.id + if ([string]::IsNullOrWhiteSpace($id)) { + Add-Failure 'A maintained surface has an empty ID.' + continue + } + if ($seenIds.ContainsKey($id)) { + Add-Failure "Duplicate public-material surface ID '$id'." + continue + } + $seenIds[$id] = $true + + if ([string]$surface.status -ne 'approved') { + Add-Failure "Maintained surface '$id' is not approved." + } + if (-not (Test-Date ([string]$surface.reviewedAt))) { + Add-Failure "Maintained surface '$id' has an invalid review date." + } + if ([string]::IsNullOrWhiteSpace([string]$surface.reviewer)) { + Add-Failure "Maintained surface '$id' has no reviewer." + } + + $evidence = @($surface.sourceEvidence) + if ($evidence.Count -eq 0) { + Add-Failure "Maintained surface '$id' has no immutable source evidence." + } + foreach ($entry in $evidence) { + Test-GitBlobEvidence $entry "Maintained surface '$id'" + } + + foreach ($thirdParty in @($surface.namedThirdParties)) { + if ([string]::IsNullOrWhiteSpace([string]$thirdParty.name) -or + [string]::IsNullOrWhiteSpace([string]$thirdParty.purpose)) { + Add-Failure "Maintained surface '$id' contains an incomplete named-third-party record." + } + } + + foreach ($claim in @($surface.compatibilityClaims)) { + $wording = [string]$claim.wording + $allowedPrefix = $false + foreach ($prefix in $allowedClaimPrefixes) { + if ($wording.StartsWith($prefix, [StringComparison]::OrdinalIgnoreCase)) { + $allowedPrefix = $true + break + } + } + if (-not $allowedPrefix) { + Add-Failure "Surface '$id' has compatibility wording outside the approved factual forms: '$wording'." + } + if ($wording -match $prohibitedClaimPattern) { + Add-Failure "Surface '$id' contains prohibited relationship wording: '$wording'." + } + if ([string]::IsNullOrWhiteSpace([string]$claim.limitations)) { + Add-Failure "Surface '$id' compatibility claim '$wording' has no limitations." + } + } + + foreach ($asset in @($surface.thirdPartyAssets)) { + if ([string]::IsNullOrWhiteSpace([string]$asset.owner) -or + [string]::IsNullOrWhiteSpace([string]$asset.useBasis) -or + [string]::IsNullOrWhiteSpace([string]$asset.approvedPurpose) -or + -not (Test-Date ([string]$asset.reviewedAt))) { + Add-Failure "Surface '$id' contains a third-party asset without complete ownership, use-basis, purpose and review evidence." + } + if ($null -ne $asset.sourceEvidence) { + Test-GitBlobEvidence $asset.sourceEvidence "Third-party asset on '$id'" + } + else { + Add-Failure "Surface '$id' contains a third-party asset without immutable source evidence." + } + } +} + +foreach ($requiredId in $knownMaintained) { + if (-not $seenIds.ContainsKey($requiredId)) { + Add-Failure "Required maintained surface '$requiredId' is absent from the registry." + } +} + +foreach ($planned in @($registry.plannedSurfaces)) { + $id = [string]$planned.id + if ([string]::IsNullOrWhiteSpace($id)) { + Add-Failure 'A planned surface has an empty ID.' + continue + } + if ($seenIds.ContainsKey($id)) { + Add-Failure "Surface ID '$id' appears more than once." + continue + } + $seenIds[$id] = $true + + if ([string]$planned.status -ne 'planned') { + Add-Failure "Future surface '$id' is not allowed to become active without moving to maintainedSurfaces with exact review evidence." + } + $issues = @($planned.trackingIssues) + if ($issues.Count -eq 0 -or @($issues | Where-Object { [int]$_ -le 0 }).Count -gt 0) { + Add-Failure "Planned surface '$id' has no valid tracking Issue." + } + if (@($planned.activationRequirements).Count -eq 0) { + Add-Failure "Planned surface '$id' has no activation requirements." + } +} + +if ($failures.Count -gt 0) { + $details = $failures | ForEach-Object { " - $_" } + throw "Public-material, trademark and DRM review failed:`n$($details -join "`n")" +} + +Write-Host "Public-material review passed for $(@($registry.maintainedSurfaces).Count) maintained surfaces; $(@($registry.plannedSurfaces).Count) future surfaces remain planned." From cdc699f4d2c4bbb241010ba83c24661684816a1c Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:39:48 +0200 Subject: [PATCH 4/8] Test rejected public material changes Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- tools/test-public-materials-negative.ps1 | 87 ++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tools/test-public-materials-negative.ps1 diff --git a/tools/test-public-materials-negative.ps1 b/tools/test-public-materials-negative.ps1 new file mode 100644 index 00000000..b12eb711 --- /dev/null +++ b/tools/test-public-materials-negative.ps1 @@ -0,0 +1,87 @@ +[CmdletBinding()] +param( + [string]$RegistryPath = + (Join-Path $PSScriptRoot '..\release\public-materials.json') +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$resolvedRegistry = (Resolve-Path -LiteralPath $RegistryPath).Path +$tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ( + 'sightadapt-public-materials-negative-' + [Guid]::NewGuid().ToString('N')) +[System.IO.Directory]::CreateDirectory($tempRoot) | Out-Null + +function Assert-Rejected( + [string]$Scenario, + [scriptblock]$Mutation) { + $scenarioPath = Join-Path $tempRoot (([regex]::Replace($Scenario, '[^A-Za-z0-9.-]', '-')) + '.json') + $registry = Get-Content -LiteralPath $resolvedRegistry -Raw | ConvertFrom-Json + & $Mutation $registry + [System.IO.File]::WriteAllText( + $scenarioPath, + ($registry | ConvertTo-Json -Depth 16) + [Environment]::NewLine, + [System.Text.UTF8Encoding]::new($false)) + + $rejected = $false + try { + & (Join-Path $PSScriptRoot 'verify-public-materials.ps1') ` + -RegistryPath $scenarioPath + } + catch { + $rejected = $true + Write-Host "$Scenario was rejected as expected: $($_.Exception.Message)" + } + + if (-not $rejected) { + throw "$Scenario unexpectedly passed public-material review." + } +} + +try { + Assert-Rejected 'A stale reviewed source hash' { + param($registry) + $registry.authoritativeNotice.gitBlobSha = '0000000000000000000000000000000000000000' + } + + Assert-Rejected 'An implied official integration claim' { + param($registry) + $surface = $registry.maintainedSurfaces | Where-Object { + [string]$_.id -eq 'repository-readme' + } | Select-Object -First 1 + $surface.compatibilityClaims = @($surface.compatibilityClaims) + @( + [pscustomobject]@{ + wording = 'official integration with Example Product' + limitations = 'None' + } + ) + } + + Assert-Rejected 'A third-party logo without use-basis evidence' { + param($registry) + $surface = $registry.maintainedSurfaces | Where-Object { + [string]$_.id -eq 'repository-brand-assets' + } | Select-Object -First 1 + $surface.thirdPartyAssets = @( + [pscustomobject]@{ + owner = 'Example Corporation' + useBasis = '' + approvedPurpose = '' + reviewedAt = '' + } + ) + } + + Assert-Rejected 'An unreviewed activation of the GitHub Release surface' { + param($registry) + $surface = $registry.plannedSurfaces | Where-Object { + [string]$_.id -eq 'github-release' + } | Select-Object -First 1 + $surface.status = 'approved' + } +} +finally { + Remove-Item -LiteralPath $tempRoot -Recurse -Force -ErrorAction SilentlyContinue +} + +Write-Host 'Negative public-material, trademark and DRM review tests passed.' From e91d72b144109692f4f95d9e963aeee570d0478f Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:40:37 +0200 Subject: [PATCH 5/8] Enforce public materials review in CI Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- .github/workflows/build.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27195be1..bcec3896 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,6 +37,14 @@ jobs: shell: pwsh run: .\tools\verify-release-metadata.ps1 -WriteGitHubOutput + - name: Verify public materials, trademarks and DRM boundaries + shell: pwsh + run: .\tools\verify-public-materials.ps1 + + - name: Verify unsafe public-material changes are rejected + shell: pwsh + run: .\tools\test-public-materials-negative.ps1 + - name: Restore application run: dotnet restore src/SightAdapt/SightAdapt.csproj From 76722ce7862791384336050c475580e1fa57d3ff Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:41:20 +0200 Subject: [PATCH 6/8] Add repository protection evidence template Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- ...REPOSITORY-PROTECTION-EVIDENCE-TEMPLATE.md | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 docs/legal/REPOSITORY-PROTECTION-EVIDENCE-TEMPLATE.md diff --git a/docs/legal/REPOSITORY-PROTECTION-EVIDENCE-TEMPLATE.md b/docs/legal/REPOSITORY-PROTECTION-EVIDENCE-TEMPLATE.md new file mode 100644 index 00000000..f750c13d --- /dev/null +++ b/docs/legal/REPOSITORY-PROTECTION-EVIDENCE-TEMPLATE.md @@ -0,0 +1,41 @@ +# Repository protection evidence template + +Use this template in Issue #87 after activating the `main` ruleset. Record only non-secret settings and public pull-request links. + +## Configuration evidence + +- Review date: `YYYY-MM-DD` +- Maintainer: `KeyffMS` +- Repository: `KeyffMS/SightAdapt` +- Ruleset name: `Protected main — DCO and build` +- Enforcement status: `Active` +- Target branch: `main` +- Pull request required: `Yes` +- Required approvals: `0` unless another maintainer is available +- Required status checks: + - `Verify commit sign-offs` + - `build` +- Require current/up-to-date head before merge: `Yes` +- Conversation resolution required: `` +- Direct pushes blocked: `Yes` +- Force pushes blocked: `Yes` +- Branch deletion blocked: `Yes` +- Bypass actors: `None` +- Evidence screenshot or non-secret export: `` + +## Blocking test + +- Test pull request: `` +- Unsigned commit SHA: `` +- DCO check result: `Failure` +- Merge control result: `Merge blocked` +- Evidence location: `` +- Corrective action: `Commit amended/recreated with a matching Signed-off-by trailer` +- Passing DCO run: `` +- Final disposition: `` + +## Maintainer statement + +> I verified that `main` requires a pull request and the current successful `Verify commit sign-offs` and `build` checks, blocks direct and force pushes and branch deletion, and has no standing bypass actor. I also verified through the linked test pull request that an unsigned commit cannot be merged. + +Do not include tokens, private administration URLs, confidential permissions or personal data in the Issue record. From 88dc3125c930afb9a461e82eb01b5d3923154ef6 Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:41:58 +0200 Subject: [PATCH 7/8] Require public material review disclosure Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- .github/pull_request_template.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1ebb13b7..4e516230 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -28,6 +28,17 @@ State `None`, or identify the tool/use and describe the human review and provena State `None`, or link the decision record in `docs/legal/CONTRIBUTION-EXCEPTIONS.md`. Do not publish confidential permission documents. +## Public materials and compatibility claims + +- [ ] This change does not create or modify public text, screenshots, videos, listings, announcements or compatibility claims; or I updated `release/public-materials.json` with exact evidence and review data. +- [ ] Any third-party name is used only for factual identification or a reviewed compatibility statement. +- [ ] Any third-party logo, icon, screenshot, badge or trade dress has a documented source, use basis and immutable evidence. +- [ ] The change does not imply partnership, certification, endorsement or DRM/access-control circumvention. + +### Public surfaces affected + +State `None`, or identify every repository, application, website, release, store, directory, mirror, social or announcement surface and its registry entry. + ## Validation List the checks or document review performed. For documentation/governance-only changes, state that no application behavior changed. From 7c4bf73348d0101fc6e6a2b5c1ca4ebfc6882d9f Mon Sep 17 00:00:00 2001 From: KeyffMS <124252104+KeyffMS@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:46:14 +0200 Subject: [PATCH 8/8] Report incomplete asset evidence explicitly Signed-off-by: KeyffMS <124252104+KeyffMS@users.noreply.github.com> --- tools/verify-public-materials.ps1 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/verify-public-materials.ps1 b/tools/verify-public-materials.ps1 index bcaf6df5..dfafee9a 100644 --- a/tools/verify-public-materials.ps1 +++ b/tools/verify-public-materials.ps1 @@ -181,8 +181,11 @@ foreach ($surface in @($registry.maintainedSurfaces)) { -not (Test-Date ([string]$asset.reviewedAt))) { Add-Failure "Surface '$id' contains a third-party asset without complete ownership, use-basis, purpose and review evidence." } - if ($null -ne $asset.sourceEvidence) { - Test-GitBlobEvidence $asset.sourceEvidence "Third-party asset on '$id'" + + $sourceEvidenceProperty = $asset.PSObject.Properties['sourceEvidence'] + if ($null -ne $sourceEvidenceProperty -and + $null -ne $sourceEvidenceProperty.Value) { + Test-GitBlobEvidence $sourceEvidenceProperty.Value "Third-party asset on '$id'" } else { Add-Failure "Surface '$id' contains a third-party asset without immutable source evidence."