Commit Graph
1691 Commits
Author SHA1 Message Date
jschoubben d89a6bacc6 Merge branch 'feat/47-G-fix11-b1g' into feat/47-G-join11
# Conflicts:
#	modules/mesh-delivery-contracts/seats/mesh-pipeline-runner/seat.json
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline/main.go
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline/steps.go
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline/verbs.go
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline/verbs_test.go
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline/views.go
#	modules/mesh-delivery-pipeline/internal/pipeline/start.go
#	modules/mesh-delivery-pipeline/manifest_test.go
#	modules/mesh-delivery-pipeline/module.json
2026-11-12 10:32:18 +01:00
jschoubben 5db642e161 Merge branch 'feat/47-G-fix11-b1f' into feat/47-G-join11
# Conflicts:
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline-tools/main.go
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline-tools/main_test.go
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline/findingwriter.go
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline/main.go
#	modules/mesh-delivery-pipeline/cmd/mesh-delivery-pipeline/views.go
#	modules/mesh-delivery-pipeline/go.mod
#	modules/mesh-delivery-pipeline/internal/pipeline/read_test.go
#	modules/mesh-delivery-pipeline/internal/pipeline/start.go
#	modules/mesh-delivery-pipeline/manifest_test.go
#	modules/mesh-delivery-pipeline/module.json
2026-11-12 10:30:22 +01:00
jschoubben 4aaa805f2a Merge branch 'feat/47-G-fix11-b1e' into feat/47-G-join11 2026-11-12 10:28:34 +01:00
jschoubben 2bb1b273fe Merge branch 'feat/47-G-fix11-b6b' into feat/47-G-join11 2026-11-12 10:28:34 +01:00
jschoubben 2551d13cf3 Merge branch 'feat/47-G-fix11-b7' into feat/47-G-join11
# Conflicts:
#	.gitignore
2026-11-12 10:28:26 +01:00
jschoubben 1e00430eef Merge remote-tracking branch 'origin/main' into feat/47-G-join11
# Conflicts:
#	modules/mesh-delivery-indexer/judge/rules.go
#	modules/mesh-delivery-indexer/judge/rules_test.go
2026-11-12 10:28:05 +01:00
jschoubben bff7b402e7 B1g-5: the catalog's revision verb answers a candidate's group alone and a branch's source revision
Builds: design 47 G A-205, A-222
2026-11-12 06:19:07 +01:00
jschoubben ef28ac17f4 Merge commit '66df2aef' into feat/47-G-fix11-b1g 2026-11-12 06:17:52 +01:00
jschoubben 8e7b8ab1d1 B1g-4: an unanswered drop is said call-unanswered on its five-minute bound key's expiry
Builds: design 47 G A-222, A-77, §350
2026-11-12 06:17:05 +01:00
jschoubben cbb678f42e B1g-3: a run's rerun asks with the candidate's catalog half, not the branch's
Builds: design 47 G A-222, A-193, A-205
2026-11-12 06:15:38 +01:00
jschoubben 0cd1ab79e4 B1g-2: the runner at its start places each run's lost pipelines from its candidate's newest revision
Builds: design 47 G A-222, A-193, A-180, A-205
2026-11-12 06:15:01 +01:00
jschoubben a8314676c9 RN10 (widens): a pipeline's end names what its change widens, from the catalog's revisions and the grants part
The candidate (the pipeline's own revision) against the branch's newest through mesh-catalog's revision; serving parts by the holder of the runner's, catalog's, steps' and composer's seats; acting rules, credentials; grants through grants-for. A read that fails says could not run. Touches steps.go (Hearer.Widens field, say's pipeline-ended), main.go (hearer.Widens), module.json invokes.

Builds: design 47 G §71, §275, §335, §441, A-207, A-215, A-220

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:11:47 +01:00
jschoubben 50f3dde9f5 RN17 (show/kept fill): show and kept carry each store's fill, read through the bundle's calls
Builds: design 47 G §366, §623, A-214

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:07:59 +01:00
jschoubben d9a9da921a RN12: the runner runs on request, its pipelines placed from the run's candidate revision
run writes each member's pipeline at once under the run's random id and its named branch and says
run-started; the candidate run-<id>'s catalog-revision, handed to the runner by meshcatalogclient's
candidates hook, is read whole through the revision verb and places each member's steps and a pipeline
of each entry the members change, saying pipeline-started once each.

