Skip to content

[Fleet incident] Disable orphaned one-shot and PR-specific workflow identities #423

Open

Description

@seonghobae

Live GitHub Actions inventory defect

The repository's Actions registry currently reports 23 workflows, with numerous temporary or PR-specific workflow records still in state: active, including:

  • one-shot-netty-sbom-refresh.yml;
  • one-shot-netty-sbom-finalize.yml;
  • one-shot-rca-action-scheduler.yml, v2, and v3;
  • one-shot-repair-hourly-yaml.yml;
  • one-shot-update-hourly-scheduler.yml;
  • repair-pr-162.yml;
  • rebase-pr-165-on-main.yml;
  • reconcile-pr-264-on-main.yml;
  • several finalizer/verification workflows tied to completed development slices.

Fresh contents-API reads on protected main return 404 Not Found for sampled active registry paths such as one-shot-rca-action-scheduler-v3.yml and repair-pr-162.yml. Their source files are absent, but GitHub still advertises the workflow identities as active.

Root cause

Temporary writer/reconciliation workflows were removed from the repository tree after use, but workflow lifecycle cleanup assumed source deletion also disabled the Actions registry identity. GitHub persists workflow records separately. Current file-level tests cannot detect a workflow record whose source no longer exists.

This is a fleet-level operational and audit defect:

  • automation inventory overstates enabled writers;
  • incident responders cannot distinguish live policy from deleted repair machinery;
  • stale PR-specific identities remain visible indefinitely;
  • the repository violates the fleet invariant that temporary write-capable/self-modifying repair workflows must not remain;
  • future workflow dispatch, policy, or App tooling may misclassify these stale identities.

Feasible remediation

Do not recreate the historical workflow files and do not add another self-deleting cleanup workflow. Through an authorized operator or normal reviewed control-plane path:

  1. paginate the complete live workflow registry;
  2. resolve the exact protected-main tree;
  3. classify every registered workflow as present, orphaned-deleted, disabled, dynamic GitHub-owned, or unresolved;
  4. disable every active orphaned repository workflow after confirming its source path is absent from protected main;
  5. retain production CI, security, dependency, and current hourly-development workflows;
  6. document any intentionally retained non-file-backed dynamic workflow separately.

The active Copilot dynamic workflow is GitHub-owned and must not be conflated with a deleted repository file; this issue does not authorize changing reviewer identity or credential policy.

Prevention contract

Add a read-only executable audit that detects active orphan identities without mutating workflow state. It must bind evidence to workflow ID/path/state, exact default-branch SHA, file-presence result, pagination receipt, and observation time. Missing permissions, 403/404/5xx ambiguity, or partial pagination must fail closed rather than produce a clean inventory.

Fresh full-registry proof — 2026-08-13 KST

A read-only three-page Actions inventory (10 + 10 + 3) returned a stable total_count=23. Protected main was resolved immediately before and after the inventory to exact SHA b66b692ce580b783cddf9e99d96c4f94aa6b1735; the ref did not move. The exact protected tree contains only .github/workflows/ci.yml and .github/workflows/fuzz.yml.

Classification against that exact tree is therefore:

  • present and active — 2: 311068487 (ci.yml), 309141912 (fuzz.yml);
  • disabled — 1: 299939793 (opencode-review.yml, disabled_manually);
  • GitHub-owned dynamic — 4: 301122706 (Copilot), 310371227 (Dependabot Updates), 299997784 (Dependency Graph), 236395131 (dynamic CodeQL);
  • active orphaned repository-path identities — 16:
    • 309734180 — .github/workflows/codeql.yml;
    • 327497416 — .github/workflows/complete-admin-retry-boundary.yml;
    • 327789462 — .github/workflows/finalize-netty-generated-evidence.yml;
    • 329954996 — .github/workflows/hourly-product-development.yml;
    • 327787889 — .github/workflows/one-shot-netty-sbom-finalize.yml;
    • 327775067 — .github/workflows/one-shot-netty-sbom-refresh.yml;
    • 329979088 — .github/workflows/one-shot-rca-action-scheduler-v2.yml;
    • 329980032 — .github/workflows/one-shot-rca-action-scheduler-v3.yml;
    • 329972184 — .github/workflows/one-shot-rca-action-scheduler.yml;
    • 329956214 — .github/workflows/one-shot-repair-hourly-yaml.yml;
    • 329947526 — .github/workflows/one-shot-update-hourly-scheduler.yml;
    • 327516598 — .github/workflows/rebase-pr-165-on-main.yml;
    • 327518346 — .github/workflows/reconcile-pr-264-on-main.yml;
    • 327442149 — .github/workflows/repair-pr-162.yml;
    • 327473855 — .github/workflows/verify-admin-stack.yml;
    • 327499242 — .github/workflows/verify-demo-integration.yml.

