LocalApplication¶
LocalApplication ¶
LocalApplication(
store: ProjectStore,
*,
owner_instance: str,
policy: PolicyFile | StaticPolicy,
capability: CapabilityReference | None,
)
One project, opened by one owner. Construct through create, open or in_memory.
The Python transport of the application contract: every operation of the operations table is
a method of the same name, taking the request's members as parameters and returning the
result type whose as_document() is the response the CLI, HTTP and MCP carry.
Examples:
>>> from openflowsheet.application.local import LocalApplication
>>> with LocalApplication.in_memory() as app:
... models = app.list_models()
files_root
property
¶
files_root: Path
The directory jobs/ and imports/ live under: the project's, or an in-memory
project's scratch directory.
create
classmethod
¶
create(
directory: str | PathLike[str],
*,
project_id: str | None = None,
exist_ok: bool = False,
) -> LocalApplication
A new project in directory (absent or empty), opened by the local owner.
With exist_ok, a directory that already holds a project is opened instead (MSG §3.8,
FB-01), so a script that creates its project can run twice. It tries to create first
and opens only on the typed refusal project_exists, so there is no check-then-act
race.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
str | PathLike[str]
|
Where the project is created; it must be absent or empty, or (with |
required |
project_id
|
str | None
|
The project's id; a fresh |
None
|
exist_ok
|
bool
|
Open the project the directory already holds instead of refusing it. |
False
|
Returns:
| Type | Description |
|---|---|
LocalApplication
|
The new (or, with |
Raises:
| Type | Description |
|---|---|
StoreError
|
Coded ( |
open
classmethod
¶
open(
directory: str | PathLike[str],
*,
capability: CapabilityReference | None = None,
executor: Executor | ProcessExecutor = "inline",
) -> LocalApplication
Open a project: load its policy, take an owner lock, recover dead owners' jobs, then
start the executor (§9.1): "inline", "process", or an unbound ProcessExecutor
(a Python caller's, e.g. one constructed with test_hooks=True). The process executor
takes the policy's executor settings in force now.
An invalid policy file with no valid one before it refuses the open
(PolicyRefusedError): a policy is never defaulted (§10.3).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
str | PathLike[str]
|
An existing project directory ( |
required |
capability
|
CapabilityReference | None
|
The capability to act as; the local owner, holding every right, when omitted. |
None
|
executor
|
Executor | ProcessExecutor
|
|
'inline'
|
Returns:
| Type | Description |
|---|---|
LocalApplication
|
The opened project. Close it with |
in_memory
classmethod
¶
in_memory() -> LocalApplication
SQLite :memory:, inline execution only, the local owner only; nothing survives.
Returns:
| Type | Description |
|---|---|
LocalApplication
|
A throw-away project; its files live in a scratch directory removed on |
validate ¶
validate(
revision_id: str,
task: Task,
optimization: Mapping[str, Any] | None = None,
) -> ValidationReport
§4.2: the stored revision's validation report for task; no side effects. read.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
revision_id
|
str
|
A revision of this project. |
required |
task
|
Task
|
|
required |
optimization
|
Mapping[str, Any] | None
|
The optimization request ( |
None
|
Returns:
| Type | Description |
|---|---|
ValidationReport
|
The status ( |
Raises:
| Type | Description |
|---|---|
ApplicationError
|
|
commit_change ¶
commit_change(
change: Change,
expected_revision: str | None,
idempotency_key: str,
) -> TransactionResult
§4.2: the K06 algorithm, persistent and typed. Needs draft.
The order: authorize; canonical check (Q29); ledger lookup (§7); build, validate and
diff outside the write lock from a snapshot; then, inside one BEGIN IMMEDIATE
transaction, the ledger again, the head check, the insert, the head move, the ledger
row and the audit row. Returned: committed, replayed (same key, same request),
conflict (the head moved) or rejected (a bad edit path, a taken or unknown id, a
non-canonical value). Raised: a refusal, and a key reused with a different request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
change
|
Change
|
The edits to apply to the head ( |
required |
expected_revision
|
str | None
|
The head the change was written against; |
required |
idempotency_key
|
str
|
A key of the caller's choosing: the same key with the same request returns the
first result ( |
required |
Returns:
| Type | Description |
|---|---|
TransactionResult
|
|
Raises:
| Type | Description |
|---|---|
ApplicationError
|
A refusal, for example |
preview_change ¶
preview_change(
change: Change, expected_revision: str | None
) -> TransactionResult
§4.2: commit_change's steps 2 and 4–6 — no head check, no write, no ledger. read.
The validation report names the id the commit would assign, so a preview and the commit that follows it with nothing in between report the same thing.
solve ¶
solve(revision_id: str, policy_id: str) -> RunResult
§4.2: submit_job with a fresh auto: key, wait_job until it ends (no time-out),
then get_job_result(...).run_result. Needs execute; a refusal at submission is raised.
policy_id may be "default", the route's registered policy (R2.3).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
revision_id
|
str
|
A revision that validates |
required |
policy_id
|
str
|
An offered solve policy id, or |
required |
Returns:
| Type | Description |
|---|---|
RunResult
|
The job status, the solver's outcome, the verifier's verdict and the artifacts the run registered (solution certificate, run manifest, replay bundle). A failed solve is a result, not an exception. |
Raises:
| Type | Description |
|---|---|
ApplicationError
|
A refusal at submission, for example |
reproduce ¶
reproduce(
bundle_path: str | PathLike[str], policy: ReplayPolicy
) -> ReplayReport
§4.2: import the bundle at bundle_path (its regular files, no symlink followed) as
import-<ordinal>:bundle, submit reproduce with a fresh auto: key, wait, and return
the report. Needs execute. A job that ends without a report raises its error, or, when
it has none (cancelled, timed_out), not_ready (§5.8 as amended by ruling round 4).
submit_job ¶
submit_job(request: JobRequest) -> SubmitResult
§4.2: authorize execute; canonical form (Q29), then the schema; the ledger (§7);
semantic admission (§5.3); accept (job, accepted, ledger row and audit row in one
transaction); hand it to the executor. Returns the job as the executor leaves it —
ended inline, queued or running under the process executor — or, same key, same request,
the existing one with replayed = true.
get_job ¶
get_job(job_id: str) -> Job
§4.2: any job of the project (read covers every principal's jobs).
list_jobs ¶
list_jobs(
*,
status: JobStatus | None = None,
cursor: str | None = None,
limit: int = 50,
) -> Page[Job]
§4.2, §11.4: the project's jobs in acceptance order, by ordinal cursor.
list_job_events ¶
list_job_events(
job_id: str,
*,
after_sequence: int = -1,
limit: int = 100,
) -> Page[JobEvent]
§4.2, §11.4: a job's events after after_sequence; the next cursor is the last
sequence returned, to pass back as after_sequence.
wait_job ¶
wait_job(
job_id: str,
*,
after_sequence: int = -1,
timeout_s: float = 20.0,
) -> JobWait
§4.2: return once the job has events after after_sequence (a cancellation request
among them), once it has ended, or at timeout_s (in-process, math.inf waits for
either); polls every 0.1 s. At most 100 events.
cancel_job ¶
cancel_job(job_id: str) -> Job
§4.2: needs execute, and policy as well for another principal's job. A queued job
ends cancelled at once; a running one is flagged and signalled, and stops at its next
checkpoint; an ended one is returned as it is. Idempotent.
get_job_result ¶
get_job_result(
job_id: str, *, display_units: str | None = None
) -> JobResult
§4.2 as amended by R4: {operation, run_result, replay_report, error} of an ended
job; not_ready before it ends. display_units (ADR 0075 D7.4, ADR 0019 Amendment 17)
is a display preference, resolved against the project's declared ambient pressure: the
result echoes it and every explanation it holds is rendered under it; its SI content is
the result without it.
get_project ¶
get_project() -> ProjectSummary
§4.2: the project, its head and counts, its solve policies, and the caller as its
credential makes it. read.
list_models ¶
list_models() -> ModelRegistryView
§4.2: each model id in MODEL_BUILDERS with its declarative ModelSignature; nothing
is constructed ("inspect manifests without executing them"). read.
Returns:
| Type | Description |
|---|---|
ModelRegistryView
|
Every model with its ports, required parameters, pins and one-of specifications, and for each pin the specification targets that can fix it. |
list_revisions ¶
list_revisions(
*, cursor: str | None = None, limit: int = 50
) -> Page[RevisionSummary]
§4.2, §11.4: the project's revisions in commit order, by ordinal cursor. read.
get_revision ¶
get_revision(
revision_id: str,
*,
pointer: str = "",
depth: int = DEFAULT_DEPTH,
cursor: str | None = None,
limit: int = DEFAULT_PAGE,
) -> Projection
§11.4: the stored revision's document — Revision.as_document(), as validate reads
it and a bundle's revision.json holds it — projected. read.
diff_revisions ¶
diff_revisions(
from_revision: str, to_revision: str
) -> SemanticDiff
§4.2: the semantic diff (content paths added, removed, changed; the title and other
descriptive members excluded) from one stored revision to another, with its
elements (ADR 0019 Amendment 3, A3.2: the items of instances, connections and
specifications that differ, paired by id). read.
inspect_structure ¶
inspect_structure(
revision_id: str,
*,
pointer: str = "",
depth: int = DEFAULT_DEPTH,
cursor: str | None = None,
limit: int = DEFAULT_PAGE,
) -> Projection
§4.2 as amended by R1.5: the structural report of the formulation solve would use,
naming its solve_path, or {"not_run_reason": …} when no route binds the revision —
revision_run.route_structure, projected. read.
get_artifact ¶
get_artifact(
artifact_id: str,
*,
pointer: str = "",
depth: int = DEFAULT_DEPTH,
cursor: str | None = None,
limit: int = DEFAULT_PAGE,
) -> Projection
§11.4: a registered artifact, projected; any principal's (read covers them all).
A file is its JSON when it holds a canonical JSON document, else its text lines. A
replay_bundle is {manifest, files: [{name, kind, artifact_id, sha256, size_bytes}]},
its members listed — solution-state.json among them when the bundle has one (ruling
round 2) — and each read in turn as <bundle id>/<file>. sha256 is the registered
one: the file's bytes, or the bundle's directory hash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artifact_id
|
str
|
An artifact id from a run's |
required |
pointer
|
str
|
A JSON pointer into the document; the whole document when empty. |
''
|
depth
|
int
|
Bounds of the projection, and the cursor of its next page. |
DEFAULT_DEPTH
|
cursor
|
int
|
Bounds of the projection, and the cursor of its next page. |
DEFAULT_DEPTH
|
limit
|
int
|
Bounds of the projection, and the cursor of its next page. |
DEFAULT_DEPTH
|
Returns:
| Type | Description |
|---|---|
Projection
|
The value at |
artifact_bytes ¶
artifact_bytes(artifact_id: str) -> bytes
§4.3, §10.4: an artifact file's bytes exactly as stored — the raw export (Python, CLI,
HTTP; never MCP). A bundle is a directory, exported member by member. read.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artifact_id
|
str
|
A file artifact, for example |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
The file's bytes as stored. |
list_audit ¶
list_audit(
*,
principal_id: str | None = None,
operation: str | None = None,
order: AuditOrder = "ascending",
cursor: str | None = None,
limit: int = 50,
) -> Page[AuditRecord]
ADR 0019 Amendment 3 (A3.3; M06 design note §4.3): the project's audit rows — every
effect and every refusal — by seq, optionally of one principal and one operation, each
allowed row with the ledger's idempotency key. read; another principal's rows, or all
principals' (principal_id omitted), need policy as well (cancel_job's rule). The
cursor is {order, seq}; one issued for the other order is refused at /cursor.