Builds: design 47 G §64, §373, §420, A-160, A-180, A-185, A-193, A-199

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:07:38 +01:00
jschoubben 9fed8edb50 A-206: the held wait's clock is the build.ended of the awaited runner, heard from the builder's stream
The runner hears the builder's stream of build ends (kept last per subject, read whole at its start, A-181: consumes
`mesh-delivery-builder.build.ended.**`) and keeps when each build ended, the stream's own time. wait-held carries it as
`clock-from`, the bound of the wait is armed from it (30 minutes less what passed), and a bound whose build has not ended is armed
when its end is heard, with wait-held said again. A failed end starts no clock.

Builds: design 47 G §266, §269, §703, A-181, A-206

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:05:29 +01:00
jschoubben 03ee0930e1 RN17 (unlogged): a step's end and its log entry are one write, appended after the end is said
The pipeline gains `unlogged`: a step's end is written in its key with its step-log entry in one compare-and-set, said as
step-ended, then appended to the step log and cleared; a log that refuses an append ends no step, says full and starts no new
pipeline; at its start the runner appends every unlogged entry in order after reading back the log's last entry of that
pipeline, and once a minute while the log is full. The tools runner_unlogged and runner_unlogged_append (a hand act).

Builds: design 47 G §486, §606, §549
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:03:08 +01:00
jschoubben a4fcf3de51 GR12: the seat mesh-grants claims its seat and serves grants-for
The part claims mesh-grants, serving grants-for: a run by its group run-<id> or a
source revision by the branch and the new optional source of mesh-catalog's
revision (contract regenerated), compared with the branch's newest by the
permissions the composed accounts gain and lose with the candidate's entries in.

Builds: design 47 G §401, §441, §449, A-205

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:02:44 +01:00
jschoubben 9fd2066711 A-206: the wait's on gains the value runner version
A pipeline held for the runner's new version says its wait-held and wait-ended on `runner version`, no longer on `build node`.
Contract (seat.json, regenerated by seatgen) gains the value.

