Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"baseline_version": "2.7.22",
"classification_rationale": "user-authorized-reset-revalidation-remediation",
"component": "product",
"event_lineage": "user-authorized-reset-revalidation-remediation",
"expected_head": "0da4ffae94f1834b957a04ea31d7ff2010fd072a",
"operation_id": "reset-revalidation-remediation-2.7.23",
"policy_revision": "forge-bootstrap-release-cadence-v2",
"product": "forge",
"projection_paths": "product-version.json",
"release_class": "PATCH",
"requested_bump": "patch",
"requested_version": null,
"schema_version": "1",
"target_version": "2.7.23"
}
24 changes: 24 additions & 0 deletions docs/architecture/FORGE_OPERATIONAL_RESET_V1.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ There is no `--force`, arbitrary table list, peer SQL or automatic rollback.
The stable machine envelope is `contract_version=operational-reset-v1` and
contains no bearer values or raw credential verifiers.

The semantic plan contract is `forge-operational-reset-plan-1.1` under reset
policy version `2`. A general preview reports current availability separately
from the approved reset meaning. Consequently, the owning prepare transition
may add its exact maintenance operation, audit entries and verified backup
without changing the plan digest. A general preview still reports
`MAINTENANCE_ALREADY_ACTIVE` and cannot start or join an operation.

Only `revalidate` may inspect an already prepared operation. It requires the
exact operation, plan, request and backup digests and re-proves the current
operator/authority, physical database binding, schema, writer-fence owner,
source-row contents, preserved security/configuration, effect set, generation,
product/implementation provenance and verified backup. It creates a distinct
read-only revalidation digest; it neither rewrites the approved plan nor emits
a new backup or authority. Plan 1.0 operations are not reinterpreted under
these rules and must be cancelled before apply or handled by their original
installed implementation.

## Schema-owned data classification

Schema version 38 owns this complete table mapping. Any additional application
Expand Down Expand Up @@ -78,6 +95,7 @@ touches repositories, source, documents, other workspaces or other instances.
read-only PREVIEW
-> PREPARED (durable writer fence + exact authority/request binding)
-> BACKUP_VERIFIED
-> read-only operation-bound REVALIDATE
-> DATABASE_APPLIED (one domain transaction)
-> APPLIED (every filesystem step reconciled)
-> VERIFIED
Expand All @@ -94,6 +112,12 @@ same-root mutation lock serializes runtime service ticks and maintenance
commands. A raw/peer SQL writer is unsupported and does not become a product
interface.

Successful revalidation is not a durable permission token. `apply` repeats
the operation, operator/authority, database identity, lifecycle, fence,
generation, meaningful-source and backup checks after entering its actual
`BEGIN IMMEDIATE` mutation boundary. Fence loss or drift after revalidation
therefore remains blocking.

`resume` rereads the same operation. A failure before the SQLite commit leaves
the whole operational population. A failure after commit continues forward.
Each external item has a durable step; if removal happened before its step write,
Expand Down
30 changes: 18 additions & 12 deletions docs/operations/FORGE_INSTALLED_UPDATE_RUNBOOK.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Forge installed update controller

Status: bounded product-owned maintenance provisioner for the selected
Forge 2.7.21 to 2.7.22 transition.
Status: bounded product-owned maintenance provisioner for the selected Forge
2.7.21 to 2.7.22 schema-37-to-38 transition and the selected 2.7.22 to 2.7.23
same-schema corrective transition.

This controller closes one concrete product provisioning gap. It is not the
universal Forge Platform installer, an installer UI, a new service supervisor,
Expand All @@ -17,8 +18,9 @@ cannot be called by the installed runtime as a second self-installer.

## Supported operation

The controller accepts only one explicitly bound existing installation and one
exact `forge-autonomy` 2.7.22 wheel. Every invocation binds:
The controller accepts only one explicitly bound existing installation and an
exact `forge-autonomy` wheel for one of those two transitions. Every invocation
binds:

- operation, runtime, installation, and peer-configuration identities;
- data root, runtime root, current command resolver, legacy interpreter, and
Expand All @@ -37,7 +39,10 @@ interpreter, version, and bytes.

