Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
5 changes: 3 additions & 2 deletions docs/adding-a-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,9 @@ also isn't an archival command for an already-published workflow.

## Know the current boundary

The code package runtime is Python 3.12.8 with the standard library, up to 60 seconds and
one declared text artifact. It supports up to eight managed model calls across four routes;
The code package runtime is Python 3.12.8 with the standard library, up to 900 seconds and
one declared text artifact of up to 1,000,000 bytes. It supports up to 32 managed model calls
across four routes; keep a run's model input under 700,000 bytes (about 200k tokens);
only the registered OpenAI Luna and Astra routes are currently admitted. There is no `pip`
installation, raw credential injection or direct network access. Use declared
[project service bindings](project-api-connections.md) for supported external requests; for
Expand Down
21 changes: 14 additions & 7 deletions docs/code-model-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,15 @@ Current supported routes are explicitly `openai/gpt-6-luna` and `openai/gpt-6-so
the existing OpenAI adapter and pinned supplier price card. Other providers/models and custom
URLs fail validation; a configured credential alone does not admit an unpriced route.

Bounds: at most four route aliases, 1–4 calls per route and eight total; 1,024–32,000 serialized
input bytes per call (instructions, data, schema and envelope included); 64–4,096 output tokens;
64,000 response bytes. Output schemas use a small closed subset: required object fields, bounded
arrays, primitives and enums; no references or remote schema loading. The runtime retains its
60-second maximum execution window, including model wait time. Each supplier call has a
30-second limit. These limits do not promise all eight calls will fit in one execution window.
Bounds: at most four route aliases, 1–16 calls per route and 32 total; 1,024–256,000 serialized
input bytes per call (instructions, data, schema and envelope included); 64–32,000 output tokens;
1,000,000 response bytes. A run's model calls should stay under 700,000 input bytes together
(about 200k tokens). That bound is a soft gate: a call that passes it is still sent, and Tin
logs one operator warning for the run, counting every call the run has started. Output schemas
use a small closed subset: required object fields, bounded arrays, primitives and enums; no
references or remote schema loading. The package's `timeout_seconds` (at most 900) is its whole
execution window, including model wait time, and also bounds each supplier call's wait. These
limits are runaway guards, not a promise that all 32 calls fit in one execution window.

## Authority, isolation and recovery

Expand Down Expand Up @@ -104,7 +107,11 @@ zero-credit admission, no paid operation or deduction. A model-enabled definitio
price card. This requires no paid estimation call or quote-approval step.

Hosted model runs require an enabled credit account. Existing project spending policy and
per-operation reservations enforce the pinned maximum. Tin records each observed call and
per-operation reservations enforce the pinned maximum. The maximum assumes every declared call
uses its route's whole output allowance, its whole `max_input_bytes` at three bytes per token,
and a 4,096-token request envelope. The 700,000-byte run warning refuses nothing, so it does not
lower the maximum. Each call reserves its own serialized input the same way
before dispatch. Runs admitted before this formula keep the maximum pinned in their terms. Tin records each observed call and
settles through the existing ledger, including usage incurred before validation failure. The
estimate ceiling rounds upward to a cent; actual usage retains the shared rounding policy.
Tiny model usage may therefore settle to $0.00 while remaining a measured, paid supplier call.
Expand Down
10 changes: 5 additions & 5 deletions docs/code-project-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ read the connected GitHub repository or another project's files. Package resourc
available through ordinary Python reads in the package directory; `code.files` still lists
the executable package's own resources, not its project data dependencies.

Each read is limited to 64,000 bytes. Globbing returns at most 100 matches and refuses a
larger result rather than silently dropping paths. A code execution permits at most 64 file
Each read is limited to 1,000,000 bytes. Globbing returns at most 100 matches and refuses a
larger result rather than silently dropping paths. A code execution permits at most 256 file
requests, separately from its model and service limits. Paths must be safe regular files;
symlinks, parent traversal and protected credential paths are rejected. Binary reads are
supported within the same bound; they do not increase the workflow's text-output or model
Expand All @@ -63,9 +63,9 @@ own: `product.code_map` writes the `### Code map` section and `product.deep_dive
`### Feature map` section of `wiki/INDEX.md`, under `## Product`. Read one with
`ctx.files.read_section(heading)`. It returns the section from its heading line (which may
carry the writer's parenthetical, such as `### Code map (verified 2026-09-04, ...)`) up to the
next heading, exactly as the writer bounds it. It works when the whole index is larger than
the 64,000-byte read limit (the index may hold up to 100,000 bytes); the section itself must
fit that limit.
next heading, exactly as the writer bounds it. It reads the index at its own size bound
(the index may hold up to 700,000 bytes) and returns only the section, which must fit the
1,000,000-byte read limit.

Some packages were written to read the Code map from `product/code-map.md`. When the project
has no such file, that read returns the `### Code map` section, so they find what
Expand Down
5 changes: 3 additions & 2 deletions docs/code-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ The definition selects `executor: workflow.code` and a `code` object with:
- `runtime: python3.12.8-stdlib-v1`;
- `entrypoint`: a declared package-relative `.py` file exporting `run(ctx, inputs)`;
- `files`: 1–32 explicitly declared UTF-8 files, at most 64,000 bytes each and 256,000 bytes total;
- `timeout_seconds`: 1–60 seconds;
- `output`: one `project.artifact` with a safe path, media type, and `max_bytes` ≤ 64,000. The file
- `timeout_seconds`: 1–900 seconds, the package's wall-clock window (it also bounds each
model call's wait);
- `output`: one `project.artifact` with a safe path, media type, and `max_bytes` ≤ 1,000,000. The file
name may carry `{date}` and `{slug}` once each, so repeated runs keep separate, readable files.

`run` may be synchronous or asynchronous and returns exactly `{ "path": "…", "content": "…" }`.
Expand Down
39 changes: 35 additions & 4 deletions docs/codex-api-pilot.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,12 @@ token stops. The controller's observed-token stop is recorded as `token_limit` f
own usage frame. The relay logs each rejection with run, operation, status and reason
code (a 422 contract rejection names `operation_not_allowed`, `request_too_large` or
`contract_mismatch`), and only the status of an upstream rejection. It never logs request or provider
bodies. The controller also prints each agent narration line (not the structured result)
bodies. The first rejection of a running attempt is also stored on its attempt receipt in
Postgres as `relay_rejection` (`status`, a reason code such as `context_bound` for an
over-size request, the 422 codes above, `request_limit`, `token_limit`, `upstream_rejected`
with `upstream_status`, `stream_unconfirmed` or `relay_timeout`, the operation and the time).
Later refusals do not replace it, and the run's failure message names the code and status.
The controller also prints each agent narration line (not the structured result)
as a bounded `TIN_CODEX_PROGRESS` frame. The switchboard redacts run secrets and projects
the latest line to the run's `progress_summary` in Postgres, unless product code owns the
run's progress steps. It never enters Temporal. Payment-card runs skip it, as they skip
Expand Down Expand Up @@ -127,10 +132,36 @@ wrote a report. Their open-egress `browser_api` image and 1800-second timeout ar
unchanged; runs admitted earlier keep v3.
[Model limits](https://developers.openai.com/api/docs/models/gpt-6-sol).

### Contract v5: a bounded context and $10 sessions (October 2, 2026)

New admissions pin **`tin-codex-api-v5`**. It keeps v4's 128,000 output tokens per response
and 8 MiB requests, but the controller declares a 256,000-token context window and compacts
from 200,000 tokens. A request therefore stays near 200,000 tokens of context in ordinary
use, below the 272,000-token long-context price band; one large tool result can still exceed
it until the next compaction. Session-funded procedures (`SESSION_CONTRACT`) have no request
or lifetime-token stop, as in v4. Codex work that is not session-funded pins the same shape
with runaway stops (`PROCEDURE_CONTRACT_V5`): 256 requests and 8,000,000 observed tokens,
four times the most seen on v3 (64 requests, 2.04M tokens). That covers included Start here
setup children, other parent children, Studio, diagrams/video (whose images fit in any 8 MiB
v5 request, so the separate v3 diagram text bound is not carried over), `content.design_md`
and `project.task`. Their funding is unchanged: included work stays Tin-funded with no
customer reservation, and the others reserve per request. A v5 request reserves $1.93: its
256,000-token context as cache writes, 128,000 output tokens and one search call.

The default ceiling of a root Codex run is $10 for new admissions ($5 before; a child inside
a parent budget keeps $5, since parent pools were composed from $5 children); explicit smaller
ceilings such as `content-refresh.v1`'s $2.50 are unchanged. Runs and quotes admitted before
v5 keep v1-v4 and $5: a still-valid quote issued before v5 is admitted with exactly the terms
it showed. The controller image reads v5's window from its own protocol table, so deploying v5
needs rebuilt isolated, browser API and Studio API templates that answer
`codex_api_config.py --check-v5`; the runtime refuses to start a v5 run on an older image.
The opt-in `bounded_context` isolation probe forces the real CLI through v5 compaction.
Keep a v4-capable image for runs already pinned to v4.

Every contract named `gpt-6-astra` until 2026-09-23. Runs admitted before then keep
that pin; new runs use `gpt-6-sol`.

Tin authorizes the existing $5 session maximum once, internally holding those credits
Tin authorizes the session maximum ($10 from v5, $5 for v4) once, internally holding those credits
until settlement. Each request checks the run grant, project membership, current spending
policy and remaining budget, and records a durable intent. It does not predict prompt
cost, repeatedly price prior receipts or fund the shared wallet again. One request may
Expand All @@ -139,15 +170,15 @@ usage updates the existing operation and run total. Settlement charges once, rou
once, releases unused authority and preserves existing uncertain-usage reconciliation.
Compaction is an ordinary paid response in this same session.

The $5 maximum is a **hard customer-charge ceiling and a soft supplier-spend stop**.
The session maximum is a **hard customer-charge ceiling and a soft supplier-spend stop**.
A response admitted before the stop may exceed the remaining budget; Tin records and
absorbs the excess, then refuses further calls. This exposure can be material: 128,000
output tokens alone cost $6.40 at the pinned standard rate, or $9.60 in its long-context
band, before input/search charges. There is no claim of an absolute supplier invoice
cap. An interruption cannot undo already-accepted provider work. Changing this tradeoff
requires an explicit provider/operating policy, not an invented precise token estimate.

Only newly admitted ordinary root procedures select v4. Existing budgets and valid
When v4 shipped, only newly admitted ordinary root procedures selected it. Existing budgets and valid
quotes retain their auth, model, price and runtime pins. Included onboarding and its
children, other parent children, Studio, diagrams/video, design tasks, interactive
tasks and managed model steps keep their existing contracts. No data migration or
Expand Down
9 changes: 9 additions & 0 deletions docs/content-plan-editorial-quality.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,12 @@ The drafts read the same files: `content.generate` 1.8.0 lists them in its pinne
checkout, `content.answer_page` 1.6.0 receives them as sources (`ANSWER_POSITIONING_V1`) and
`content.refresh` pins them before compute. Each presents the product the way those files do.


## A larger output cap (content-editorial-v8)

`content.plan` 0.9.0 pins `content-editorial-v8`: v7 with a 32,000-token output cap instead of
16,000. GPT-6 Luna counts reasoning against the cap, and a cap only stops a plan; billing
charges the tokens the call actually used. Instructions, schema, page and input bounds are v7's.
At its bounds the call reads about 254,000 tokens and costs at most $0.088 at long-context
rates, still under the $0.10 the plan's $1 share in the organic system is sized from. Plans
pinned to v7 and older keep their caps.
4 changes: 2 additions & 2 deletions docs/content-refresh.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ new pages.
file changed.
- If a text is not in the source verbatim (a title built from a template, for example) or
appears in several places, delivery stops and says which text and why. It never guesses.
- Tin searches source files up to 512 KB. Images, video, fonts and built bundles over 2 MB
- Tin searches source files up to 512 KB. Images, video, fonts and built bundles over 10 MB
are left out of the snapshot and don't matter here. Any other file Tin couldn't read (a
source or data file over 2 MB, a link, a submodule) stops delivery, and the reason names
source or data file over 10 MB, a link, a submodule) stops delivery, and the reason names
it, because the page's text could live there.
- Several changed files land as one commit, so a failure never leaves main half changed.
- A retry after a failed delivery reads the current head when the failed attempt opened no
Expand Down
2 changes: 1 addition & 1 deletion docs/feature-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ inputs, prerequisites and supported schedule modes.
| Organic traffic system | The current parent (0.6.0, organic-traffic-v6) can plan, optionally fix what the audit found through website.change (`source: audit`; the rows wait for the founder), draft the next eligible planned item, wait for review/revisions and put the approved article on the site through website.change: merged once the required checks pass when approved with commit to main, otherwise a PR. It then saves a weekly schedule that drafts the next planned article, one review at a time. | GitHub delivery requires the selected connection. Without GitHub, or in draft-only mode, the approved Markdown remains in project Files. Runs pinned to v5 still use content.deliver and organic.technical_fix. Weekly drafts follow the program's delivery settings, not the parent's repository adaptation, and pause when the plan runs out or the next article needs the founder. Plan dates alone publish nothing. |
| Website changes | `website.change` puts an approved article, answer page or public article on the site at the founder's chosen route, fixes what the latest audit found (`source: audit`, site-fix-v5's rules), makes the redirects and noindex changes page decisions and the site plan made (`planned`), and applies the blog index plan (`blog_index`, no Codex session). Each audit fix, planned change or plan is a change row approved or declined once, in Decisions or over MCP. A page approved with commit to main, or approved rows, publish (Tin merges the PR once the repository's required checks pass, then checks the live site for fixes and redirects); anything else opens a PR. `preflight_website_change` previews each source and its judgment calls. See [website.change](website-change.md). | organic.technical_fix is hidden and kept for pinned runs; the traffic system's recipe still starts it. Deleting a page stays with the founder. The blog index source needs #239's content.blog_index planner; without its runs it says so. Agent-only. Protected paths are the shared auth pages, the project's protected pages (a setting with its history) and a per-run input. Fixture-tested; no live merge yet. |
| Content review | Read the draft, request changes in text, review a new revision and approve through dashboard or MCP. Generation notes stay separate from publishable copy. | Approval applies to the reviewed revision. PR delivery neither merges the PR nor publishes the website. |
| Saved schedules | Eligible definitions support daily or selected-weekday execution at a local time in an IANA timezone, with skip-overlap and bounded catch-up. | Not every workflow is schedulable. Paid scheduled occurrences need standing spending authority, not just a positive balance; hosted default policies include $10 per scheduled run. |
| Saved schedules | Eligible definitions support daily or selected-weekday execution at a local time in an IANA timezone, with skip-overlap and bounded catch-up. | Not every workflow is schedulable. Paid scheduled occurrences need standing spending authority, not just a positive balance; hosted default policies include $50 per scheduled run ($10 for projects created before October 2, 2026). |
| Locked dashboard for browser sign-ups | A project with no workflow or run yet shows a locked dashboard: rail dimmed, one page that sends the person to their coding agent with the install line. Agent connection links and callbacks can finish the requested account and resource setup while the dashboard stays locked. Unlocks on the next reload once a workflow or run exists. `TIN_LITE_BROWSER_LOCK_ENABLED=false` turns it off. | Browser onboarding does not exist yet; the lock stands in for it. |
| One-off tasks | `project.task` has its own conversation, questions, pause/resume and exact-diff review. | It is not a reusable private code workflow or a replacement for the shared workflow engine. |

Expand Down
2 changes: 1 addition & 1 deletion docs/isolated-codex-runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The provider key stays on the switchboard. Pooled ChatGPT authentication is reti
## Contract

- A pinned procedure may select `sandbox.profile: isolated` with fenced egress and the
existing 1–3600-second timeout contract. The switchboard must explicitly configure
existing 1–7200-second timeout contract (1–3600 before October 2, 2026). The switchboard must explicitly configure
`TIN_LITE_E2B_ISOLATED_TEMPLATE`; no missing-image fallback to the default is allowed.
- The separate `tin-lite-codex-isolated` image pins Codex CLI 0.156.1 and `gpt-6-sol`.
The controller uses Codex's native experimental exec-server environment to run command,
Expand Down
Loading