This proves the defect is broader than sampled one-shot paths: the registry currently advertises 16 active repository workflow identities whose source is absent from exact protected main. No source file should be recreated merely to disable them.

PR #424 owns the deterministic prevention/audit code. Its current branch additionally covers an interrupted registry-evidence stream so transport interruption is normalized to controlled incomplete evidence rather than escaping as an unrelated exception. Registry-state mutation remains a separate operator/control-plane action because the current GitHub connector exposes workflow re-run/read operations but not the disable-workflow mutation.

Acceptance criteria

  • all registry pages inspected;
  • every active repository-path workflow absent from protected main is disabled or has an explicit evidence-backed exception;
  • no production scheduled/reusable workflow is disabled;
  • no old one-shot writer is recreated;
  • adversarial tests cover pagination truncation, default-branch movement, path case differences, transient API failure, dynamic GitHub-owned workflows, and a currently present workflow with a historical one-shot-like name;
  • exact-head CI/security/review gates pass;
  • normal protected-main integration;
  • post-remediation live inventory proves the orphan identities are disabled and the current hourly product-development workflow remains operational.

This issue belongs to the organization-wide GitHub Actions fleet incident. Clearfolio's dedicated writer loop owns implementation; the fleet audit remains read-only and tracks protected-main evidence.

Activity

  1. seonghobae commented on Aug 12, 2026

    @seonghobae
    CollaboratorAuthor

    Severity update: the production hourly identity is also orphaned

    The live registry record for .github/workflows/hourly-product-development.yml is not merely stale metadata for a completed one-shot workflow. The file is absent from protected main, while the registry reports it active. Its recorded runs are feature-branch push runs associated with Draft PR #271; no protected-main scheduled run exists.

    This means Clearfolio currently has no operating Hourly Product Development scheduler, despite an active-looking workflow identity. The separate RCA and realistic integration options are recorded on #271. During registry remediation, do not simply disable this identity without coordinating the product scheduler path:

    • if feat(automation): prevent status-only early termination #271 or a clean replacement reaches protected main, the identity becomes a present supported production workflow and must remain active;
    • until then it must be classified as orphan_active_pending_supported_integration, not as evidence of operational hourly development;
    • acceptance requires a real protected-main scheduled/manual run from the merged SHA, not a feature-branch push run.

    The lifecycle audit therefore needs both source-presence classification and product-owner intent; name or current state alone is insufficient.

  2. added
    area: authAuthentication, authorization, identity, or tenant isolation
    area: ci-cdCI, GitHub Actions, checks, release, or supply chain
    area: securitySecurity boundary, hardening, or vulnerability prevention
    status: triagedOpen issue has an organization taxonomy assignment
    type: featureNew or expanded product capability
    on Aug 22, 2026
  3. added
    bugSomething isn't working
    type: bugDefect or incorrect behavior
    and removed
    area: authAuthentication, authorization, identity, or tenant isolation
    on Sep 2, 2026
  4. seonghobae commented on Sep 28, 2026

    @seonghobae
    CollaboratorAuthor

    2026-09-28 live workflow registry check: Clearfolio has 25 workflow identities, of which 6 are active. The two active repository-owned YAML paths are .github/workflows/ci.yml (ID 311068487) and .github/workflows/fuzz.yml (ID 309141912); both exist at the unchanged default main SHA 06633a25109c62e24a7015ae04fb9f6e0a246f7e. The other four active identities use GitHub-owned dynamic/ paths (Copilot, two Dependabot entries, and code scanning). Thus this snapshot has zero active repository-owned default-branch-absent IDs. No Clearfolio workflow state was changed; historical disabled identities remain in the registry for audit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: securitySecurity boundary, hardening, or vulnerability preventionbugSomething isn't workingpriority: mediumNormal-priority or P2 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: bugDefect or incorrect behaviortype: featureNew or expanded product capability

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions