Remove legacy credential-format compatibility after migration #26

Closed
opened 2026-09-12 01:09:01 +01:00 by allod-agent · 2 comments
Member

Remove the legacy credential shape (format plus structured verify.type) from every public consumer once an executable witness shows no registry still carries it, so the value-template contract of allod/secrets#23 is the only shape left and the one-shot migration code goes with it.

Primary goals:

  • Evidence gates the removal — an executable witness over every registry the deployment composes, public and private, proves that no credential carries format and that the local_auth_refresh source has moved to the new contract; a hand inventory or a passing deployment-health command is not sufficient.
  • Delete the legacy validator path — the credential-registry check in allod/secrets stops accepting format and structured verification, and its legacy positive fixture and legacy sabotage witnesses go with it, while the new-contract coverage stays.
  • Retire the one-shot migration code — allod secret migrate, its legacy translation table, the format and target-level user fields in the registry structs, and the "run migrate first" refusals in create and rotate are removed from allod/tools.
  • Finish the archetypes consumer — the local_auth_refresh source predicate accepts only the template shape; the legacy credential-store-url branch is removed.
  • Fail loud on reintroduction — a format field anywhere in a registry is a check failure afterwards.

Trigger and decision criterion

Start when the witness passes on the composed deployment: no registry entry carries format, and the refresh path that allod/nexus#52 decides no longer requires the legacy shape. Until both hold, the transition union stays in place and this issue waits.

Removal scope

In allod/secrets, remove legacy acceptance from the credential-registry check and delete the legacy fixtures while keeping one sabotage witness per remaining validator. In allod/tools, delete secret_migrate.go, the legacy verify translation, the format and user registry fields, and the legacy refusal paths, and update the docs and tests that describe them. In allod/archetypes, remove the legacy branch of the local_auth_refresh source predicate and its legacy fixture. Delete documentation and tests made obsolete by these paths, and keep a check that makes a reintroduced format field fail.

rotate-token is not retired here; allod/nexus#52 owns that and decides the local_auth_refresh transition. This cleanup follows the private migration handoff filed with allod/secrets#23; renaming the registry stays with allod/secrets#22.

Scope

In scope: cross-repository removal of legacy validation, fixtures, migration code, refusal paths, the legacy predicate branch, and obsolete documentation and tests after the witness passes. Out of scope: the private registry migration itself, live deployment or revocation, and the rotate-token retirement in allod/nexus#52.

Remove the legacy credential shape (`format` plus structured `verify.type`) from every public consumer once an executable witness shows no registry still carries it, so the value-template contract of allod/secrets#23 is the only shape left and the one-shot migration code goes with it. Primary goals: - **Evidence gates the removal** — an executable witness over every registry the deployment composes, public and private, proves that no credential carries `format` and that the `local_auth_refresh` source has moved to the new contract; a hand inventory or a passing deployment-health command is not sufficient. - **Delete the legacy validator path** — the `credential-registry` check in allod/secrets stops accepting `format` and structured verification, and its legacy positive fixture and legacy sabotage witnesses go with it, while the new-contract coverage stays. - **Retire the one-shot migration code** — `allod secret migrate`, its legacy translation table, the `format` and target-level `user` fields in the registry structs, and the "run migrate first" refusals in `create` and `rotate` are removed from allod/tools. - **Finish the archetypes consumer** — the `local_auth_refresh` source predicate accepts only the template shape; the legacy `credential-store-url` branch is removed. - **Fail loud on reintroduction** — a `format` field anywhere in a registry is a check failure afterwards. ### Trigger and decision criterion Start when the witness passes on the composed deployment: no registry entry carries `format`, and the refresh path that allod/nexus#52 decides no longer requires the legacy shape. Until both hold, the transition union stays in place and this issue waits. ### Removal scope In allod/secrets, remove legacy acceptance from the `credential-registry` check and delete the legacy fixtures while keeping one sabotage witness per remaining validator. In allod/tools, delete `secret_migrate.go`, the legacy verify translation, the `format` and `user` registry fields, and the legacy refusal paths, and update the docs and tests that describe them. In allod/archetypes, remove the legacy branch of the `local_auth_refresh` source predicate and its legacy fixture. Delete documentation and tests made obsolete by these paths, and keep a check that makes a reintroduced `format` field fail. ### Related work `rotate-token` is not retired here; allod/nexus#52 owns that and decides the `local_auth_refresh` transition. This cleanup follows the private migration handoff filed with allod/secrets#23; renaming the registry stays with allod/secrets#22. ### Scope In scope: cross-repository removal of legacy validation, fixtures, migration code, refusal paths, the legacy predicate branch, and obsolete documentation and tests after the witness passes. Out of scope: the private registry migration itself, live deployment or revocation, and the `rotate-token` retirement in allod/nexus#52.
Author
Member

Audit of this issue's goals against master today, prompted by a question about handing it to an agent. Four of the five are done, and one of the four landed in a deliberately different form from what this issue specifies.