1. Read the wheel once through a no-follow descriptor; validate its digest,
canonical RECORD, purelib tag, package metadata, member allowlist, and the
exact terminal release/reconciliation receipt without importing it.
exact terminal release receipt without importing it. The historical
2.7.22 reconciliation receipt retains its dedicated validation; 2.7.23 must
have the normal protected release-complete publication/readback/cleanup
shape and cannot be presented to the older transition.
2. Create an isolated versioned runtime slot outside the source checkout with
the explicit Python interpreter. Extract only the already validated bytes
into a pip-free virtual environment, then verify every installed file and
Expand All @@ -56,10 +61,11 @@ interpreter, version, and bytes.
6. Take a SQLite backup through the backup API while the writer fence is held.
Verify `integrity_check`, foreign keys, digest, and the complete logical
pre-migration snapshot.
7. Migrate an isolated copy of that backup through the staged candidate's
normal `forge ... server init` path. Require schema 38, the exact new reset
table set, an idle reset control row, and byte-logical preservation of every
pre-existing domain table and protected metadata/binding.
7. Re-open an isolated copy of that backup through the staged candidate's
normal `forge ... server init` path. The 37-to-38 route requires exactly the
reset-table additions and a fresh idle control row. The 38-to-38 route
permits no table additions and requires the complete reset state and every
domain/security/configuration row to remain byte-logically unchanged.
8. Point the stable resolver at a maintenance fence. Take an exclusive SQLite
writer boundary, prove the live database is still byte-logically identical
to the backed-up snapshot, and atomically install the already Forge-migrated
Expand All @@ -83,11 +89,11 @@ authorized read-only Forge-to-EP check.
Re-run the same exact operation ID and arguments. A conflicting request is
rejected.

- Before atomic database replacement, failure restores the retained 2.7.21
- Before atomic database replacement, failure restores the retained prior
command route only when the complete live snapshot still equals `before`.
A hard interruption may leave the explicit maintenance fence; resuming the
same operation reconciles it from durable evidence.
- From the first schema-38 readback or any ambiguous partial state onward, the
- From the first target-schema readback or any ambiguous partial state onward, the
old binary is never selected. Any caught activation/readback failure selects
the maintenance fence; replay reconciles the exact protected candidate.
- A completed receipt is idempotently returned only after revalidating its
Expand All @@ -103,7 +109,7 @@ separate authority and compatibility proof.
## Qualification boundary

`tests/test_installed_forge_update.py` covers exact release binding, target and
writer rejection, the real Forge schema-37 to schema-38 migrator, preservation
writer rejection, both bounded schema transitions, preservation
of Missions, allocations, reviews, execution receipts, governance grants,
configuration and identity, concurrent-operation exclusion, resolver adoption,
canonical receipt shape, path safety, exact slot contents, exclusive atomic
Expand Down
29 changes: 24 additions & 5 deletions docs/operations/FORGE_OPERATIONAL_RESET_RUNBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,25 @@ consistent backup and returns `request_digest` plus verified `backup.digest`.
If backup creation fails, leave the instance in maintenance and use `status`;
do not start another operation.

## 3. Apply the reset — DESTRUCTIVE
## 3. Revalidate this prepared operation — READ-ONLY

Do not repeat the general preview as the same-operation gate. It correctly
blocks any new reset while maintenance is active. Instead, bind the exact
prepared receipt:

```text
forge --data-root "/absolute/Forge Server" server reset revalidate \
--operation-id "forge-reset-<approved-reference>" \
--plan-digest "sha256:<preview-plan>" \
--request-digest "sha256:<prepared-request>" \
--backup-digest "sha256:<verified-backup>"
```

Require `allowed=true`, no blockers, the unchanged plan/relevant-source and
preserved-bindings digests, the exact fence owner and a revalidation digest.
This command must not change owning status, data, authority or backup bytes.

## 4. Apply the reset — DESTRUCTIVE

```text
forge --data-root "/absolute/Forge Server" server reset apply \
Expand All @@ -54,7 +72,7 @@ forge --data-root "/absolute/Forge Server" server reset apply \
--backup-digest "sha256:<verified-backup>"
```

## 4. Verify — MAINTENANCE REMAINS ACTIVE
## 5. Verify — MAINTENANCE REMAINS ACTIVE

```text
forge --data-root "/absolute/Forge Server" server reset verify \
Expand All @@ -67,7 +85,7 @@ forge --data-root "/absolute/Forge Server" server reset verify \
Require `state=VERIFIED`, all operational counts zero, all integrity checks
green, unchanged target/bindings and a non-empty `verification_digest`.

## 5. Interrupted operation
## 6. Interrupted operation

```text
forge --data-root "/absolute/Forge Server" server reset status \
Expand All @@ -85,7 +103,7 @@ before a backup digest exists, omit `--backup-digest`; the same PREPARED operati
finishes its backup first. Do not automatically restore or create a replacement
operation.

