Skip to content
Draft
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

<!-- Copyright 2026 Firefly Software Foundation. SPDX-License-Identifier: Apache-2.0 -->

## 0.2.47 — Unreleased

- Add immutable, version-isolated official framework references, bounded refresh operations, verified private-cache reads, and generation target pins. Extend the prompt catalog with eleven entries while retaining the original 322, and expose 182 MCP tools.
- Prepare same-attempt continuity for one already consumed, statically rejected evidence read through offline SDK reconstruction, explicit compatible policy/tool-contract migration, and a finite ownership lease. Preserve original receipts, scope, history and limits; charge new native commands once against their existing lifetime ledger.
- Add separately acknowledged version-2 continuity for unavailable pinned source-read observations. Keep the policy disabled by default and preserve singleton version-1 requests and historical receipts.
- Retain exact native Agentic call intents and results for nine implementation tools across API and Bridge providers, including raw and validated arguments, large JSON artifacts and nested effect links. Hold uncertain writes and commands before further work; show explicit uncaptured-tool coverage.
- Present native tool calls and retained output as structured Studio cards with original-record links and technical detail kept separately.
- Recognize the registered historical SDK checkpoint format through a separate migration witness. Preserve usage counters, exact source telemetry values and each tool's original optional-field presence; ordinary checkpoint restoration still requires its original supported runtime.
- Reconcile uncertain framework-source writes after cancellation through administrator-authorized observation. Preserve the cancelled state and refuse new source submissions or corpus activation during that observation.
- Honor the caller's finite metadata timeout for native CLI discovery without submitting a model request.
- Compose the current Studio guides and 550 registered walkthrough rasters. The successor source/profile, PostgreSQL/controller and actual retained-run qualification remain separate gates; this entry does not claim publication or CRM delivery.

## 0.2.46 — changes included in the 0.2.47 preview

- Give `read_run_evidence` a strict model-facing query schema. Validate fields, types and pagination before the native callback; return checkpoint-safe `invalid_query` results so malformed queries can be corrected within existing execution budgets.
- Default worker evidence pages to ten records, matching the native worker limit. Keep the operator API's separate page size and all authorization, integrity and unknown-effect checks.
- Bind the worker query and evidence reader to the source admission and checkpoint runtime inventories. Historical native profiles remain unchanged; the new runtime requires fresh qualification before admission.

## 0.2.45 — 2026-10-25

- Page project and campaign data without a fixed project-count ceiling, retain revision-bound references, and configure finite campaign execution windows with durable usage accounting.
Expand Down
20 changes: 10 additions & 10 deletions deploy/flycanon/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
import urllib.request
from pathlib import Path

RELEASE = "https://github.com/fireflyframework/flycanon/releases/download/v26.10.5/"
RELEASE = "https://github.com/fireflyframework/flycanon/releases/download/v26.10.6/"
ASSETS = {
"flycanon-26.10.5-py3-none-any.whl": "1f0099aeea2d3c3d775ae7cae81b343dad8ca635ab0a1ffda6236e3481230ea6",
"flycanon-26.10.5.tar.gz": "1db735770081a845b125f23ba9fdaaae81f7213cea61f6a1e272dcfe85c1957f",
"runtime-requirements-26.10.5.txt": "f2452338a89e24962d9348c42ec75cca6d3437ddbaa322649384125fe6022d6a",
"flycanon-26.10.6-py3-none-any.whl": "cebe71df52417deb71e908be0830be916e206bc5c9a5335a91673ad482a80f28",
"flycanon-26.10.6.tar.gz": "3341a79b6d840279677b5304ad5311084f3136944ac93aa98b7973daee11ed2c",
"runtime-requirements-26.10.6.txt": "9233e0585053c667cca3b03c5ac075271585d9928f498d6bb381afdd834fdaa8",
}

with tempfile.TemporaryDirectory() as directory:
Expand All @@ -24,26 +24,26 @@
if hashlib.sha256(data).hexdigest() != digest:
raise SystemExit("Released flycanon asset checksum mismatch: " + name)
(target / name).write_bytes(data)
with tarfile.open(target / "flycanon-26.10.5.tar.gz") as archive:
with tarfile.open(target / "flycanon-26.10.6.tar.gz") as archive:
members = [
member
for member in archive.getmembers()
if member.name.startswith("flycanon-26.10.5/migrations/") or member.name == "flycanon-26.10.5/alembic.ini"
if member.name.startswith("flycanon-26.10.6/migrations/") or member.name == "flycanon-26.10.6/alembic.ini"
]
archive.extractall(target / "scaffold", members=members, filter="data")
import shutil