Builds: design 47 G §534, §696, A-206

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:02:35 +01:00
jschoubben d44c45c9b9 A-206: the bound's expiry writes the finding pipeline-waits through the runner's finding writer
ReleaseExpired says each pipeline it started through the starter's Late, and the process writes the finding pipeline-waits
(scope module, id the pipeline's key `<branch>.<id>.<module>`) naming the awaited runner and since when.

Builds: design 47 G §266, §269, A-206

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:02:16 +01:00
jschoubben 56c45eb7d6 RN8: a newer commit or publish supersedes the older running pipeline, its asks dropped where they stand
A step keeps the node whose holder said ask-taken; a superseded step's drop is asked of that node's holder, an
untaken ask's of any holder, as kept calls; steps on mesh-builds and mesh-wants are only ended superseded. A
pipeline a publish started says that publish (published), so a newer publish of the package supersedes it.

Builds: design 47 G §31, §119, §350, A-182, A-202

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:01:44 +01:00
jschoubben 6635dda18f A-206: the seat verb release and the tool runner_release start the held pipelines by hand
The seat mesh-pipeline-runner gains the act verb `release` (why; answers how many it started) beside start and ask-again, its
hand act written first through mesh-hand-acts; each released wait ends `released` and its bound is dropped. The tool
runner_release asks the verb. Contract regenerated with seatgen.

Builds: design 47 G §276, §534, A-206 (A-195)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:01:22 +01:00
jschoubben 2a46134d14 RN22: a recovery's steps are asked on the build seats' stream delivery
The runner keeps each commit the seat mesh-delivery says a recovery merged in its state recoveries; a pipeline whose commit is
named there has its go, node and image steps asked on delivery.step, ahead of the first round, at its start, its resume and a
rerun; a recovery heard after its pipeline started asks nothing again.

Builds: design 47 G §81, §86, §415, A-207
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 06:00:36 +01:00
jschoubben 41ecd473da GR5: a module's sent store is read by the callers and consumers it is for
Derived at every pass from the catalog graph's manifests and the seat definitions'
callers, never from a manifest field.

Builds: design 47 G §59, §124, §442

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:59:54 +01:00
jschoubben 3eb07835f7 GR6: a state's <state>-objects store is granted to the state's owner alone
Builds: design 47 G §58, §91

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:59:50 +01:00
jschoubben edc8bbd9ab §7, §428 (watchman): a bus user is said by its module's name, the tool runner's no differently
signals.go BusUserWords: the node-tools special word is gone (the node-engine's node.<node> user stays, a bus account form, not a
module name). The watchman's ControlNodeModule (signals.go:591, nats) and builderModule (names.go:17) went with A-197 and WM13.

Builds: design 47 G §7, §428

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:59:49 +01:00
jschoubben e0b4f73c9e RN17 (fill): the runner says its stores' fill and a full store refuses a start
The seat gains the events filling, full and room; at each step's end and each start the runner reads the fill of pipelines,
step-outputs, kept and step-log against their caps, says filling past 80 %, full at the cap and room below 70 %, and a start
while a store is full is refused, said in the journal and heard again by the bus.

Builds: design 47 G §366, §181
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:59:18 +01:00
jschoubben 3eca094c5c A-197: the watchman reads no node-engine state: have and health go, running ends a want's pulse
Removed with the reads of node-engine.have and mesh-host.health: the findings module-unhealthy (module <module>.<node>, token
unhealthy, urgent after four hours), kept-as-it-runs (module <module>.<node>, token kept), apply-failing from a have that failed
(machine <node>; the provisioner clients' half stays), machine-network, network-rewritten, network-unreachable, machine-units,
relogin-needed, directory-used-as-found, node-account-fallback, and the urgency of a silent control node. A want's pulse now ends on
the node-engine's running event (consumes node-engine.running).

Builds: design 47 G A-197, A-192, §541

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:58:55 +01:00
jschoubben 6182730923 GR2: grants_callers and grants_why_refused
The first reads the callers each verb and accepted kind of the seat definitions
admits, the second says which call subject an account lacks (the bus's own
nats_user_can) beside the definition's callers.

Builds: design 47 G §83, §391, §395

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:58:25 +01:00
jschoubben e053605e82 RN19, RN21: the pipelines of a change to the runner are held until its new version runs healthy
The seat's pipeline record gains `held` (since, the fingerprint awaited). A take-in giving the runner's own module a new
fingerprint holds every pipeline it starts, and a later take-in's while any is held; wait-held (step pipeline) is said, the
30-minute bound is a key of the state bounds. The node-engine seat's running of the runner's module at the awaited
fingerprint, healthy, or the bound's expiry, releases them: steps placed and asked, wait-ended and pipeline-started said. A
runner starting at the awaited fingerprint releases at its start. runner_waits lists the held pipelines.

Builds: design 47 G §65, §266, §276, §534, §19 (lead answer A-195)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:57:05 +01:00
jschoubben d68e6b877d RN16: the runner ages its own kept data by its own deletes, in the step log's order
Three step-log sequences in the state aged, one per retention (7, 30, 90 days); at each step's end up to 20 entries per
sequence past their retention delete the output and the pipeline (7 days), a kept result not read for 30 days (30 days) and a
passed pipeline (90 days), never a pipeline that is its branch's newest; each delete is a journal line. The step log is
written to and read from the log's stream (design 47 G §470); a log entry names the kept results it wrote or carried and a
kept result its last read.

Builds: design 47 G §330, §410, §470
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:56:54 +01:00
jschoubben 161d6e6451 WM16: a record is covered only by what is late for the entries of its own revision
record-opened is joined to the take-in.taken of its milestone, <branch>.<source revision>, whose entries name the modules; the
record-open finding is left unwritten only while one of those modules is held by an acting-part-late wait (or a store says full),
no longer while any wait is late. A record whose revision is not known taken is covered by a standing take-in-waits.

Builds: design 47 G §502, A-200

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:56:33 +01:00
jschoubben f8bae4bee8 GR13: a build seat's queues take named asks beside main's, each asker granted its own
Each queue gets a named worker filtered to accept.<queue>.*; an asker is granted
accept.<queue>.<its seat> for the queues of the kinds it is a caller of, read from
the definitions' callers lists; main's accept.<queue> is the checker's and the
builder's alone. The purge of named subjects and workers (grants_named_purge) is
not in this commit.

Builds: design 47 G §543, §544, §600, §601, A-163, A-170, A-184

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:56:06 +01:00
jschoubben 1abc5ae6d9 WM9, WM15: the manifest findings are the indexer's verdicts heard as events
manifest-refused raises manifest-refused; manifest-accepted, which carries problems, raises manifest-outgrown or clears it
and any refusal; the start seeds both from indexer_verdicts. The indexer's modules view (ModuleVerdict, views.modules,
indexer_read_modules) is no longer followed, and manifest-waits is no longer written (§500).

Builds: design 47 G §500, §196, §668

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:55:02 +01:00
jschoubben faec6b5333 WM13 (watchman half): the builder's builds are no longer read; a package wait is heard as wait-held
The watchman's read of mesh-delivery-builder.builds (Build in mirror.go, the bucket, its manifest reads) goes; it hears the
builder's wait-held and wait-ended on the builder's stream, naming a package as their part, and times them as an acting
part's wait. A toolchain wait (no part) is left to the builder's own finding. The node-engine's have and mesh-host.health
reads stay: no event carries a have's phase, kept data, node record or a node's health report (asked of the lead).

Builds: design 47 G A-192, §484, §496, §602, §548

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:53:23 +01:00
jschoubben 267bd0a9cb RN11: the runner says a failed head as the finding pipeline-failed
A required step that failed or could not run writes the finding of its commit, owned by the commit's author as the forge
records it (read through the seat git's pull); one with no known author has no owner and says why, written at the next step
end of that commit; a newer revision passing the steps clears it. The runner's finding writer is the held writer.

Builds: design 47 G §33, §540, A-191
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:53:20 +01:00
jschoubben 6676b42dab RN5: an empty approval status is no step and asks the operator nothing
Builds: design 47 G §553, §23, §26 (lead answer A-196)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:53:07 +01:00
jschoubben 524fbb02ef WM13 (builder half): a key queued behind a package says wait-held and wait-ended in the one wait form
The builder says wait-held for a key queued behind a package, the package as its part and on (package:<ref>), on its
stream waits, and wait-ended published once the key is claimed; a toolchain wait never ends by that, and a package wait
never by a toolchain's end. Files: internal/build/waits.go (Package, On, WaitPublished), internal/build/run.go (Hold at
the queued result, End at the claim), cmd/mesh-delivery-builder/waits.go (Part in the body, the End rule).

Builds: design 47 G A-192, §499

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:52:10 +01:00
jschoubben e5c864c246 RN9: pipeline-ended carries test counts and over-budget; group-ended says a group's end
pipeline-ended carries the module's test counts (the sum of its steps') and over-budget
past 500 unit or 50 integration tests; once every member of a group on a watched branch's
source revision ended, group-ended is said under the group.