Goal State Evidence
Evidence gates the removal Superseded in the public tree; open only for the private registry lib.forgejoTokenGroups is wrapped in validateCredentialRegistry (secrets/flake.nix:215, :141), which throws, so a registry carrying format cannot be read at all rather than merely failing a check. The private registry is not in this workspace and cannot be witnessed from here.
Delete the legacy validator path Done allod/secrets PR 28. The legacy-new-mix, migrating, legacy-format and legacy-verify fixtures are gone; credential-registry refuses format at flake.nix:67 and :113, and requires a one-line verify at :42 and :107.
Retire the one-shot migration code Done except for one item, deliberately reversed secret_migrate.go is gone, no command mentions migrate, and the target-level user field is gone. The format field on the registry struct was kept on purpose.
Finish the archetypes consumer Done allod/archetypes PR 77. isCredentialStoreUrlSource (flake.nix:797) is !(credential ? format) && isCredentialStoreUrlTemplate credential. The allod/nexus consumer followed in allod/nexus#56.
Fail loud on reintroduction Done The refusal at secrets/flake.nix:113, pinned by the format-field and format-field-non-string-name sabotage fixtures at :342 and :357.

The one item worth stopping on before anyone implements this. This issue asks to remove "the format and target-level user fields in the registry structs" from allod/tools. The user field went. Format is still on registryCredential at cmd/allod/secret.go:199, and it is there deliberately: Go's json.Unmarshal silently ignores a field the struct does not declare, so without it a stray format entry would decode as absent and reach every command as if the registry were clean. firstCredentialCarryingFormat at :726 is the one place that notices and refuses by name, wired into the registry decode at :714. Deleting the field as written here would not tidy up a legacy remnant, it would remove a working refusal and restore silent acceptance.

This issue also overlaps heavily with allod/secrets#27, which covered the same removal from the public check and the private validator and was closed on 13 September when PR 28 merged. The two were filed a day apart by different authors and describe substantially the same work.

Suggested disposition: close this as settled by allod/secrets#27 and PR 28, or narrow it to the single genuinely open question, which is whether the private registry has an executable witness that no entry carries format. That question cannot be answered or implemented from this workspace, so it belongs in a handoff rather than in a bundle of public implementation work.

Audit of this issue's goals against master today, prompted by a question about handing it to an agent. Four of the five are done, and one of the four landed in a deliberately different form from what this issue specifies. | Goal | State | Evidence | |---|---|---| | Evidence gates the removal | Superseded in the public tree; open only for the private registry | `lib.forgejoTokenGroups` is wrapped in `validateCredentialRegistry` (`secrets/flake.nix:215`, `:141`), which throws, so a registry carrying `format` cannot be read at all rather than merely failing a check. The private registry is not in this workspace and cannot be witnessed from here. | | Delete the legacy validator path | Done | allod/secrets PR 28. The `legacy-new-mix`, `migrating`, `legacy-format` and `legacy-verify` fixtures are gone; `credential-registry` refuses `format` at `flake.nix:67` and `:113`, and requires a one-line `verify` at `:42` and `:107`. | | Retire the one-shot migration code | Done except for one item, deliberately reversed | `secret_migrate.go` is gone, no command mentions `migrate`, and the target-level `user` field is gone. The `format` field on the registry struct was kept on purpose. | | Finish the archetypes consumer | Done | allod/archetypes PR 77. `isCredentialStoreUrlSource` (`flake.nix:797`) is `!(credential ? format) && isCredentialStoreUrlTemplate credential`. The allod/nexus consumer followed in allod/nexus#56. | | Fail loud on reintroduction | Done | The refusal at `secrets/flake.nix:113`, pinned by the `format-field` and `format-field-non-string-name` sabotage fixtures at `:342` and `:357`. | The one item worth stopping on before anyone implements this. This issue asks to remove "the `format` and target-level `user` fields in the registry structs" from allod/tools. The `user` field went. `Format` is still on `registryCredential` at `cmd/allod/secret.go:199`, and it is there deliberately: Go's `json.Unmarshal` silently ignores a field the struct does not declare, so without it a stray `format` entry would decode as absent and reach every command as if the registry were clean. `firstCredentialCarryingFormat` at `:726` is the one place that notices and refuses by name, wired into the registry decode at `:714`. Deleting the field as written here would not tidy up a legacy remnant, it would remove a working refusal and restore silent acceptance. This issue also overlaps heavily with allod/secrets#27, which covered the same removal from the public check and the private validator and was closed on 13 September when PR 28 merged. The two were filed a day apart by different authors and describe substantially the same work. Suggested disposition: close this as settled by allod/secrets#27 and PR 28, or narrow it to the single genuinely open question, which is whether the private registry has an executable witness that no entry carries `format`. That question cannot be answered or implemented from this workspace, so it belongs in a handoff rather than in a bundle of public implementation work.
Owner

duplicate of #27

duplicate of #27
vnprc closed this issue 2026-09-18 22:27:52 +01:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
allod/secrets#26
No description provided.