scaffold = target / "scaffold/flycanon-26.10.5"
scaffold = target / "scaffold/flycanon-26.10.6"
shutil.copytree(scaffold / "migrations", "/app/migrations")
shutil.copyfile(scaffold / "alembic.ini", "/app/alembic.ini")
requirements = (target / "runtime-requirements-26.10.5.txt").read_text().splitlines()
requirements[0] = "flycanon @ " + (target / "flycanon-26.10.5-py3-none-any.whl").as_uri()
requirements = (target / "runtime-requirements-26.10.6.txt").read_text().splitlines()
requirements[0] = "flycanon @ " + (target / "flycanon-26.10.6-py3-none-any.whl").as_uri()
(target / "install.txt").write_text("\n".join(requirements) + "\n")
subprocess.run(
[sys.executable, "-m", "pip", "install", "--no-cache-dir", "-r", str(target / "install.txt")], check=True
)
# The release's pyfly configuration is packaged as a separately checksummed asset.
with urllib.request.urlopen(RELEASE + "pyfly-26.10.5.yaml", timeout=120) as response:
with urllib.request.urlopen(RELEASE + "pyfly-26.10.6.yaml", timeout=120) as response:
configuration = response.read()
if hashlib.sha256(configuration).hexdigest() != "5288abf593807f5bdc6642c361ca033741f35b9fca940792778e28f97b2adc1e":
raise SystemExit("Released flycanon configuration checksum mismatch")
Expand Down
6 changes: 6 additions & 0 deletions docs/agent-integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ Publication and cancellation are worker-mediated requests. Python `execution_req

Python `reconcile_execution_request(run_id, request_id, reconciliation_id)`, MCP `reconcile_execution_request`, and CLI `forge reconcile-execution-request` ask the server to match existing evidence. They accept a stable 32-character hexadecimal reconciliation ID and no caller-supplied outcome. They do not dispatch delivery or repeat an uncertain effect. Read [delivery request recovery](recovery.md#reconcile-worker-delivery-requests) for authority checks, idempotency and unknown-result handling.

## Retained checkpoint continuations

Use `checkpoint_continuation_candidate(run_id, request_id)` to inspect an existing ticket. After reviewing a ready candidate, `request_checkpoint_continuation(run_id, request_id, action_id, request)` saves one explicitly acknowledged finite continuation. Read `checkpoint_continuation_status(run_id, request_id)` after an uncertain response and match the saved action ID. The typed input is `CheckpointContinuationInputV1`; all identifiers and acknowledgements are validated before transport.

These methods preserve the original attempt, history, completed effects and remaining budgets. A retained response is consumed once, and completed effects are reused from their original receipts. See [retained checkpoint continuation](checkpoint-continuations.md) for policy, eligibility, input fields and status meanings.

## Exact observation attempts

V2 source-verification attempts can distinguish an immutable local refusal from an uncertain operation. They read an existing flycanon source and its citations; they do not create or ingest a source. The original observation and verified-receipt APIs remain available with their existing UUID request identifiers.
Expand Down
14 changes: 14 additions & 0 deletions docs/agent-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,17 @@ Reading requires current access to the run's repository and project, when scoped
For integrations, read `GET /api/v1/runs/{run_id}/worker-messages` and send `POST /api/v1/runs/{run_id}/worker-requests/{request_id}/respond` with a stable `id`, an `actor` label and an `answer`. Reusing an ID with changed content is refused. New responses also bind the ID to the authenticated replying user. SDK clients use `worker_messages` and `respond_worker`; MCP clients use `respond_worker_request`. Keep credentials out of all question and answer fields.

**Execution record references** shows the question and answer event digests. The portal checks each displayed event separately. The filtered conversation omits other execution events; inspect the full **Plan > Execution journal** when you need the complete journal verification.

## Durable native tool observations

API and bridge workers use the public Agentic `wrap_tool_execute` capability to record exact tool calls. The current text-tool coverage is `list_files`, `read_file`, `search_text`, `git_diff`, `write_file`, `edit_lines`, `execute_command`, `knowledge_lookup` and `read_run_evidence`. The intent binds both exact public raw arguments and SDK-validated normalized arguments, with separate digests. The native factory records an intent before the callback and retains its credential-checked result afterward. A retained result establishes what the callback returned; inspect that content to determine whether its operation succeeded.

A repeated call identity can reuse its retained result only after current owner, actor, configuration, task, arguments, invocation and source admission. A committed intent with an unavailable result remains unresolved. It cannot cause the callback to run again. An unresolved source write or command also holds later tool calls, model requests and final worker completion in that task attempt. Native tool callbacks are serialized within their invocation so an active sibling is not mistaken for a lost effect. There is no generic reconciliation API for these new records: inspection alone cannot turn an unknown effect into a retained result. Changed arguments or scope are refused. The run journal distinguishes `agentic_tool_intent`, `agentic_tool_result` and `agentic_tool_unknown`; an interrupted owner can leave only the intent, which also means the result is unavailable.

Large JSON arguments and results use immutable private artifacts with canonical byte counts and SHA-256 digests. They preserve the existing tool limits instead of imposing a smaller journal window. Keep the factory data directory, including `agentic-tool-results`, with its PostgreSQL backups. Missing, changed, linked or unreadable artifacts cannot authorize retained-result reuse.

Nested command and broker receipts keep their own effect identities and quota accounting. Separate `agentic_tool_effect_link` records connect their exact journal digests to the public tool call. The wrapper does not reserve a second broker charge. Read these records through the existing journal evidence projection; custody does not change the legacy evidence query validator.

Browser, image, profiling, Internet search and external MCP handlers are outside this initial coverage. Their existing effect receipts still apply, but this feature does not claim their exact public call/result custody. Standalone `execute_agentic` use without a native factory invocation reports `native_factory_invocation_missing` and lists its uncaptured tools in usage metadata. Configured model providers, including bridge transport, share the same capability boundary.

A newly recorded result cannot supply a missing historical observation. In particular, the old CRM `list_files` call has no durable result receipt; this change neither reconstructs a listing nor repeats that callback.
2 changes: 1 addition & 1 deletion docs/agent-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Use the [tool prerequisites guide](tooling-prerequisites.md) to check every phas

Native tool arguments reject known configured credentials before file writes or external requests. Text returned by every native tool is redacted against the shared server credential registry before the model receives it. This checks known values and their configured representations; it does not discover every possible secret in a repository.

Paths cannot traverse outside the component. Source read and write operations reject symlinks, hardlinks, Git metadata and credential filenames. Git diff reads only the component's admitted source paths and does not update the index. A rejected line edit requires reading the new file before retrying.
Paths cannot traverse outside the component. Source read and write operations reject symlinks, hardlinks, Git metadata and credential filenames. Git diff reads only the component's admitted source paths and does not update the index. It includes tracked changes and nonignored untracked source files, representing new files as added-file patches without staging them. The response covers at most 100 paths and 128,000 characters, with explicit truncation; it is not a complete project diff when truncated. A rejected line edit requires reading the new file before retrying.

The table is a conditional native registry, not a promise that every provider receives all sixteen tools. Ordinary Codex and Claude Code execution uses the CLI's own permissions; role tool lists alone do not enforce those providers' tool access. Firefly Agentic and bridge execution use the native Python admission boundary.

Expand Down
3 changes: 3 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ After grant confirmation, refresh the final-allowance candidate and include `cod
| GET | `/runs/{id}/agent-checkpoints/candidates` | Discover bounded original-result references without continuing work |
| POST | `/runs/{id}/agent-checkpoints/{completion_id}/restores` | Admit one reviewed original-result continuation |
| GET | `/runs/{id}/agent-checkpoints/{completion_id}/restores/{request_id}` | Read that exact continuation ticket without dispatch |
| GET | `/runs/{id}/checkpoint-continuations/requests/{request_id}/candidate` | Inspect a retained checkpoint and original ticket without admitting work |
| POST | `/runs/{id}/checkpoint-continuations/requests/{request_id}/actions/{action_id}` | Save a reviewed finite continuation on the same execution request |
| GET | `/runs/{id}/checkpoint-continuations/requests/{request_id}/status` | Read the saved checkpoint-continuation action and worker status |
| GET | `/runs/{id}/execution-requests` | Read worker delivery and cancellation requests with their receipts |
| POST | `/runs/{id}/execution-requests/{request_id}/reconcile` | Settle an unknown request only from matching recorded server evidence |
| POST | `/runs/{id}/runner-continuations` | Admit one explicit continuation of the original eligible queued pool command |
Expand Down
Loading
Loading