## 6. Release maintenance — MUTATING
## 7. Release maintenance — MUTATING

```text
forge --data-root "/absolute/Forge Server" server reset finish \
Expand Down Expand Up @@ -113,7 +131,8 @@ HTTP authentication/preflight; it must not create a Mission or submission.
if the normal allocator cannot produce the desired display label.
3. Prepare both owning operations; confirm both durable maintenance states and
both verified backups.
4. Recheck both exact plans under their writer fences.
4. Invoke both owning operation-bound `revalidate` commands under their writer
fences. Do not substitute general preview.
5. Apply each owning reset sequentially. If either fails, keep both products in
maintenance and resume the same owning operation; never auto-resume the first.
6. Verify both empty operational generations, preserved identities/peer binding,
Expand Down
18 changes: 12 additions & 6 deletions docs/reports/FORGE_OPERATIONAL_RESET_DELIVERY_STATUS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Forge operational reset delivery status

The bounded Forge-owned operational-history reset is implemented in source with
schema 38 and the `forge server reset` command family. It is independent from
schema 38 and the `forge server reset` command family. Patch 2.7.23 separates
general availability preview from operation-bound revalidation and adds the
explicit installed `revalidate` command. It is independent from
the planned Operations Console, full export/import/relocation product and Forge
Server daemon. Those broader nodes remain planned.

Expand All @@ -11,8 +13,8 @@ Status dimensions are deliberately separate:
| --- | --- |
| Architecture/contract | IMPLEMENTED in `FORGE_OPERATIONAL_RESET_V1.md` |
| Application service and CLI | IMPLEMENTED |
| Isolated synthetic positive/negative/crash qualification | PASSED locally: 23 reset regressions within `scripts/validate.sh` |
| Full repository source gate | PASSED locally: 694 tests, product-version and offline-projection validation |
| Same-operation revalidation regressions | PASSED locally: stable semantic plan, real row-content drift, backup, authority and fence checks |
| Joint subprocess candidate sequence | PASSED locally with non-editable candidate wheels and the real coordinator; protected installed-release repetition remains required |
| Independent protected-candidate review/checks | NOT YET EVIDENCED |
| Protected review/merge | NOT YET EVIDENCED in this source branch |
| Stable release publication | NOT YET EVIDENCED |
Expand All @@ -21,9 +23,13 @@ Status dimensions are deliberately separate:
| Production reset | NOT AUTHORIZED / NOT PERFORMED |
| Mission 3 | NOT STARTED |

The intended stable patch release is `2.7.22` under
The corrective stable patch release is `2.7.23` under
`forge-bootstrap-release-cadence-v2`: protected exact-head review/merge, one
clean wheel/sdist build, full qualification bound to their SHA-256 values,
draft GitHub release, PyPI publication, registry digest readback, installed-wheel
smoke, durable publication/cleanup receipt and completion. No branch-local test
or wheel build is presented as published or installed evidence.
smoke, durable publication/cleanup receipt and completion. The earlier
qualification missed the defect because the coordinator revalidation path was
covered by a fixture state machine and product reset tests invoked the owning
services directly; no installed two-product sequence performed general preview
after both prepares. No branch-local test or wheel build is presented as
published or installed evidence.
3 changes: 2 additions & 1 deletion forge/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def main(argv: list[str] | None = None) -> int:
prepare_reset.add_argument("--plan-digest", required=True)
prepare_reset.add_argument("--acknowledge-operational-fk", action="append", default=[])
for name, help_text in (
("revalidate", "revalidate the exact prepared operation without changing it"),
("apply", "apply the authorized destructive reset"),
("verify", "verify reset integrity and preserved bindings"),
):
Expand Down Expand Up @@ -179,7 +180,7 @@ def main(argv: list[str] | None = None) -> int:
expected_plan_digest=args.plan_digest,
acknowledge_operational_fk=args.acknowledge_operational_fk,
)
elif args.reset_command in {"apply", "verify"}:
elif args.reset_command in {"revalidate", "apply", "verify"}:
result = getattr(service, args.reset_command)(
operation_id=args.operation_id, plan_digest=args.plan_digest,
request_digest=args.request_digest, backup_digest=args.backup_digest,
Expand Down
Loading
Loading