# Update Package Specification v1

## ZIP structure

```text
update-0.1.1.zip
├── manifest.json
└── payload/
    ├── app/...
    ├── database/migrations/...
    ├── resources/...
    └── public/build/...
```

## Manifest

```json
{
  "package_type": "etebar-update-v1",
  "version": "0.1.1",
  "minimum_version": "0.1.0",
  "release_date": "2026-08-16",
  "changelog": [
    "Fix example"
  ],
  "migrations": [
    "database/migrations/2026_08_16_000001_example.php"
  ],
  "files": {
    "app/Example.php": "<sha256>",
    "database/migrations/2026_08_16_000001_example.php": "<sha256>"
  },
  "delete": [],
  "package": {
    "name": "Inquiry Platform Update",
    "mode": "patch"
  }
}
```

## Validation / security rules

- `manifest.json` must be at ZIP root;
- only entries under `payload/` are accepted;
- every payload file must be listed in `files`;
- every listed SHA-256 is verified;
- package SHA-256 is rechecked immediately before install;
- absolute paths, `..`, dot-segments and null bytes are rejected;
- undeclared files are rejected;
- declared-but-missing files are rejected;
- uncompressed-size ceiling reduces ZIP-bomb risk;
- sensitive paths cannot be modified:
  - `.env`
  - `.env.example`
  - `VERSION`
  - `storage`
  - `bootstrap/cache`
  - `.git`
  - `node_modules`
  - `vendor`
  - local SQLite database file
- only authenticated Super Admin with `updates.manage` may upload/install;
- Laravel CSRF protection applies to upload and install;
- `VERSION` is changed only by the installer after successful migrations.

Because an update package intentionally contains executable application code,
provenance/signing for centrally distributed packages will be added with the
future Remote Update Source. Local ZIP installation is deliberately limited
to Super Admin and strict package/path/checksum validation.

## Execution

1. Validate staged ZIP again.
2. Create Update Log.
3. Create portable DB backup.
4. Back up every project file that will be replaced/deleted.
5. Extract safely to private working directory.
6. Enter Maintenance Mode.
7. Atomically replace files.
8. Run pending migrations with `--force`.
9. Record actually executed migrations.
10. Clear optimized/cache state.
11. Record new version in DB and `VERSION`.
12. Leave Maintenance Mode.

## Failure / recovery

If any step after backup fails:

- restore project files;
- restore database backup;
- mark update `rolled_back`;
- leave Maintenance Mode.

If recovery itself fails:

- keep the application in Maintenance Mode;
- mark `failed_requires_recovery` when DB access is possible;
- preserve backup directory for deterministic manual recovery.

## Future central update server

Package staging and package installation are intentionally separate. A future
Remote Update Source will perform:

- check latest compatible version;
- fetch manifest/package;
- verify central cryptographic signature;
- download package into the same private staging area;
- invoke the existing validator/installer.

The install pipeline does not need to be rewritten.
