Place deterministic tools in tools/, complete capabilities requiring model reasoning or workflow orchestration in workflow/, and complete products in packages/. Keep only the basic call primitives llm() and agent().
Status: current designScope: source, registration, Programs UI, packaging
1. Canonical directory contract
openprogram/
├── agentic_programming/
│ ├── llm.py # single model-call primitive
│ └── agent.py # Agent-loop primitive with tool calls
└── programs/
├── tools/ # deterministic, directly callable tools
│ ├── files/ web/ code/ planning/ ...
├── workflow/ # all model reasoning, Agent orchestration, and composite capabilities
│ ├── auto_workflow.py # complete single-file Workflow; no empty same-name directory
│ ├── goal/ # single Goal Workflow and session Goal mechanism
│ │ ├── __init__.py
│ │ ├── goal.py # public entry goal()
│ │ ├── command.py # /goal command adapter
│ │ ├── judge.py # completion-condition evaluation
│ │ ├── refinement.py # goal specification and acceptance checklist
│ │ ├── loop.py # state transitions, retries, and stop rules of the single loop
│ │ ├── state.py # persistent state and events of the same GoalRun
│ │ └── notices.py # session status notifications
│ ├── browser/ document/ research/ ...
├── packages/ # independent packages providing callable capabilities
├── _registry.py # shared registration and discovery
└── _programs.py # Application provenance and installation metadata
Remove programs/functions/, programs/functions/agentic/, programs/workflows/ or agentic_programming/goal.py. Each capability has one authoritative implementation and one public import path.
2. Three Program categories
programs/tools/
Tools
Ordinary code determines outputs from inputs, without model inference or an Agent loop. Register with @function for reuse by Agents, Workflows, and Applications.
Portable package sources
Project-local Programs record locations as relative paths scoped by programs. An external installation binding connects the installed runtime to the source checkout. Relative paths do not use the chat working directory. Only exact authorized package names participate in Python resolution; the entire external directory is not added to import scope. Migration, rejection conditions, and publishing rules follow the Workflow package contract.
programs/workflow/
Workflow
Any capability calling llm(), agent(), other Workflows, or containing multi-stage state and completion checks belongs here. Single-model-call capabilities are also Workflows; there is no separate Agentic Function directory.
Portable package sources
Project-local Programs record locations as relative paths scoped by programs. An external installation binding connects the installed runtime to the source checkout. Relative paths do not use the chat working directory. Only exact authorized package names participate in Python resolution; the entire external directory is not added to import scope. Migration, rejection conditions, and publishing rules follow the Workflow package contract.
programs/packages/
Packages
A package is an installation unit for callable capabilities, with its own dependencies and release boundary; it can provide multiple Tools or Workflows. Software Applications use separate management pages, declarations, and registration directories and call public Program capabilities; they are not part of this source classification. Legacy applications/ package locations retain read compatibility.
Portable package sources
Project-local Programs record locations as relative paths scoped by programs. An external installation binding connects the installed runtime to the source checkout. Relative paths do not use the chat working directory. Only exact authorized package names participate in Python resolution; the entire external directory is not added to import scope. Migration, rejection conditions, and publishing rules follow the Workflow package contract.
3. Basic primitives and Workflows
WorkflowDefines flow, state, and acceptance
→
agent()Multi-round model reasoning with Tools
→
llm()Single model request and structured output
Entry
Meaning
Canonical location
llm()
One model call without a tool loop.
agentic_programming/llm.py
agent()
Model tool-call loop.
agentic_programming/agent.py
goal()
Repeatedly runs an Agent and checks completion conditions; a complete Workflow, not a third basic primitive.
programs/workflow/goal/
4. Goal has one execution function
Single Workflow
from openprogram.programs.workflow.goal import goal is the sole execution function, owning GoalRun initialization, spec refinement, Agent rounds, completion evaluation, user questions, stop rules, state writes, and terminal states. No second Goal loop may remain in the dispatcher, command adapter, or another module.
Programs form
The form directly calls goal(prompt, condition, context_mode="isolated", ...). Run records may belong to the current session, but goal() model context does not read pre-call chat history; it reads only form parameters and calls already produced in this GoalRun.
Chat command
/goal <condition> is only a session adapter for the same Workflow: parse the command, then call goal(prompt=condition, condition=condition, context_mode="session", ...).context_mode="session" reads the current session view at execution start; otherwise it uses the same state machine as the form.
State and control
Both entry points produce identical GoalState, progress events, GoalChip, questions, cancellation, clear/status, and terminal states./goal clear controls the GoalRun associated with the current session, without starting or maintaining a second Goal object type.
Internal modules
judge.py, refinement.py, state.py, loop.py serve only this function.command.py only parses set/status/clear and constructs one goal() call. It does not create state, refine goals, or run continuation.
No duplication
Do not retain continue_goal_turns() and goal() as two round controllers. Do not copy spec/checklist from session Goal to isolated Goal or change default rounds, need_user, or terminal semantics based on entry point.
Result ownership and model context are separate fields: form runs may write DAG/runtime cards into the current session, but must still use render_range.callers=0 to isolate pre-call history. Session commands restore current chat evidence through explicit session-context input.
4.1 Implementation and verification records
Type
Confirmed evidence
Implementation
0629e2fd and preceding commits removed Goal continuation from the dispatcher; /goal constructs one goal(..., context_mode="session") forced call. The Programs form still calls the same function and defaults to isolated.
Independent specification review
Passed. Review covered the single function, both context modes, clear races during refinement/judge, round budgets, and terminal states.
Independent quality review
Passed. Review covered cancellation, exceptions, questions in the final round, cross-process Goal events, and Web/CLI adapters.
Automated verification
Focused Goal/Programs/Web/CLI/process-bridge suite 116 passed; Web unit tests 54 passed; TypeScript tsc --noEmit, Ruff, documentation links, and git diff --check passed.
This section records reviewed implementation evidence only and does not alter the design contract above.
5. Choosing files and directories
Form
When to use
Example
Single .py
One public entry and a few local helpers; the file can be read independently.
workflow/auto_workflow.py
Same-name package
Multiple modules with distinct responsibilities, resource files, or session adapters.
workflow/goal/, workflow/browser/
Internal directory
Shared implementation serving only adjacent Workflows; its name begins with _ and it does not become a Programs UI node.
workflow/_runtime/
Do not create same-name folders for every Workflow merely for uniformity. File count and responsibility boundaries determine package splitting.
6. Permitted dependency directions
Caller
Allowed
Forbidden
Tool
Standard library, approved dependencies, and deterministic helpers.
llm(), agent(), Workflow, Application.
Workflow
Tools, llm(), agent(), other Workflows without dependency cycles.
Depending on Applications, copying other Workflows, or dispatch by string name.
Application
Public Tools, public Workflows, and the application’s own UI and services.
Modifying the called Program or maintaining a second implementation.
7. Registration and Programs UI
Shared registration
_registry.py loads public entries from tools/ and workflow/; Applications use provenance records and installation contracts.
Top-level UI
Show only Tools, Workflow, Applications, without historical levels such as Functions, Vanilla, or Agentic Function.
Entity recognition
A registered entry is runnable, so the Programs sidebar shows Use. Expanding a same-name package lists responsibility modules from the actual directory (such as goal/command.py). These files can be opened to inspect call relationships but are not registered as additional Programs and have no Use action.__init__.py and _ internal directories still do not become nodes.
Canonical path
After migration, only new imports are supported. Old paths fail directly, with no aliases or dual scanning of old and new directories.
Stable contract
Moving source does not change public names, parameter Schemas, permissions, DAG semantics, or session state formats.
8. One-time migration acceptance
Migration item
Target state
functions/vanilla → tools
All deterministic tools register from new paths; old directories are absent.
functions/agentic + workflows → workflow
Model capabilities and composite flows load only from singular workflow/.
Goal consolidation
agentic_programming exports only llm, agent; Goal exists only in workflow/goal/.
Caller
Python imports, registries, CLI, Server, Web Programs, documentation, and packaging configuration all use new paths.
Old structure
No old directories, compatibility modules, duplicate decorator registrations, or dual-path scanning.
Functionality
Public names and Schemas remain unchanged; Goal, Auto Workflow, Programs browsing, and run entry points remain usable.
9. Excluded designs
No new decorators
Do not add @workflow; directories and metadata express classification.
Portable package sources
Project-local Programs record locations as relative paths scoped by programs. An external installation binding connects the installed runtime to the source checkout. Relative paths do not use the chat working directory. Only exact authorized package names participate in Python resolution; the entire external directory is not added to import scope. Migration, rejection conditions, and publishing rules follow the Workflow package contract.
No string-based dispatch
Workflows use ordinary Python imports and calls, without adding call_workflow(name).
Portable package sources
Project-local Programs record locations as relative paths scoped by programs. An external installation binding connects the installed runtime to the source checkout. Relative paths do not use the chat working directory. Only exact authorized package names participate in Python resolution; the entire external directory is not added to import scope. Migration, rejection conditions, and publishing rules follow the Workflow package contract.
No parallel structures
Do not keep versioned old/new directories or choose between them at runtime.
Portable package sources
Project-local Programs record locations as relative paths scoped by programs. An external installation binding connects the installed runtime to the source checkout. Relative paths do not use the chat working directory. Only exact authorized package names participate in Python resolution; the entire external directory is not added to import scope. Migration, rejection conditions, and publishing rules follow the Workflow package contract.
Source, registry, Programs explorer, and /goal all load according to this page’s directory contract. Source moves do not change public names or Schemas.
Installed Wiki prompt substitutions
The installed wiki_agent generation and enrichment prompts substitute only their declared content fields. Literal CSS examples such as alert-{info|warning|success|error} survive Python formatting unchanged; they are not substitution fields. Ingest and enrich reach their existing model and owned-vault operations without a formatting exception from the default prompt. The repair escapes those two literals in the existing prompt strings and preserves the Wiki generation, slot, Git and index mechanisms. Public acceptance invokes the actual registered entry for both actions, observes the unchanged literal at a controlled generation boundary, and verifies owned page and slot writes. The prompt literal repair has passed independent specification and quality reviews and is imported into the local package. Combined source and installed-interface acceptance are recorded separately.
Dynamic tool argument mappings
Canonical tool schemas distinguish mappings whose keys are provided at invocation time from objects with declared fields. The public program.args mapping accepts a registered program's legal keyword arguments, including task. Anonymous object mappings and Python dict/Mapping annotations retain open keys and any declared value schema. Objects with properties, including an empty declared property set, retain fixed-field closure. Explicit additionalProperties: false is never opened; nullable mappings retain their existing null behavior. Existing implicit-open top-level parameter objects are not newly closed by this repair.
Canonical object
Local validation
Provider tool mode
Anonymous or typed mapping
Accept legal dynamic keys; enforce object and declared value types
Preserve the mapping schema with non-strict tool mode
Declared fixed fields or explicit closed object
Retain required fields, types and closed-field rejection
Retain the existing strict mode when supported
Mixed request containing both tool kinds
Validate each call against its canonical schema
Select mode per tool; no request-wide disabling of strict validation
The shared provider schema adapter must not turn an open mapping into an empty closed object. OpenAI function calling requires closed objects for strict mode and documents explicit strict: false to preserve non-strict behavior in Responses. Dynamic-mapping tools therefore use that explicit flag for Responses, Codex and Chat Completions; compatible fixed-field tools continue to use strict mode. Anthropic strict tool use similarly applies strict validation per tool; mapping tools retain the ordinary input schema without the strict flag. Existing provider availability, authentication, request-level feature gates and other schema dialects remain unchanged.
Acceptance uses the real public schema, production local validator and registered program consumer in an owned session. Valid task arguments reach the consumer; foreign programs and unsupported child keywords retain their existing errors, and wrong mapping types or values remain invalid. Production provider payloads preserve a dynamic mapping while a closed companion tool remains strict. The fixed execute_code schema remains strict and no dynamic parameter is added to it. Tests include fixed-object extra-key rejection, nullable and typed nested mappings, nonmutation, affected provider/program suites and repository contracts. Existing live sessions, App, worker and user state are excluded from controlled testing.
Implementation state: the canonical design is complete; implementation, independent specification review, fresh quality review and separate installed acceptance are pending.
Wiki change metadata
Public Wiki ingestion reports the actual touched and created content pages, including pages inside newly created directories and paths containing Unicode, spaces or quotation marks. Change discovery requests individual untracked files and consumes Git porcelain records with NUL delimiters, preserving exact path spelling rather than decoding display quoting or splitting filenames on an arrow string. Rename records consume their paired original path while retaining the destination. Existing content-page suffix, folder-index exclusion, file-existence and Git-ignore rules remain; no unrelated link, page, template, generation, commit or index behavior changes.
Acceptance creates a new nested page through the registered ingestion entry, verifies its slot, actual Git commit and searchable index, and checks nonzero page and folder metadata passed to the existing conclusion step. Owned Git cases verify Unicode and special paths, renames, ignored files and excluded folder indexes. The original dirty ops file is preserved in a dedicated input-baseline commit. The path discovery and reindexing repair has passed independent specification and quality reviews and is imported into the local package. Combined source and installed-interface acceptance are recorded separately.