Repository navigation
Serve footer logos from the published brand assets and keep legacy URLs migratable - #124
Merged
Merged
Conversation
Retain recognized legacy footer URLs for safe README migration. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
The account paying for this security review has reached its Codex usage limits. The payer can check the Codex usage dashboard. For personal accounts, using credits requires enabling “Use credits for security reviews” in Code review settings. If you do not manage the paying account, contact this repository's admins. |
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…ooter images - callout_only (variants G and H) now replaces a recognized old footer, marked or unmarked, and reports the replaced lines to the preservation check. - is_footer_copy requires every src/srcset to be a footer logo URL; a matching alt no longer vouches for a custom image. - decisions.md: drop the unsupported user-request attribution, add a neutral note outside the verbatim excerpt. - Tests for G/H marked and unmarked legacy footers, the guard, the scheduled workflow and the deliberately legacy template fixture. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Old footers that reference assets/logo.png (and the other former local logo names) are a footer copy again when the image alt is exactly the company or the footer alt. Published URLs still must be footer logo URLs, and any other src keeps the image from counting as a footer copy. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
… URLs Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… makes footer check report drift callout_only now tracks whether a recognized footer was removed (marked loop or drop_old_footer) and appends the replacement in that case, even when footermod.check reports fail:drift because of footer-like text inside a fenced example. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Label the decision 18 logo-URL repair as a skill amendment pending user confirmation, move the repair paragraph out of the quoted decision text, and neutralize the line-5 note and file preamble. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…fenced-example and decisions provenance tests - footer-assets.yml: add push to main with the same paths filter; on pull_request check the configured footer logo paths exist in the PR checkout; the online HEAD runs only off pull_request. - tests: G/H regression for a fenced footer-like example plus a marked legacy footer; workflow trigger test. - validate_quality.py: gate_decisions_provenance (decisions.md line 3 not fully verbatim; skill note outside quote). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Remove gate_decisions_provenance and its call in main(). It hard-coded decisions.md line numbers and exact English sentences, so harmless document reorganisation would fail it. It sits outside the behavioural footer repair. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Brand files row named the former CompleteTech-LLC/.github/brand/ location, which returns 404. Name the published masters in assets/brand/ (the copies the generators and footer use), keep the former location as historical only, and note the matching sha256 for the logo pair. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…air (#47) Restore the decision 18 exact markup to the origin/main text and keep the current footer URLs only in the labelled skill note. Remove the requester, date and confirmation wording the repair notes carried. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…nize picture local logos, report only changed footer lines as removed (#47) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
) Adds tests/test_footer_upgrade_preservation.py. Partner, foreign and look-alike host images carrying the company alt must survive readme.upgrade with no removed allowance; the demonstrated own-site legacy logos (the company website host derived from brand data, and docs/images/logo.svg) still migrate. Helper tests use the own_site flag from the agreed interface. Against e58465e the partner, foreign and derived-host negatives and the own_site helper tests fail; they reproduce the upgrade() loose_src deletion for the readme.py fix to address. The write-flow test is omitted: no cheap public entry point exists (see module comment). Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…never alt-only trust (#47) Replace loose_src=True in upgrade() with own_site=True: under a company alt only the brand website host (brand_strings.website) and docs/images/logo.svg migrate; partner, foreign and look-alike images stay authored. loose_src stays an opt-in helper kwarg. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ce semantics (#47) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…footer lines (#47) - _own_site_logo accepts only the exact OWN_SITE_LOGO_PATHS on the configured company website host, so other files on that host stay authored content. - upgrade() shares one multiset of re-emitted footer lines across the marked and unmarked branches; unmarked old-footer lines the new footer carries again are no longer reported as removed (_unreemitted). Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…footer lines (#47) Adds tests/test_footer_r7_regressions.py. Same-host non-logo images must survive upgrade, a historical logo path with a query still migrates, a regular unmarked footer must not hide lost banner anchors, and removed must not include re-emitted footer lines. The new tests that depend on the readme.py fix fail at 020f30a as expected; no existing test is changed. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…y footer; docs: own-site logo paths (#47) The anchor regression now fails if the whole old footer is exempted again (verified by reverting to 'removed += old_footer'). CHANGELOG and readme-variants describe OWN_SITE_LOGO_PATHS recognition and the multiset-limited removed report. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…urls (#47) Remove the hardcoded OWN_SITE_LOGO_PATHS from Python; the website logo URL is brand data in references/brand.yaml (lock refreshed via config --write-lock). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…hored images Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…igration (#47) callout_only called drop_old_footer without own_site=True, so an unmarked trailing footer using footer.legacy_logo_urls or docs/images/logo.svg was rejected for G/H forks and archived repos. Match upgrade(). Marked footers stay strict, as in upgrade(). Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…ssions; drop stale OWN_SITE_LOGO_PATHS wording (#47) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
footer-online now runs footer --check README.md --online on pull_request, push, schedule and workflow_dispatch (contents: read, no continue-on-error); the PR-only local-file step stays as extra coverage. The refreshed acceptance overrides the older r2-authoritative-ci-criteria adjudication on PR online checks, so the renamed regression is a deliberate change, not a weakening. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…line-on-PR docs claims (#47) Reverts the invented online-HEAD-on-pull-request gate from 384f443 per the binding adjudications (issue #47/#50 acceptance: scheduled check or CI step, offline-friendly mock). Restores footer-assets.yml and the footer migration test to bec6391 content; docs state that pull requests run the offline file-existence step and the online HEAD runs on push to main, weekly and manual dispatch. Bootstrap-refusal, G/H own-site and legacy_logo_urls wording fixes are kept. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
tests/test_footer_upgrade_preservation.py defined gh_ctx twice (lines 253 and 343), failing ruff F811 in validate_quality. Both bodies were identical, so the second definition with its duplicate GH_VARIANTS, PARENT and UPSTREAM constants is removed. The G/H tests now use the shared GH_UPSTREAM constant. No test function, parametrization or assertion changed. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The authored-footer safeguard only ran for an edited template body. A pristine or unmarked (none) README reached header_only(), which replaced the marked footer and silently deleted a partner or foreign image. Move the check into _authored_footer_refusal() and run it on the original text before dispatching on bootstrap_state(), so every state refuses before writing. The edited-branch guard reuses the same helper with its existing problem text and preservation details. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…bootstrap states (#47) Add CLI-level regression tests for `readme --bootstrap --write` where the marked footer holds an authored partner or foreign image (https://example.test/partner-badge.png and assets/partner.png) in the pristine and none states. They expect a readme-shrink refusal with README.md byte-identical; against the unfixed showcase.py they fail (the write succeeds and the partner image is replaced), which reproduces the P1 finding. Positive controls: an own-site legacy footer still migrates to the current brand logo in both states, and a current footer is idempotent across two runs. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…rap (#47) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Line 255 (upgrade row) no longer lets a matching company alt qualify a footer logo image. Qualifying URLs are the brand footer logo URL, a footer.legacy_logo_urls entry, or docs/images/logo.svg under the company alt; alt alone never qualifies. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
test_scheduled_workflow_really_heads_the_footer_logos now asserts that the online HEAD step is guarded by `if: github.event_name != 'pull_request'`, that a pull_request trigger exists, and that the offline file-exists step is pull_request-only. Test-only change; no existing assertion is weakened. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Nov 1, 2026
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.
Change and affected skills
Resolves #47
Resolves #48
Resolves #49
Resolves #50
footer --check --onlinefailed because both footer logo URLs pointed atCompleteTech-LLC/.github/main/brand/, which returns 404. The footer now points at the logo masters published in this repository (assets/brand/logo.pngandlogo-dark.pngonmain, HTTP 200 with the expected hashes), and the former URLs stay infooter.legacy_logo_urlsso existing READMEs still migrate safely.references/brand.yaml,brand.schema.json,brand.lock.jsonregenerated through the CLI): the published URLs pluslegacy_logo_urls, which also lists the historical company-website logo URL. All brand URLs and hosts live inbrand.yaml; no brand path is hardcoded in Python.scripts/ctshowcase/readme.py,scripts/showcase.py):upgrade()replaces an old footer only for a demonstrated historical logo (a configuredlegacy_logo_urlsentry matched on parsedsrc/srcsetURLs, or the conventional localdocs/images/logo.svg) together with the strong footer signature. Alt text alone is never provenance. Images are classified from whole parsed attributes (exact names, first occurrence wins, including valueless first attributes), sodata-alt,titletext, spoofed hosts, userinfo and unexpected ports never count. Authored partner and foreign images, authored anchors and the generated banner's link wrapper are preserved; a change that would lose one is flagged by the preservation guard and the CLI refuses the write.readme --bootstrap --writerefuses to regenerate a marked footer that holds an authored image in EVERY bootstrap state (none, pristine and edited: it fails withreadme-shrinkand leaves the README byte-unchanged), and the G/H unmarked website-logo anddocs/images/logo.svgfooters now migrate. The two existing legacy-footer tests are unchanged..github/workflows/footer-assets.yml, jobfooter-online): pull requests run the OFFLINE step that the configured logo files exist in the checkout underassets/brand/. The realfooter --check README.md --onlineHEAD runs on push tomain(footer-related paths), on the weekly schedule and on manual dispatch, withcontents: readonly. This matches issuefooter --check --onlinefails: both footer logo URLs return 404 #47 ("a scheduled check or CI step fails when they do not") and E2.4.3 Add a CI check with an offline-friendly mock #50 ("offline-friendly mock", "real HEAD on a schedule", mocked unit tests for the gate logic); the online step has not yet run in hosted CI and is first exercised after merge (a manual dispatch will confirm).references/decisions.mdkeeps decision 18's quoted markup verbatim and explains the configured URLs in a separate, clearly labelled skill-maintenance note;references/readme-variants.md(the upgrade row now says a logo qualifies by its parsed src/srcset or the localdocs/images/logo.svg, never by alt alone),references/art-direction.md, the changelog, examples andassets/brand/README.mddescribe the published URLs and the actual CI behaviour. No brand mark was created or redrawn.tests/test_footer_public_assets.py(offline mock of the published assets),tests/test_footer.py,tests/test_footer_fenced_example_migration.py,tests/test_footer_upgrade_preservation.pyand attribute-token tests cover the partner, foreign, spoof, valueless-attribute, banner-wrapper, bootstrap and G/H cases; synthetic fixtures only.Prior work
Searched this repository's PRs and issues for the footer logo URL problem (search repeated before this refresh):
dd720f9) "Repair footer logo URLs and safely migrate existing footers" made this same repair: publishedfooter.logo_*_urlvalues,legacy_logo_urls, safe migration of existing footers, and tests.f9ec72a) "Add opt-in T3 showcase support and Pick Your AI identity" merged afterwards and restored the oldCompleteTech-LLC/.github/main/brand/values inreferences/brand.yaml, somainis back to the 404 URLs.footer --check --onlinefails: both footer logo URLs return 404 #47 is a regression of Repair footer logo URLs and safely migrate existing footers #19's repair, not a new design.footer --check --onlinefails: both footer logo URLs return 404 #47 and sub-issues E2.4.1 Find where the logos actually live #48-E2.4.3 Add a CI check with an offline-friendly mock #50 are the only issues covering this; no other open PR touches the footer URLs. This PR reuses Repair footer logo URLs and safely migrate existing footers #19's approach on top of currentmain, recovers the legacy local-logo footer recognition, and adds thefooter-onlineCI guard (sub-issue E2.4.3 Add a CI check with an offline-friendly mock #50) so a future merge cannot silently revert it.Provenance
Commits
dfc93ed03acf4d23c187c33ada1ebfbf4fe70dbcand5a3d78d8de9e0eac7f59d3e70b8ff5a5873a0373are inherited, already-published history that predates the current remediation. They carry genericCo-Authored-By: Claudetrailers; no more specific model is claimed for them because no native evidence is available.Three already-published merge commits in this branch have no
Co-Authored-Bytrailer. Commit metadata is immutable once published and the user's instruction forbids force-push, so these are recorded as provenance exceptions, not defects fixed by changing source:366c735c994f361c13a6259e36ef1c67d47297ebhk/47-r3decisions.md skill note (Haiku commitd5c63ca, Haiku trailer)fix:#47:r3, native agenta755d4e54043aaf95, runtime modelclaude-sonnet-5-576ee8b61fe4323f8da22e8eff470c9c5d37694achk/47-r3README footer replacement fix (Haiku commit740303d, Haiku trailer)fix:#47:r3,a755d4e54043aaf95,claude-sonnet-5-57fc3743b951173e02fc447a5d32f5fa409d2654d849f67e(Haiku commit, Haiku trailer)fix:#47:r2, native agenta5f0db6ef29599f82, runtime modelclaude-sonnet-5-5Nothing is rewritten, no trailer is claimed that does not exist, and no model beyond the native evidence is asserted. From here on, every commit and merge commit carries the verified trailer of the role that made it before it is published (Haiku 5.5 for file workers, Sonnet 5.5 for owner commits and merges). This is a provenance record only; it is not an approval of the code.
Additional integration merges without a trailer (the model trailer on merge commits is a convention of the orchestration prompt, not a repository rule; recorded, not rewritten, no attribution invented):
cad87ddf1662e5f3c5088217255fce891ec1922fc017dd14e3e318e6ac700b3653f8eaeb17e05417(decisions.md wording)fix:#47:r5, native agenta7a484513792f76f1,claude-sonnet-5-5512f13e4b707c7c6e6b2a14fdde56362bd9dad522b0e0b0723b96429a39ff750e20aae66003304b8(art-direction.md)a7a484513792f76f1,claude-sonnet-5-5Further integration merges without a trailer (convention of the orchestration prompt, not a repository rule; recorded, not rewritten):
9a5ae0d(adopts Haikud4d4c0b,claude-haiku-5-5) and the e58465e/97b775d line, made by the Sonnet owner integrationsfix:#47:r0(native agenta6f7eade5) andfix:#47:r1(native agentafefb0a7e), bothclaude-sonnet-5-5; the Haiku source commits carry Haiku 5.5 trailers.Later history on this branch, recorded as it happened (nothing rewritten): commit
384f443briefly changed the CI workflow to run the online HEAD on pull requests, which contradicts the real acceptance of #47/#50;0f1eec8restored the workflow and its original test byte-for-byte (verified againstbec6391), and76f0108removed a duplicate test helper flagged by Ruff F811;d17909eextended the bootstrap refusal to the none and pristine states;7a72de1corrected the readme-variants logo wording, pinned the CI policy in a test and normalized one new test file to LF. The merge commits after the table above follow the same convention (integration merges by the Sonnet owner, Haiku source commits carry Haiku 5.5 trailers); this section is a provenance record, not an approval.Evidence (exact head
7a72de1c706a6f5ee815aa28d7589c90620ad13b, basemain85f12d8198f77a1bea150a9b0afff0125af9e990integrated by a normal merge)vm-7a72de1c706a6f5ee815aa28d7589c90620ad13b-result.json): package tests, package validator, full pytest and quality validator passed; pytest 1198 passed, 11 skipped, 37 subtests. The skips are the pre-existing absent external fixtures; the Windows-only symlink cases run in Linux; no jsonschema or changed-feature skip.logo.png243500 bytesa5c3c4ef...1621,logo-dark.png210785 bytes0dc00c0e...7ec) all pass. A deliberately missing asset fails withfail:offline(negative control).validate-package(ubuntu, windows, macos),pytest(ubuntu, windows, macos),validateandfooter-onlineall completed with success (15 check runs, push and pull-request matrices). One macOSvalidate-packagejob was left by GitHub in an inconsistent state (status in_progress with conclusion success while its workflow run was completed); it was rerun as a targeted job rerun, the original record is preserved, and the rerun completed with success.git commitsetup in the local signing environment; those logs are preserved and are not evidence for this head.claude-opus-5-5) and Codexgpt-6.1-solat max effort each returned an explicit approve with zero findings. An earlier Sol review of this head returned incomplete (it had no network and the live HTTP receipts were not in its context); the receipts are now supplied inline and the incomplete record is kept. Earlier reviews of older heads (including a lifecycle-only request for explicit closing keywords, resolved by the keywords above) do not carry over.Limitations
main, the weekly schedule or a manual dispatch (to be triggered after merge).editedbranch, broader path filters forfooter-assets.yml(scripts/ctshowcase/readme.py,references/brand.lock.json), a clearer error if a logo URL is ever offmain, and narrowing the historical bare local logo forms. A follow-up issue will coverreadme --mode header, which still regenerates a marked footer without the authored-content refusal (pre-existing, outside this change).Boundaries
Activation keys, consent, approval gates and specialist entry points are unchanged. Branding decisions are not altered beyond repairing the unreachable URLs (the quoted decision text is untouched). No registry release, visibility change or live external action is implied. Shared validators (
scripts/validate_package.py,tests/test_package_contract.py) are byte-identical tomain.Family consistency
Single-repository change; no sibling skill PRs are affected.
🤖 Generated with Claude Code