Builds: design 47 G §24, §73, §332, §419

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:51:33 +01:00
jschoubben 8953adad88 RN5: a step whose status a policy leaves empty is optional and runs
A step neither the artifact's nor the module's policy names is placed as an optional step
(Status returns optional), no longer no step; a failure of it holds nothing.

Builds: design 47 G §553, §23, §32, §535

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:50:24 +01:00
jschoubben 62de8d0bb8 WM4, WM5: the watchman hears the node-engine's wait-held and wait-ended
A hold of the composition standing past 30 minutes is delivery-waits (node, module, reason), a wait for a kept build
past 60 minutes is kept-build-waits; each clears on wait-ended. The node-engine's version is not yet named in them
(it needs the catalog entry of the fingerprint running.<node>.<node-engine's module> names).

Builds: design 47 G §499, §541, §271, §376

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:49:48 +01:00
jschoubben f3c35722d9 AM-D2: the grants part's own copy of the wire pattern goes
A reader turns a stream's events into the bus's subjects with mesh-sdk's
buscompose.WirePattern; the grants part's copy goes. The catalog graph
entry already carries the validated manifest whole, its needs-approval,
emits and streams with their grant among it (design 47 G §443).

Builds: design 46 7-approval-mark §5

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:48:49 +01:00
jschoubben 464206d2de WM1 (step half): a head behind a pending revision of its branch raises no pipeline-stands
The watchman keeps the watched branch each open take-in wait names (take-in.pending's branch) and times a head only
while its branch has none; once the revision is taken in the head is timed again from its own move. The head on a
branch whose branch-unprotected stands (§497's second sentence) is not built: nothing the watchman hears says it
(the forge bridge writes that finding, no event).

Builds: design 47 G §12, §75, §497

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:48:30 +01:00
jschoubben 58e4a737d5 AM-D5: a per-machine state reaches its machine's keys below it
A per-machine state's account reaches its machine's key and the keys
below it (mesh-sdk PerMachineKeys), no other machine's, so the tool
runner's approvals keep <node>.ask.<id> and <node>.act.<digest>; the
membership names the machine's key in the same form.

Builds: design 46 7-approval-mark §13

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:48:17 +01:00
jschoubben 558a93c25b AM-D1: the validator refuses a mark nothing enforces
A manifest marking a tool its tools do not list, a verb its claims do not
serve or an event it does not carry, one name both a tool and an event, a
marked tool or verb (or a held seat verb its seat marks) without
operator-channel in uses, or a marked tool or verb while every bundle it
builds is run by its own process, is refused by both paths, naming the
entry and the rule. The login shell's captured manifest is copied at
AM-K1, which gives it operator-channel.

Builds: design 46 7-approval-mark §4, §7, §21; design 34 every-event §32; lead answers A-177, A-183

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:46:16 +01:00
jschoubben d6c1e27259 Merge branch 'feat/47-G-fix11-b5b' into feat/47-G-fix11-b7 2026-11-12 05:43:07 +01:00
jschoubben 4b47e88369 RN25: runner_health reads the consumer facts mesh-sdk's ledger writes
The runner's own writer of its consumer's oldest unacknowledged delivery is
replaced by mesh-sdk's consumer ledger: each message the hub hands a handler is
noted delivered, and applied when the handler acknowledges or ends it; one it
asks again stays unacknowledged. The key form is the same, a key per consumer
by its name in the state consumers. A runner that heard no event yet is healthy.

Builds: design 47 G §76, §468, §495; lead answers A-166, A-176

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:42:33 +01:00
jschoubben 459c03933c TL1: the teller's integration bed grants and creates the state widens-said
Builds: design 47 G §335
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:41:38 +01:00
jschoubben 9199bb20f4 RN14: the runner serves start and ask-again
start starts by hand the pipeline of a watched branch's head from the runner's
catalog half, refusing a head already started; ask-again asks a declined
approval once more under an ask of its own, its id following from when it was
asked again so the ask rebuilt for its warrant is the same. Each is recorded in
the hand-act log first; the process answers both beside review, rerun, accept
and cancel.

Builds: design 47 G §30, §39, §306, §36, §394

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:41:03 +01:00
jschoubben 893f425c56 WM14: a put without hold that stands is the finding put-stands
A wait held with step put (no part) raises put-stands once its bound has run from its clock, and wait-ended ends it; a pipeline's
wait raises nothing for it. The seed from assigner_puts waits on that tool answering since and bound (assigner's, not built here).

Builds: design 47 G §498
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:39:03 +01:00
jschoubben 7ce80ce590 EE-D4: the validator has no rule about the waits list
The manifest no longer carries what a session waits on (mesh-sdk EE-S2), so
the rule judging it and its token form go; a manifest still carrying waits
is a field the validator does not know, refused by Shelf and set aside by
ShelfWaiting, and the tool runner's manifest without it is accepted.

Builds: design 34 every-event §10

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 05:38:52 +01:00